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')]}"/>
+ attrs="{'invisible': ['|', '|', '|', ('state', '!=', 'draft'), ('auto_post', '=', True), ('move_type', '=', 'entry'), ('display_inactive_currency_warning','=',True)]}"/>