diff --git a/contract/models/contract.py b/contract/models/contract.py index 3a2a3e581..0090d8c7f 100644 --- a/contract/models/contract.py +++ b/contract/models/contract.py @@ -34,8 +34,12 @@ class ContractContract(models.Model): ) currency_id = fields.Many2one( compute="_compute_currency_id", + inverse="_inverse_currency_id", comodel_name="res.currency", string="Currency", + ) + manual_currency_id = fields.Many2one( + comodel_name="res.currency", readonly=True, ) contract_template_id = fields.Many2one( @@ -149,23 +153,46 @@ class ContractContract(models.Model): ) return invoices - @api.depends("pricelist_id", "partner_id", "journal_id", "company_id") + def _get_computed_currency(self): + """Helper method for returning the theoretical computed currency.""" + self.ensure_one() + currency = self.env['res.currency'] + if any(self.contract_line_ids.mapped('automatic_price')): + # Use pricelist currency + currency = ( + self.pricelist_id.currency_id or + self.partner_id.with_context( + force_company=self.company_id.id, + ).property_product_pricelist.currency_id + ) + return ( + currency or self.journal_id.currency_id or + self.company_id.currency_id + ) + + @api.depends( + "manual_currency_id", + "pricelist_id", + "partner_id", + "journal_id", + "company_id", + ) def _compute_currency_id(self): for rec in self: - currency = self.env['res.currency'] - if any(rec.contract_line_ids.mapped('automatic_price')): - # Use pricelist currency - currency = ( - rec.pricelist_id.currency_id or - rec.partner_id.with_context( - force_company=rec.company_id.id, - ).property_product_pricelist.currency_id - ) - rec.currency_id = ( - currency.id or - rec.journal_id.currency_id.id or - rec.company_id.currency_id.id - ) + if rec.manual_currency_id: + rec.currency_id = rec.manual_currency_id + else: + rec.currency_id = rec._get_computed_currency() + + def _inverse_currency_id(self): + """If the currency is different from the computed one, then save it + in the manual field. + """ + for rec in self: + if rec._get_computed_currency() != rec.currency_id: + rec.manual_currency_id = rec.currency_id + else: + rec.manual_currency_id = False @api.multi def _compute_invoice_count(self): diff --git a/contract/tests/test_contract.py b/contract/tests/test_contract.py index 87039a25a..c795e1eff 100644 --- a/contract/tests/test_contract.py +++ b/contract/tests/test_contract.py @@ -2512,3 +2512,39 @@ class TestContract(TestContractBase): 'terminate_comment', to_date('2018-02-13'), ) + + def test_currency(self): + currency_eur = self.env.ref("base.EUR") + currency_cad = self.env.ref("base.CAD") + # Get currency from company + self.contract2.journal_id = False + self.assertEqual( + self.contract2.currency_id, self.contract2.company_id.currency_id) + # Get currency from journal + journal = self.env["account.journal"].create({ + "name": "Test journal CAD", + "code": "TCAD", + "type": "sale", + "currency_id": currency_cad.id, + }) + self.contract2.journal_id = journal.id + self.assertEqual(self.contract2.currency_id, currency_cad) + # Get currency from contract pricelist + pricelist = self.env['product.pricelist'].create({ + "name": "Test pricelist", + "currency_id": currency_eur.id, + }) + self.contract2.pricelist_id = pricelist.id + self.contract2.contract_line_ids.automatic_price = True + self.assertEqual(self.contract2.currency_id, currency_eur) + # Get currency from partner pricelist + self.contract2.pricelist_id = False + self.contract2.partner_id.property_product_pricelist = pricelist.id + pricelist.currency_id = currency_cad.id + self.assertEqual(self.contract2.currency_id, currency_cad) + # Assign manual currency + self.contract2.manual_currency_id = currency_eur.id + self.assertEqual(self.contract2.currency_id, currency_eur) + # Assign same currency as computed one + self.contract2.currency_id = currency_cad.id + self.assertFalse(self.contract2.manual_currency_id)