[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 <smetl@users.noreply.github.com>
This commit is contained in:
@@ -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 = {
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -523,7 +523,7 @@
|
||||
attrs="{'invisible': ['|', '|', ('state', '!=', 'draft'), ('auto_post', '=', True), ('move_type', '!=', 'entry')]}"/>
|
||||
<button name="action_post" string="Confirm" class="oe_highlight"
|
||||
type="object" groups="account.group_account_invoice"
|
||||
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)]}"/>
|
||||
<!-- Send (only invoices) -->
|
||||
<button name="action_invoice_sent"
|
||||
type="object"
|
||||
@@ -562,24 +562,33 @@
|
||||
</header>
|
||||
<!-- Invoice outstanding credits -->
|
||||
<div groups="account.group_account_invoice,account.group_account_readonly"
|
||||
class="alert alert-warning" role="alert" style="margin-bottom:0px;"
|
||||
class="alert alert-warning mb-0" role="alert"
|
||||
attrs="{'invisible': ['|', ('state', '!=', 'draft'), ('tax_lock_date_message', '=', False)]}">
|
||||
<field name="tax_lock_date_message" nolabel="1"/>
|
||||
</div>
|
||||
<div groups="account.group_account_invoice,account.group_account_readonly"
|
||||
class="alert alert-info" role="alert" style="margin-bottom:0px;"
|
||||
class="alert alert-info mb-0" role="alert"
|
||||
attrs="{'invisible': ['|', '|', ('move_type', 'not in', ('out_invoice', 'out_refund')), ('invoice_has_outstanding', '=', False), ('payment_state', 'not in', ('not_paid', 'partial'))]}">
|
||||
You have <bold><a class="alert-link" href="#outstanding" role="button">outstanding payments</a></bold> for this customer. You can allocate them to mark this invoice as paid.
|
||||
</div>
|
||||
<div groups="account.group_account_invoice,account.group_account_readonly"
|
||||
class="alert alert-info" role="alert" style="margin-bottom:0px;"
|
||||
class="alert alert-info mb-0" role="alert"
|
||||
attrs="{'invisible': ['|', '|', ('move_type', 'not in', ('in_invoice', 'in_refund')), ('invoice_has_outstanding', '=', False), ('payment_state', 'not in', ('not_paid', 'partial'))]}">
|
||||
You have <bold><a class="alert-link" href="#outstanding" role="button">outstanding debits</a></bold> for this vendor. You can allocate them to mark this bill as paid.
|
||||
</div>
|
||||
<div class="alert alert-info" role="alert" style="margin-bottom:0px;"
|
||||
<div class="alert alert-info mb-0" role="alert"
|
||||
attrs="{'invisible': ['|', ('state', '!=', 'draft'), ('auto_post', '=', False)]}">
|
||||
This move is configured to be posted automatically at the accounting date: <field name="date" readonly="1"/>.
|
||||
</div>
|
||||
<!-- Currency consistency -->
|
||||
<div class="alert alert-warning mb-0" role="alert"
|
||||
attrs="{'invisible': ['|', ('display_inactive_currency_warning', '=', False), ('move_type', 'not in', ('in_invoice', 'in_refund', 'in_receipt'))]}">
|
||||
In order to validate this bill, you must <button class="oe_link" type="object" name="action_activate_currency" style="padding: 0; vertical-align: baseline;">activate the currency of the bill</button>. The journal entries need to be computed by Odoo before being posted in your company's currency.
|
||||
</div>
|
||||
<div class="alert alert-warning mb-0" role="alert"
|
||||
attrs="{'invisible': ['|', ('display_inactive_currency_warning', '=', False), ('move_type', 'not in', ('out_invoice', 'out_refund', 'out_receipt'))]}">
|
||||
In order to validate this invoice, you must <button class="oe_link" type="object" name="action_activate_currency" style="padding: 0; vertical-align: baseline;">activate the currency of the invoice</button>. The journal entries need to be computed by Odoo before being posted in your company's currency.
|
||||
</div>
|
||||
<sheet>
|
||||
<div name="button_box" class="oe_button_box">
|
||||
<button name="open_reconcile_view"
|
||||
@@ -626,6 +635,7 @@
|
||||
<field name="has_reconciled_entries" invisible="1"/>
|
||||
<field name="restrict_mode_hash_table" invisible="1"/>
|
||||
<field name="country_code" invisible="1"/>
|
||||
<field name="display_inactive_currency_warning" invisible="1"/>
|
||||
|
||||
<div class="oe_title">
|
||||
<!-- Invoice draft header -->
|
||||
|
||||
Reference in New Issue
Block a user