From ba190bb6a9b3db191915faaddd84b5c69244dedd Mon Sep 17 00:00:00 2001 From: Remi <remi@le-filament.com> Date: Tue, 23 Apr 2019 14:54:50 +0200 Subject: [PATCH] Fix coding according to standards --- LICENSE | 29 +--- __init__.py | 3 +- __manifest__.py | 52 +++--- models/__init__.py | 3 +- models/project.py | 264 ++++++++++++++++++++---------- static/src/js/cash_flow.js | 4 +- static/src/xml/cash_flow.xml | 49 +++--- views/assets.xml | 8 +- views/lefilament_projets_view.xml | 60 +++---- 9 files changed, 264 insertions(+), 208 deletions(-) diff --git a/LICENSE b/LICENSE index 7e5dad2..fb0e255 100644 --- a/LICENSE +++ b/LICENSE @@ -200,31 +200,4 @@ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY C If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. -END OF TERMS AND CONDITIONS - -How to Apply These Terms to Your New Programs - -If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. - -To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -Also add information on how to contact you by electronic and paper mail. - -If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a "Source" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements. - -You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see <https://www.gnu.org/licenses/>. \ No newline at end of file +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/__init__.py b/__init__.py index a5e7e1d..b44d765 100644 --- a/__init__.py +++ b/__init__.py @@ -1,3 +1,4 @@ # -*- coding: utf-8 -*- +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -import models \ No newline at end of file +from . import models diff --git a/__manifest__.py b/__manifest__.py index 7abf96f..c623a78 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -1,35 +1,37 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { - 'name': 'Le Filament - Cash Flow project', + 'name': 'Le Filament - Cash Flow project', - 'summary': """ + 'summary': """ Cash Flow project Le Filament""", - 'version': '10.0.1.0', - 'license': 'AGPL-3', - 'description': """ - - Module Cash Flow Project Le Filament + 'version': '10.0.1.0.0', + 'license': 'AGPL-3', + 'description': """ - This module depends upon *lefilament_projets* module. + Module Cash Flow Project Le Filament - This module provides: - - the project cash flow graph - """, - - 'author': 'LE FILAMENT', - 'category': 'Project', - 'depends': ['lefilament_projets'], - 'contributors': [ + This module depends upon *lefilament_projets* module. + + This module provides: + - the project cash flow graph + """, + + 'author': 'LE FILAMENT', + 'category': 'Project', + 'depends': ['lefilament_projets'], + 'contributors': [ 'Benjamin Rivier <benjamin@le-filament.com>', - 'Rémi Cazenave <remi@le-filament.com>', - 'Juliana Poudou <juliana@le-filament.com>', + 'Rémi Cazenave <remi@le-filament.com>', + 'Juliana Poudou <juliana@le-filament.com>', + ], + 'website': 'https://le-filament.com', + 'data': [ + 'views/assets.xml', + 'views/lefilament_projets_view.xml', ], - 'website': 'https://le-filament.com', - 'data': [ - 'views/assets.xml', - 'views/lefilament_projets_view.xml', - ], - 'qweb': [ - 'static/src/xml/*.xml', + 'qweb': [ + 'static/src/xml/*.xml', ], } diff --git a/models/__init__.py b/models/__init__.py index ba24131..c75f263 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -1,3 +1,4 @@ # -*- coding: utf-8 -*- +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -import project \ No newline at end of file +from . import project diff --git a/models/project.py b/models/project.py index 472f86d..20b2c65 100644 --- a/models/project.py +++ b/models/project.py @@ -3,10 +3,9 @@ # © 2017 Le Filament (<http://www.le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from datetime import datetime, date -import time -from odoo import tools -from odoo import models, fields, api, osv +from datetime import datetime +from odoo import models, fields, api + class FilamentProjetCashFlow(models.Model): _inherit = 'project.project' @@ -16,63 +15,94 @@ class FilamentProjetCashFlow(models.Model): lf_advance = fields.Float('Advanced cash', compute='_advance') lf_balance = fields.Float('Current balance', compute='_balance') - ## Time to first invoice + # Time to first invoice @api.one def _delay(self): account_id = self.analytic_account_id.id - prospection_tasks = self.env['project.task'].search([('name','=ilike','Prospection'+'%'),('project_id','=',self.id)]).ids + prospection_tasks = self.env['project.task'].search( + [('name', '=ilike', 'Prospection'+'%'), + ('project_id', '=', self.id)]).ids if not prospection_tasks: self.env.cr.execute(""" - SELECT date - FROM account_analytic_line - where account_id=%s and project_id is not null order by date - ;""", (account_id, ) ) + SELECT date + FROM account_analytic_line + WHERE account_id=%s AND project_id IS NOT NULL + ORDER BY date + ;""", (account_id, )) else: self.env.cr.execute(""" - SELECT date - FROM account_analytic_line - where account_id=%s and (task_id not in %s or task_id is null) and project_id is not null order by date - ;""", (account_id, tuple(prospection_tasks), ) ) - + SELECT date + FROM account_analytic_line + WHERE account_id=%s AND (task_id not IN %s OR task_id IS NULL) + AND project_id IS NOT NULL + ORDER BY date + ;""", (account_id, tuple(prospection_tasks), )) + d_cost = self.env.cr.fetchall() self.env.cr.execute(""" - SELECT date - FROM account_analytic_line - where account_id=%s and project_id is null and ref is null order by date limit 1 - ;""", (account_id, ) ) + SELECT date + FROM account_analytic_line + WHERE account_id=%s AND project_id IS NULL AND ref IS NULL + ORDER BY date LIMIT 1 + ;""", (account_id, )) d_invoice = self.env.cr.fetchone() if d_cost: if d_invoice: - self.lf_delay = (datetime.strptime(d_invoice[0], "%Y-%m-%d").date() - datetime.strptime(d_cost[0][0], "%Y-%m-%d").date()).days + self.lf_delay = ( + datetime.strptime(d_invoice[0], "%Y-%m-%d").date() + - datetime.strptime(d_cost[0][0], "%Y-%m-%d").date() + ).days else: - self.lf_delay = (datetime.strptime(d_cost[-1][0], "%Y-%m-%d").date() - datetime.strptime(d_cost[0][0], "%Y-%m-%d").date()).days + self.lf_delay = ( + datetime.strptime(d_cost[-1][0], "%Y-%m-%d").date() + - datetime.strptime(d_cost[0][0], "%Y-%m-%d").date() + ).days else: self.lf_delay = 0 - ## Total Days + # Total Days @api.one def _total_days(self): account_id = self.analytic_account_id.id - prospection_tasks = self.env['project.task'].search([('name','=ilike','Prospection'+'%'),('project_id','=',self.id)]).ids + prospection_tasks = self.env['project.task'].search( + [('name', '=ilike', 'Prospection'+'%'), + ('project_id', '=', self.id)] + ).ids if not prospection_tasks: self.env.cr.execute(""" - SELECT - date(d_last) - date(d_first) as datediff - from - (select date FROM account_analytic_line where account_id=%s and project_id is not null order by date limit 1) as d_first, - (select date FROM account_analytic_line where account_id=%s and project_id is not null order by date desc limit 1) as d_last - ;""", (account_id, account_id, ) ) + SELECT date(d_last) - date(d_first) AS datediff + FROM + (SELECT date + FROM account_analytic_line + WHERE account_id=%s AND project_id IS NOT NULL + ORDER BY date LIMIT 1) AS d_first, + (SELECT date + FROM account_analytic_line + WHERE account_id=%s AND project_id IS NOT NULL + ORDER BY date DESC LIMIT 1) AS d_last + ;""", (account_id, account_id, )) else: - self.env.cr.execute(""" - SELECT - date(d_last) - date(d_first) as datediff - from - (select date FROM account_analytic_line where account_id=%s and (task_id not in %s or task_id is null) and project_id is not null order by date limit 1) as d_first, - (select date FROM account_analytic_line where account_id=%s and (task_id not in %s or task_id is null) and project_id is not null order by date desc limit 1) as d_last - ;""", (account_id, tuple(prospection_tasks), account_id, tuple(prospection_tasks), ) ) - + self.env.cr.execute( + """ + SELECT date(d_last) - date(d_first) AS datediff + FROM + (SELECT date FROM account_analytic_line + WHERE account_id=%s + AND (task_id not IN %s OR task_id IS NULL) + AND project_id IS NOT NULL + ORDER BY date LIMIT 1) AS d_first, + (SELECT date FROM account_analytic_line + WHERE account_id=%s + AND (task_id not IN %s OR task_id IS NULL) + AND project_id IS NOT NULL + ORDER BY date DESC LIMIT 1) AS d_last + ;""", + (account_id, tuple(prospection_tasks), + account_id, tuple(prospection_tasks), ) + ) + lf_total_days = self._cr.fetchone() if lf_total_days: @@ -80,57 +110,87 @@ class FilamentProjetCashFlow(models.Model): else: self.lf_total_days = 0 - ## Balance + # Balance @api.one def _balance(self): account_id = self.analytic_account_id.id - prospection_tasks = self.env['project.task'].search([('name','=ilike','Prospection'+'%'),('project_id','=',self.id)]).ids + prospection_tasks = self.env['project.task'].search( + [('name', '=ilike', 'Prospection'+'%'), + ('project_id', '=', self.id)]).ids if not prospection_tasks: self.env.cr.execute(""" - SELECT sum(amount) as Total + SELECT SUM(amount) AS Total FROM account_analytic_line WHERE account_id=%s - ;""", (account_id, ) ) + ;""", (account_id, )) self.lf_balance = self._cr.fetchone()[0] else: self.env.cr.execute(""" - SELECT sum(amount) as Total + SELECT SUM(amount) AS Total FROM account_analytic_line - WHERE account_id=%s and (task_id not in %s or task_id is null) - ;""", (account_id, tuple(prospection_tasks), ) ) + WHERE account_id=%s AND (task_id not IN %s OR task_id IS NULL) + ;""", (account_id, tuple(prospection_tasks), )) self.lf_balance = self._cr.fetchone()[0] - ## Advance cash + # Advance cash @api.one def _advance(self): account_id = self.analytic_account_id.id - prospection_tasks = self.env['project.task'].search([('name','=ilike','Prospection'+'%'),('project_id','=',self.id)]).ids + prospection_tasks = self.env['project.task'].search( + [('name', '=ilike', 'Prospection'+'%'), + ('project_id', '=', self.id)]).ids if not prospection_tasks: - self.env.cr.execute(""" - SELECT sum(amount) as Total + self.env.cr.execute( + """ + SELECT SUM(amount) AS Total FROM account_analytic_line - WHERE account_id=%s - and date < (case when - (select date FROM account_analytic_line where account_id=%s and project_id is null and ref is null order by date limit 1) IS NOT NULL then - (select date FROM account_analytic_line where account_id=%s and project_id is null and ref is null order by date limit 1) else current_date end - );""", (account_id, account_id, account_id, ) ) + WHERE account_id=%s AND date < + (CASE WHEN + (SELECT date FROM account_analytic_line + WHERE account_id=%s + AND project_id IS NULL + AND ref IS NULL + ORDER BY date LIMIT 1) IS NOT NULL + THEN + (SELECT date FROM account_analytic_line + WHERE account_id=%s + AND project_id IS NULL + AND ref IS NULL + ORDER BY date LIMIT 1) + ELSE current_date + END); + """, + (account_id, account_id, account_id, )) else: - self.env.cr.execute(""" - SELECT sum(amount) as Total + self.env.cr.execute( + """ + SELECT SUM(amount) AS Total FROM account_analytic_line - WHERE account_id=%s - and date < (case when - (select date FROM account_analytic_line where account_id=%s and project_id is null and ref is null order by date limit 1) IS NOT NULL then - (select date FROM account_analytic_line where account_id=%s and project_id is null and ref is null order by date limit 1) else current_date end - ) and (task_id not in %s or task_id is null);""", (account_id, account_id, account_id, tuple(prospection_tasks), ) ) + WHERE account_id=%s AND date < + (CASE WHEN + (SELECT date FROM account_analytic_line + WHERE account_id=%s + AND project_id IS NULL + AND ref is NULL + ORDER BY date LIMIT 1) IS NOT NULL + THEN + (SELECT date FROM account_analytic_line + WHERE account_id=%s + AND project_id IS NULL + AND ref IS NULL + ORDER BY date LIMIT 1) + ELSE current_date + END) + AND (task_id NOT IN %s OR task_id IS NULL); + """, + (account_id, account_id, account_id, + tuple(prospection_tasks), )) self.lf_advance = self._cr.fetchone()[0] - #################################################### - ### Actions ### + # Actions # #################################################### - def open_cash_flow(self): return { 'type': 'ir.actions.client', @@ -144,60 +204,82 @@ class FilamentProjetCashFlow(models.Model): } #################################################### - ### Widget Function ### + # Widget Function # #################################################### @api.model def cash_flow(self, account_id, project_id): - account = self.env['account.analytic.account'].search([('id', '=', account_id)]) + account = self.env['account.analytic.account'].search( + [('id', '=', account_id)]) project = self.env['project.project'].search([('id', '=', project_id)]) - - ## Analytic account name + + # Analytic account name nom = account.name - ## Cash Flow Request - prospection_tasks = self.env['project.task'].search([('name','=ilike','Prospection'+'%'),('project_id','=',project_id)]).ids + # Cash Flow Request + prospection_tasks = self.env['project.task'].search( + [('name', '=ilike', 'Prospection'+'%'), + ('project_id', '=', project_id)]).ids if not prospection_tasks: - self.env.cr.execute(""" - SELECT date, sum(sum(amount)) over (order by date) as Total, - sum(sum(case when project_id is not null then amount else 0 end)) over (order by date) as Timesheet, - sum(sum(case when project_id is null and ref is not null then amount else 0 end)) over (order by date) as Fournisseurs, - sum(sum(case when project_id is null and ref is null then amount else 0 end)) over (order by date) as Clients + self.env.cr.execute( + """ + SELECT date, + SUM(SUM(amount)) OVER (ORDER BY date) AS Total, + SUM(SUM(CASE WHEN project_id IS NOT NULL + THEN amount ELSE 0 END)) + OVER (ORDER BY date) AS Timesheet, + SUM(SUM(CASE WHEN project_id IS NULL AND ref IS NOT NULL + THEN amount ELSE 0 END)) + OVER (ORDER BY date) AS Fournisseurs, + SUM(SUM(CASE WHEN project_id IS NULL AND ref IS NULL + THEN amount ELSE 0 END)) + OVER (ORDER BY date) AS Clients FROM account_analytic_line WHERE account_id=%s - group by date; - """, (account_id, ) ) + GROUP BY date; + """, (account_id, )) else: - self.env.cr.execute(""" - SELECT date, - sum(sum(case when (task_id not in %s or task_id is null) then amount else 0 end)) over (order by date) as Total, - sum(sum(case when project_id is not null and (task_id not in %s or task_id is null) then amount else 0 end)) over (order by date) as Timesheet, - sum(sum(case when project_id is null and ref is not null then amount else 0 end)) over (order by date) as Fournisseurs, - sum(sum(case when project_id is null and ref is null then amount else 0 end)) over (order by date) as Clients + self.env.cr.execute( + """ + SELECT date, + SUM(SUM(CASE WHEN (task_id NOT IN %s OR task_id IS NULL) + THEN amount ELSE 0 END)) + OVER (ORDER BY date) AS Total, + SUM(SUM(CASE WHEN project_id IS NOT NULL + AND (task_id not in %s or task_id IS NULL) + THEN amount ELSE 0 END)) + OVER (ORDER BY date) AS Timesheet, + SUM(SUM(CASE WHEN project_id IS NULL AND ref IS NOT NULL + THEN amount ELSE 0 END)) + OVER (ORDER BY date) AS Fournisseurs, + SUM(SUM(CASE WHEN project_id IS NULL AND ref IS NULL + THEN amount ELSE 0 END)) + OVER (ORDER BY date) AS Clients FROM account_analytic_line WHERE account_id=%s - group by date; - """, (tuple(prospection_tasks), tuple(prospection_tasks), account_id, ) ) + GROUP BY date; + """, + (tuple(prospection_tasks), tuple(prospection_tasks), + account_id, )) cash_flow = self._cr.dictfetchall() - ## Time to first invoice + # Time to first invoice delay = project.lf_delay - ## Total Days + # Total Days total_days = project.lf_total_days - ## Balance + # Balance balance = project.lf_balance - ## Advance cash - advance = project.lf_advance + # Advance cash + advance = project.lf_advance return { - 'nom' : nom, + 'nom': nom, 'cash_flow': cash_flow, 'delay': delay, 'balance': balance, 'advance': advance, 'total_days': total_days, } - diff --git a/static/src/js/cash_flow.js b/static/src/js/cash_flow.js index 55535d1..3f88f53 100644 --- a/static/src/js/cash_flow.js +++ b/static/src/js/cash_flow.js @@ -1,5 +1,5 @@ -// # © 2017 Le Filament (<http://www.le-filament.com>) -// # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +// © 2017 Le Filament (<http://www.le-filament.com>) +// License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). odoo.define('lefilament_cash_flow.cashFlow', function(require) { 'use strict'; diff --git a/static/src/xml/cash_flow.xml b/static/src/xml/cash_flow.xml index 2a7a3ef..3cbb0b9 100644 --- a/static/src/xml/cash_flow.xml +++ b/static/src/xml/cash_flow.xml @@ -1,29 +1,26 @@ <?xml version="1.0" encoding="UTF-8"?> <templates xml:space="preserve"> - - <t t-name="CashFlow"> - <div class="card"> - <table class="table"> - <thead> - <tr> - <th>Current balance</th> - <th>Project duration</th> - <th>Delay 1st facture</th> - <th>Advanced cash</th> - </tr> - </thead> - <tbody> - <tr> - <td><t t-esc="widget.render_monetary(widget.balance)"></t></td> - <td><t t-esc="widget.total_days"></t> days</td> - <td><t t-esc="widget.delay"></t> days</td> - <td><t t-esc="widget.render_monetary(widget.advance)"></t></td> - </tr> - </tbody> - </table> - <canvas id="cash_flow" width="auto" height="100"></canvas> - </div> - </t> - - + <t t-name="CashFlow"> + <div class="card"> + <table class="table"> + <thead> + <tr> + <th>Current balance</th> + <th>Project duration</th> + <th>Delay 1st facture</th> + <th>Advanced cash</th> + </tr> + </thead> + <tbody> + <tr> + <td><t t-esc="widget.render_monetary(widget.balance)"></t></td> + <td><t t-esc="widget.total_days"></t> days</td> + <td><t t-esc="widget.delay"></t> days</td> + <td><t t-esc="widget.render_monetary(widget.advance)"></t></td> + </tr> + </tbody> + </table> + <canvas id="cash_flow" width="auto" height="100"></canvas> + </div> + </t> </templates> \ No newline at end of file diff --git a/views/assets.xml b/views/assets.xml index d0943f1..d2fb65a 100644 --- a/views/assets.xml +++ b/views/assets.xml @@ -1,14 +1,14 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2017 Le Filament (<https://www.le-filament.com>) + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> + <odoo> <data> - <template id="lefilament_tdb_assets_backend" inherit_id="web.assets_backend"> <xpath expr="." position="inside"> - <script type="text/javascript" src="/lefilament_cash_flow/static/src/lib/chart.js"></script> + <script type="text/javascript" src="/lefilament_cash_flow/static/src/lib/chart.js"></script> <script type="text/javascript" src="/lefilament_cash_flow/static/src/js/cash_flow.js"></script> - </xpath> </template> - </data> </odoo> diff --git a/views/lefilament_projets_view.xml b/views/lefilament_projets_view.xml index 584f358..8f3f066 100644 --- a/views/lefilament_projets_view.xml +++ b/views/lefilament_projets_view.xml @@ -1,34 +1,34 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2017 Le Filament (<https://www.le-filament.com>) + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> <odoo> - <data> - - <!-- Project Form --> - <record id="view_form_lefilament_cashflow_form_inherited" model="ir.ui.view"> - <field name="name">Le Filament Projets Cash Flow</field> - <field name="model">project.project</field> - <field name="inherit_id" ref="lefilament_projets.view_form_lefilament_project_form_inherited"/> - <field name="arch" type="xml"> - <xpath expr="//sheet" position="before"> - <header> - <button string="See the Cash Flow" type="object" name="open_cash_flow" class="oe_highlight"/> - </header> - </xpath> - <xpath expr="//notebook" position="before"> - <group> - <group> - <field name="lf_total_days" /> - <field name="lf_balance" widget="monetary" options="{'currency_field': 'company_currency'}" /> - </group> - <group> - <field name="lf_delay" /> - <field name="lf_advance" widget="monetary" options="{'currency_field': 'company_currency'}" /> - </group> - </group> - <div class="clearfix"></div> - </xpath> - </field> - </record> - - </data> + <data> + <!-- Project Form --> + <record id="view_form_lefilament_cashflow_form_inherited" model="ir.ui.view"> + <field name="name">Le Filament Projets Cash Flow</field> + <field name="model">project.project</field> + <field name="inherit_id" ref="lefilament_projets.view_form_lefilament_project_form_inherited"/> + <field name="arch" type="xml"> + <xpath expr="//sheet" position="before"> + <header> + <button string="See the Cash Flow" type="object" name="open_cash_flow" class="oe_highlight"/> + </header> + </xpath> + <xpath expr="//notebook" position="before"> + <group> + <group> + <field name="lf_total_days" /> + <field name="lf_balance" widget="monetary" options="{'currency_field': 'company_currency'}" /> + </group> + <group> + <field name="lf_delay" /> + <field name="lf_advance" widget="monetary" options="{'currency_field': 'company_currency'}" /> + </group> + </group> + <div class="clearfix"></div> + </xpath> + </field> + </record> + </data> </odoo> -- GitLab