From b94b52ff7e57472ea3de55c67540e1598500ea65 Mon Sep 17 00:00:00 2001 From: "Nicolas (vin)" Date: Fri, 3 Jul 2020 09:35:52 +0000 Subject: [PATCH] [IMP] account: Prevent inconsistent amounts and currencies on vendor bills. when a Vendor bill in an inactive currency is created (via an an EDI or the OCR, or when the user create the invoice in an active foreign currency, then desactivate it) it should not be possible to validate it. Task ID: #2289537 closes odoo/odoo#54096 Signed-off-by: Laurent Smet --- addons/account/models/account_move.py | 15 +++++++++++++ .../account/tests/test_account_move_entry.py | 22 +++++++++++++++++++ addons/account/views/account_move_views.xml | 20 ++++++++++++----- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 3aab065ed2c..8825ca162d3 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -316,6 +316,9 @@ class AccountMove(models.Model): tax_lock_date_message = fields.Char( compute='_compute_tax_lock_date_message', help="Technical field used to display a message when the invoice's accounting date is prior of the tax lock date.") + display_inactive_currency_warning = fields.Boolean( + compute="_compute_display_inactive_currency_warning", + help="Technical field used for tracking the status of the currency") # Technical field to hide Reconciled Entries stat button has_reconciled_entries = fields.Boolean(compute="_compute_has_reconciled_entries") show_reset_to_draft_button = fields.Boolean(compute='_compute_show_reset_to_draft_button') @@ -1355,6 +1358,11 @@ class AccountMove(models.Model): vendor_display_name = _('#Created by: %s', move.sudo().create_uid.name or self.env.user.name) move.invoice_partner_display_name = vendor_display_name + @api.depends('currency_id') + def _compute_display_inactive_currency_warning(self): + for move in self.with_context(active_test=False): + move.display_inactive_currency_warning = not move.currency_id.active + def _compute_payments_widget_to_reconcile_info(self): for move in self: move.invoice_outstanding_credits_debits_widget = json.dumps(False) @@ -2404,6 +2412,10 @@ class AccountMove(models.Model): if move.is_invoice(include_receipts=True) and float_compare(move.amount_total, 0.0, precision_rounding=move.currency_id.rounding) < 0: raise UserError(_("You cannot validate an invoice with a negative total amount. You should create a credit note instead. Use the action menu to transform it into a credit note or refund.")) + if move.display_inactive_currency_warning: + raise UserError(_("You cannot validate an invoice with an inactive currency: %s", + move.currency_id.name)) + # Handle case when the invoice_date is not set. In that case, the invoice_date is set at today and then, # lines are recomputed accordingly. # /!\ 'check_move_validity' must be there since the dynamic lines will be recomputed outside the 'onchange' @@ -2769,6 +2781,9 @@ class AccountMove(models.Model): action['res_id'] = self.copy().id return action + def action_activate_currency(self): + self.currency_id.filtered(lambda currency: not currency.active).write({'active': True}) + @api.model def _move_dict_to_preview_vals(self, move_vals, currency_id=None): preview_vals = { diff --git a/addons/account/tests/test_account_move_entry.py b/addons/account/tests/test_account_move_entry.py index 6b78445e442..2689cacf119 100644 --- a/addons/account/tests/test_account_move_entry.py +++ b/addons/account/tests/test_account_move_entry.py @@ -745,3 +745,25 @@ class TestAccountMove(AccountTestInvoicingCommon): # You can remove journal items if the related journal entry is draft. self.test_move.button_draft() self.test_move.line_ids.unlink() + + def test_account_move_inactive_currency_raise_error_on_post(self): + """ Ensure a move cannot be posted when using an inactive currency """ + move = self.env['account.move'].create({ + 'move_type': 'in_invoice', + 'partner_id': self.partner_a.id, + 'invoice_date': fields.Date.from_string('2019-01-01'), + 'currency_id': self.currency_data['currency'].id, + 'invoice_payment_term_id': self.pay_terms_a.id, + 'invoice_line_ids': [{}] + }) + + move.currency_id.active = False + + with self.assertRaises(UserError), self.cr.savepoint(): + move.action_post() + + # Make sure that the invoice can still be posted when the currency is active + move.action_activate_currency() + move.action_post() + + self.assertEqual(move.state, 'posted') diff --git a/addons/account/views/account_move_views.xml b/addons/account/views/account_move_views.xml index 6ff7f1c9e2d..6c83724046b 100644 --- a/addons/account/views/account_move_views.xml +++ b/addons/account/views/account_move_views.xml @@ -523,7 +523,7 @@ attrs="{'invisible': ['|', '|', ('state', '!=', 'draft'), ('auto_post', '=', True), ('move_type', '!=', 'entry')]}"/> . The journal entries need to be computed by Odoo before being posted in your company's currency. + +