diff --git a/product_secondary_unit/models/product_secondary_unit_mixin.py b/product_secondary_unit/models/product_secondary_unit_mixin.py index 276c4184b92..7129d152ce5 100644 --- a/product_secondary_unit/models/product_secondary_unit_mixin.py +++ b/product_secondary_unit/models/product_secondary_unit_mixin.py @@ -55,6 +55,7 @@ def _get_default_secondary_uom(self): def _get_uom_line(self): return self[self._secondary_unit_fields["uom_field"]] + # TODO: This method is now not used in this module. Deprecate it in future. def _get_factor_line(self): uom_line = self._get_uom_line() return self.secondary_uom_id.factor * ( @@ -72,6 +73,19 @@ def _get_secondary_uom_qty_depends(self): return [] return [self._secondary_unit_fields["qty_field"]] + @api.model + def _convert_qty_to_secondary_uom(self, qty): + # Intended to be called from other operations if needed. + self.ensure_one() + uom_line = self._get_uom_line() + uom_product = self.product_id[self._product_uom_field] + if uom_line != uom_product: + qty = uom_line._compute_quantity(qty, uom_product) + return float_round( + qty / (self.secondary_uom_id.factor or 1.0), + precision_rounding=self.secondary_uom_id.uom_id.rounding, + ) + @api.depends(lambda x: x._get_secondary_uom_qty_depends()) def _compute_secondary_uom_qty(self): for line in self: @@ -80,13 +94,8 @@ def _compute_secondary_uom_qty(self): continue elif line.secondary_uom_id.dependency_type == "independent": continue - factor = line._get_factor_line() qty_line = line._get_quantity_from_line() - qty = float_round( - qty_line / (factor or 1.0), - precision_rounding=line.secondary_uom_id.uom_id.rounding, - ) - line.secondary_uom_qty = qty + line.secondary_uom_qty = line._convert_qty_to_secondary_uom(qty_line) def _get_default_value_for_qty_field(self): return self.default_get([self._secondary_unit_fields["qty_field"]]).get( @@ -114,12 +123,11 @@ def _compute_helper_target_field_qty(self): rec.env.remove_to_compute( field=rec._fields["secondary_uom_qty"], records=rec ) - factor = rec._get_factor_line() - qty = float_round( - rec.secondary_uom_qty * factor, - precision_rounding=rec._get_uom_line().rounding, - ) - rec[rec._secondary_unit_fields["qty_field"]] = qty + qty_base = rec.secondary_uom_qty * rec.secondary_uom_id.factor + uom_line = rec._get_uom_line() + uom_product = rec.product_id[rec._product_uom_field] + qty_line = uom_product._compute_quantity(qty_base, uom_line) + rec[rec._secondary_unit_fields["qty_field"]] = qty_line def _onchange_helper_product_uom_for_secondary(self): """Helper method to be called from onchange method of uom field in @@ -130,13 +138,8 @@ def _onchange_helper_product_uom_for_secondary(self): return elif self.secondary_uom_id.dependency_type == "independent": return - factor = self._get_factor_line() - line_qty = self._get_quantity_from_line() - qty = float_round( - line_qty / (factor or 1.0), - precision_rounding=self.secondary_uom_id.uom_id.rounding, - ) - self.secondary_uom_qty = qty + qty_line = self._get_quantity_from_line() + self.secondary_uom_qty = self._convert_qty_to_secondary_uom(qty_line) @api.model def default_get(self, fields_list): diff --git a/product_secondary_unit/tests/test_secondary_unit_mixin.py b/product_secondary_unit/tests/test_secondary_unit_mixin.py index 79427234eaa..44e61510d02 100644 --- a/product_secondary_unit/tests/test_secondary_unit_mixin.py +++ b/product_secondary_unit/tests/test_secondary_unit_mixin.py @@ -15,14 +15,13 @@ def setUpClass(cls): from .models import SecondaryUnitFake cls.loader.update_registry((SecondaryUnitFake,)) - cls.product_uom_kg = cls.env.ref("uom.product_uom_kgm") cls.product_uom_unit = cls.env.ref("uom.product_uom_unit") cls.product_uom_dozen = cls.env.ref("uom.product_uom_dozen") cls.product_template = cls.env["product.template"].create( { "name": "test", - "uom_id": cls.product_uom_kg.id, - "uom_po_id": cls.product_uom_kg.id, + "uom_id": cls.product_uom_unit.id, + "uom_po_id": cls.product_uom_unit.id, "secondary_uom_ids": [ Command.create( { @@ -151,3 +150,44 @@ def test_independent_type(self): fake_model.write({"secondary_uom_qty": 4}) self.assertEqual(fake_model.product_uom_qty, 17) self.assertEqual(fake_model.secondary_uom_qty, 4) + + def test_secondary_uom_qty_conversion_with_different_line_uom(self): + product_uom_litre = self.env.ref("uom.product_uom_litre") + volume_category = self.env.ref("uom.product_uom_categ_vol") + product_uom_millilitre = self.env["uom.uom"].create( + { + "name": "mL", + "category_id": volume_category.id, + "uom_type": "smaller", + "factor": 1000.0, + "rounding": 0.01, + } + ) + product_template = self.env["product.template"].create( + { + "name": "Test", + "uom_id": product_uom_millilitre.id, + "uom_po_id": product_uom_millilitre.id, + "secondary_uom_ids": [ + Command.create( + { + "name": "Bottle", + "uom_id": product_uom_millilitre.id, + "factor": 1200.0, + "dependency_type": "dependent", + } + ) + ], + } + ) + bottle_secondary_uom = product_template.secondary_uom_ids + fake_model = self.env["secondary.unit.fake"].create( + { + "name": "Secondary unit fake (volume)", + "product_id": product_template.product_variant_ids.id, + "product_uom_id": product_uom_litre.id, + "product_uom_qty": 1.2, + "secondary_uom_id": bottle_secondary_uom.id, + } + ) + self.assertEqual(fake_model.secondary_uom_qty, 1.0)