diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index d7d69b46379..f00ac1137bb 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -3342,6 +3342,23 @@ class AccountMove(models.Model): exchange_diff_moves.append(partial.exchange_move_id.id) return invoice_partials, exchange_diff_moves + def _reconcile_reversed_moves(self, reverse_moves, move_reverse_cancel): + ''' Reconciles moves in self and reverse moves + :param move_reverse_cancel: parameter used when lines are reconciled + will determine whether the tax cash basis journal entries should be created + :param reverse_moves: An account.move recordset, reverse of the current self. + :return: An account.move recordset, reverse of the current self. + ''' + for move, reverse_move in zip(self, reverse_moves): + group = (move.line_ids + reverse_move.line_ids) \ + .filtered(lambda l: not l.reconciled) \ + .grouped(lambda l: (l.account_id, l.currency_id)) + for (account, _currency), lines in group.items(): + if account.reconcile or account.account_type in ('asset_cash', 'liability_credit_card'): + lines.with_context(move_reverse_cancel=move_reverse_cancel).reconcile() + return reverse_moves + + def _reverse_moves(self, default_values_list=None, cancel=False): ''' Reverse a recordset of account.move. If cancel parameter is true, the reconcilable or liquidity lines @@ -3383,13 +3400,7 @@ class AccountMove(models.Model): # Reconcile moves together to cancel the previous one. if cancel: reverse_moves.with_context(move_reverse_cancel=cancel)._post(soft=False) - for move, reverse_move in zip(self, reverse_moves): - group = (move.line_ids + reverse_move.line_ids)\ - .filtered(lambda l: not l.reconciled)\ - .grouped(lambda l: (l.account_id, l.currency_id)) - for (account, _currency), lines in group.items(): - if account.reconcile or account.account_type in ('asset_cash', 'liability_credit_card'): - lines.with_context(move_reverse_cancel=cancel).reconcile() + reverse_moves = self._reconcile_reversed_moves(reverse_moves, cancel) return reverse_moves @@ -3456,8 +3467,8 @@ class AccountMove(models.Model): to_post = self for move in to_post: - if move.state == 'posted': - raise UserError(_('The entry %s (id %s) is already posted.') % (move.name, move.id)) + if move.state in ['posted', 'cancel']: + raise UserError(_('The entry %s (id %s) must be in draft.') % (move.name, move.id)) if not move.line_ids.filtered(lambda line: line.display_type not in ('line_section', 'line_note')): raise UserError(_('You need to add a line before posting.')) if move.auto_post != 'no' and move.date > fields.Date.context_today(self): @@ -3498,11 +3509,16 @@ class AccountMove(models.Model): if wrong_lines: wrong_lines.write({'partner_id': invoice.commercial_partner_id.id}) + # reconcile if state is in draft and move has reversal_entry_id set + draft_reverse_moves = to_post.filtered(lambda move: move.reversed_entry_id) + to_post.write({ 'state': 'posted', 'posted_before': True, }) + draft_reverse_moves.reversed_entry_id._reconcile_reversed_moves(draft_reverse_moves, False) + for invoice in to_post: invoice.message_subscribe([ p.id diff --git a/addons/account/tests/test_account_move_date_algorithm.py b/addons/account/tests/test_account_move_date_algorithm.py index c06ec23b45e..8a3ef917b3f 100644 --- a/addons/account/tests/test_account_move_date_algorithm.py +++ b/addons/account/tests/test_account_move_date_algorithm.py @@ -49,9 +49,8 @@ class TestAccountMoveDateAlgorithm(AccountTestInvoicingCommon): .create({ 'journal_id': invoice.journal_id.id, 'reason': "no reason", - 'refund_method': 'cancel', }) - reversal = move_reversal.reverse_moves() + reversal = move_reversal.refund_moves() return self.env['account.move'].browse(reversal['res_id']) # ------------------------------------------------------------------------- diff --git a/addons/account/tests/test_account_move_entry.py b/addons/account/tests/test_account_move_entry.py index 8936f78e3d6..d90f9c41626 100644 --- a/addons/account/tests/test_account_move_entry.py +++ b/addons/account/tests/test_account_move_entry.py @@ -606,10 +606,9 @@ class TestAccountMove(AccountTestInvoicingCommon): move_reversal = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=move.ids).create({ 'date': fields.Date.from_string('2021-02-01'), - 'refund_method': 'refund', 'journal_id': move.journal_id.id, }) - reversal = move_reversal.reverse_moves() + reversal = move_reversal.refund_moves() reversed_move = self.env['account.move'].browse(reversal['res_id']) self.assertRecordValues(reversed_move.line_ids, [ { diff --git a/addons/account/tests/test_account_move_in_invoice.py b/addons/account/tests/test_account_move_in_invoice.py index d98fae1ef34..d7ee2c60633 100644 --- a/addons/account/tests/test_account_move_in_invoice.py +++ b/addons/account/tests/test_account_move_in_invoice.py @@ -1116,10 +1116,9 @@ class TestAccountMoveInInvoiceOnchanges(AccountTestInvoicingCommon): move_reversal = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=self.invoice.ids).create({ '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() + reversal = move_reversal.refund_moves() reverse_move = self.env['account.move'].browse(reversal['res_id']) self.assertEqual(self.invoice.payment_state, 'not_paid', "Refunding with a draft credit note should keep the invoice 'not_paid'.") @@ -1168,10 +1167,9 @@ class TestAccountMoveInInvoiceOnchanges(AccountTestInvoicingCommon): move_reversal = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=self.invoice.ids).create({ 'date': fields.Date.from_string('2019-02-01'), 'reason': 'no reason again', - 'refund_method': 'modify', 'journal_id': self.invoice.journal_id.id, }) - reversal = move_reversal.reverse_moves() + reversal = move_reversal.modify_moves() new_move = self.env['account.move'].browse(reversal['res_id']) self.assertEqual(self.invoice.payment_state, 'reversed', "After cancelling it with a reverse invoice, an invoice should be in 'reversed' state.") @@ -1231,10 +1229,9 @@ class TestAccountMoveInInvoiceOnchanges(AccountTestInvoicingCommon): move_reversal = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=self.invoice.ids).create({ '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() + reversal = move_reversal.refund_moves() reverse_move = self.env['account.move'].browse(reversal['res_id']) self.assertEqual(self.invoice.payment_state, 'not_paid', "Refunding with a draft credit note should keep the invoice 'not_paid'.") @@ -1289,10 +1286,9 @@ class TestAccountMoveInInvoiceOnchanges(AccountTestInvoicingCommon): move_reversal = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=self.invoice.ids).create({ 'date': fields.Date.from_string('2017-01-01'), 'reason': 'no reason again', - 'refund_method': 'modify', 'journal_id': self.invoice.journal_id.id, }) - reversal = move_reversal.reverse_moves() + reversal = move_reversal.modify_moves() new_move = self.env['account.move'].browse(reversal['res_id']) self.assertEqual(self.invoice.payment_state, 'reversed', "After cancelling it with a reverse invoice, an invoice should be in 'reversed' state.") @@ -2182,10 +2178,9 @@ class TestAccountMoveInInvoiceOnchanges(AccountTestInvoicingCommon): .with_context(active_model='account.move', active_ids=move.ids)\ .create({ 'reason': 'no reason', - 'refund_method': 'refund', 'journal_id': move.journal_id.id, }) - reversal = move_reversal.reverse_moves() + reversal = move_reversal.refund_moves() reverse_move = self.env['account.move'].browse(reversal['res_id']) if reverse_move.move_type in ('out_refund', 'in_refund'): reverse_move.write({ @@ -2202,9 +2197,6 @@ class TestAccountMoveInInvoiceOnchanges(AccountTestInvoicingCommon): }) reverse_move.action_post() - (move + reverse_move).line_ids\ - .filtered(lambda line: line.account_type in ('asset_receivable', 'liability_payable'))\ - .reconcile() move = create_move(move_type, amount) line = move.line_ids.filtered(lambda line: line.account_type in ('asset_receivable', 'liability_payable')) diff --git a/addons/account/tests/test_account_move_out_invoice.py b/addons/account/tests/test_account_move_out_invoice.py index 0f0068f8ae9..e350eea5332 100644 --- a/addons/account/tests/test_account_move_out_invoice.py +++ b/addons/account/tests/test_account_move_out_invoice.py @@ -1732,10 +1732,9 @@ class TestAccountMoveOutInvoiceOnchanges(AccountTestInvoicingCommon): move_reversal = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=self.invoice.ids).create({ '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() + reversal = move_reversal.refund_moves() reverse_move = self.env['account.move'].browse(reversal['res_id']) self.assertEqual(self.invoice.payment_state, 'not_paid', "Refunding with a draft credit note should keep the invoice 'not_paid'.") @@ -1785,10 +1784,9 @@ class TestAccountMoveOutInvoiceOnchanges(AccountTestInvoicingCommon): move_reversal = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=self.invoice.ids).create({ 'date': fields.Date.from_string('2019-02-01'), 'reason': 'no reason', - 'refund_method': 'modify', 'journal_id': self.invoice.journal_id.id, }) - reversal = move_reversal.reverse_moves() + reversal = move_reversal.modify_moves() new_move = self.env['account.move'].browse(reversal['res_id']) self.assertEqual(self.invoice.payment_state, 'reversed', "After cancelling it with a reverse invoice, an invoice should be in 'reversed' state.") @@ -1848,10 +1846,9 @@ class TestAccountMoveOutInvoiceOnchanges(AccountTestInvoicingCommon): move_reversal = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=self.invoice.ids).create({ '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() + reversal = move_reversal.refund_moves() reverse_move = self.env['account.move'].browse(reversal['res_id']) self.assertEqual(self.invoice.payment_state, 'not_paid', "Refunding with a draft credit note should keep the invoice 'not_paid'.") @@ -1906,10 +1903,9 @@ class TestAccountMoveOutInvoiceOnchanges(AccountTestInvoicingCommon): move_reversal = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=self.invoice.ids).create({ 'date': fields.Date.from_string('2017-01-01'), 'reason': 'no reason', - 'refund_method': 'modify', 'journal_id': self.invoice.journal_id.id, }) - reversal = move_reversal.reverse_moves() + reversal = move_reversal.modify_moves() new_move = self.env['account.move'].browse(reversal['res_id']) self.assertEqual(self.invoice.payment_state, 'reversed', "After cancelling it with a reverse invoice, an invoice should be in 'reversed' state.") @@ -1967,10 +1963,9 @@ class TestAccountMoveOutInvoiceOnchanges(AccountTestInvoicingCommon): move_reversal = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=self.invoice.ids).create({ 'date': fields.Date.today() + timedelta(days=7), 'reason': 'no reason', - 'refund_method': 'modify', 'journal_id': self.invoice.journal_id.id, }) - move_reversal.reverse_moves() + move_reversal.modify_moves() refund = self.env['account.move'].search([('move_type', '=', 'out_refund'), ('company_id', '=', self.invoice.company_id.id)]) self.assertRecordValues(refund, [{ diff --git a/addons/account/tests/test_account_move_reconcile.py b/addons/account/tests/test_account_move_reconcile.py index 80b5230e517..bf70a2a2f55 100644 --- a/addons/account/tests/test_account_move_reconcile.py +++ b/addons/account/tests/test_account_move_reconcile.py @@ -3835,10 +3835,9 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon): .with_context(active_model='account.move', active_ids=invoice.ids)\ .create({ 'reason': "test_reconcile_cash_basis_tax_grid_reversal", - 'refund_method': 'refund', 'journal_id': invoice.journal_id.id, }) - refund = self.env['account.move'].browse(reversal_wizard.reverse_moves()['res_id']) + refund = self.env['account.move'].browse(reversal_wizard.refund_moves()['res_id']) refund.action_post() self.assertRecordValues(refund.line_ids.sorted('balance'), [ @@ -3851,10 +3850,9 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon): .with_context(active_model='account.move', active_ids=refund.ids)\ .create({ 'reason': "test_reconcile_cash_basis_tax_grid_reversal", - 'refund_method': 'refund', 'journal_id': refund.journal_id.id, }) - reversed_refund = self.env['account.move'].browse(reversal_wizard.reverse_moves()['res_id']) + reversed_refund = self.env['account.move'].browse(reversal_wizard.refund_moves()['res_id']) self.assertRecordValues(reversed_refund.line_ids.sorted('balance'), [ {'debit': 0.0, 'credit': 1000.0, 'tax_tag_ids': [], 'account_id': self.company_data['default_account_revenue'].id}, diff --git a/addons/account/wizard/account_move_reversal.py b/addons/account/wizard/account_move_reversal.py index 0ac44a19d09..33bf8eb4695 100644 --- a/addons/account/wizard/account_move_reversal.py +++ b/addons/account/wizard/account_move_reversal.py @@ -14,21 +14,11 @@ class AccountMoveReversal(models.TransientModel): move_ids = fields.Many2many('account.move', 'account_move_reversal_move', 'reversal_id', 'move_id', domain=[('state', '=', 'posted')]) new_move_ids = fields.Many2many('account.move', 'account_move_reversal_new_move', 'reversal_id', 'new_move_id') - date_mode = fields.Selection(selection=[ - ('custom', 'Specific'), - ('entry', 'Journal Entry Date') - ], required=True, default='custom') date = fields.Date(string='Reversal date', default=fields.Date.context_today) - reason = fields.Char(string='Reason') - refund_method = fields.Selection(selection=[ - ('refund', 'Partial Refund'), - ('cancel', 'Full Refund'), - ('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.') + reason = fields.Char(string='Reason displayed on Credit Note') journal_id = fields.Many2one( comodel_name='account.journal', - string='Use Specific Journal', + string='Journal', required=True, compute='_compute_journal_id', readonly=False, @@ -82,8 +72,6 @@ class AccountMoveReversal(models.TransientModel): 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)] - if 'refund_method' in fields: - res['refund_method'] = (len(move_ids) > 1 or move_ids.move_type == 'entry') and 'cancel' or 'refund' return res @api.depends('move_ids') @@ -95,7 +83,7 @@ class AccountMoveReversal(models.TransientModel): record.move_type = move_ids.move_type if len(move_ids) == 1 else (any(move.move_type in ('in_invoice', 'out_invoice') for move in move_ids) and 'some_invoice' or False) def _prepare_default_reversal(self, move): - reverse_date = self.date if self.date_mode == 'custom' else move.date + reverse_date = self.date return { 'ref': _('Reversal of: %(move_name)s, %(reason)s', move_name=move.name, reason=self.reason) if self.reason @@ -109,7 +97,7 @@ class AccountMoveReversal(models.TransientModel): 'auto_post': 'at_date' if reverse_date > fields.Date.context_today(self) else 'no', } - def reverse_moves(self): + def reverse_moves(self, is_modify=False): self.ensure_one() moves = self.move_ids @@ -124,7 +112,7 @@ class AccountMoveReversal(models.TransientModel): ] for move, default_vals in zip(moves, default_values_list): is_auto_post = default_vals.get('auto_post') != 'no' - is_cancel_needed = not is_auto_post and self.refund_method in ('cancel', 'modify') + is_cancel_needed = not is_auto_post and is_modify batch_index = 0 if is_cancel_needed else 1 batches[batch_index][0] |= move batches[batch_index][1].append(default_vals) @@ -134,10 +122,10 @@ class AccountMoveReversal(models.TransientModel): for moves, default_values_list, is_cancel_needed in batches: new_moves = moves._reverse_moves(default_values_list, cancel=is_cancel_needed) - if self.refund_method == 'modify': + if is_modify: moves_vals_list = [] for move in moves.with_context(include_business_fields=True): - moves_vals_list.append(move.copy_data({'date': self.date if self.date_mode == 'custom' else move.date})[0]) + moves_vals_list.append(move.copy_data({'date': self.date})[0]) new_moves = self.env['account.move'].create(moves_vals_list) moves_to_redirect |= new_moves @@ -164,3 +152,9 @@ class AccountMoveReversal(models.TransientModel): if len(set(moves_to_redirect.mapped('move_type'))) == 1: action['context'] = {'default_move_type': moves_to_redirect.mapped('move_type').pop()} return action + + def refund_moves(self): + return self.reverse_moves(is_modify=False) + + def modify_moves(self): + return self.reverse_moves(is_modify=True) diff --git a/addons/account/wizard/account_move_reversal_view.xml b/addons/account/wizard/account_move_reversal_view.xml index 96652d6f6b6..0ec7eaf035d 100644 --- a/addons/account/wizard/account_move_reversal_view.xml +++ b/addons/account/wizard/account_move_reversal_view.xml @@ -12,35 +12,13 @@ - - - - -
- The credit note is created in draft and can be edited before being issued. -
-
- The credit note is auto-validated and reconciled with the invoice. -
-
- The credit note is auto-validated and reconciled with the invoice. - The original invoice is duplicated as a new draft. -
-
-
- - - - - - + - - - +
-
diff --git a/addons/account_qr_code_sepa/tests/test_sepa_qr.py b/addons/account_qr_code_sepa/tests/test_sepa_qr.py index 1613e60566a..83e31ab8e98 100644 --- a/addons/account_qr_code_sepa/tests/test_sepa_qr.py +++ b/addons/account_qr_code_sepa/tests/test_sepa_qr.py @@ -71,10 +71,9 @@ class TestSEPAQRCode(AccountTestInvoicingCommon): move_reversal = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=self.sepa_qr_invoice.ids).create({ 'date': fields.Date.from_string('2019-02-01'), 'reason': 'no reason', - 'refund_method': 'refund', 'journal_id': self.sepa_qr_invoice.journal_id.id, }) - reversal = move_reversal.reverse_moves() + reversal = move_reversal.refund_moves() reverse_move = self.env['account.move'].browse(reversal['res_id']) self.assertFalse(reverse_move.qr_code_method, "qr_code_method for credit note should be None") diff --git a/addons/l10n_ar/demo/account_customer_refund_demo.xml b/addons/l10n_ar/demo/account_customer_refund_demo.xml index 3c1366c24de..6ef957ae544 100644 --- a/addons/l10n_ar/demo/account_customer_refund_demo.xml +++ b/addons/l10n_ar/demo/account_customer_refund_demo.xml @@ -4,34 +4,31 @@ Mercadería defectuosa - refund - + Venta cancelada - cancel - + Venta cancelada - cancel - + diff --git a/addons/l10n_ar/demo/account_supplier_refund_demo.xml b/addons/l10n_ar/demo/account_supplier_refund_demo.xml index edf3b0abe54..234449e5a8d 100644 --- a/addons/l10n_ar/demo/account_supplier_refund_demo.xml +++ b/addons/l10n_ar/demo/account_supplier_refund_demo.xml @@ -4,29 +4,26 @@ Mercadería defectuosa - refund 0001-01234567 - + Venta cancelada - cancel 0001-01234566 - + demo_sup_refund_invoice_5: liquido producto bill refund (credit note) - cancel 00011-00000012 @@ -34,6 +31,6 @@ - + diff --git a/addons/l10n_ar/tests/common.py b/addons/l10n_ar/tests/common.py index 2968387f0bd..27531d189a2 100644 --- a/addons/l10n_ar/tests/common.py +++ b/addons/l10n_ar/tests/common.py @@ -699,14 +699,13 @@ class TestAr(AccountTestInvoicingCommon): data = data or {} refund_wizard = self.env['account.move.reversal'].with_context({'active_ids': [invoice.id], 'active_model': 'account.move'}).create({ 'reason': data.get('reason', 'Mercadería defectuosa'), - 'refund_method': data.get('refund_method', 'refund'), 'journal_id': invoice.journal_id.id}) forced_document_type = data.get('document_type') if forced_document_type: refund_wizard.l10n_latam_document_type_id = forced_document_type.id - res = refund_wizard.reverse_moves() + res = refund_wizard.refund_moves() if data.get('refund_method', 'refund') == 'refund' else refund_wizard.modify_moves() refund = self.env['account.move'].browse(res['res_id']) return refund diff --git a/addons/l10n_es_edi_facturae/tests/test_edi_xml.py b/addons/l10n_es_edi_facturae/tests/test_edi_xml.py index c6c07b85b1b..4c0b4528131 100644 --- a/addons/l10n_es_edi_facturae/tests/test_edi_xml.py +++ b/addons/l10n_es_edi_facturae/tests/test_edi_xml.py @@ -207,11 +207,10 @@ class TestEdiFacturaeXmls(AccountEdiTestCommon): 'move_ids': invoice.ids, 'journal_id': invoice.journal_id.id, 'date': self.frozen_today, - 'refund_method': 'modify', 'company_id': self.company_data['company'].id, 'l10n_es_edi_facturae_reason_code': '01' }) - reversal_wizard.reverse_moves() + reversal_wizard.modify_moves() refund = invoice.reversal_move_id generated_file = refund._l10n_es_edi_facturae_render_facturae() self.assertTrue(generated_file) diff --git a/addons/l10n_es_edi_facturae/wizard/account_move_reversal.py b/addons/l10n_es_edi_facturae/wizard/account_move_reversal.py index 21fc498602a..9fcb73d46b7 100644 --- a/addons/l10n_es_edi_facturae/wizard/account_move_reversal.py +++ b/addons/l10n_es_edi_facturae/wizard/account_move_reversal.py @@ -30,8 +30,8 @@ class AccountMoveReversal(models.TransientModel): ('85', 'Taxable income modified by unpaid tax assessments. Order of declaration of bankruptcy'), ], string='Spanish Facturae EDI Reason Code', default='10') - def reverse_moves(self): + def reverse_moves(self, is_modify=False): # Extends account_account - res = super(AccountMoveReversal, self).reverse_moves() + res = super(AccountMoveReversal, self).reverse_moves(is_modify) self.new_move_ids.l10n_es_edi_facturae_reason_code = self.l10n_es_edi_facturae_reason_code return res diff --git a/addons/l10n_latam_invoice_document/wizards/account_move_reversal_view.xml b/addons/l10n_latam_invoice_document/wizards/account_move_reversal_view.xml index 90f7a67a57b..22318049a2c 100644 --- a/addons/l10n_latam_invoice_document/wizards/account_move_reversal_view.xml +++ b/addons/l10n_latam_invoice_document/wizards/account_move_reversal_view.xml @@ -12,8 +12,8 @@ - - + + diff --git a/addons/purchase_stock/tests/test_anglo_saxon_valuation_reconciliation.py b/addons/purchase_stock/tests/test_anglo_saxon_valuation_reconciliation.py index 69e51c811aa..05a43e4ee0a 100644 --- a/addons/purchase_stock/tests/test_anglo_saxon_valuation_reconciliation.py +++ b/addons/purchase_stock/tests/test_anglo_saxon_valuation_reconciliation.py @@ -106,11 +106,10 @@ class TestValuationReconciliation(ValuationReconciliationTestCommon): # Refund the invoice refund_invoice_wiz = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=[invoice.id]).create({ 'reason': 'test_invoice_shipment_refund', - 'refund_method': 'modify', 'date': '2018-03-15', 'journal_id': invoice.journal_id.id, }) - new_invoice = self.env['account.move'].browse(refund_invoice_wiz.reverse_moves()['res_id']) + new_invoice = self.env['account.move'].browse(refund_invoice_wiz.modify_moves()['res_id']) refund_invoice = invoice.reversal_move_id # Check the result self.assertEqual(invoice.payment_state, 'reversed', "Invoice should be in 'reversed' state") diff --git a/addons/sale/tests/test_sale_refund.py b/addons/sale/tests/test_sale_refund.py index ccb0b6c2fc5..0410fde6323 100644 --- a/addons/sale/tests/test_sale_refund.py +++ b/addons/sale/tests/test_sale_refund.py @@ -92,11 +92,10 @@ class TestSaleRefund(TestSaleCommon): # Make a credit note credit_note_wizard = self.env['account.move.reversal'].with_context({'active_ids': [self.invoice.id], 'active_id': self.invoice.id, 'active_model': 'account.move'}).create({ - 'refund_method': 'refund', # this is the only mode for which the SO line is linked to the refund (https://github.com/odoo/odoo/commit/e680f29560ac20133c7af0c6364c6ef494662eac) 'reason': 'reason test create', 'journal_id': self.invoice.journal_id.id, }) - credit_note_wizard.reverse_moves() + credit_note_wizard.refund_moves() invoice_refund = self.sale_order.invoice_ids.sorted(key=lambda inv: inv.id, reverse=False)[-1] # the first invoice, its refund, and the new invoice # Check invoice's type and number @@ -153,67 +152,6 @@ class TestSaleRefund(TestSaleCommon): self.assertEqual(line.untaxed_amount_invoiced, 0.0, "Amount invoiced decreased as the refund is now confirmed") self.assertEqual(len(line.invoice_lines), 2, "The line 'ordered service' is invoiced, so it should be linked to 2 invoice lines (invoice and refund)") - def test_refund_cancel(self): - """ Test invoice with a refund in 'cancel' mode, meaning a refund will be created and auto confirm to completely cancel the first - customer invoice. The SO will have 2 invoice (customer + refund) in a paid state at the end. """ - # Increase quantity of an invoice lines - with Form(self.invoice) as invoice_form: - with invoice_form.invoice_line_ids.edit(0) as line_form: - line_form.quantity = 6 - with invoice_form.invoice_line_ids.edit(1) as line_form: - line_form.quantity = 4 - - # Validate invoice - self.invoice.action_post() - - # Check quantity to invoice on SO lines - for line in self.sale_order.order_line: - if line.product_id.invoice_policy == 'delivery': - self.assertEqual(line.qty_to_invoice, 0.0, "Quantity to invoice should be same as ordered quantity") - self.assertEqual(line.qty_invoiced, 0.0, "Invoiced quantity should be zero as no any invoice created for SO") - self.assertEqual(line.untaxed_amount_to_invoice, 0.0, "The amount to invoice should be zero, as the line based on delivered quantity") - self.assertEqual(line.untaxed_amount_invoiced, 0.0, "The invoiced amount should be zero, as the line based on delivered quantity") - self.assertFalse(line.invoice_lines, "The line based on delivered qty are not invoiced, so they should not be linked to invoice line") - else: - self.assertEqual(line.untaxed_amount_to_invoice, line.price_unit * line.qty_to_invoice, "Amount to invoice is now set as qty to invoice * unit price since no price change on invoice, for ordered products") - self.assertEqual(line.untaxed_amount_invoiced, line.price_unit * line.qty_invoiced, "Amount invoiced is now set as qty invoiced * unit price since no price change on invoice, for ordered products") - self.assertEqual(len(line.invoice_lines), 1, "The lines 'ordered' qty are invoiced, so it should be linked to 1 invoice lines") - - self.assertEqual(line.qty_invoiced, line.product_uom_qty + 1, "The quantity invoiced is +1 unit from the one of the sale line, as we modified invoice lines (%s)" % (line.name,)) - self.assertEqual(line.qty_to_invoice, -1, "The quantity to invoice is negative as we invoice more than ordered") - - # Make a credit note - credit_note_wizard = self.env['account.move.reversal'].with_context({'active_ids': self.invoice.ids, 'active_id': self.invoice.id, 'active_model': 'account.move'}).create({ - 'refund_method': 'cancel', - 'reason': 'reason test cancel', - 'journal_id': self.invoice.journal_id.id, - }) - invoice_refund = self.env['account.move'].browse(credit_note_wizard.reverse_moves()['res_id']) - - # Check invoice's type and number - self.assertEqual(invoice_refund.move_type, 'out_refund', 'The last created invoiced should be a customer invoice') - self.assertEqual(invoice_refund.payment_state, 'paid', 'Last Customer creadit note should be in paid state') - self.assertEqual(self.sale_order.invoice_count, 2, "The SO should have 3 related invoices: the original, the refund, and the new one") - self.assertEqual(len(self.sale_order.invoice_ids.filtered(lambda inv: inv.move_type == 'out_refund')), 1, "The SO should be linked to only one refund") - self.assertEqual(len(self.sale_order.invoice_ids.filtered(lambda inv: inv.move_type == 'out_invoice')), 1, "The SO should be linked to only one customer invoices") - - # At this time, the invoice 1 is opened (validated) and its refund validated too, so the amounts invoiced are zero for - # all sale line. All invoiceable Sale lines have - for line in self.sale_order.order_line: - if line.product_id.invoice_policy == 'delivery': - self.assertEqual(line.qty_to_invoice, 0.0, "Quantity to invoice should be same as ordered quantity") - self.assertEqual(line.qty_invoiced, 0.0, "Invoiced quantity should be zero as no any invoice created for SO line based on delivered qty") - self.assertEqual(line.untaxed_amount_to_invoice, 0.0, "The amount to invoice should be zero, as the line based on delivered quantity") - self.assertEqual(line.untaxed_amount_invoiced, 0.0, "The invoiced amount should be zero, as the line based on delivered quantity") - self.assertFalse(line.invoice_lines, "The line based on delivered are not invoiced, so they should not be linked to invoice line") - else: - self.assertEqual(line.qty_to_invoice, line.product_uom_qty, "The quantity to invoice should be the ordered quantity") - self.assertEqual(line.qty_invoiced, 0, "The quantity invoiced is zero as the refund (paid) completely cancel the first invoice") - - self.assertEqual(line.untaxed_amount_to_invoice, line.price_unit * line.qty_to_invoice, "Amount to invoice is now set as qty to invoice * unit price since no price change on invoice, for ordered products") - self.assertEqual(line.untaxed_amount_invoiced, line.price_unit * line.qty_invoiced, "Amount invoiced is now set as qty invoiced * unit price since no price change on invoice, for ordered products") - self.assertEqual(len(line.invoice_lines), 2, "The lines 'ordered' qty are invoiced, so it should be linked to 1 invoice lines") - def test_refund_modify(self): """ Test invoice with a refund in 'modify' mode, and check customer invoices credit note is created from respective invoice """ # Decrease quantity of an invoice lines @@ -247,11 +185,10 @@ class TestSaleRefund(TestSaleCommon): # Make a credit note credit_note_wizard = self.env['account.move.reversal'].with_context({'active_ids': [self.invoice.id], 'active_id': self.invoice.id, 'active_model': 'account.move'}).create({ - 'refund_method': 'modify', # this is the only mode for which the SO line is linked to the refund (https://github.com/odoo/odoo/commit/e680f29560ac20133c7af0c6364c6ef494662eac) 'reason': 'reason test modify', 'journal_id': self.invoice.journal_id.id, }) - invoice_refund = self.env['account.move'].browse(credit_note_wizard.reverse_moves()['res_id']) + invoice_refund = self.env['account.move'].browse(credit_note_wizard.modify_moves()['res_id']) # Check invoice's type and number self.assertEqual(invoice_refund.move_type, 'out_invoice', 'The last created invoiced should be a customer invoice') @@ -384,11 +321,10 @@ class TestSaleRefund(TestSaleCommon): so_invoice.action_post() credit_note_wizard = self.env['account.move.reversal'].with_context({'active_ids': [so_invoice.id], 'active_id': so_invoice.id, 'active_model': 'account.move'}).create({ - 'refund_method': 'refund', 'reason': 'reason test refund with downpayment', 'journal_id': so_invoice.journal_id.id, }) - credit_note_wizard.reverse_moves() + credit_note_wizard.refund_moves() invoice_refund = sale_order_refund.invoice_ids.sorted(key=lambda inv: inv.id, reverse=False)[-1] invoice_refund.action_post() diff --git a/addons/sale_mrp/tests/test_sale_mrp_anglo_saxon_valuation.py b/addons/sale_mrp/tests/test_sale_mrp_anglo_saxon_valuation.py index a2a9838d085..dde258af42c 100644 --- a/addons/sale_mrp/tests/test_sale_mrp_anglo_saxon_valuation.py +++ b/addons/sale_mrp/tests/test_sale_mrp_anglo_saxon_valuation.py @@ -302,10 +302,9 @@ class TestSaleMRPAngloSaxonValuation(ValuationReconciliationTestCommon): # Add a credit note for the returned kit ctx = {'active_model': 'account.move', 'active_ids': invoice.ids} refund_wizard = self.env['account.move.reversal'].with_context(ctx).create({ - 'refund_method': 'refund', 'journal_id': invoice.journal_id.id, }) - action = refund_wizard.reverse_moves() + action = refund_wizard.refund_moves() reverse_invoice = self.env['account.move'].browse(action['res_id']) with Form(reverse_invoice) as reverse_invoice_form: with reverse_invoice_form.invoice_line_ids.edit(0) as line: diff --git a/addons/sale_mrp/tests/test_sale_mrp_flow.py b/addons/sale_mrp/tests/test_sale_mrp_flow.py index ea88818af98..9e57a6a022f 100644 --- a/addons/sale_mrp/tests/test_sale_mrp_flow.py +++ b/addons/sale_mrp/tests/test_sale_mrp_flow.py @@ -2220,10 +2220,9 @@ class TestSaleMrpFlow(ValuationReconciliationTestCommon): invoice01.action_post() move_reversal = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=invoice01.ids).create({ - 'refund_method': 'modify', 'journal_id': invoice01.journal_id.id, }) - reversal = move_reversal.reverse_moves() + reversal = move_reversal.modify_moves() invoice02 = self.env['account.move'].browse(reversal['res_id']) invoice02.action_post() diff --git a/addons/sale_stock/tests/test_anglo_saxon_valuation.py b/addons/sale_stock/tests/test_anglo_saxon_valuation.py index 4423c0881a9..1b8de31822b 100644 --- a/addons/sale_stock/tests/test_anglo_saxon_valuation.py +++ b/addons/sale_stock/tests/test_anglo_saxon_valuation.py @@ -1441,10 +1441,9 @@ class TestAngloSaxonValuation(ValuationReconciliationTestCommon): # Add a credit note for the returned product ctx = {'active_model': 'account.move', 'active_ids': invoice.ids} refund_wizard = self.env['account.move.reversal'].with_context(ctx).create({ - 'refund_method': 'refund', 'journal_id': invoice.journal_id.id, }) - action = refund_wizard.reverse_moves() + action = refund_wizard.refund_moves() reverse_invoice = self.env['account.move'].browse(action['res_id']) with Form(reverse_invoice) as reverse_invoice_form: with reverse_invoice_form.invoice_line_ids.edit(0) as line: @@ -1672,10 +1671,9 @@ class TestAngloSaxonValuation(ValuationReconciliationTestCommon): invoice01.action_post() move_reversal = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=invoice01.ids).create({ - 'refund_method': 'modify', 'journal_id': invoice01.journal_id.id, }) - reversal = move_reversal.reverse_moves() + reversal = move_reversal.modify_moves() invoice02 = self.env['account.move'].browse(reversal['res_id']) invoice02.action_post() diff --git a/addons/sale_stock/tests/test_anglo_saxon_valuation_reconciliation.py b/addons/sale_stock/tests/test_anglo_saxon_valuation_reconciliation.py index 763253041a8..13eb570d8be 100644 --- a/addons/sale_stock/tests/test_anglo_saxon_valuation_reconciliation.py +++ b/addons/sale_stock/tests/test_anglo_saxon_valuation_reconciliation.py @@ -116,10 +116,9 @@ class TestValuationReconciliation(TestValuationReconciliationCommon): return_pick._action_done() refund_invoice_wiz = self.env['account.move.reversal'].with_context(active_model='account.move', active_ids=[invoice.id]).create({ 'reason': 'test_invoice_shipment_refund', - 'refund_method': 'modify', 'journal_id': invoice.journal_id.id, }) - new_invoice = self.env['account.move'].browse(refund_invoice_wiz.reverse_moves()['res_id']) + new_invoice = self.env['account.move'].browse(refund_invoice_wiz.modify_moves()['res_id']) self.assertEqual(invoice.payment_state, 'reversed', "Invoice should be in 'reversed' state.") self.assertEqual(invoice.reversal_move_id.payment_state, 'paid', "Refund should be in 'paid' state.") self.assertEqual(new_invoice.state, 'draft', "New invoice should be in 'draft' state.") diff --git a/addons/sale_stock/tests/test_sale_stock_report.py b/addons/sale_stock/tests/test_sale_stock_report.py index 3c8f86bf8a1..2d8d565d409 100644 --- a/addons/sale_stock/tests/test_sale_stock_report.py +++ b/addons/sale_stock/tests/test_sale_stock_report.py @@ -394,11 +394,11 @@ class TestSaleStockInvoices(TestSaleCommon): # Refund the invoice refund_wizard = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=invoice01.ids).create({ - 'refund_method': 'cancel', 'journal_id': invoice01.journal_id.id, }) - res = refund_wizard.reverse_moves() + res = refund_wizard.refund_moves() refund_invoice = self.env['account.move'].browse(res['res_id']) + refund_invoice.action_post() # recieve the returned product stock_return_picking_form = Form(self.env['stock.return.picking'].with_context(active_ids=picking.ids, active_id=picking.sorted().ids[0], active_model='stock.picking')) @@ -454,10 +454,9 @@ class TestSaleStockInvoices(TestSaleCommon): # Refund the invoice with full refund and new draft invoice refund_wizard = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=invoice01.ids).create({ - 'refund_method': 'modify', 'journal_id': invoice01.journal_id.id, }) - res = refund_wizard.reverse_moves() + res = refund_wizard.modify_moves() invoice02 = self.env['account.move'].browse(res['res_id']) invoice02.action_post() diff --git a/addons/sale_timesheet/tests/test_reinvoice.py b/addons/sale_timesheet/tests/test_reinvoice.py index d10df27b5fc..a405f7be2aa 100644 --- a/addons/sale_timesheet/tests/test_reinvoice.py +++ b/addons/sale_timesheet/tests/test_reinvoice.py @@ -350,10 +350,9 @@ class TestReInvoice(TestCommonSaleTimesheet): } refund_invoice_wiz = self.env['account.move.reversal'].with_context(wiz_context).create({ 'reason': 'please reverse :c', - 'refund_method': 'refund', 'date': today, }) - refund_invoice = self.env['account.move'].browse(refund_invoice_wiz.reverse_moves()['res_id']) + refund_invoice = self.env['account.move'].browse(refund_invoice_wiz.refund_moves()['res_id']) refund_invoice.action_post() # reversing with action_reverse and then action_post does not reset the invoice_status to 'to invoice' in tests diff --git a/addons/stock_account/tests/test_stockvaluationlayer.py b/addons/stock_account/tests/test_stockvaluationlayer.py index 986525c32ff..e3d3be0d894 100644 --- a/addons/stock_account/tests/test_stockvaluationlayer.py +++ b/addons/stock_account/tests/test_stockvaluationlayer.py @@ -1150,10 +1150,9 @@ class TestAngloSaxonAccounting(AccountTestInvoicingCommon, TestStockValuationCom self.assertEqual(self.product1.standard_price, 15) refund_wizard = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=invoice.ids).create({ - 'refund_method': 'refund', 'journal_id': invoice.journal_id.id, }) - action = refund_wizard.reverse_moves() + action = refund_wizard.refund_moves() reverse_invoice = self.env['account.move'].browse(action['res_id']) with Form(reverse_invoice) as reverse_invoice_form: with reverse_invoice_form.invoice_line_ids.edit(0) as line: