[FIX] sale: downpayment invoice and credit note

The aim of this commit is to fix the computation behavior of the downpayment
line of the sale order.

Context:
Create a sale order and invoice a down payment.
Make a credit note for the downpayment invoice for a part of the
invoice's amount.

Before the commit:
The downpayment line on the sale order gets its price_unit updated to
the amount of the last credit note.

After the commit:
The downpayment line on the sale order gets its price_unit updated to
the sum of the amount of all linked invoice.

closes odoo/odoo#150274

Task-id: 3634439
X-original-commit: 48995672ed58c99b1d8b143225a6535104d3bf8d
Signed-off-by: Brice Bartoletti (bib) <bib@odoo.com>
Signed-off-by: William André (wan) <wan@odoo.com>
This commit is contained in:
Brice bib Bartoletti
2024-01-20 05:31:54 +00:00
parent 3689958cac
commit be3058bfb6
2 changed files with 57 additions and 15 deletions
+12 -11
View File
@@ -59,20 +59,21 @@ class AccountMove(models.Model):
return super()._reverse_moves(default_values_list=default_values_list, cancel=cancel)
def action_post(self):
#inherit of the function from account.move to validate a new tax and the priceunit of a downpayment
# inherit of the function from account.move to validate a new tax and the priceunit of a downpayment
res = super(AccountMove, self).action_post()
down_payment_lines = self.line_ids.filtered('is_downpayment')
for line in down_payment_lines:
if not any(sol.display_type for sol in line.sale_line_ids):
line.sale_line_ids._compute_name()
if any(order.locked for order in line.sale_line_ids.order_id):
# We cannot change lines content on locked SO, changes on invoices are not
# forwarded to the SO if the SO is locked.
continue
# We cannot change lines content on locked SO, changes on invoices are not forwarded to the SO if the SO is locked
downpayment_lines = self.line_ids.sale_line_ids.filtered(lambda l: l.is_downpayment and not l.display_type and not l.order_id.locked)
other_so_lines = downpayment_lines.order_id.order_line - downpayment_lines
real_invoices = set(other_so_lines.invoice_lines.move_id)
for so_dpl in downpayment_lines:
so_dpl.price_unit = sum(
l.price_unit if l.move_id.move_type == 'out_invoice' else -l.price_unit
for l in so_dpl.invoice_lines
if l.move_id.state == 'posted' and l.move_id not in real_invoices # don't recompute with the final invoice
)
so_dpl.tax_id = so_dpl.invoice_lines.tax_ids
line.sale_line_ids.tax_id = line.tax_ids
line.sale_line_ids.price_unit = line.price_unit
return res
def button_draft(self):
+45 -4
View File
@@ -186,16 +186,17 @@ class TestSaleToInvoice(TestSaleCommon):
'deposit_account_id': self.company_data['default_account_revenue'].id
})
downpayment.create_invoices()
# Let's do the invoice
# Let's do the invoice for the remaining amount
payment = self.env['sale.advance.payment.inv'].with_context(context).create({
'deposit_account_id': self.company_data['default_account_revenue'].id
})
payment.create_invoices()
# Confirm all invoices
for invoice in sale_order.invoice_ids:
invoice.action_post()
downpayment_line = sale_order.order_line.filtered(lambda l: l.is_downpayment and not l.display_type)
self.assertEqual(downpayment_line[0].price_unit, 50, 'The down payment unit price should not change on SO')
# Confirm all invoices
sale_order.invoice_ids.action_post()
self.assertEqual(downpayment_line[0].price_unit, 50, 'The down payment unit price should not change on SO')
def test_downpayment_fixed_amount_with_zero_total_amount(self):
# Create the SO with one line and amount total is zero
@@ -261,6 +262,46 @@ class TestSaleToInvoice(TestSaleCommon):
invoice.action_post()
self.assertEqual(downpayment_line.price_unit, self.sale_order.amount_total/2, 'downpayment should have the correct amount')
def test_downpayment_invoice_and_partial_credit_note(self):
"""This test check that the downpayment line amount on the sale order remains consistent"""
self.sale_order.action_confirm()
# Create an invoice for a Down payment of 100
payment = self.env['sale.advance.payment.inv'].with_context(self.context).create({
'advance_payment_method': 'fixed',
'fixed_amount': 100,
'deposit_account_id': self.company_data['default_account_revenue'].id,
})
payment.create_invoices()
# Ensure the downpayment line on the sale order is correctly set to 100
downpayment_line = self.sale_order.order_line.filtered(lambda l: l.is_downpayment and not l.display_type)
self.assertEqual(downpayment_line.price_unit, 100)
# post the downpayment invoice and ensure the downpayment_line amount is still 100
downpayment_invoice = downpayment_line.order_id.order_line.invoice_lines.move_id
downpayment_invoice.action_post()
self.assertEqual(downpayment_line.price_unit, 100)
# Create a credit note for a part of the downpayment invoice and post it
move_reversal = self.env['account.move.reversal'].with_context(
active_model="account.move",
active_ids=downpayment_invoice.ids,
).create({
'date': '2020-02-01',
'reason': 'no reason',
'journal_id': downpayment_invoice.journal_id.id,
})
reversal_action = move_reversal.reverse_moves()
reverse_move = self.env['account.move'].browse(reversal_action['res_id'])
with Form(reverse_move) as form_reverse:
with form_reverse.invoice_line_ids.edit(0) as line_form:
line_form.price_unit = 20.0
reverse_move.action_post()
self.assertEqual(downpayment_line.price_unit, 80,
"The downpayment line amount should be equal to the sum of the invoice and credit note amount")
def test_invoice_with_discount(self):
""" Test invoice with a discount and check discount applied on both SO lines and an invoice lines """
# Update discount and delivered quantity on SO lines