From fe16c4d87234a67e94f4462199daee096e1f8e67 Mon Sep 17 00:00:00 2001 From: Carlos Dauden Date: Wed, 8 Nov 2017 15:51:32 +0100 Subject: [PATCH] [IMP] contract: Module contract improvements (#107) --- contract/__manifest__.py | 5 +- contract/i18n/es.po | 111 ++++++++++++------ contract/models/__init__.py | 1 + contract/models/account_analytic_account.py | 46 ++++++-- contract/models/res_partner.py | 46 ++++++++ contract/tests/test_contract.py | 35 ++++++ .../views/account_analytic_account_view.xml | 24 +++- contract/views/account_invoice_view.xml | 14 ++- contract/views/res_partner_view.xml | 20 ++++ 9 files changed, 247 insertions(+), 55 deletions(-) create mode 100644 contract/models/res_partner.py create mode 100644 contract/views/res_partner_view.xml diff --git a/contract/__manifest__.py b/contract/__manifest__.py index 9c1aafed..6cea4b90 100644 --- a/contract/__manifest__.py +++ b/contract/__manifest__.py @@ -2,14 +2,14 @@ # Copyright 2004-2010 OpenERP SA # Copyright 2014-2017 Tecnativa - Pedro M. Baeza # Copyright 2015 Domatix -# Copyright 2016 Tecnativa - Carlos Dauden +# Copyright 2016-2017 Tecnativa - Carlos Dauden # Copyright 2017 Tecnativa - Vicent Cubells # Copyright 2016-2017 LasLabs Inc. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { 'name': 'Contracts Management - Recurring', - 'version': '10.0.2.1.0', + 'version': '10.0.3.0.0', 'category': 'Contract Management', 'license': 'AGPL-3', 'author': "OpenERP SA, " @@ -27,6 +27,7 @@ 'views/account_analytic_account_view.xml', 'views/account_analytic_contract_view.xml', 'views/account_invoice_view.xml', + 'views/res_partner_view.xml', ], 'installable': True, } diff --git a/contract/i18n/es.po b/contract/i18n/es.po index 010a6d32..f99f2aee 100644 --- a/contract/i18n/es.po +++ b/contract/i18n/es.po @@ -1,22 +1,23 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: # * contract -# +# # Translators: # OCA Transbot , 2016 msgid "" msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-08-17 01:05+0000\n" -"PO-Revision-Date: 2017-08-17 01:05+0000\n" -"Last-Translator: OCA Transbot , 2016\n" +"POT-Creation-Date: 2017-10-23 19:54+0200\n" +"PO-Revision-Date: 2017-10-23 19:58+0200\n" +"Last-Translator: Carlos Dauden \n" "Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n" +"Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: es\n" +"Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 1.8.7.1\n" #. module: contract #: model:mail.template,body_html:contract.email_contract_template @@ -120,7 +121,7 @@ msgstr "" #. module: contract #: model:mail.template,subject:contract.email_contract_template msgid "${object.company_id.name} Contract (Ref ${object.name or 'n/a'})" -msgstr "" +msgstr "${object.company_id.name} Contrato (Ref ${object.name or 'n/a'})" #. module: contract #: model:ir.ui.view,arch_db:contract.account_analytic_account_recurring_form_form @@ -137,12 +138,12 @@ msgstr "#START#: Fecha inicio del periodo facturado" #. module: contract #: model:ir.ui.view,arch_db:contract.report_contract_document msgid "Contract: " -msgstr "" +msgstr "Contrato: " #. module: contract #: model:ir.ui.view,arch_db:contract.report_contract_document msgid "Date Start: " -msgstr "" +msgstr "Fecha inicio: " #. module: contract #: model:ir.ui.view,arch_db:contract.report_contract_document @@ -172,7 +173,7 @@ msgstr "Elementos recurrentes" #. module: contract #: model:ir.ui.view,arch_db:contract.report_contract_document msgid "Responsible: " -msgstr "" +msgstr "Responsable: " #. module: contract #: model:ir.ui.view,arch_db:contract.report_contract_document @@ -199,7 +200,7 @@ msgstr "Cuenta analítica" #. module: contract #: model:ir.actions.act_window,help:contract.account_analytic_contract_action msgid "Click to create a new contract template." -msgstr "" +msgstr "Pinche para crear una nueva plantilla de contrato" #. module: contract #: model:ir.actions.act_window,help:contract.action_account_analytic_overdue_all @@ -207,23 +208,29 @@ msgid "Click to create a new contract." msgstr "Pinche para crear un contrato nuevo. " #. module: contract -#: code:addons/contract/models/account_analytic_account.py:216 +#: code:addons/contract/models/account_analytic_account.py:254 #, python-format msgid "Compose Email" msgstr "Componer correo electrónico" #. module: contract #: model:ir.actions.report.xml,name:contract.report_contract +#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_line_analytic_account_id #: model:ir.model.fields,field_description:contract.field_account_invoice_contract_id #: model:mail.template,report_name:contract.email_contract_template msgid "Contract" msgstr "Contrato" +#. module: contract +#: model:ir.model,name:contract.model_account_analytic_contract_line +msgid "Contract Lines" +msgstr "Líneas de contrato" + #. module: contract #: model:ir.model.fields,field_description:contract.field_account_analytic_account_contract_template_id #: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_form msgid "Contract Template" -msgstr "" +msgstr "Plantilla de contrato" #. module: contract #: model:ir.actions.act_window,name:contract.account_analytic_contract_action @@ -231,12 +238,15 @@ msgstr "" #: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_search #: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_tree msgid "Contract Templates" -msgstr "" +msgstr "Plantillas de contrato" #. module: contract #: model:ir.actions.act_window,name:contract.action_account_analytic_overdue_all +#: model:ir.model.fields,field_description:contract.field_res_partner_contract_count +#: model:ir.model.fields,field_description:contract.field_res_users_contract_count #: model:ir.ui.menu,name:contract.menu_action_account_analytic_overdue_all #: model:ir.ui.menu,name:contract.menu_config_contract +#: model:ir.ui.view,arch_db:contract.view_partner_form msgid "Contracts" msgstr "Contratos" @@ -247,26 +257,34 @@ msgstr "Crear facturas" #. module: contract #: model:ir.model.fields,field_description:contract.field_account_analytic_contract_create_uid +#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_line_create_uid #: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_create_uid msgid "Created by" msgstr "Creado por" #. module: contract #: model:ir.model.fields,field_description:contract.field_account_analytic_contract_create_date +#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_line_create_date #: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_create_date msgid "Created on" msgstr "Creado en" #. module: contract -#: model:ir.model.fields,field_description:contract.field_account_analytic_account_recurring_next_date -msgid "Date of Next Invoice" -msgstr "Próxima fecha de factura" +#: model:ir.model.fields,field_description:contract.field_account_analytic_account_date_end +#: model:ir.ui.view,arch_db:contract.view_account_analytic_account_contract_search +msgid "Date End" +msgstr "Fecha fin" #. module: contract #: model:ir.model.fields,field_description:contract.field_account_analytic_account_date_start -msgid "Date start" +msgid "Date Start" msgstr "Fecha inicio" +#. module: contract +#: model:ir.model.fields,field_description:contract.field_account_analytic_account_recurring_next_date +msgid "Date of Next Invoice" +msgstr "Próxima fecha de factura" + #. module: contract #: selection:account.analytic.account,recurring_rule_type:0 #: selection:account.analytic.contract,recurring_rule_type:0 @@ -274,36 +292,41 @@ msgid "Day(s)" msgstr "Día(s)" #. module: contract +#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_line_name #: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_name msgid "Description" msgstr "Descripción" #. module: contract +#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_line_discount #: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_discount msgid "Discount (%)" msgstr "Descuento (%)" #. module: contract -#: code:addons/contract/models/account_analytic_invoice_line.py:56 +#: code:addons/contract/models/account_analytic_invoice_line.py:77 #, python-format msgid "Discount should be less or equal to 100" msgstr "El descuento debería ser menor o igual a 100" #. module: contract +#: model:ir.model.fields,help:contract.field_account_analytic_contract_line_discount #: model:ir.model.fields,help:contract.field_account_analytic_invoice_line_discount -msgid "" -"Discount that is applied in generated invoices. It should be less or equal " -"to 100" -msgstr "" -"Descuento que es aplicado en las facturas generadas. Debería ser menor o " -"igual a 100" +msgid "Discount that is applied in generated invoices. It should be less or equal to 100" +msgstr "Descuento que es aplicado en las facturas generadas. Debería ser menor o igual a 100" #. module: contract #: model:ir.model.fields,field_description:contract.field_account_analytic_contract_display_name +#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_line_display_name #: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_display_name msgid "Display Name" msgstr "Nombre mostrado" +#. module: contract +#: model:ir.ui.view,arch_db:contract.view_account_analytic_account_contract_search +msgid "Finished" +msgstr "Finalizado" + #. module: contract #: model:ir.model.fields,field_description:contract.field_account_analytic_account_recurring_invoices msgid "Generate recurring invoices automatically" @@ -316,6 +339,7 @@ msgstr "Agrupar por..." #. module: contract #: model:ir.model.fields,field_description:contract.field_account_analytic_contract_id +#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_line_id #: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_id msgid "ID" msgstr "ID (identificación)" @@ -340,7 +364,7 @@ msgstr "Facturas" #. module: contract #: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_search msgid "Invoicing Type" -msgstr "" +msgstr "Tipo Facturación" #. module: contract #: model:ir.model.fields,field_description:contract.field_account_analytic_account_recurring_invoicing_type @@ -357,17 +381,20 @@ msgstr "Diario" #. module: contract #: model:ir.model.fields,field_description:contract.field_account_analytic_contract___last_update +#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_line___last_update #: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line___last_update msgid "Last Modified on" msgstr "Última modificación en" #. module: contract +#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_line_write_uid #: model:ir.model.fields,field_description:contract.field_account_analytic_contract_write_uid #: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_write_uid msgid "Last Updated by" msgstr "Última actualización de" #. module: contract +#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_line_write_date #: model:ir.model.fields,field_description:contract.field_account_analytic_contract_write_date #: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_write_date msgid "Last Updated on" @@ -377,8 +404,7 @@ msgstr "Última actualización en" #: model:ir.ui.view,arch_db:contract.account_analytic_account_recurring_form_form #: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_form msgid "Legend (for the markers inside invoice lines description)" -msgstr "" -"Leyenda (para los marcadores dentro de descripción en lineas de factura)" +msgstr "Leyenda (para los marcadores dentro de descripción en lineas de factura)" #. module: contract #: selection:account.analytic.account,recurring_rule_type:0 @@ -403,7 +429,17 @@ msgid "Next Invoice" msgstr "Próxima factura" #. module: contract -#: code:addons/contract/models/account_analytic_account.py:137 +#: model:ir.ui.view,arch_db:contract.view_account_analytic_account_contract_search +msgid "Valid" +msgstr "Vigente" + +#. module: contract +#: model:ir.model,name:contract.model_res_partner +msgid "Partner" +msgstr "" + +#. module: contract +#: code:addons/contract/models/account_analytic_account.py:170 #, python-format msgid "Please define a sale journal for the company '%s'." msgstr "Por favor define un diario de ventas para la compañía '%s'." @@ -428,11 +464,13 @@ msgid "Pricelist" msgstr "Lista de precios" #. module: contract +#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_line_product_id #: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_product_id msgid "Product" msgstr "Producto" #. module: contract +#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_line_quantity #: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_quantity msgid "Quantity" msgstr "Cantidad" @@ -442,7 +480,7 @@ msgstr "Cantidad" #: model:ir.model.fields,field_description:contract.field_account_analytic_contract_recurring_rule_type #: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_search msgid "Recurrence" -msgstr "" +msgstr "Recurrencia" #. module: contract #: model:ir.ui.view,arch_db:contract.account_analytic_account_recurring_form_form @@ -482,20 +520,22 @@ msgstr "Especifica el intervalo para la generación de facturas automática." #: model:ir.model.fields,help:contract.field_account_analytic_account_recurring_invoicing_type #: model:ir.model.fields,help:contract.field_account_analytic_contract_recurring_invoicing_type msgid "Specify if process date is 'from' or 'to' invoicing date" -msgstr "" -"Especifica si la fecha de proceso es desde o hasta la fecha de facturación" +msgstr "Especifica si la fecha de proceso es desde o hasta la fecha de facturación" #. module: contract +#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_line_price_subtotal #: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_price_subtotal msgid "Sub Total" msgstr "Subtotal" #. module: contract +#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_line_price_unit #: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_price_unit msgid "Unit Price" msgstr "Precio unidad" #. module: contract +#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_line_uom_id #: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_uom_id msgid "Unit of Measure" msgstr "Unidad de medida" @@ -518,7 +558,7 @@ msgid "Year(s)" msgstr "Año(s)" #. module: contract -#: code:addons/contract/models/account_analytic_account.py:129 +#: code:addons/contract/models/account_analytic_account.py:162 #, python-format msgid "You must first select a Customer for Contract %s!" msgstr "¡Seleccione un cliente para este contrato %s!" @@ -533,6 +573,11 @@ msgstr "" msgid "account.analytic.invoice.line" msgstr "account.analytic.invoice.line" +#. module: contract +#: model:ir.ui.view,arch_db:contract.view_partner_form +msgid "show the contracts for this partner" +msgstr "Mostrar los contratos de este partner" + #. module: contract #: model:ir.ui.view,arch_db:contract.account_analytic_account_recurring_form_form msgid "⇒ Show recurring invoices" diff --git a/contract/models/__init__.py b/contract/models/__init__.py index 35a1de5e..3a3ee1be 100644 --- a/contract/models/__init__.py +++ b/contract/models/__init__.py @@ -6,3 +6,4 @@ from . import account_analytic_account from . import account_analytic_invoice_line from . import account_analytic_contract_line from . import account_invoice +from . import res_partner diff --git a/contract/models/account_analytic_account.py b/contract/models/account_analytic_account.py index b9b8355d..89afa911 100644 --- a/contract/models/account_analytic_account.py +++ b/contract/models/account_analytic_account.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- -# © 2004-2010 OpenERP SA -# © 2014 Angel Moya -# © 2015 Pedro M. Baeza -# © 2016 Carlos Dauden +# Copyright 2004-2010 OpenERP SA +# Copyright 2014 Angel Moya +# Copyright 2015 Pedro M. Baeza +# Copyright 2016-2017 Carlos Dauden # Copyright 2016-2017 LasLabs Inc. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). @@ -29,7 +29,14 @@ class AccountAnalyticAccount(models.Model): inverse_name='analytic_account_id', copy=True, ) - date_start = fields.Date(default=fields.Date.context_today) + date_start = fields.Date( + string='Date Start', + default=fields.Date.context_today, + ) + date_end = fields.Date( + string='Date End', + index=True, + ) recurring_invoices = fields.Boolean( string='Generate recurring invoices automatically', ) @@ -198,9 +205,19 @@ class AccountAnalyticAccount(models.Model): @api.multi def recurring_create_invoice(self): + """ + Create invoices from contracts + :return: invoices created + """ + invoices = self.env['account.invoice'] for contract in self: - old_date = fields.Date.from_string( - contract.recurring_next_date or fields.Date.today()) + ref_date = contract.recurring_next_date or fields.Date.today() + if (contract.date_start > ref_date or + contract.date_end and contract.date_end < ref_date): + raise ValidationError( + _("You must review start and end dates!\n%s") % + contract.name) + old_date = fields.Date.from_string(ref_date) new_date = old_date + self.get_relative_delta( contract.recurring_rule_type, contract.recurring_interval) ctx = self.env.context.copy() @@ -211,17 +228,22 @@ class AccountAnalyticAccount(models.Model): 'force_company': contract.company_id.id, }) # Re-read contract with correct company - contract.with_context(ctx)._create_invoice() + invoices |= contract.with_context(ctx)._create_invoice() contract.write({ 'recurring_next_date': new_date.strftime('%Y-%m-%d') }) - return True + return invoices @api.model def cron_recurring_create_invoice(self): - contracts = self.search( - [('recurring_next_date', '<=', fields.date.today()), - ('recurring_invoices', '=', True)]) + today = fields.Date.today() + contracts = self.search([ + ('recurring_invoices', '=', True), + ('recurring_next_date', '<=', today), + '|', + ('date_end', '=', False), + ('date_end', '>=', today), + ]) return contracts.recurring_create_invoice() @api.multi diff --git a/contract/models/res_partner.py b/contract/models/res_partner.py new file mode 100644 index 00000000..30723d2a --- /dev/null +++ b/contract/models/res_partner.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Carlos Dauden +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ResPartner(models.Model): + _inherit = 'res.partner' + + contract_count = fields.Integer( + string='Contracts', + compute='_compute_contract_count', + ) + + def _compute_contract_count(self): + Contract = self.env['account.analytic.account'] + today = fields.Date.today() + for partner in self: + partner.contract_count = Contract.search_count([ + ('recurring_invoices', '=', True), + ('partner_id', '=', partner.id), + ('date_start', '<=', today), + '|', + ('date_end', '=', False), + ('date_end', '>=', today), + ]) + + def act_show_contract(self): + """ This opens contract view + @return: the contract view + """ + self.ensure_one() + res = self.env['ir.actions.act_window'].for_xml_id( + 'contract', 'action_account_analytic_overdue_all') + res.update( + context=dict( + self.env.context, + search_default_recurring_invoices=True, + search_default_not_finished=True, + default_partner_id=self.id, + default_recurring_invoices=True, + ), + domain=[('partner_id', '=', self.id)], + ) + return res diff --git a/contract/tests/test_contract.py b/contract/tests/test_contract.py index 90eaf964..b1ad529c 100644 --- a/contract/tests/test_contract.py +++ b/contract/tests/test_contract.py @@ -3,6 +3,7 @@ # Copyright 2017 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import fields from odoo.exceptions import ValidationError from odoo.tests import common @@ -232,3 +233,37 @@ class TestContract(TestContractBase): '\n'.join([line.product_id.name, line.product_id.description_sale, ])) + + def test_contract_count(self): + """It should return contract count.""" + count = self.partner.contract_count + 2 + self.contract.copy() + self.contract.copy() + self.assertEqual(self.partner.contract_count, count) + + def test_date_end(self): + """It should don't create invoices from finished contract.""" + AccountInvoice = self.env['account.invoice'] + self.contract.date_end = '2015-12-31' + with self.assertRaises(ValidationError): + self.contract.recurring_create_invoice() + init_count = AccountInvoice.search_count( + [('contract_id', '=', self.contract.id)]) + self.contract.cron_recurring_create_invoice() + last_count = AccountInvoice.search_count( + [('contract_id', '=', self.contract.id)]) + self.assertEqual(last_count, init_count) + + def test_same_date_start_and_date_end(self): + """It should create one invoice with same start and end date.""" + AccountInvoice = self.env['account.invoice'] + self.contract.date_start = self.contract.date_end = fields.Date.today() + self.contract.recurring_next_date = self.contract.date_start + init_count = AccountInvoice.search_count( + [('contract_id', '=', self.contract.id)]) + self.contract.cron_recurring_create_invoice() + last_count = AccountInvoice.search_count( + [('contract_id', '=', self.contract.id)]) + self.assertEqual(last_count, init_count + 1) + with self.assertRaises(ValidationError): + self.contract.recurring_create_invoice() diff --git a/contract/views/account_analytic_account_view.xml b/contract/views/account_analytic_account_view.xml index d56270bc..9898d842 100644 --- a/contract/views/account_analytic_account_view.xml +++ b/contract/views/account_analytic_account_view.xml @@ -35,7 +35,7 @@ /> - +