From aba2eb40f860f42ac47ef1eb752c04e08d6c9c7f Mon Sep 17 00:00:00 2001 From: Lois Rilo Date: Mon, 14 Feb 2022 19:44:45 +0100 Subject: [PATCH] [FIX] mrp_multi_level_estimate: do not overstate estimates when group days of estimates is greater than the lengh of the date range in the estimate, the estimate is overstated and can generate unexpected result. Enhance help message to highligh this and prevent it from happening. --- .../models/product_mrp_area.py | 5 +- .../tests/test_mrp_multi_level_estimate.py | 47 +++++++++++++++++-- .../wizards/mrp_multi_level.py | 15 ++++-- 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/mrp_multi_level_estimate/models/product_mrp_area.py b/mrp_multi_level_estimate/models/product_mrp_area.py index 0831b6db8..88ceee090 100644 --- a/mrp_multi_level_estimate/models/product_mrp_area.py +++ b/mrp_multi_level_estimate/models/product_mrp_area.py @@ -12,8 +12,9 @@ class ProductMRPArea(models.Model): string="Group Days of Estimates", default=1, help="The days to group your estimates as demand for the MRP." - "It can be different from the lenght of the date ranges you " - "use in the estimates.", + "It can be different from the length of the date ranges you " + "use in the estimates but it should not be greater, in that case" + "only grouping until the total lenght of the date range will be done.", ) _sql_constraints = [ 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 fe0bd3ec8..280c9a47b 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 @@ -29,7 +29,7 @@ class TestMrpMultiLevelEstimate(TestMrpMultiLevelCommon): "location_id": cls.estimate_loc.id, } ) - cls.product_mrp_area_obj.create( + cls.test_mrp_parameter = cls.product_mrp_area_obj.create( { "product_id": cls.prod_test.id, "mrp_area_id": cls.estimate_area.id, @@ -113,8 +113,8 @@ class TestMrpMultiLevelEstimate(TestMrpMultiLevelCommon): ) self.assertEqual(len(inventories), 18) - def test_02_group_demand_estimates(self): - """Test demand grouping functionality, `nbr_days`.""" + def test_02_demand_estimates_group_plans(self): + """Test requirement grouping functionality, `nbr_days`.""" estimates = self.estimate_obj.search( [ ("product_id", "=", self.prod_test.id), @@ -146,3 +146,44 @@ class TestMrpMultiLevelEstimate(TestMrpMultiLevelCommon): self.assertIn(abs(week_2_expected), quantities) week_3_expected = sum(moves_from_estimates[14:].mapped("mrp_qty")) self.assertIn(abs(week_3_expected), quantities) + + def test_03_group_demand_estimates(self): + """Test demand grouping functionality, `group_estimate_days`.""" + self.test_mrp_parameter.group_estimate_days = 7 + self.mrp_multi_level_wiz.create({}).run_mrp_multi_level() + estimates = self.estimate_obj.search( + [ + ("product_id", "=", self.prod_test.id), + ("location_id", "=", self.estimate_loc.id), + ] + ) + self.assertEqual(len(estimates), 3) + 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) + # 210 weekly -> 30 daily -> 30 * 4 days not consumed = 120 + 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) + # Test group_estimate_days greater than date range, it should not + # generate greater demand. + self.test_mrp_parameter.group_estimate_days = 10 + 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), + ] + ) + moves_from_estimates = moves.filtered(lambda m: m.mrp_type == "d") + self.assertEqual(len(moves_from_estimates), 3) + 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) diff --git a/mrp_multi_level_estimate/wizards/mrp_multi_level.py b/mrp_multi_level_estimate/wizards/mrp_multi_level.py index 83ebd1d63..c784538b1 100644 --- a/mrp_multi_level_estimate/wizards/mrp_multi_level.py +++ b/mrp_multi_level_estimate/wizards/mrp_multi_level.py @@ -23,6 +23,15 @@ class MultiLevelMrp(models.TransientModel): precision_rounding=product_mrp_area.product_id.uom_id.rounding, rounding_method="HALF-UP", ) + today = fields.Date.today() + days_consumed = 0 + if product_mrp_area.group_estimate_days > 1: + start = estimate.date_from + if start < today: + days_consumed = (today - start).days + group_estimate_days = min( + product_mrp_area.group_estimate_days, estimate.duration - days_consumed + ) return { "mrp_area_id": product_mrp_area.mrp_area_id.id, "product_id": product_mrp_area.product_id.id, @@ -31,7 +40,7 @@ class MultiLevelMrp(models.TransientModel): "purchase_order_id": None, "purchase_line_id": None, "stock_move_id": None, - "mrp_qty": -daily_qty * product_mrp_area.group_estimate_days, + "mrp_qty": -daily_qty * group_estimate_days, "current_qty": -daily_qty, "mrp_date": date, "current_date": date, @@ -61,11 +70,11 @@ class MultiLevelMrp(models.TransientModel): domain = self._estimates_domain(product_mrp_area) estimates = self.env["stock.demand.estimate"].search(domain) for rec in estimates: - start = rec.date_range_id.date_start + start = rec.date_from if start < today: start = today mrp_date = fields.Date.from_string(start) - date_end = fields.Date.from_string(rec.date_range_id.date_end) + date_end = fields.Date.from_string(rec.date_to) delta = timedelta(days=product_mrp_area.group_estimate_days) while mrp_date <= date_end: mrp_move_data = self._prepare_mrp_move_data_from_estimate(