[FIX] sale,sale_project: downpayment rounding issue with multiple so lines
Create a SO with the following lines: 1. Price Unit 10000, tax 20% 2. Price Unit 10000, tax 20% 3. Price Unit 10000, tax 20% 4. Price Unit 50, tax 20% Confirm, Create a downpayment of 840.0 Check the downpayment Issue: Amount will be 840.01 This occurs because we compute the downpayment values aggregating so line amounts line by line, each time multiplying for the downpayment percentage and rounding the result. Over multiple lines this mechanism may accumulate a rounding error. opw-3812925 closes odoo/odoo#160781 X-original-commit: 1a21f40274d7d7c3c5029c3bb83214618cc2384f Signed-off-by: de Wouters de Bouchout Jean-Benoît (jbw) <jbw@odoo.com> Signed-off-by: Andrea Grazioso (agr) <agr@odoo.com>
This commit is contained in:
@@ -811,3 +811,45 @@ class TestSaleOrderDownPayment(TestSaleCommon):
|
||||
[self.receivable_account.id, [], 5550.0, 0.0 ],
|
||||
]
|
||||
self._assert_invoice_lines_values(invoice.line_ids, expected)
|
||||
|
||||
def test_so_with_multiple_line_rounding(self):
|
||||
"""Test downpayment fixed amount rounding when the sale order has
|
||||
multiple lines that would create a sensible difference in rounding.
|
||||
"""
|
||||
tax_20 = self.create_tax(20)
|
||||
|
||||
for i, price_unit in enumerate((10000, 10000, 10000, 50)):
|
||||
self.sale_order.order_line[i].product_id = self.company_data['product_delivery_no'].id
|
||||
self.sale_order.order_line[i].product_uom_qty = 1
|
||||
self.sale_order.order_line[i].qty_delivered = 1
|
||||
self.sale_order.order_line[i].tax_id = tax_20
|
||||
self.sale_order.order_line[i].price_unit = price_unit
|
||||
|
||||
self.sale_order.order_line.qty_delivered_method = 'manual'
|
||||
self.sale_order.action_confirm()
|
||||
|
||||
so_context = {
|
||||
'active_model': 'sale.order',
|
||||
'active_ids': [self.sale_order.id],
|
||||
'active_id': self.sale_order.id,
|
||||
'default_journal_id': self.company_data['default_journal_sale'].id,
|
||||
}
|
||||
payment_params = {
|
||||
'advance_payment_method': 'fixed',
|
||||
'fixed_amount': 840.0, # with 20% tax applied, amount tax excluded is 700.0
|
||||
'deposit_account_id': self.revenue_account.id,
|
||||
}
|
||||
downpayment = self.env['sale.advance.payment.inv'].with_context(so_context).create(payment_params)
|
||||
action = downpayment.create_invoices()
|
||||
invoice = self.env['account.move'].browse(action['res_id'])
|
||||
expected = [
|
||||
# keys
|
||||
['account_id', 'tax_ids', 'balance', 'price_total'],
|
||||
# base lines
|
||||
[self.revenue_account.id, tax_20.ids, -700, 840.0],
|
||||
# taxes
|
||||
[self.tax_account.id, [], -140, 0.0],
|
||||
# receivable
|
||||
[self.receivable_account.id, [], 840.0, 0.0],
|
||||
]
|
||||
self._assert_invoice_lines_values(invoice.line_ids, expected)
|
||||
|
||||
@@ -362,8 +362,11 @@ class SaleAdvancePaymentInv(models.TransientModel):
|
||||
'product_uom_qty': 0.0,
|
||||
'price_unit': 0.0,
|
||||
})
|
||||
downpayment_line_map[grouping_key]['price_unit'] += \
|
||||
order.currency_id.round(price_subtotal * percentage)
|
||||
downpayment_line_map[grouping_key]['price_unit'] += price_subtotal
|
||||
for key in downpayment_line_map:
|
||||
downpayment_line_map[key]['price_unit'] = \
|
||||
order.currency_id.round(downpayment_line_map[key]['price_unit'] * percentage)
|
||||
|
||||
|
||||
return list(downpayment_line_map.values())
|
||||
|
||||
|
||||
@@ -593,7 +593,7 @@ class TestSaleProjectProfitability(TestProjectProfitabilityCommon, TestSaleCommo
|
||||
})
|
||||
# When a down payment is created, the default 15% tax is included. The SOL associated it then created by removing the taxed amount.
|
||||
# Therefore, the amount of the dp is higher than the amount of the sol created.
|
||||
down_payment_invoiced = 100.01
|
||||
down_payment_invoiced = 100.00
|
||||
downpayment.create_invoices()
|
||||
self.sale_order.invoice_ids[2].action_post()
|
||||
# Ensures the down payment is correctly computed for the project profitability.
|
||||
|
||||
Reference in New Issue
Block a user