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. + +