fix: Prevent floating point dust in _update_raw_moves by cleaning quantities after Odoo's UP rounding.

This commit is contained in:
Suherdy Yacob 2026-03-05 11:18:15 +07:00
parent 390e19333f
commit a22e49faf8

View File

@ -37,9 +37,26 @@ class MrpProduction(models.Model):
return moves return moves
def _update_raw_moves(self, factor): def _update_raw_moves(self, factor):
# Prevent floating point noise during UPDATE quantity # Odoo core _update_raw_moves multiplies `old_qty * factor` and rounds UP.
clean_factor = round(factor, 8) # If factor is 0.9799118079... and old_qty is 71435, the math results in 70000.00000000004
return super()._update_raw_moves(clean_factor) # Odoo's UP rounding elevates this dust to 70000.001!
# We must let Odoo do its thing, but then surgically clean the dust.
res = super()._update_raw_moves(factor)
clean_res = []
for move, old_qty, new_qty in res:
exact_qty = old_qty * factor
# Clean floating point microscopic dust (e.g. 70000.0000000004 -> 70000.0)
clean_exact_qty = round(exact_qty, 8)
from odoo.tools import float_round
ideal_qty = float_round(clean_exact_qty, precision_rounding=move.product_uom.rounding, rounding_method='UP')
if move.product_uom_qty != ideal_qty:
move.write({'product_uom_qty': ideal_qty})
clean_res.append((move, old_qty, ideal_qty))
return clean_res
packaging_id = fields.Many2one('mrp.packaging', string='Packaging', domain="[('product_tmpl_id', '=', product_tmpl_id)]", check_company=True) packaging_id = fields.Many2one('mrp.packaging', string='Packaging', domain="[('product_tmpl_id', '=', product_tmpl_id)]", check_company=True)
packaging_qty = fields.Float('Quantity Packaging', compute='_compute_packaging_qty', inverse='_inverse_packaging_qty', store=True, readonly=False) packaging_qty = fields.Float('Quantity Packaging', compute='_compute_packaging_qty', inverse='_inverse_packaging_qty', store=True, readonly=False)