From 63b98de217b02b4aad97be16655d83a6898cfa0e Mon Sep 17 00:00:00 2001 From: Remi <remi@le-filament.com> Date: Wed, 20 Feb 2019 11:58:27 +0100 Subject: [PATCH] Align coding rules --- __manifest__.py | 12 +- models/hr_employee.py | 7 +- models/lefilament_tdb.py | 415 ++++++++++++++++++++++++++++----------- models/res_company.py | 37 ++-- 4 files changed, 328 insertions(+), 143 deletions(-) diff --git a/__manifest__.py b/__manifest__.py index d6db749..566f296 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -7,26 +7,26 @@ 'description': """ Tableaux de Bord Le Filament - Affichage de tableaux de bord : + Affichage de tableaux de bord : - suivi annuel Factures/Commandes/Pipe et Trésorerie - tableau des performances mensuelles - graphe de la tésorerie sur 1 an glissant - prévisionnel de la trésorerie sur 6 mois - + """, 'author': "LE FILAMENT", 'category': 'dashboard', - 'website': "http://www.le-filament.com", - 'version': '10.0.1', + 'website': "https://le-filament.com", + 'version': '12.0.1.0.0', 'license': 'AGPL-3', - 'depends': ['crm','account','hr_expense'], + 'depends': ['account', 'crm', 'hr_expense', 'sale'], 'data': [ 'security/lefilament_dashboard_security.xml', 'security/ir.model.access.csv', 'views/assets.xml', 'views/views.xml', 'views/schedule.xml', - 'data/ir_module_category.xml' + 'data/ir_module_category.xml' ], 'qweb': [ 'static/src/xml/*.xml', diff --git a/models/hr_employee.py b/models/hr_employee.py index 1a5bca9..a6fb569 100644 --- a/models/hr_employee.py +++ b/models/hr_employee.py @@ -3,8 +3,9 @@ from odoo import models, fields + class hr_employee(models.Model): - _name = "hr.employee" - _inherit = "hr.employee" + _name = "hr.employee" + _inherit = "hr.employee" - capital = fields.Float( "Apport Capital Social" ) + capital = fields.Float("Apport Capital Social") diff --git a/models/lefilament_tdb.py b/models/lefilament_tdb.py index 8b9da87..cdea31b 100644 --- a/models/lefilament_tdb.py +++ b/models/lefilament_tdb.py @@ -1,11 +1,10 @@ # © 2019 Le Filament (<http://www.le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from datetime import datetime, timedelta +from datetime import datetime from dateutil.relativedelta import relativedelta from odoo import models, fields, api -from odoo import tools from odoo.fields import Date @@ -15,58 +14,102 @@ class LeFilamentTdb(models.Model): _description = "Le Filament Dashboard" _order = "date_tdb desc" - name = fields.Char( 'Mois', compute='get_month', store=True) - date_tdb = fields.Date( 'Date', required=True, default=Date.context_today, store=True) - - ca_mois = fields.Float( 'Facturé', compute="dashboard_values", store=True) - - cmd_mois = fields.Float( 'Commandes', compute="dashboard_values", store=True) - - pipe_mois = fields.Float( 'Pipe', compute="dashboard_values", store=True ) - - - treso = fields.Float( 'Trésorerie', compute="dashboard_values", store=True ) - variation = fields.Float( 'Variation', compute="dashboard_values", store=True ) - charges = fields.Float( 'Décaissé', compute="dashboard_values", store=True ) - encaisse = fields.Float( 'Encaissé', compute="dashboard_values", store=True ) - charges_fixes = fields.Float( 'Charges Fixes', default=10000 ) - runway = fields.Float( 'Runway', compute="runway_value", ) + name = fields.Char('Mois', compute='get_month', store=True) + date_tdb = fields.Date('Date', + required=True, + default=Date.context_today, + store=True + ) + ca_mois = fields.Float('Facturé', compute="dashboard_values", store=True) + cmd_mois = fields.Float('Commandes', + compute="dashboard_values", + store=True + ) + pipe_mois = fields.Float('Pipe', compute="dashboard_values", store=True) + treso = fields.Float('Trésorerie', compute="dashboard_values", store=True) + variation = fields.Float('Variation', + compute="dashboard_values", + store=True + ) + charges = fields.Float('Décaissé', compute="dashboard_values", store=True) + encaisse = fields.Float('Encaissé', compute="dashboard_values", store=True) + charges_fixes = fields.Float('Charges Fixes', default=10000) + runway = fields.Float('Runway', compute="runway_value") @api.multi @api.depends('date_tdb') def dashboard_values(self): for record in self: - if record.date_tdb : + if record.date_tdb: date_tdb = Date.from_string(record.date_tdb) - - ############## CA ################ + # FACTURÉ - self.env.cr.execute("select sum(amount_untaxed_signed) from account_invoice where state!='draft' and (type='out_invoice' or type='out_refund') and date >= date_trunc('month', %s) and date < date_trunc('month', %s + interval '1' month);", (date_tdb, date_tdb) ) + self.env.cr.execute( + "SELECT SUM(amount_untaxed_signed) \ + FROM account_invoice \ + WHERE state != 'draft' \ + AND (type = 'out_invoice' OR type = 'out_refund') \ + AND date >= date_trunc('month', %s) \ + AND date < date_trunc('month', %s + interval '1' month);", + (date_tdb, date_tdb) + ) ca_mois = self.env.cr.fetchone()[0] - ############## COMMANDES ################ - # TOTAL - self.env.cr.execute("select sum(amount_untaxed) from sale_order where invoice_status='to invoice' and date_order >= date_trunc('month', %s) and date_order < date_trunc('month', %s + interval '1' month);", (date_tdb, date_tdb) ) + # COMMANDES TOTAL + self.env.cr.execute( + "SELECT SUM(amount_untaxed) \ + FROM sale_order \ + WHERE invoice_status = 'to invoice' \ + AND date_order >= date_trunc('month', %s) \ + AND date_order < date_trunc('month', %s \ + + interval '1' month);", + (date_tdb, date_tdb) + ) cmd_mois = self.env.cr.fetchone()[0] - ############## TRESO ################ # Trésorerie - self.env.cr.execute("select sum(amount) from account_bank_statement_line where date < date_trunc('month', %s + interval '1' month);", (date_tdb, ) ) + self.env.cr.execute( + "SELECT SUM(amount) \ + FROM account_bank_statement_line \ + WHERE date < date_trunc('month', %s \ + + interval '1' month);", + (date_tdb) + ) treso_total = self.env.cr.fetchone()[0] # CHARGES - self.env.cr.execute("select sum(amount) from account_bank_statement_line where amount < 0 and date >= date_trunc('month', %s) and date < date_trunc('month', %s + interval '1' month);", (date_tdb, date_tdb) ) + self.env.cr.execute( + "SELECT SUM(amount) \ + FROM account_bank_statement_line \ + WHERE amount < 0 \ + AND date >= date_trunc('month', %s) \ + AND date < date_trunc('month', %s + interval '1' month);", + (date_tdb, date_tdb) + ) charges = self.env.cr.fetchone()[0] # ENCAISSE - self.env.cr.execute("select sum(amount) from account_bank_statement_line where amount > 0 and date >= date_trunc('month', %s) and date < date_trunc('month', %s + interval '1' month);", (date_tdb, date_tdb) ) + self.env.cr.execute( + "SELECT SUM(amount) \ + FROM account_bank_statement_line \ + WHERE amount > 0 \ + AND date >= date_trunc('month', %s) \ + AND date < date_trunc('month', %s + interval '1' month);", + (date_tdb, date_tdb) + ) encaisse = self.env.cr.fetchone()[0] - ############## CHARGES ################ - self.env.cr.execute("select charges_fixes from res_company" ) + # CHARGES FIXES + self.env.cr.execute( + "SELECT charges_fixes \ + FROM res_company" + ) charges_fixes = self.env.cr.fetchone()[0] - ############## PIPE ################ - # TOTAL - self.env.cr.execute("select sum(planned_revenue*probability/100) from crm_lead where active=True;") + # PIPE + self.env.cr.execute( + "SELECT SUM(planned_revenue * probability / 100) \ + FROM crm_lead \ + WHERE active = True" + ) pipe = self.env.cr.fetchone()[0] if not encaisse: @@ -83,39 +126,56 @@ class LeFilamentTdb(models.Model): record.charges_fixes = charges_fixes record.pipe_mois = pipe - @api.multi - @api.depends('charges_fixes','treso') + @api.depends('charges_fixes', 'treso') def runway_value(self): for record in self: - if record.charges_fixes : + if record.charges_fixes: record.runway = record.treso / record.charges_fixes @api.multi @api.depends('date_tdb') def get_month(self): for record in self: - months = ['Janv', 'Fév', 'Mars', 'Avr', 'Mai', 'Juin', 'Juil', 'Août', 'Sept', 'Oct', 'Nov', 'Dec'] - record.name = months[record.date_tdb.month-1] + " " + str(record.date_tdb.year) - + months = ['Janv', + 'Fév', + 'Mars', + 'Avr', + 'Mai', + 'Juin', + 'Juil', + 'Août', + 'Sept', + 'Oct', + 'Nov', + 'Dec' + ] + record.name = months[record.date_tdb.month-1] \ + + " " + str(record.date_tdb.year) @api.model def _new_data(self): - print("Nouvelle ligne", Date.today() ) - self.create({ 'date_tdb': Date.today() }) + print("Nouvelle ligne", Date.today()) + self.create({'date_tdb': Date.today()}) @api.model def retrieve_datas_dashboard(self): - ## Get fiscal years - fiscal_date = datetime(datetime.now().year, self.env.user.company_id.fiscalyear_last_month, self.env.user.company_id.fiscalyear_last_day) + # Get fiscal years + fiscal_date = datetime( + datetime.now().year, + self.env.user.company_id.fiscalyear_last_month, + self.env.user.company_id.fiscalyear_last_day + ) if datetime.now() > fiscal_date: fiscal_year = "'" + Date.to_string(fiscal_date) + "'" - fiscal_year_next = "'" + Date.to_string(fiscal_date+relativedelta(years=1)) + "'" + fiscal_year_next = "'" + Date.to_string( + fiscal_date + relativedelta(years=1)) + "'" else: - fiscal_year = "'" + Date.to_string(fiscal_date-relativedelta(years=1)) + "'" + fiscal_year = "'" + Date.to_string( + fiscal_date - relativedelta(years=1)) + "'" fiscal_year_next = "'" + Date.to_string(fiscal_date) + "'" - ## Prepare values + # Prepare values res = { 'facture': 0, 'commandes': 0, @@ -137,127 +197,242 @@ class LeFilamentTdb(models.Model): 'fiscal_year_next': fiscal_year_next, } - self._cr.execute(""" + self._cr.execute( + """ SELECT - (select count(*) from account_invoice) as id, - (select sum(amount_untaxed_signed) from account_invoice where state!='draft' and (type='out_invoice' or type='out_refund') and date > %s and date <= %s ) as facture, - (select sum(residual_company_signed) from account_invoice where state!='draft' and type='out_invoice' ) as a_encaisser, - (select sum(residual_company_signed) from account_invoice where state!='draft' and type='in_invoice' ) as a_payer, - (select sum(planned_revenue*probability/100) from crm_lead where active=True and (date_deadline <= %s or date_deadline is null) ) as pipe, - (select sum(planned_revenue*probability/100) from crm_lead where active=True and date_deadline > %s ) as pipe_n1, - (select sum(planned_revenue*probability/100) from crm_lead where active=True and probability=100 and (date_deadline <= %s or date_deadline is null) ) as pipe_win, - (select sum(planned_revenue*probability/100) from crm_lead where active=True and probability!=100 and (date_deadline < %s or date_deadline is null) ) as pipe_to_win, - (select date from account_bank_statement ORDER BY ID DESC LIMIT 1) as date_maj, - (select sum(amount) from account_bank_statement_line ) as tresorerie, - (select sum(amount) from account_bank_statement_line where amount > 0 and date > %s ) as entree, - (select sum(amount) from account_bank_statement_line where amount < 0 and date > %s ) as sortie, - (select sum(amount) from account_bank_statement_line where date > %s ) as variation, - (select sum(e.total_amount) from hr_expense_sheet es, hr_expense e where es.id = e.sheet_id and e.payment_mode='own_account' and es.state!='done' ) as cca, - (select sum(price_subtotal-qty_invoiced*price_unit) from sale_order_line where invoice_status='to invoice') as commandes; """ - % (fiscal_year, fiscal_year_next, fiscal_year_next, fiscal_year_next, fiscal_year_next, fiscal_year_next, fiscal_year, fiscal_year, fiscal_year) ) + (SELECT COUNT(*) + FROM account_invoice + ) AS id, + (SELECT SUM(amount_untaxed_signed) + FROM account_invoice + WHERE state!='draft' + AND (type='out_invoice' OR type='out_refund') + AND date > %s AND date <= %s + ) AS facture, + (SELECT SUM(residual_company_signed) + FROM account_invoice + WHERE state!='draft' AND type='out_invoice' + ) AS a_encaisser, + (SELECT SUM(residual_company_signed) + FROM account_invoice + WHERE state!='draft' AND type='in_invoice' + ) AS a_payer, + (SELECT SUM(planned_revenue * probability / 100) + FROM crm_lead + WHERE active=True + AND (date_deadline <= %s OR date_deadline is NULL) + ) AS pipe, + (SELECT SUM(planned_revenue * probability / 100) + FROM crm_lead WHERE active=True AND date_deadline > %s + ) AS pipe_n1, + (SELECT SUM(planned_revenue * probability / 100) + FROM crm_lead + WHERE active=True + AND probability = 100 + AND (date_deadline <= %s OR date_deadline is NULL) + ) AS pipe_win, + (SELECT SUM(planned_revenue * probability / 100) + FROM crm_lead + WHERE active=True + AND probability != 100 + AND (date_deadline < %s OR date_deadline is NULL) + ) AS pipe_to_win, + (SELECT date + FROM account_bank_statement + ORDER BY ID DESC LIMIT 1 + ) AS date_maj, + (SELECT SUM(amount) + FROM account_bank_statement_line + ) AS tresorerie, + (SELECT SUM(amount) + FROM account_bank_statement_line + WHERE amount > 0 AND date > %s + ) AS entree, + (SELECT SUM(amount) + FROM account_bank_statement_line + WHERE amount < 0 AND date > %s + ) AS sortie, + (SELECT SUM(amount) + FROM account_bank_statement_line + WHERE date > %s + ) AS variation, + (SELECT SUM(e.total_amount) + FROM hr_expense_sheet es, hr_expense e + WHERE es.id = e.sheet_id + AND e.payment_mode='own_account' + AND es.state!='done' + ) AS cca, + (SELECT SUM(price_subtotal - qty_invoiced * price_unit) + FROM sale_order_line + WHERE invoice_status='to invoice' + ) AS commandes; + """ + % (fiscal_year, + fiscal_year_next, + fiscal_year_next, + fiscal_year_next, + fiscal_year_next, + fiscal_year_next, + fiscal_year, + fiscal_year, + fiscal_year + ) + ) datas = self._cr.dictfetchall() - self._cr.execute("select ca_target from res_company;") + self._cr.execute("SELECT ca_target FROM res_company;") ca_target = self._cr.dictfetchall() - self._cr.execute("select sum(capital) as capital from hr_employee;") + self._cr.execute("SELECT sum(capital) AS capital FROM hr_employee;") capital = self._cr.dictfetchall() if datas[0]['facture']: - res['facture'] =+ datas[0]['facture'] + res['facture'] += datas[0]['facture'] if datas[0]['a_encaisser']: - res['a_encaisser'] =+ datas[0]['a_encaisser'] + res['a_encaisser'] += datas[0]['a_encaisser'] if datas[0]['a_payer']: - res['a_payer'] =+ datas[0]['a_payer'] + res['a_payer'] += datas[0]['a_payer'] if datas[0]['pipe']: - res['pipe'] =+ datas[0]['pipe'] + res['pipe'] += datas[0]['pipe'] if datas[0]['pipe_win']: - res['pipe_win'] =+ datas[0]['pipe_win'] + res['pipe_win'] += datas[0]['pipe_win'] if datas[0]['pipe_to_win']: - res['pipe_to_win'] =+ datas[0]['pipe_to_win'] + res['pipe_to_win'] += datas[0]['pipe_to_win'] if datas[0]['pipe_n1']: - res['pipe_n1'] =+ datas[0]['pipe_n1'] + res['pipe_n1'] += datas[0]['pipe_n1'] if datas[0]['tresorerie']: - res['tresorerie'] =+ datas[0]['tresorerie'] + res['tresorerie'] += datas[0]['tresorerie'] if datas[0]['date_maj']: res['date_maj'] = datas[0]['date_maj'] if datas[0]['entree']: - res['entree'] =+ datas[0]['entree'] + res['entree'] += datas[0]['entree'] if datas[0]['sortie']: - res['sortie'] =+ datas[0]['sortie'] + res['sortie'] += datas[0]['sortie'] if datas[0]['variation']: - res['variation'] =+ datas[0]['variation'] + res['variation'] += datas[0]['variation'] if datas[0]['commandes']: - res['commandes'] =+ datas[0]['commandes'] + res['commandes'] += datas[0]['commandes'] if datas[0]['cca']: - res['cca'] =+ datas[0]['cca'] + res['cca'] += datas[0]['cca'] if ca_target[0]['ca_target']: - res['target'] =+ ca_target[0]['ca_target'] - if capital[0]['capital']: - res['capital'] =+ capital[0]['capital'] + res['target'] += ca_target[0]['ca_target'] + if capital[0]['capital']: + res['capital'] += capital[0]['capital'] return res @api.model def tresorerie(self): - self._cr.execute("""SELECT to_char(date_trunc('month', date),'YYYY-MM') as mois, - sum(case when amount > 0 then amount else 0 end ) as entree, - sum(case when amount < 0 then amount else 0 end ) as sortie, - sum(amount) as variation - from account_bank_statement_line - group by date_trunc('month', date) - order by date_trunc('month', date);""") + self._cr.execute( + """ + SELECT to_char(date_trunc('month', date),'YYYY-MM') AS mois, + SUM(CASE WHEN amount > 0 THEN amount ELSE 0 END) AS entree, + SUM(CASE WHEN amount < 0 THEN amount ELSE 0 END) AS sortie, + SUM(amount) AS variation + FROM account_bank_statement_line + GROUP BY date_trunc('month', date) + ORDER BY date_trunc('month', date); + """ + ) tresorerie = self._cr.dictfetchall() - self._cr.execute("""SELECT - (select sum(e.total_amount) as fonds_propres from hr_expense_sheet es, hr_expense e where es.id = e.sheet_id and e.payment_mode='own_account' and es.state!='done') as cca, - (select sum(capital) as capital from hr_employee) as capital;""") + self._cr.execute( + """ + SELECT + (SELECT SUM(e.total_amount) AS fonds_propres + FROM hr_expense_sheet es, hr_expense e + WHERE es.id = e.sheet_id + AND e.payment_mode='own_account' + AND es.state!='done' + ) AS cca, + (SELECT SUM(capital) AS capital FROM hr_employee) AS capital; + """ + ) fonds_propres = self._cr.dictfetchall()[0] if not fonds_propres['cca']: fonds_propres['cca'] = 0 - return { 'tresorerie': tresorerie, 'fonds_propres': fonds_propres } + return {'tresorerie': tresorerie, 'fonds_propres': fonds_propres} @api.model def previ_tresorerie(self): - self._cr.execute("""SELECT to_char(date_trunc('month', date),'YYYY-MM') as mois, sum(sum(amount)) - over ( order by date_trunc('month', date) ) as treso - from account_bank_statement_line - group by date_trunc('month', date) - order by date_trunc('month', date) desc limit 6;""") + self._cr.execute( + """ + SELECT to_char(date_trunc('month', date),'YYYY-MM') AS mois, + SUM(SUM(amount)) OVER ( + ORDER BY date_trunc('month', date) + ) AS treso + FROM account_bank_statement_line + GROUP BY date_trunc('month', date) + ORDER BY date_trunc('month', date) DESC LIMIT 6; + """ + ) tresorerie = self._cr.dictfetchall() - self._cr.execute("""SELECT - (select sum(e.total_amount) as fonds_propres from hr_expense_sheet es, hr_expense e where es.id = e.sheet_id and e.payment_mode='own_account' and es.state!='done') as cca, - (select sum(capital) as capital from hr_employee) as capital;""") + self._cr.execute( + """ + SELECT + (SELECT SUM(e.total_amount) AS fonds_propres + FROM hr_expense_sheet es, hr_expense e + WHERE es.id = e.sheet_id + AND e.payment_mode = 'own_account' + AND es.state != 'done' + ) as cca, + (SELECT SUM(capital) AS capital FROM hr_employee) AS capital; + """ + ) fonds_propres = self._cr.dictfetchall()[0] - self._cr.execute("""SELECT to_char(date_trunc('month', date_due),'YYYY-MM') as mois, - sum(case when type='in_invoice' then residual_company_signed else 0 end ) as f_fournisseur, - sum(case when type='out_invoice' then residual_company_signed else 0 end ) as f_client - from account_invoice - where state!='draft' and state!='paid' - group by date_trunc('month', date_due) - order by date_trunc('month', date_due);""") + self._cr.execute( + """ + SELECT to_char(date_trunc('month', date_due),'YYYY-MM') AS mois, + SUM(CASE WHEN type = 'in_invoice' + THEN residual_company_signed + ELSE 0 END + ) AS f_fournisseur, + SUM(CASE WHEN type = 'out_invoice' + THEN residual_company_signed + ELSE 0 END + ) AS f_client + FROM account_invoice + WHERE state!='draft' AND state != 'paid' + GROUP BY date_trunc('month', date_due) + ORDER BY date_trunc('month', date_due); + """ + ) factures = self._cr.dictfetchall() - self._cr.execute("""SELECT periode, - sum(montant) - from previ_treso - where periode != 1 - group by periode - order by periode;""") + self._cr.execute( + """ + SELECT periode, + SUM(montant) + FROM previ_treso + WHERE periode != 1 + GROUP BY periode + ORDER BY periode; + """ + ) charges_periode = self._cr.dictfetchall() - self._cr.execute("""SELECT to_char(date_trunc('month', date),'YYYY-MM') as mois, - sum(montant) - from previ_treso - where periode = 1 - group by date_trunc('month', date);""") + self._cr.execute( + """ + SELECT to_char(date_trunc('month', date), 'YYYY-MM') as mois, + SUM(montant) + FROM previ_treso + WHERE periode = 1 + GROUP BY date_trunc('month', date); + """ + ) charges_fixes = self._cr.dictfetchall() if not fonds_propres['cca']: fonds_propres['cca'] = 0 - return { 'tresorerie': tresorerie, 'fonds_propres': fonds_propres, 'factures': factures, 'charges_fixes': charges_fixes, 'charges_periode':charges_periode, } + return { + 'tresorerie': tresorerie, + 'fonds_propres': fonds_propres, + 'factures': factures, + 'charges_fixes': charges_fixes, + 'charges_periode': charges_periode, + } diff --git a/models/res_company.py b/models/res_company.py index 0dfc14b..d9f309f 100644 --- a/models/res_company.py +++ b/models/res_company.py @@ -1,24 +1,33 @@ # © 2019 Le Filament (<http://www.le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import models, fields, api +from odoo import models, fields -class res_company(models.Model): - _inherit = "res.company" - ca_target = fields.Integer( "Objectif Chiffre d'Affaire" ) - charges_fixes = fields.Integer( 'Charges Fixes' ) - previ_treso_ids = fields.One2many('previ.treso', 'company_id', 'Prévisionnel') +class res_company(models.Model): + _inherit = "res.company" + ca_target = fields.Integer("Objectif Chiffre d'Affaire") + charges_fixes = fields.Integer('Charges Fixes') + previ_treso_ids = fields.One2many('previ.treso', + 'company_id', + 'Prévisionnel' + ) class previ_treso(models.Model): - _name = "previ.treso" - _description = "Previsionnel de tresorerie" - _order = 'name' + _name = "previ.treso" + _description = "Previsionnel de tresorerie" + _order = 'name' - company_id = fields.Many2one('res.company', 'Company', default=lambda self: self.env.user.company_id.id ) - name = fields.Char('Nom') - periode = fields.Selection([(12,'Mensuel'),(3,'Trimestriel'),(1,'Annuel')], srting='Période') - date = fields.Date('Date') - montant = fields.Float('Montant') \ No newline at end of file + company_id = fields.Many2one( + 'res.company', + 'Company', + default=lambda self: self.env.user.company_id.id) + name = fields.Char('Nom') + periode = fields.Selection( + [(12, 'Mensuel'), (3, 'Trimestriel'), (1, 'Annuel')], + srting='Période' + ) + date = fields.Date('Date') + montant = fields.Float('Montant') -- GitLab