[FIX] sale_stock, purchase_stock: fix conversion qty received
Rounding in purchase order is 'UP' which is causing issue when doing receipt in a different uom than the purchase. Rounding should be 'HALF-UP' Added test in purchase and sales to ensure this issue is detected in the future. closes odoo/odoo#76006 X-original-commit: 9d3d1949d20834c92449c989299ac8e67f26d05d Signed-off-by: William Henrotin <Whenrow@users.noreply.github.com>
This commit is contained in:
@@ -308,7 +308,7 @@ class PurchaseOrderLine(models.Model):
|
||||
if move.state == 'done':
|
||||
if move.location_dest_id.usage == "supplier":
|
||||
if move.to_refund:
|
||||
total -= move.product_uom._compute_quantity(move.product_uom_qty, line.product_uom)
|
||||
total -= move.product_uom._compute_quantity(move.product_uom_qty, line.product_uom, rounding_method='HALF-UP')
|
||||
elif move.origin_returned_move_id and move.origin_returned_move_id._is_dropshipped() and not move._is_dropshipped_returned():
|
||||
# Edge case: the dropship is returned to the stock, no to the supplier.
|
||||
# In this case, the received quantity on the PO is set although we didn't
|
||||
@@ -323,9 +323,9 @@ class PurchaseOrderLine(models.Model):
|
||||
[("id", "child_of", move.warehouse_id.view_location_id.id)]
|
||||
)
|
||||
):
|
||||
total -= move.product_uom._compute_quantity(move.product_uom_qty, line.product_uom)
|
||||
total -= move.product_uom._compute_quantity(move.product_uom_qty, line.product_uom, rounding_method='HALF-UP')
|
||||
else:
|
||||
total += move.product_uom._compute_quantity(move.product_uom_qty, line.product_uom)
|
||||
total += move.product_uom._compute_quantity(move.product_uom_qty, line.product_uom, rounding_method='HALF-UP')
|
||||
line._track_qty_received(total)
|
||||
line.qty_received = total
|
||||
|
||||
|
||||
@@ -336,3 +336,33 @@ class TestPurchaseOrder(ValuationReconciliationTestCommon):
|
||||
po_on_time_rate = po.on_time_rate
|
||||
# 4. Check both are equals.
|
||||
self.assertEqual(partner_on_time_rate, po_on_time_rate)
|
||||
|
||||
def test_04_multi_uom(self):
|
||||
yards_uom = self.env['uom.uom'].create({
|
||||
'category_id': self.env.ref('uom.uom_categ_length').id,
|
||||
'name': 'Yards',
|
||||
'factor_inv': 0.9144,
|
||||
'uom_type': 'bigger',
|
||||
})
|
||||
self.product_id_2.write({
|
||||
'uom_id': self.env.ref('uom.product_uom_meter').id,
|
||||
'uom_po_id': yards_uom.id,
|
||||
})
|
||||
po = self.env['purchase.order'].create({
|
||||
'partner_id': self.partner_a.id,
|
||||
'order_line': [
|
||||
(0, 0, {
|
||||
'name': self.product_id_2.name,
|
||||
'product_id': self.product_id_2.id,
|
||||
'product_qty': 4.0,
|
||||
'product_uom': self.product_id_2.uom_po_id.id,
|
||||
'price_unit': 1.0,
|
||||
'date_planned': datetime.today().strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
||||
})
|
||||
],
|
||||
})
|
||||
po.button_confirm()
|
||||
picking = po.picking_ids[0]
|
||||
picking.move_line_ids.write({'qty_done': 3.66})
|
||||
picking.button_validate()
|
||||
self.assertEqual(po.order_line.mapped('qty_received'), [4.0], 'Purchase: no conversion error on receipt in different uom"')
|
||||
|
||||
@@ -1090,3 +1090,32 @@ class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon):
|
||||
so.picking_ids.action_cancel()
|
||||
|
||||
self.assertEqual(so.invoice_status, 'no')
|
||||
|
||||
def test_16_multi_uom(self):
|
||||
yards_uom = self.env['uom.uom'].create({
|
||||
'category_id': self.env.ref('uom.uom_categ_length').id,
|
||||
'name': 'Yards',
|
||||
'factor_inv': 0.9144,
|
||||
'uom_type': 'bigger',
|
||||
})
|
||||
product = self.env.ref('product.product_product_11').copy({
|
||||
'uom_id': self.env.ref('uom.product_uom_meter').id,
|
||||
'uom_po_id': yards_uom.id,
|
||||
})
|
||||
so = self.env['sale.order'].create({
|
||||
'partner_id': self.partner_a.id,
|
||||
'order_line': [
|
||||
(0, 0, {
|
||||
'name': product.name,
|
||||
'product_id': product.id,
|
||||
'product_uom_qty': 4.0,
|
||||
'product_uom': yards_uom.id,
|
||||
'price_unit': 1.0,
|
||||
})
|
||||
],
|
||||
})
|
||||
so.action_confirm()
|
||||
picking = so.picking_ids[0]
|
||||
picking.move_lines.write({'quantity_done': 3.66})
|
||||
picking.button_validate()
|
||||
self.assertEqual(so.order_line.mapped('qty_delivered'), [4.0], 'Sale: no conversion error on delivery in different uom"')
|
||||
|
||||
Reference in New Issue
Block a user