diff --git a/mrp_multi_level_estimate/tests/test_mrp_multi_level_estimate.py b/mrp_multi_level_estimate/tests/test_mrp_multi_level_estimate.py index 280c9a47b..b143f0f9a 100644 --- a/mrp_multi_level_estimate/tests/test_mrp_multi_level_estimate.py +++ b/mrp_multi_level_estimate/tests/test_mrp_multi_level_estimate.py @@ -14,6 +14,8 @@ class TestMrpMultiLevelEstimate(TestMrpMultiLevelCommon): super().setUpClass() cls.estimate_obj = cls.env["stock.demand.estimate"] + cls.uom_unit = cls.env.ref("uom.product_uom_unit") + # Create new clean area: cls.estimate_loc = cls.loc_obj.create( { @@ -187,3 +189,41 @@ class TestMrpMultiLevelEstimate(TestMrpMultiLevelCommon): self.assertEqual(moves_from_estimates[0].mrp_qty, -120) self.assertEqual(moves_from_estimates[1].mrp_qty, -280) self.assertEqual(moves_from_estimates[2].mrp_qty, -350) + + def test_04_group_demand_estimates_rounding(self): + """Test demand grouping functionality, `group_estimate_days` and rounding.""" + self.test_mrp_parameter.group_estimate_days = 7 + self.uom_unit.rounding = 1.00 + + estimates = self.estimate_obj.search( + [ + ("product_id", "=", self.prod_test.id), + ("location_id", "=", self.estimate_loc.id), + ] + ) + self.assertEqual(len(estimates), 3) + # Change qty of estimates to quantities that divided by 7 days return a decimal result + qty = 400 + for estimate in estimates: + estimate.product_uom_qty = qty + qty += 100 + + self.mrp_multi_level_wiz.create({}).run_mrp_multi_level() + moves = self.mrp_move_obj.search( + [ + ("product_id", "=", self.prod_test.id), + ("mrp_area_id", "=", self.estimate_area.id), + ] + ) + # 3 weekly estimates, demand from estimates grouped in batches of 7 + # days = 3 days of estimates mrp moves: + moves_from_estimates = moves.filtered(lambda m: m.mrp_type == "d") + self.assertEqual(len(moves_from_estimates), 3) + # Rounding should be done at the end of the calculation, using the daily + # quantity already rounded can lead to errors. + # 400 weekly -> 57.41 daily -> 57.41 * 4 days not consumed = 228,57 = 229 + self.assertEqual(moves_from_estimates[0].mrp_qty, -229) + # 500 weekly -> 71.42 daily -> 71,42 * 7 = 500 + self.assertEqual(moves_from_estimates[1].mrp_qty, -500) + # 600 weekly -> 85.71 daily -> 85.71 * 7 = 600 + self.assertEqual(moves_from_estimates[2].mrp_qty, -600) diff --git a/mrp_multi_level_estimate/wizards/mrp_multi_level.py b/mrp_multi_level_estimate/wizards/mrp_multi_level.py index c784538b1..8a6c68783 100644 --- a/mrp_multi_level_estimate/wizards/mrp_multi_level.py +++ b/mrp_multi_level_estimate/wizards/mrp_multi_level.py @@ -18,6 +18,7 @@ class MultiLevelMrp(models.TransientModel): def _prepare_mrp_move_data_from_estimate(self, estimate, product_mrp_area, date): mrp_type = "d" origin = "fc" + daily_qty_unrounded = estimate.daily_qty daily_qty = float_round( estimate.daily_qty, precision_rounding=product_mrp_area.product_id.uom_id.rounding, @@ -32,6 +33,11 @@ class MultiLevelMrp(models.TransientModel): group_estimate_days = min( product_mrp_area.group_estimate_days, estimate.duration - days_consumed ) + mrp_qty = float_round( + daily_qty_unrounded * group_estimate_days, + precision_rounding=product_mrp_area.product_id.uom_id.rounding, + rounding_method="HALF-UP", + ) return { "mrp_area_id": product_mrp_area.mrp_area_id.id, "product_id": product_mrp_area.product_id.id, @@ -40,7 +46,7 @@ class MultiLevelMrp(models.TransientModel): "purchase_order_id": None, "purchase_line_id": None, "stock_move_id": None, - "mrp_qty": -daily_qty * group_estimate_days, + "mrp_qty": -mrp_qty, "current_qty": -daily_qty, "mrp_date": date, "current_date": date,