mirror of
https://github.com/OCA/bank-payment.git
synced 2025-02-02 10:37:31 +02:00
@@ -417,15 +417,42 @@ class AccountPaymentOrder(models.Model):
|
||||
return action
|
||||
|
||||
def generated2uploaded(self):
|
||||
"""Post payments and reconcile against source journal items
|
||||
|
||||
Partially reconcile payments that don't match their source journal items,
|
||||
then reconcile the rest in one go.
|
||||
"""
|
||||
self.payment_ids.action_post()
|
||||
# Perform the reconciliation of payments and source journal items
|
||||
for payment in self.payment_ids:
|
||||
(
|
||||
payment.payment_line_ids.move_line_id
|
||||
+ payment.move_id.line_ids.filtered(
|
||||
lambda x: x.account_id == payment.destination_account_id
|
||||
)
|
||||
).reconcile()
|
||||
payment_move_line_id = payment.move_id.line_ids.filtered(
|
||||
lambda x: x.account_id == payment.destination_account_id
|
||||
)
|
||||
apr = self.env["account.partial.reconcile"]
|
||||
excl_pay_lines = self.env["account.payment.line"]
|
||||
for line in payment.payment_line_ids:
|
||||
if not line.move_line_id:
|
||||
continue
|
||||
if line.amount_currency != -line.move_line_id.amount_residual_currency:
|
||||
if line.move_line_id.amount_residual_currency < 0:
|
||||
debit_move_id = payment_move_line_id.id
|
||||
credit_move_id = line.move_line_id.id
|
||||
else:
|
||||
debit_move_id = line.move_line_id.id
|
||||
credit_move_id = payment_move_line_id.id
|
||||
apr.create(
|
||||
{
|
||||
"debit_move_id": debit_move_id,
|
||||
"credit_move_id": credit_move_id,
|
||||
"amount": abs(line.amount_company_currency),
|
||||
"debit_amount_currency": abs(line.amount_currency),
|
||||
"credit_amount_currency": abs(line.amount_currency),
|
||||
}
|
||||
)
|
||||
excl_pay_lines |= line
|
||||
pay_lines = payment.payment_line_ids - excl_pay_lines
|
||||
if pay_lines:
|
||||
(pay_lines.move_line_id + payment_move_line_id).reconcile()
|
||||
self.write(
|
||||
{"state": "uploaded", "date_uploaded": fields.Date.context_today(self)}
|
||||
)
|
||||
|
||||
@@ -305,6 +305,62 @@ class TestPaymentOrderOutbound(TestPaymentOrderOutboundBase):
|
||||
fields.Date.context_today(outbound_order),
|
||||
)
|
||||
|
||||
def test_partial_reconciliation(self):
|
||||
"""
|
||||
Confirm both supplier invoices
|
||||
Add invoices to payment order
|
||||
Reduce payment amount of first invoice from 100 to 80
|
||||
Take payment order all the way to uploaded
|
||||
Confirm 80 reconciled with first, not second invoice
|
||||
|
||||
generated2uploaded() does partial reconciliation of non-matching
|
||||
line amounts before running .reconcile() against the remaining
|
||||
matching line amounts.
|
||||
"""
|
||||
# Open both invoices
|
||||
self.invoice.action_post()
|
||||
self.invoice_02.action_post()
|
||||
|
||||
# Add to payment order using the wizard
|
||||
self.env["account.invoice.payment.line.multi"].with_context(
|
||||
active_model="account.move",
|
||||
active_ids=self.invoice.ids + self.invoice_02.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), 2)
|
||||
self.assertFalse(payment_order.payment_ids)
|
||||
|
||||
# Reduce payment of first invoice from 100 to 80
|
||||
first_payment_line, second_payment_line = payment_order.payment_line_ids
|
||||
first_payment_line.write({"amount_currency": 80.0})
|
||||
|
||||
# Open payment order
|
||||
payment_order.draft2open()
|
||||
|
||||
# Confirm single payment (grouped - two invoices one partner)
|
||||
self.assertEqual(payment_order.payment_count, 1)
|
||||
|
||||
# Generate and upload
|
||||
payment_order.open2generated()
|
||||
payment_order.generated2uploaded()
|
||||
|
||||
self.assertEqual(payment_order.state, "uploaded")
|
||||
with self.assertRaises(UserError):
|
||||
payment_order.unlink()
|
||||
|
||||
# Confirm payments were reconciled against correct invoices
|
||||
self.assertEqual(first_payment_line.amount_currency, 80.0)
|
||||
self.assertEqual(
|
||||
first_payment_line.move_line_id.amount_residual_currency, -20.0
|
||||
)
|
||||
self.assertEqual(second_payment_line.amount_currency, 100.0)
|
||||
self.assertEqual(second_payment_line.move_line_id.amount_residual_currency, 0.0)
|
||||
|
||||
def test_supplier_refund(self):
|
||||
"""
|
||||
Confirm the supplier invoice
|
||||
|
||||
Reference in New Issue
Block a user