From 6adaec714a9d8635b4ac4b1c0bf7c0be25b73af9 Mon Sep 17 00:00:00 2001 From: jbw Date: Fri, 18 Jun 2021 12:37:35 +0000 Subject: [PATCH] [IMP] account: Reversal on same journal type as original AccountMove For data quality purposes and bug prevention, when I reverse an entry, the reversal should always be postable on a journal having the same type as the initial Journal Entry's journal. closes odoo/odoo#72431 Task: 2497529 Related: odoo/enterprise#19543 Signed-off-by: Laurent Smet --- .../tests/test_account_move_in_invoice.py | 4 ++ .../tests/test_account_move_out_invoice.py | 5 +++ .../account/wizard/account_move_reversal.py | 40 ++++++++++++++++++- .../wizard/account_move_reversal_view.xml | 19 ++++----- ...st_anglo_saxon_valuation_reconciliation.py | 1 + addons/sale/tests/test_sale_refund.py | 3 ++ ...st_anglo_saxon_valuation_reconciliation.py | 1 + 7 files changed, 62 insertions(+), 11 deletions(-) diff --git a/addons/account/tests/test_account_move_in_invoice.py b/addons/account/tests/test_account_move_in_invoice.py index c9df200825c..e390599c54f 100644 --- a/addons/account/tests/test_account_move_in_invoice.py +++ b/addons/account/tests/test_account_move_in_invoice.py @@ -1141,6 +1141,7 @@ class TestAccountMoveInInvoiceOnchanges(AccountTestInvoicingCommon): 'date': fields.Date.from_string('2019-02-01'), 'reason': 'no reason', 'refund_method': 'refund', + 'journal_id': self.invoice.journal_id.id, }) reversal = move_reversal.reverse_moves() reverse_move = self.env['account.move'].browse(reversal['res_id']) @@ -1192,6 +1193,7 @@ class TestAccountMoveInInvoiceOnchanges(AccountTestInvoicingCommon): 'date': fields.Date.from_string('2019-02-01'), 'reason': 'no reason again', 'refund_method': 'cancel', + 'journal_id': self.invoice.journal_id.id, }) reversal = move_reversal.reverse_moves() reverse_move = self.env['account.move'].browse(reversal['res_id']) @@ -1255,6 +1257,7 @@ class TestAccountMoveInInvoiceOnchanges(AccountTestInvoicingCommon): 'date': fields.Date.from_string('2017-01-01'), 'reason': 'no reason', 'refund_method': 'refund', + 'journal_id': self.invoice.journal_id.id, }) reversal = move_reversal.reverse_moves() reverse_move = self.env['account.move'].browse(reversal['res_id']) @@ -1312,6 +1315,7 @@ class TestAccountMoveInInvoiceOnchanges(AccountTestInvoicingCommon): 'date': fields.Date.from_string('2017-01-01'), 'reason': 'no reason again', 'refund_method': 'cancel', + 'journal_id': self.invoice.journal_id.id, }) reversal = move_reversal.reverse_moves() reverse_move = self.env['account.move'].browse(reversal['res_id']) diff --git a/addons/account/tests/test_account_move_out_invoice.py b/addons/account/tests/test_account_move_out_invoice.py index 198ddbf426a..2d716d54d3f 100644 --- a/addons/account/tests/test_account_move_out_invoice.py +++ b/addons/account/tests/test_account_move_out_invoice.py @@ -1746,6 +1746,7 @@ class TestAccountMoveOutInvoiceOnchanges(AccountTestInvoicingCommon): 'date': fields.Date.from_string('2019-02-01'), 'reason': 'no reason', 'refund_method': 'refund', + 'journal_id': self.invoice.journal_id.id, }) reversal = move_reversal.reverse_moves() reverse_move = self.env['account.move'].browse(reversal['res_id']) @@ -1798,6 +1799,7 @@ class TestAccountMoveOutInvoiceOnchanges(AccountTestInvoicingCommon): 'date': fields.Date.from_string('2019-02-01'), 'reason': 'no reason', 'refund_method': 'cancel', + 'journal_id': self.invoice.journal_id.id, }) reversal = move_reversal.reverse_moves() reverse_move = self.env['account.move'].browse(reversal['res_id']) @@ -1861,6 +1863,7 @@ class TestAccountMoveOutInvoiceOnchanges(AccountTestInvoicingCommon): 'date': fields.Date.from_string('2017-01-01'), 'reason': 'no reason', 'refund_method': 'refund', + 'journal_id': self.invoice.journal_id.id, }) reversal = move_reversal.reverse_moves() reverse_move = self.env['account.move'].browse(reversal['res_id']) @@ -1918,6 +1921,7 @@ class TestAccountMoveOutInvoiceOnchanges(AccountTestInvoicingCommon): 'date': fields.Date.from_string('2017-01-01'), 'reason': 'no reason', 'refund_method': 'cancel', + 'journal_id': self.invoice.journal_id.id, }) reversal = move_reversal.reverse_moves() reverse_move = self.env['account.move'].browse(reversal['res_id']) @@ -1978,6 +1982,7 @@ class TestAccountMoveOutInvoiceOnchanges(AccountTestInvoicingCommon): 'date': fields.Date.today() + timedelta(days=7), 'reason': 'no reason', 'refund_method': 'modify', + 'journal_id': self.invoice.journal_id.id, }) move_reversal.reverse_moves() refund = self.env['account.move'].search([('move_type', '=', 'out_refund'), ('company_id', '=', self.invoice.company_id.id)]) diff --git a/addons/account/wizard/account_move_reversal.py b/addons/account/wizard/account_move_reversal.py index d532f8bb716..c7e13569c08 100644 --- a/addons/account/wizard/account_move_reversal.py +++ b/addons/account/wizard/account_move_reversal.py @@ -26,14 +26,50 @@ class AccountMoveReversal(models.TransientModel): ('modify', 'Full refund and new draft invoice') ], string='Credit Method', required=True, help='Choose how you want to credit this invoice. You cannot "modify" nor "cancel" if the invoice is already reconciled.') - journal_id = fields.Many2one('account.journal', string='Use Specific Journal', help='If empty, uses the journal of the journal entry to be reversed.', check_company=True) + journal_id = fields.Many2one( + comodel_name='account.journal', + string='Use Specific Journal', + required=True, + compute='_compute_journal_id', + readonly=False, + store=True, + check_company=True, + help='If empty, uses the journal of the journal entry to be reversed.', + ) company_id = fields.Many2one('res.company', required=True, readonly=True) + available_journal_ids = fields.Many2many('account.journal', compute='_compute_available_journal_ids') # computed fields residual = fields.Monetary(compute="_compute_from_moves") currency_id = fields.Many2one('res.currency', compute="_compute_from_moves") move_type = fields.Char(compute="_compute_from_moves") + @api.depends('move_ids') + def _compute_journal_id(self): + for record in self: + if record.journal_id: + record.journal_id = record.journal_id + else: + journals = record.move_ids.journal_id.filtered(lambda x: x.active) + record.journal_id = journals[0] if journals else None + + @api.depends('move_ids') + def _compute_available_journal_ids(self): + for record in self: + if record.move_ids: + record.available_journal_ids = self.env['account.journal'].search([ + ('company_id', '=', record.company_id.id), + ('type', 'in', record.move_ids.journal_id.mapped('type')), + ]) + else: + record.available_journal_ids = self.env['account.journal'].search([('company_id', '=', record.company_id.id)]) + + @api.constrains('journal_id', 'move_ids') + def _check_journal_type(self): + for record in self: + if record.journal_id.type not in record.move_ids.journal_id.mapped('type'): + raise UserError(_('Journal should be of type of reversed entry.')) + @api.model def default_get(self, fields): res = super(AccountMoveReversal, self).default_get(fields) @@ -65,7 +101,7 @@ class AccountMoveReversal(models.TransientModel): else _('Reversal of: %s', move.name), 'date': reverse_date, 'invoice_date': move.is_invoice(include_receipts=True) and (self.date or move.date) or False, - 'journal_id': self.journal_id and self.journal_id.id or move.journal_id.id, + 'journal_id': self.journal_id.id, 'invoice_payment_term_id': None, 'invoice_user_id': move.invoice_user_id.id, 'auto_post': True if reverse_date > fields.Date.context_today(self) else False, diff --git a/addons/account/wizard/account_move_reversal_view.xml b/addons/account/wizard/account_move_reversal_view.xml index 2087b5165a4..0aa100b71e5 100644 --- a/addons/account/wizard/account_move_reversal_view.xml +++ b/addons/account/wizard/account_move_reversal_view.xml @@ -10,6 +10,7 @@ + @@ -28,15 +29,15 @@ - - - - - - - - - + + + + + + + + +