From 4aaaa4549ef8027ef0d384aade4efccc7c7fc228 Mon Sep 17 00:00:00 2001 From: mreficent Date: Wed, 4 Jul 2018 19:07:35 +0200 Subject: [PATCH] [IMP] Make sure it works for sale and purchase contracts [UPD] Update contract.pot --- contract/README.rst | 7 +- contract/__manifest__.py | 2 +- contract/i18n/contract.pot | 81 ++++++++++++++++--- contract/models/account_analytic_account.py | 17 ++-- contract/models/account_analytic_contract.py | 17 ++-- .../models/account_analytic_contract_line.py | 1 - .../models/account_analytic_invoice_line.py | 2 +- contract/models/res_partner.py | 47 ++++++++--- contract/readme/CONTRIBUTORS.rst | 1 + contract/readme/DESCRIPTION.rst | 6 +- contract/tests/test_contract.py | 45 ++++++++--- .../views/account_analytic_account_view.xml | 44 +++++----- .../views/account_analytic_contract_view.xml | 16 +++- contract/views/res_partner_view.xml | 11 ++- 14 files changed, 212 insertions(+), 85 deletions(-) diff --git a/contract/README.rst b/contract/README.rst index af3ce01d1..57ffab1bb 100644 --- a/contract/README.rst +++ b/contract/README.rst @@ -25,10 +25,10 @@ Contracts Management - Recurring |badge1| |badge2| |badge3| |badge4| |badge5| -This module brings back the contracts management with recurring invoicing -features. Also you can print and send by email contract report. +This module enables contracts management with recurring +invoicing functions. Also you can print and send by email contract report. -In upstream Odoo, this functionality was moved into the Enterprise edition. +It works for customer contract and supplier contracts. **Table of contents** @@ -106,6 +106,7 @@ Contributors * Angel Moya * Dave Lasley * Vicent Cubells +* Miquel Raïch Maintainers ~~~~~~~~~~~ diff --git a/contract/__manifest__.py b/contract/__manifest__.py index 37155810c..f065ff524 100644 --- a/contract/__manifest__.py +++ b/contract/__manifest__.py @@ -8,7 +8,7 @@ { 'name': 'Contracts Management - Recurring', - 'version': '11.0.3.0.0', + 'version': '11.0.4.0.0', 'category': 'Contract Management', 'license': 'AGPL-3', 'author': "OpenERP SA, " diff --git a/contract/i18n/contract.pot b/contract/i18n/contract.pot index 104f77653..2d5673636 100644 --- a/contract/i18n/contract.pot +++ b/contract/i18n/contract.pot @@ -156,7 +156,8 @@ msgid "Click to create a new contract template." msgstr "" #. module: contract -#: model:ir.actions.act_window,help:contract.action_account_analytic_overdue_all +#: model:ir.actions.act_window,help:contract.action_account_analytic_purchase_overdue_all +#: model:ir.actions.act_window,help:contract.action_account_analytic_sale_overdue_all msgid "Click to create a new contract." msgstr "" @@ -166,7 +167,7 @@ msgid "Company" msgstr "" #. module: contract -#: code:addons/contract/models/account_analytic_account.py:332 +#: code:addons/contract/models/account_analytic_account.py:342 #, python-format msgid "Compose Email" msgstr "" @@ -211,12 +212,15 @@ msgid "Contract Templates" msgstr "" #. 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.model.fields,field_description:contract.field_account_analytic_account_contract_type +#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_contract_type +#: model:ir.model.fields,field_description:contract.field_project_project_contract_type +#: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_search +msgid "Contract Type" +msgstr "" + +#. module: contract #: model:ir.ui.menu,name:contract.menu_config_contract -#: model:ir.ui.view,arch_db:contract.view_partner_form msgid "Contracts" msgstr "" @@ -245,6 +249,19 @@ msgstr "" msgid "Created on" msgstr "" +#. module: contract +#: selection:account.analytic.account,contract_type:0 +#: selection:account.analytic.contract,contract_type:0 +#: model:ir.ui.view,arch_db:contract.account_analytic_account_sale_form +msgid "Customer" +msgstr "" + +#. module: contract +#: model:ir.actions.act_window,name:contract.action_account_analytic_sale_overdue_all +#: model:ir.ui.menu,name:contract.menu_action_account_analytic_sale_overdue_all +msgid "Customer Contracts" +msgstr "" + #. module: contract #: model:ir.model.fields,field_description:contract.field_account_analytic_account_date_end #: model:ir.model.fields,field_description:contract.field_project_project_date_end @@ -306,7 +323,7 @@ msgid "Discount (%)" msgstr "" #. module: contract -#: code:addons/contract/models/account_analytic_contract_line.py:180 +#: code:addons/contract/models/account_analytic_contract_line.py:179 #, python-format msgid "Discount should be less or equal to 100" msgstr "" @@ -454,9 +471,9 @@ msgid "Partner and dependents" msgstr "" #. module: contract -#: code:addons/contract/models/account_analytic_account.py:214 +#: code:addons/contract/models/account_analytic_account.py:220 #, python-format -msgid "Please define a sale journal for the company '%s'." +msgid "Please define a %s journal for the company '%s'." msgstr "" #. module: contract @@ -485,6 +502,13 @@ msgstr "" msgid "Product" msgstr "" +#. module: contract +#: model:ir.model.fields,field_description:contract.field_res_partner_purchase_contract_count +#: model:ir.model.fields,field_description:contract.field_res_users_purchase_contract_count +#: model:ir.ui.view,arch_db:contract.view_partner_form +msgid "Purchase Contracts" +msgstr "" + #. 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 @@ -524,6 +548,13 @@ msgstr "" msgid "Responsible" msgstr "" +#. module: contract +#: model:ir.model.fields,field_description:contract.field_res_partner_sale_contract_count +#: model:ir.model.fields,field_description:contract.field_res_users_sale_contract_count +#: model:ir.ui.view,arch_db:contract.view_partner_form +msgid "Sale Contracts" +msgstr "" + #. module: contract #: model:ir.ui.view,arch_db:contract.account_analytic_account_recurring_form_form msgid "Send by Email" @@ -543,7 +574,12 @@ msgstr "" #. module: contract #: model:ir.ui.view,arch_db:contract.view_partner_form -msgid "Show the contracts for this partner" +msgid "Show the purchase contracts for this partner" +msgstr "" + +#. module: contract +#: model:ir.ui.view,arch_db:contract.view_partner_form +msgid "Show the sale contracts for this partner" msgstr "" #. module: contract @@ -572,6 +608,19 @@ msgstr "" msgid "Sub Total" msgstr "" +#. module: contract +#: selection:account.analytic.account,contract_type:0 +#: selection:account.analytic.contract,contract_type:0 +#: model:ir.ui.view,arch_db:contract.account_analytic_account_purchase_form +msgid "Supplier" +msgstr "" + +#. module: contract +#: model:ir.actions.act_window,name:contract.action_account_analytic_purchase_overdue_all +#: model:ir.ui.menu,name:contract.menu_action_account_analytic_purchase_overdue_all +msgid "Supplier Contracts" +msgstr "" + #. 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 @@ -613,13 +662,19 @@ msgid "You can't have a next invoicing date before the start of the contract '%s msgstr "" #. module: contract -#: code:addons/contract/models/account_analytic_account.py:206 +#: code:addons/contract/models/account_analytic_account.py:211 #, python-format msgid "You must first select a Customer for Contract %s!" msgstr "" #. module: contract -#: code:addons/contract/models/account_analytic_account.py:284 +#: code:addons/contract/models/account_analytic_account.py:207 +#, python-format +msgid "You must first select a Supplier for Contract %s!" +msgstr "" + +#. module: contract +#: code:addons/contract/models/account_analytic_account.py:294 #, python-format msgid "You must review start and end dates!\n" "%s" diff --git a/contract/models/account_analytic_account.py b/contract/models/account_analytic_account.py index 01f390376..bc268f79d 100644 --- a/contract/models/account_analytic_account.py +++ b/contract/models/account_analytic_account.py @@ -202,14 +202,19 @@ class AccountAnalyticAccount(models.Model): def _prepare_invoice(self, journal=None): self.ensure_one() if not self.partner_id: - raise ValidationError( - _("You must first select a Customer for Contract %s!") % - self.name) + if self.contract_type == 'purchase': + raise ValidationError( + _("You must first select a Supplier for Contract %s!") % + self.name) + else: + raise ValidationError( + _("You must first select a Customer for Contract %s!") % + self.name) if not journal: journal = self.journal_id or self.env['account.journal'].search([ - ('type', '=', self.contract_type), - ('company_id', '=', self.company_id.id) - ], limit=1) + ('type', '=', self.contract_type), + ('company_id', '=', self.company_id.id) + ], limit=1) if not journal: raise ValidationError( _("Please define a %s journal for the company '%s'.") % diff --git a/contract/models/account_analytic_contract.py b/contract/models/account_analytic_contract.py index 1d67fb3b5..162206cb6 100644 --- a/contract/models/account_analytic_contract.py +++ b/contract/models/account_analytic_contract.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2004-2010 OpenERP SA # Copyright 2014 Angel Moya # Copyright 2016 Carlos Dauden @@ -6,7 +5,7 @@ # Copyright 2015-2017 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models, _ +from odoo import api, fields, models class AccountAnalyticContract(models.Model): @@ -28,9 +27,9 @@ class AccountAnalyticContract(models.Model): ) contract_type = fields.Selection( selection=[ - ('sale', _('Sale')), - ('purchase', _('Purchase')), - ], default='sale' + ('sale', 'Customer'), + ('purchase', 'Supplier'), + ], default='sale', ) pricelist_id = fields.Many2one( comodel_name='product.pricelist', @@ -70,7 +69,8 @@ class AccountAnalyticContract(models.Model): 'account.journal', string='Journal', default=lambda s: s._default_journal(), - domain="[('company_id', '=', company_id)]", + domain="[('type', '=', contract_type)," + "('company_id', '=', company_id)]", ) company_id = fields.Many2one( 'res.company', @@ -81,6 +81,9 @@ class AccountAnalyticContract(models.Model): @api.onchange('contract_type') def _onchange_contract_type(self): + if self.contract_type == 'purchase': + self.recurring_invoice_line_ids.filtered('automatic_price').update( + {'automatic_price': False}) self.journal_id = self.env['account.journal'].search([ ('type', '=', self.contract_type), ('company_id', '=', self.company_id.id) @@ -91,6 +94,6 @@ class AccountAnalyticContract(models.Model): company_id = self.env.context.get( 'company_id', self.env.user.company_id.id) domain = [ - ('type', '=', 'sale'), + ('type', '=', self.contract_type), ('company_id', '=', company_id)] return self.env['account.journal'].search(domain, limit=1) diff --git a/contract/models/account_analytic_contract_line.py b/contract/models/account_analytic_contract_line.py index 5eff76aa7..9dbb0f05a 100644 --- a/contract/models/account_analytic_contract_line.py +++ b/contract/models/account_analytic_contract_line.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2004-2010 OpenERP SA # Copyright 2014 Angel Moya # Copyright 2016 Carlos Dauden diff --git a/contract/models/account_analytic_invoice_line.py b/contract/models/account_analytic_invoice_line.py index 9328178c0..a82c8ee63 100644 --- a/contract/models/account_analytic_invoice_line.py +++ b/contract/models/account_analytic_invoice_line.py @@ -9,7 +9,7 @@ class AccountAnalyticInvoiceLine(models.Model): _inherit = 'account.analytic.contract.line' analytic_account_id = fields.Many2one( - 'account.analytic.account', + comodel_name='account.analytic.account', string='Analytic Account', required=True, ondelete='cascade', diff --git a/contract/models/res_partner.py b/contract/models/res_partner.py index f175912a2..ead5e4c76 100644 --- a/contract/models/res_partner.py +++ b/contract/models/res_partner.py @@ -7,30 +7,45 @@ from odoo import fields, models class ResPartner(models.Model): _inherit = 'res.partner' - contract_count = fields.Integer( - string='Contracts', + sale_contract_count = fields.Integer( + string='Sale Contracts', + compute='_compute_contract_count', + ) + purchase_contract_count = fields.Integer( + string='Purchase Contracts', compute='_compute_contract_count', ) def _compute_contract_count(self): - Contract = self.env['account.analytic.account'] + contract_model = self.env['account.analytic.account'] today = fields.Date.today() + fetch_data = contract_model.read_group([ + ('recurring_invoices', '=', True), + ('partner_id', 'child_of', self.ids), + '|', + ('date_end', '=', False), + ('date_end', '>=', today)], + ['partner_id', 'contract_type'], ['partner_id', 'contract_type'], + lazy=False) + result = [[data['partner_id'][0], data['contract_type'], + data['__count']] for data in fetch_data] for partner in self: - partner.contract_count = Contract.search_count([ - ('recurring_invoices', '=', True), - ('partner_id', 'child_of', partner.ids), - '|', - ('date_end', '=', False), - ('date_end', '>=', today), - ]) + partner_child_ids = partner.child_ids.ids + partner.ids + partner.sale_contract_count = sum([ + r[2] for r in result + if r[0] in partner_child_ids and r[1] == 'sale']) + partner.purchase_contract_count = sum([ + r[2] for r in result + if r[0] in partner_child_ids and r[1] == 'purchase']) 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') + contract_type = self._context.get('contract_type') + + res = self._get_act_window_contract_xml(contract_type) res.update( context=dict( self.env.context, @@ -43,3 +58,11 @@ class ResPartner(models.Model): ), ) return res + + def _get_act_window_contract_xml(self, contract_type): + if contract_type == 'purchase': + return self.env['ir.actions.act_window'].for_xml_id( + 'contract', 'action_account_analytic_purchase_overdue_all') + else: + return self.env['ir.actions.act_window'].for_xml_id( + 'contract', 'action_account_analytic_sale_overdue_all') diff --git a/contract/readme/CONTRIBUTORS.rst b/contract/readme/CONTRIBUTORS.rst index c749c1ef5..ed395a7dd 100644 --- a/contract/readme/CONTRIBUTORS.rst +++ b/contract/readme/CONTRIBUTORS.rst @@ -3,3 +3,4 @@ * Angel Moya * Dave Lasley * Vicent Cubells +* Miquel Raïch diff --git a/contract/readme/DESCRIPTION.rst b/contract/readme/DESCRIPTION.rst index ab6e258df..7498c8300 100644 --- a/contract/readme/DESCRIPTION.rst +++ b/contract/readme/DESCRIPTION.rst @@ -1,4 +1,4 @@ -This module brings back the contracts management with recurring invoicing -features. Also you can print and send by email contract report. +This module enables contracts management with recurring +invoicing functions. Also you can print and send by email contract report. -In upstream Odoo, this functionality was moved into the Enterprise edition. +It works for customer contract and supplier contracts. diff --git a/contract/tests/test_contract.py b/contract/tests/test_contract.py index df9c05258..cc676bbbf 100644 --- a/contract/tests/test_contract.py +++ b/contract/tests/test_contract.py @@ -32,6 +32,15 @@ class TestContractBase(common.SavepointCase): 'date_start': '2016-02-15', 'recurring_next_date': '2016-02-29', }) + cls.contract2 = cls.env['account.analytic.account'].create({ + 'name': 'Test Contract 2', + 'partner_id': cls.partner.id, + 'pricelist_id': cls.partner.property_product_pricelist.id, + 'recurring_invoices': True, + 'date_start': '2016-02-15', + 'recurring_next_date': '2016-02-29', + 'contract_type': 'purchase', + }) cls.line_vals = { 'analytic_account_id': cls.contract.id, 'product_id': cls.product.id, @@ -275,24 +284,27 @@ class TestContract(TestContractBase): ])) def test_contract_count(self): - """It should return contract count.""" - count = self.partner.contract_count + 2 + """It should return sale contract count.""" + count = self.partner.sale_contract_count + 2 self.contract.copy() self.contract.copy() - self.assertEqual(self.partner.contract_count, count) + self.assertEqual(self.partner.sale_contract_count, count) + count = self.partner.purchase_contract_count + 1 + self.contract2.copy() + self.assertEqual(self.partner.purchase_contract_count, 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'] + account_invoice_model = self.env['account.invoice'] self.contract.write({ 'date_start': fields.Date.today(), 'date_end': fields.Date.today(), 'recurring_next_date': fields.Date.today(), }) - init_count = AccountInvoice.search_count( + init_count = account_invoice_model.search_count( [('contract_id', '=', self.contract.id)]) self.contract.cron_recurring_create_invoice() - last_count = AccountInvoice.search_count( + last_count = account_invoice_model.search_count( [('contract_id', '=', self.contract.id)]) self.assertEqual(last_count, init_count + 1) with self.assertRaises(ValidationError): @@ -311,14 +323,29 @@ class TestContract(TestContractBase): self.assertFalse(self.contract.create_invoice_visibility) def test_extend_invoice(self): - AccountInvoice = self.env['account.invoice'] + account_invoice_model = self.env['account.invoice'] self.contract.recurring_create_invoice() - invoice = AccountInvoice.search( + invoice = account_invoice_model.search( [('contract_id', '=', self.contract.id)]) invoice.origin = 'Orig Invoice' self.contract._create_invoice(invoice) self.assertEqual(invoice.origin, 'Orig Invoice Test Contract') - invoice_count = AccountInvoice.search_count( + invoice_count = account_invoice_model.search_count( [('contract_id', '=', self.contract.id)]) self.assertEqual(invoice_count, 1) self.assertEqual(len(invoice.invoice_line_ids), 2) + + def test_act_show_contract(self): + show_contract = self.partner.\ + with_context(contract_type='sale').act_show_contract() + self.assertDictContainsSubset( + { + 'name': 'Customer Contracts', + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'res_model': 'account.analytic.account', + 'xml_id': 'contract.action_account_analytic_sale_overdue_all', + }, + show_contract, + 'There was an error and the view couldn\'t be opened.' + ) diff --git a/contract/views/account_analytic_account_view.xml b/contract/views/account_analytic_account_view.xml index bf9ef8d5e..1db6df28f 100644 --- a/contract/views/account_analytic_account_view.xml +++ b/contract/views/account_analytic_account_view.xml @@ -16,6 +16,9 @@ +