fix: Standardize quantity calculations to 8 decimal places and refine decimal cleaning thresholds for improved precision.
This commit is contained in:
parent
c25da22149
commit
4b9efd08a8
@ -9,14 +9,14 @@ class MrpBom(models.Model):
|
|||||||
@api.onchange('packaging_qty')
|
@api.onchange('packaging_qty')
|
||||||
def _onchange_packaging_qty(self):
|
def _onchange_packaging_qty(self):
|
||||||
if self.packaging_id and self.packaging_qty:
|
if self.packaging_id and self.packaging_qty:
|
||||||
self.product_qty = self.packaging_id.qty * self.packaging_qty
|
self.product_qty = round(self.packaging_id.qty * self.packaging_qty, 8)
|
||||||
|
|
||||||
@api.onchange('packaging_id')
|
@api.onchange('packaging_id')
|
||||||
def _onchange_packaging_id(self):
|
def _onchange_packaging_id(self):
|
||||||
if self.packaging_id and self.packaging_id.qty:
|
if self.packaging_id and self.packaging_id.qty:
|
||||||
self.packaging_qty = self.product_qty / self.packaging_id.qty
|
self.packaging_qty = round(self.product_qty / self.packaging_id.qty, 8)
|
||||||
|
|
||||||
@api.onchange('product_qty')
|
@api.onchange('product_qty')
|
||||||
def _onchange_product_qty(self):
|
def _onchange_product_qty(self):
|
||||||
if self.packaging_id and self.packaging_id.qty:
|
if self.packaging_id and self.packaging_id.qty:
|
||||||
self.packaging_qty = self.product_qty / self.packaging_id.qty
|
self.packaging_qty = round(self.product_qty / self.packaging_id.qty, 8)
|
||||||
|
|||||||
@ -25,7 +25,8 @@ class MrpProduction(models.Model):
|
|||||||
bom_line = production.env['mrp.bom.line'].browse(move_vals['bom_line_id'])
|
bom_line = production.env['mrp.bom.line'].browse(move_vals['bom_line_id'])
|
||||||
|
|
||||||
# Instead of Odoo's noisy exploded qty, use the clean factor
|
# Instead of Odoo's noisy exploded qty, use the clean factor
|
||||||
line_quantity = clean_factor * bom_line.product_qty
|
# Round to 8 decimals before applying the UoM rounding method (UP)
|
||||||
|
line_quantity = round(clean_factor * bom_line.product_qty, 8)
|
||||||
|
|
||||||
# It's important to use float_round rather than just python round
|
# It's important to use float_round rather than just python round
|
||||||
# so we respect the UOM rounding method (UP), but on the CLEANED number!
|
# so we respect the UOM rounding method (UP), but on the CLEANED number!
|
||||||
@ -66,7 +67,7 @@ class MrpProduction(models.Model):
|
|||||||
for record in self:
|
for record in self:
|
||||||
if record.packaging_id and record.packaging_id.qty:
|
if record.packaging_id and record.packaging_id.qty:
|
||||||
qty_in_base = record.product_uom_id._compute_quantity(record.product_qty, record.product_id.uom_id, round=False)
|
qty_in_base = record.product_uom_id._compute_quantity(record.product_qty, record.product_id.uom_id, round=False)
|
||||||
new_qty = qty_in_base / record.packaging_id.qty
|
new_qty = round(qty_in_base / record.packaging_id.qty, 8)
|
||||||
if float_compare(new_qty, record.packaging_qty, precision_digits=2) != 0:
|
if float_compare(new_qty, record.packaging_qty, precision_digits=2) != 0:
|
||||||
record.packaging_qty = new_qty
|
record.packaging_qty = new_qty
|
||||||
else:
|
else:
|
||||||
@ -76,7 +77,7 @@ class MrpProduction(models.Model):
|
|||||||
for record in self:
|
for record in self:
|
||||||
if record.packaging_id and record.packaging_id.qty:
|
if record.packaging_id and record.packaging_id.qty:
|
||||||
qty_in_base = record.packaging_qty * record.packaging_id.qty
|
qty_in_base = record.packaging_qty * record.packaging_id.qty
|
||||||
record.product_qty = record.product_id.uom_id._compute_quantity(qty_in_base, record.product_uom_id, round=False)
|
record.product_qty = round(record.product_id.uom_id._compute_quantity(qty_in_base, record.product_uom_id, round=False), 8)
|
||||||
|
|
||||||
|
|
||||||
qty_producing_packaging = fields.Float('Quantity Producing Packaging', compute='_compute_qty_producing_packaging', inverse='_inverse_qty_producing_packaging', digits=(16, 2))
|
qty_producing_packaging = fields.Float('Quantity Producing Packaging', compute='_compute_qty_producing_packaging', inverse='_inverse_qty_producing_packaging', digits=(16, 2))
|
||||||
@ -86,7 +87,7 @@ class MrpProduction(models.Model):
|
|||||||
for record in self:
|
for record in self:
|
||||||
if record.packaging_id and record.packaging_id.qty:
|
if record.packaging_id and record.packaging_id.qty:
|
||||||
qty_in_base = record.product_uom_id._compute_quantity(record.qty_producing, record.product_id.uom_id, round=False)
|
qty_in_base = record.product_uom_id._compute_quantity(record.qty_producing, record.product_id.uom_id, round=False)
|
||||||
record.qty_producing_packaging = qty_in_base / record.packaging_id.qty
|
record.qty_producing_packaging = round(qty_in_base / record.packaging_id.qty, 8)
|
||||||
else:
|
else:
|
||||||
record.qty_producing_packaging = 0.0
|
record.qty_producing_packaging = 0.0
|
||||||
|
|
||||||
@ -94,7 +95,7 @@ class MrpProduction(models.Model):
|
|||||||
for record in self:
|
for record in self:
|
||||||
if record.packaging_id and record.packaging_id.qty:
|
if record.packaging_id and record.packaging_id.qty:
|
||||||
qty_in_base = record.qty_producing_packaging * record.packaging_id.qty
|
qty_in_base = record.qty_producing_packaging * record.packaging_id.qty
|
||||||
record.qty_producing = record.product_id.uom_id._compute_quantity(qty_in_base, record.product_uom_id, round=False)
|
record.qty_producing = round(record.product_id.uom_id._compute_quantity(qty_in_base, record.product_uom_id, round=False), 8)
|
||||||
record._merge_finished_move_lines()
|
record._merge_finished_move_lines()
|
||||||
|
|
||||||
@api.onchange('qty_producing_packaging')
|
@api.onchange('qty_producing_packaging')
|
||||||
@ -132,14 +133,17 @@ class MrpProduction(models.Model):
|
|||||||
def _clean_lingering_decimals(self):
|
def _clean_lingering_decimals(self):
|
||||||
for production in self:
|
for production in self:
|
||||||
for move in production.move_raw_ids:
|
for move in production.move_raw_ids:
|
||||||
|
rounding = move.product_uom.rounding
|
||||||
if move.product_uom_qty:
|
if move.product_uom_qty:
|
||||||
|
# Clean quantities that moved away from clean decimals by exactly the rounding amount
|
||||||
|
# E.g. 60.030 instead of 60.000 where component increment is 0.010
|
||||||
clean_qty = round(move.product_uom_qty, 2)
|
clean_qty = round(move.product_uom_qty, 2)
|
||||||
if 0.0001 < abs(move.product_uom_qty - clean_qty) < 0.01:
|
if 0.000001 < abs(move.product_uom_qty - clean_qty) < (rounding * 1.5):
|
||||||
move.product_uom_qty = clean_qty
|
move.product_uom_qty = clean_qty
|
||||||
for ml in move.move_line_ids:
|
for ml in move.move_line_ids:
|
||||||
if ml.quantity:
|
if ml.quantity:
|
||||||
clean_done = round(ml.quantity, 2)
|
clean_done = round(ml.quantity, 2)
|
||||||
if 0.0001 < abs(ml.quantity - clean_done) < 0.01:
|
if 0.000001 < abs(ml.quantity - clean_done) < (rounding * 1.5):
|
||||||
ml.quantity = clean_done
|
ml.quantity = clean_done
|
||||||
|
|
||||||
def _merge_finished_move_lines(self):
|
def _merge_finished_move_lines(self):
|
||||||
|
|||||||
@ -19,7 +19,7 @@ class StockMove(models.Model):
|
|||||||
bom_qty = bom.product_uom_id._compute_quantity(bom.product_qty, bom.product_tmpl_id.uom_id, round=False)
|
bom_qty = bom.product_uom_id._compute_quantity(bom.product_qty, bom.product_tmpl_id.uom_id, round=False)
|
||||||
|
|
||||||
if bom_qty:
|
if bom_qty:
|
||||||
move.unit_factor = line_qty / bom_qty
|
move.unit_factor = round(line_qty / bom_qty, 8)
|
||||||
|
|
||||||
def _set_quantity_done_prepare_vals(self, qty):
|
def _set_quantity_done_prepare_vals(self, qty):
|
||||||
# Workaround for Odoo UI onchange bug where move_line_ids (NewId) are sometimes passed
|
# Workaround for Odoo UI onchange bug where move_line_ids (NewId) are sometimes passed
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user