[FIX] account_payment_order: Define the value of the communication field correctly

- Purchases: Ref field from invoice always.
- Sales: Payment_ref or ref field from invoice.

TT45153
This commit is contained in:
Víctor Martínez
2023-09-19 12:59:36 +02:00
parent 0b75edc4fd
commit 84282d211f
4 changed files with 100 additions and 49 deletions

View File

@@ -38,6 +38,54 @@ class AccountMove(models.Model):
payment_mode = move.payment_mode_id
move.payment_order_ok = payment_mode.payment_order_ok
def _get_payment_order_communication_direct(self):
"""Retrieve the communication string for this direct item."""
communication = self.payment_reference or self.ref or self.name or ""
if self.is_invoice():
if (self.reference_type or "none") != "none":
communication = self.ref
elif self.is_purchase_document():
communication = self.ref or self.payment_reference
else:
communication = self.payment_reference or self.name
return communication
def _get_payment_order_communication_full(self):
"""Retrieve the full communication string for the payment order.
Reversal moves and partial payments references added.
Avoid having everything in the same method to avoid infinite recursion
with partial payments.
"""
communication = self._get_payment_order_communication_direct()
references = []
# Build a recordset to gather moves from which references have already
# taken in order to avoid duplicates
reference_moves = self.env["account.move"].browse()
# If we have credit note(s) - reversal_move_id is a one2many
if self.reversal_move_id:
references.extend(
[
move._get_payment_order_communication_direct()
for move in self.reversal_move_id
]
)
reference_moves |= self.reversal_move_id
# Retrieve partial payments - e.g.: manual credit notes
for (
_x,
_y,
payment_move_line,
) in self._get_reconciled_invoices_partials():
payment_move = payment_move_line.move_id
if payment_move not in reference_moves:
references.append(
payment_move._get_payment_order_communication_direct()
)
# Add references to communication from lines move
if references:
communication += " " + " ".join(references)
return communication
def _prepare_new_payment_order(self, payment_mode=None):
self.ensure_one()
if payment_mode is None:

View File

@@ -42,40 +42,6 @@ class AccountMoveLine(models.Model):
else:
ml.partner_bank_id = ml.partner_bank_id
def _get_linked_move_communication(self):
"""
This will collect the references from referral moves:
- Reversal moves
- Partial payments
"""
self.ensure_one()
references = []
# Build a recordset to gather moves from which references have already
# taken in order to avoid duplicates
reference_moves = self.env["account.move"].browse()
# If we have credit note(s) - reversal_move_id is a one2many
if self.move_id.reversal_move_id:
references.extend(
[
move.payment_reference or move.ref
for move in self.move_id.reversal_move_id
if move.payment_reference or move.ref
]
)
reference_moves |= self.move_id.reversal_move_id
# 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 not in reference_moves and (
payment_move.payment_reference or payment_move.ref
):
references.append(payment_move.payment_reference or payment_move.ref)
return references
def _get_communication(self):
"""
Retrieve the communication string for the payment order
@@ -83,25 +49,12 @@ class AccountMoveLine(models.Model):
aplo = self.env["account.payment.line"]
# default values for communication_type and communication
communication_type = "normal"
communication = self.ref or self.name
communication = self.move_id._get_payment_order_communication_full()
# change these default values if move line is linked to an invoice
if self.move_id.is_invoice():
if (self.move_id.reference_type or "none") != "none":
communication = self.move_id.ref
ref2comm_type = aplo.invoice_reference_type2communication_type()
communication_type = ref2comm_type[self.move_id.reference_type]
else:
if (
self.move_id.move_type in ("in_invoice", "in_refund")
and self.move_id.ref
):
communication = self.move_id.payment_reference or self.move_id.ref
elif "out" in self.move_id.move_type:
# Force to only put invoice number here
communication = self.move_id.payment_reference or self.move_id.name
references = self._get_linked_move_communication()
if references:
communication += " " + " ".join(references)
return communication_type, communication
def _prepare_payment_line_vals(self, payment_order):

View File

@@ -92,6 +92,21 @@ class TestPaymentOrderInbound(TestPaymentOrderInboundBase):
with self.assertRaises(ValidationError):
self.inbound_order.date_scheduled = date.today() - timedelta(days=1)
def test_invoice_communication_01(self):
self.assertEqual(
self.invoice.name, self.invoice._get_payment_order_communication_direct()
)
self.invoice.ref = "R1234"
self.assertEqual(
self.invoice.name, self.invoice._get_payment_order_communication_direct()
)
def test_invoice_communication_02(self):
self.invoice.payment_reference = "R1234"
self.assertEqual(
"R1234", self.invoice._get_payment_order_communication_direct()
)
def test_creation(self):
payment_order = self.inbound_order
self.assertEqual(len(payment_order.ids), 1)

View File

@@ -261,6 +261,21 @@ class TestPaymentOrderOutbound(TestPaymentOrderOutboundBase):
with self.assertRaises(ValidationError):
outbound_order.date_scheduled = date.today() - timedelta(days=2)
def test_invoice_communication_01(self):
self.assertEqual(
"F1242", self.invoice._get_payment_order_communication_direct()
)
self.invoice.ref = "F1243"
self.assertEqual(
"F1243", self.invoice._get_payment_order_communication_direct()
)
def test_invoice_communication_02(self):
self.invoice.payment_reference = "R1234"
self.assertEqual(
"F1242", self.invoice._get_payment_order_communication_direct()
)
def test_manual_line_and_manual_date(self):
# Create payment order
outbound_order = self.env["account.payment.order"].create(
@@ -330,7 +345,13 @@ class TestPaymentOrderOutbound(TestPaymentOrderOutboundBase):
"""
# Open both invoices
self.invoice.action_post()
self.assertEqual(
"F1242", self.invoice._get_payment_order_communication_direct()
)
self.invoice_02.action_post()
self.assertEqual(
"F1243", self.invoice_02._get_payment_order_communication_direct()
)
# Add to payment order using the wizard
self.env["account.invoice.payment.line.multi"].with_context(
@@ -382,6 +403,9 @@ class TestPaymentOrderOutbound(TestPaymentOrderOutboundBase):
and the credit note one
"""
self.invoice.action_post()
self.assertEqual(
"F1242", self.invoice._get_payment_order_communication_direct()
)
self.refund = self._create_supplier_refund(self.invoice)
with Form(self.refund) as refund_form:
refund_form.ref = "R1234"
@@ -389,6 +413,7 @@ class TestPaymentOrderOutbound(TestPaymentOrderOutboundBase):
line_form.price_unit = 75.0
self.refund.action_post()
self.assertEqual("R1234", self.refund._get_payment_order_communication_direct())
self.env["account.invoice.payment.line.multi"].with_context(
active_model="account.move", active_ids=self.invoice.ids
@@ -415,13 +440,18 @@ class TestPaymentOrderOutbound(TestPaymentOrderOutboundBase):
"""
self.invoice.payment_reference = "F/1234"
self.invoice.action_post()
self.assertEqual(
"F1242", self.invoice._get_payment_order_communication_direct()
)
self.refund = self._create_supplier_refund(self.invoice)
with Form(self.refund) as refund_form:
refund_form.ref = "R1234"
refund_form.payment_reference = "FR/1234"
with refund_form.invoice_line_ids.edit(0) as line_form:
line_form.price_unit = 75.0
self.refund.action_post()
self.assertEqual("R1234", self.refund._get_payment_order_communication_direct())
# The user add the outstanding payment to the invoice
invoice_line = self.invoice.line_ids.filtered(
@@ -443,7 +473,8 @@ class TestPaymentOrderOutbound(TestPaymentOrderOutboundBase):
self.assertEqual(len(payment_order.payment_line_ids), 1)
self.assertEqual("F/1234 R1234", payment_order.payment_line_ids.communication)
self.assertEqual("F1242 R1234", payment_order.payment_line_ids.communication)
self.assertNotIn("FR/1234", payment_order.payment_line_ids.communication)
def test_supplier_manual_refund(self):
"""
@@ -456,11 +487,15 @@ class TestPaymentOrderOutbound(TestPaymentOrderOutboundBase):
and the credit note one
"""
self.invoice.action_post()
self.assertEqual(
"F1242", self.invoice._get_payment_order_communication_direct()
)
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.assertEqual("R1234", self.refund._get_payment_order_communication_direct())
(self.invoice.line_ids + self.refund.line_ids).filtered(
lambda line: line.account_internal_type == "payable"