diff --git a/account_payment_order/models/account_move_line.py b/account_payment_order/models/account_move_line.py index 0638c4ddc..bc9a5e80a 100644 --- a/account_payment_order/models/account_move_line.py +++ b/account_payment_order/models/account_move_line.py @@ -58,6 +58,7 @@ class AccountMoveLine(models.Model): communication = self.ref or self.name # change these default values if move line is linked to an invoice if self.move_id.is_invoice(): + references = [] if (self.move_id.reference_type or "none") != "none": communication = self.move_id.ref ref2comm_type = aplo.invoice_reference_type2communication_type() @@ -73,11 +74,25 @@ class AccountMoveLine(models.Model): communication = self.move_id.payment_reference or self.move_id.name # If we have credit note(s) - reversal_move_id is a one2many if self.move_id.reversal_move_id: - references = [ - move.payment_reference or move.ref - for move in self.move_id.reversal_move_id - if move.payment_reference or move.ref - ] + references.extend( + [ + move.payment_reference or move.ref + for move in self.move_id.reversal_move_id + if move.payment_reference or move.ref + ] + ) + # Retrieve partial payments - e.g.: manual credit notes + for ( + _, + _, + payment_move_line, + ) in self.move_id._get_reconciled_invoices_partials(): + payment_move = payment_move_line.move_id + if payment_move.payment_reference or payment_move.ref: + references.append( + payment_move.payment_reference or payment_move.ref + ) + if references: communication += " " + " ".join(references) return communication_type, communication diff --git a/account_payment_order/tests/test_payment_order_outbound.py b/account_payment_order/tests/test_payment_order_outbound.py index 99cf6f188..dd243b9fd 100644 --- a/account_payment_order/tests/test_payment_order_outbound.py +++ b/account_payment_order/tests/test_payment_order_outbound.py @@ -86,7 +86,31 @@ class TestPaymentOrderOutboundBase(AccountTestInvoicingCommon): return invoice - def _create_supplier_refund(self, move): + def _create_supplier_refund(self, move, manual=False): + if manual: + # Do the supplier refund manually + vals = { + "partner_id": self.partner.id, + "move_type": "in_refund", + "ref": move.ref, + "payment_mode_id": self.mode.id, + "invoice_date": fields.Date.today(), + "invoice_line_ids": [ + ( + 0, + None, + { + "product_id": self.env.ref("product.product_product_4").id, + "quantity": 1.0, + "price_unit": 90.0, + "name": "refund of 90.0", + "account_id": self.invoice_line_account.id, + }, + ) + ], + } + move = self.env["account.move"].create(vals) + return move wizard = ( self.env["account.move.reversal"] .with_context(active_model="account.move", active_ids=move.ids) @@ -341,3 +365,37 @@ class TestPaymentOrderOutbound(TestPaymentOrderOutboundBase): self.assertEqual(len(payment_order.payment_line_ids), 1) self.assertEqual("F/1234 R1234", payment_order.payment_line_ids.communication) + + def test_supplier_manual_refund(self): + """ + Confirm the supplier invoice with reference + Create a credit note manually + Confirm the credit note + Reconcile move lines together + Create the payment order + The communication should be a combination of the invoice payment reference + and the credit note one + """ + self.invoice.action_post() + self.refund = self._create_supplier_refund(self.invoice, manual=True) + with Form(self.refund) as refund_form: + refund_form.ref = "R1234" + + self.refund.action_post() + + (self.invoice.line_ids + self.refund.line_ids).filtered( + lambda line: line.account_internal_type == "payable" + ).reconcile() + + self.env["account.invoice.payment.line.multi"].with_context( + active_model="account.move", active_ids=self.invoice.ids + ).create({}).run() + + payment_order = self.env["account.payment.order"].search(self.domain) + self.assertEqual(len(payment_order), 1) + + payment_order.write({"journal_id": self.bank_journal.id}) + + self.assertEqual(len(payment_order.payment_line_ids), 1) + + self.assertEqual("F1242 R1234", payment_order.payment_line_ids.communication)