fix: Adjust total consumed quantities for microscopic rounding errors by applying the difference to a single move line instead of individual lines.

This commit is contained in:
Suherdy Yacob 2026-03-19 13:19:35 +07:00
parent 12ec80e82c
commit 9d6044dd49

View File

@ -157,18 +157,28 @@ class MrpProduction(models.Model):
# 2. Fix "Consumed" (move_line_ids.quantity)
# If the line is FULLY consumed (e.g. qty_producing == product_qty),
# then move lines should match the ideal quantity.
# then total consumed should match the ideal quantity.
total_done = sum(move.move_line_ids.mapped('quantity'))
if production.qty_producing == production.product_qty:
for ml in move.move_line_ids:
if abs(ml.quantity - ideal_qty) > 0.000001:
ml.quantity = ideal_qty
diff = ideal_qty - total_done
# Only auto-fix if it's a microscopic rounding drift (not a user overriding quantity intentionally)
if 0.000001 < abs(diff) < (move.product_uom.rounding * 1.5):
for ml in move.move_line_ids:
# Safely apply the tiny difference to the first line that has enough quantity
if ml.quantity and ml.quantity + diff >= 0:
ml.quantity += diff
break
else:
# Otherwise just round to 2 decimals if it's "close enough" to a clean decimal
# but drifted by microscopic dust.
for ml in move.move_line_ids:
clean_done = round(ml.quantity, 2)
if 0.000001 < abs(ml.quantity - clean_done) < (move.product_uom.rounding * 1.5):
ml.quantity = clean_done
# Otherwise just round to 2 decimals if the total drifted by microscopic dust.
# We shouldn't blindly round every single line if they are split in strange ways,
# but we can fix the tiny decimal dust on the first available line.
clean_total = round(total_done, 2)
diff = clean_total - total_done
if 0.000001 < abs(diff) < (move.product_uom.rounding * 1.5):
for ml in move.move_line_ids:
if ml.quantity and ml.quantity + diff >= 0:
ml.quantity += diff
break
def _merge_finished_move_lines(self):
for production in self: