Skip to content

Commit 286ea6b

Browse files
committed
[FIX] purchase_stock: small discount at invoicing
- Create stockable product P: FIFO, Automated Valuation - Set the price difference account - Configure Decimal Accuracy for Discounts to 5. - Create a PO - Add a line with: Product P Quantity: 10,000 Price unit: 100 A tax - Confirm the PO, receive the product and create the invoice - Set a discount of 0.92431 on the invoice line - Post the invoice The journal entries for the invoices contains the price difference move, the amount must be 9,243.10 but is 9,200.00. In case taxes are defined on the the invoice line, we call `compute_all` which will round the `price_unit`. In this case, we don't want to round it. Fixes odoo#56832 opw-2329028 X-original-commit: 498238f
1 parent 8254116 commit 286ea6b

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

addons/purchase_stock/models/account_invoice.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,15 @@ def _stock_account_prepare_anglo_saxon_in_lines_vals(self):
115115

116116
price_unit = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
117117
if line.tax_ids:
118-
price_unit = line.tax_ids.compute_all(
118+
# We do not want to round the price unit since :
119+
# - It does not follow the currency precision
120+
# - It may include a discount
121+
# Since compute_all still rounds the total, we use an ugly workaround:
122+
# multiply then divide the price unit.
123+
price_unit *= line.quantity
124+
price_unit = line.tax_ids.with_context(round=False).compute_all(
119125
price_unit, currency=move.currency_id, quantity=1.0, is_refund=move.move_type == 'in_refund')['total_excluded']
126+
price_unit /= line.quantity
120127

121128
if float_compare(valuation_price_unit, price_unit, precision_digits=invoice_cur_prec) != 0 \
122129
and float_compare(line['price_unit'], line.price_unit, precision_digits=invoice_cur_prec) == 0:

addons/purchase_stock/tests/test_anglo_saxon_valuation_reconciliation.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def setup_company_data(cls, company_name, chart_template=None, **kwargs):
2929
})
3030
return company_data
3131

32-
def _create_purchase(self, product, date, quantity=1.0):
32+
def _create_purchase(self, product, date, quantity=1.0, set_tax=False):
3333
rslt = self.env['purchase.order'].create({
3434
'partner_id': self.partner_a.id,
3535
'currency_id': self.currency_data['currency'].id,
@@ -41,6 +41,7 @@ def _create_purchase(self, product, date, quantity=1.0):
4141
'product_uom': product.uom_po_id.id,
4242
'price_unit': 66.0,
4343
'date_planned': date,
44+
'taxes_id': [(6, 0, product.supplier_taxes_id.ids)] if set_tax else False,
4445
})],
4546
'date_order': date,
4647
})
@@ -146,3 +147,38 @@ def test_multiple_shipments_invoices(self):
146147
self._process_pickings(purchase_order.picking_ids.filtered(lambda x: x.state != 'done'), quantity=3.0)
147148
picking = self.env['stock.picking'].search([('purchase_id', '=', purchase_order.id)], order='id desc', limit=1)
148149
self.check_reconciliation(invoice2, picking)
150+
151+
def test_rounding_discount(self):
152+
self.env.ref("product.decimal_discount").digits = 5
153+
tax_exclude_id = self.env["account.tax"].create(
154+
{
155+
"name": "Exclude tax",
156+
"amount": "0.00",
157+
"type_tax_use": "purchase",
158+
}
159+
)
160+
161+
test_product = self.test_product_delivery
162+
test_product.supplier_taxes_id = [(6, 0, tax_exclude_id.ids)]
163+
date_po_and_delivery = '2018-01-01'
164+
165+
purchase_order = self._create_purchase(test_product, date_po_and_delivery, quantity=10000, set_tax=True)
166+
self._process_pickings(purchase_order.picking_ids, date=date_po_and_delivery)
167+
168+
invoice = self._create_invoice_for_po(purchase_order, '2018-01-01')
169+
170+
# Set a discount
171+
move_form = Form(invoice)
172+
with move_form.invoice_line_ids.edit(0) as line_form:
173+
line_form.discount = 0.92431
174+
move_form.save()
175+
176+
invoice.action_post()
177+
178+
# Check the price difference amount.
179+
price_diff_line = invoice.line_ids.filtered(lambda l: l.account_id == self.stock_account_product_categ.property_account_creditor_price_difference_categ)
180+
self.assertTrue(len(price_diff_line) == 1, "A price difference line should be created")
181+
self.assertAlmostEqual(price_diff_line.price_total, -6100.446)
182+
183+
picking = self.env['stock.picking'].search([('purchase_id','=',purchase_order.id)])
184+
self.check_reconciliation(invoice, picking)

0 commit comments

Comments
 (0)