[FIX] account, sale: prevent reversal of moves across companies/branches

Steps to reproduce:

- Create a child company.
- In the child company, create a new sales journal.
- Create and confirm an invoice using this new journal.
- Attempt to create a credit note from that invoice.

In this scenario, you would encounter an error.

Cause:

The `AccountMoveReversal` wizard is currently setting its company to the
root company of the moves, which in this case is the parent company.
However, its journal is set to the one created in the child company.
This mismatch causes an error due to company inconsistency.

Fix:

The `company_id` of `AccountMoveReversal` will now be assigned to the
company of the moves, rather than the root company. To ensure this works
correctly, we also added a check to guarantee that all moves being
reversed are from the same company.

Note:

This fix also resolves an issue where a traceback occurred if two
invoices were created (one in the child company and another in the
parent company) and an attempt was made to reverse both simultaneously.

opw-3640719

closes odoo/odoo#153396

X-original-commit: cd62e3fcaab3e71e606607308cace739bc480c4f
Signed-off-by: Florian Gilbert (flg) <flg@odoo.com>
Signed-off-by: Séna Serge Nshimiyimana (sesn) <sesn@odoo.com>
This commit is contained in:
sesn-odoo
2024-02-13 08:30:15 +00:00
parent dca2dd0550
commit c5e380fc56
3 changed files with 39 additions and 7 deletions
@@ -4050,3 +4050,32 @@ class TestAccountMoveOutInvoiceOnchanges(AccountTestInvoicingCommon):
# The integrity check should work
integrity_check = invoice.company_id._check_hash_integrity()['results'][0]
self.assertEqual(integrity_check['msg_cover'], 'All entries are hashed.')
def test_out_invoice_create_cross_branch_refund(self):
"""You should not be able to reverse moves from different branches."""
# create a new branch
self.env.company.write({
'child_ids': [
Command.create({'name': 'Branch A'}),
],
})
self.cr.precommit.run() # load the CoA
# create an invoice on the new branch
branch_a = self.env.company.child_ids
branch_invoice = self.init_invoice('out_invoice', products=self.product_a, company=branch_a)
branch_invoice.action_post()
self.invoice.action_post()
with self.assertRaises(UserError) as error_catcher:
# attempt to reverse both the parent's and the branch's move at once
move_reversal = self.env['account.move.reversal'].with_context(
active_model="account.move",
active_ids=(branch_invoice + self.invoice).ids,
).create({})
move_reversal.refund_moves()
self.assertEqual(error_catcher.exception.args[0], "All selected moves for reversal must belong to the same company.")
@@ -68,10 +68,13 @@ class AccountMoveReversal(models.TransientModel):
res = super(AccountMoveReversal, self).default_get(fields)
move_ids = self.env['account.move'].browse(self.env.context['active_ids']) if self.env.context.get('active_model') == 'account.move' else self.env['account.move']
if len(move_ids.company_id) > 1:
raise UserError(_("All selected moves for reversal must belong to the same company."))
if any(move.state != "posted" for move in move_ids):
raise UserError(_('You can only reverse posted moves.'))
if 'company_id' in fields:
res['company_id'] = move_ids.company_id.root_id.id or self.env.company.id
res['company_id'] = move_ids.company_id.id or self.env.company.id
if 'move_ids' in fields:
res['move_ids'] = [(6, 0, move_ids.ids)]
return res
+6 -6
View File
@@ -93,12 +93,12 @@ class TestSaleOrderCreditLimit(TestSaleCommon):
invoice.action_post()
# Create a credit note reversing the invoice
self.env['account.move.reversal'].with_company(self.env.company).create(
{
'move_ids': [Command.set((invoice.id,))],
'journal_id': invoice.journal_id.id
}
).reverse_moves()
self.env['account.move.reversal'].with_company(self.env.company).with_context(
active_model="account.move",
active_ids=invoice.ids,
).create({
'journal_id': invoice.journal_id.id,
}).reverse_moves()
credit_note = sale_order.invoice_ids[1]
credit_note.action_post()