[IMP] mrp_multi_level_estimate: Stock moves from MO should always be considered

When we consider forecasts as the 'Indirect' demand, we should always keep considering the demand coming from Manufacturing Orders, as they are 'Direct' demand.
This commit is contained in:
BernatPForgeFlow
2023-05-25 08:11:54 +02:00
parent 8ea2a1f927
commit 8ad7e65d4e
2 changed files with 112 additions and 2 deletions

View File

@@ -3,6 +3,8 @@
from datetime import datetime, timedelta
from odoo.tests import Form
from odoo.addons.mrp_multi_level.tests.common import TestMrpMultiLevelCommon
@@ -333,3 +335,108 @@ class TestMrpMultiLevelEstimate(TestMrpMultiLevelCommon):
self.assertEqual(
demand_from_other_sources.mrp_date, self.date_without_ranges.date()
)
def test_06_estimate_and_other_sources_strat_with_mo(self):
"""
Tests demand estimates and other sources strategies with MOs.
Components demand from MOs is always indirect demand, so even if we
have estimates, we should consider that demand.
"""
# Get manufactured product, component and bom
fp_1 = self.env.ref("mrp_multi_level.product_product_fp_1")
pp_1 = self.env.ref("mrp_multi_level.product_product_pp_1")
fp_1_bom = self.env.ref("mrp_multi_level.mrp_bom_fp_1")
self.product_mrp_area_obj.create(
{"product_id": fp_1.id, "mrp_area_id": self.estimate_area.id}
)
self.product_mrp_area_obj.create(
{"product_id": pp_1.id, "mrp_area_id": self.estimate_area.id}
)
# Create 1 estimate of 1 week length for the component.
date_start = datetime.today().replace(hour=0)
date_end = date_start + timedelta(days=6)
self._create_demand_estimate(pp_1, self.estimate_loc, date_start, date_end, 7)
date_mo = date_start + timedelta(days=1)
# Create 1 MO for fp_1 that has two pp_1 in its components
mo_form = Form(self.mo_obj)
mo_form.product_id = fp_1
mo_form.bom_id = fp_1_bom
mo_form.product_qty = 10
mo_form.date_planned_start = date_mo
mo_form.location_src_id = self.estimate_loc
mo = mo_form.save()
mo.action_confirm()
# Create 1 picking out that represents a Delivery Order from a sale
self._create_picking_out(pp_1, 5, date_mo, location=self.estimate_loc)
# 1. "all"
# Expected result: Consider all sources of demand
self.estimate_area.estimate_demand_and_other_sources_strat = "all"
self.mrp_multi_level_wiz.create(
{"mrp_area_ids": [(6, 0, self.estimate_area.ids)]}
).run_mrp_multi_level()
moves = self.mrp_move_obj.search(
[
("product_id", "=", pp_1.id),
("mrp_area_id", "=", self.estimate_area.id),
]
)
demand_from_estimates = moves.filtered(
lambda m: m.mrp_type == "d" and m.mrp_origin == "fc"
)
demand_from_other_sources = moves.filtered(
lambda m: m.mrp_type == "d" and m.mrp_origin != "fc"
)
self.assertEqual(len(demand_from_estimates), 7)
self.assertEqual(sum(demand_from_estimates.mapped("mrp_qty")), -7)
self.assertEqual(len(demand_from_other_sources), 2)
self.assertEqual(sum(demand_from_other_sources.mapped("mrp_qty")), -25)
# 2. "ignore_others_if_estimates"
# Expected result: Consider estimates and demand from MO
self.estimate_area.estimate_demand_and_other_sources_strat = (
"ignore_others_if_estimates"
)
self.mrp_multi_level_wiz.create(
{"mrp_area_ids": [(6, 0, self.estimate_area.ids)]}
).run_mrp_multi_level()
moves = self.mrp_move_obj.search(
[
("product_id", "=", pp_1.id),
("mrp_area_id", "=", self.estimate_area.id),
]
)
demand_from_estimates = moves.filtered(
lambda m: m.mrp_type == "d" and m.mrp_origin == "fc"
)
demand_from_other_sources = moves.filtered(
lambda m: m.mrp_type == "d" and m.mrp_origin != "fc"
)
self.assertEqual(len(demand_from_estimates), 7)
self.assertEqual(sum(demand_from_estimates.mapped("mrp_qty")), -7)
self.assertEqual(len(demand_from_other_sources), 1)
self.assertEqual(sum(demand_from_other_sources.mapped("mrp_qty")), -20)
# 3. "ignore_overlapping"
# Expected result: Consider estimates and demand from MO
self.estimate_area.estimate_demand_and_other_sources_strat = (
"ignore_overlapping"
)
self.mrp_multi_level_wiz.create(
{"mrp_area_ids": [(6, 0, self.estimate_area.ids)]}
).run_mrp_multi_level()
moves = self.mrp_move_obj.search(
[
("product_id", "=", pp_1.id),
("mrp_area_id", "=", self.estimate_area.id),
]
)
demand_from_estimates = moves.filtered(
lambda m: m.mrp_type == "d" and m.mrp_origin == "fc"
)
demand_from_other_sources = moves.filtered(
lambda m: m.mrp_type == "d" and m.mrp_origin != "fc"
)
self.assertEqual(len(demand_from_estimates), 7)
self.assertEqual(sum(demand_from_estimates.mapped("mrp_qty")), -7)
self.assertEqual(len(demand_from_other_sources), 1)
self.assertEqual(sum(demand_from_other_sources.mapped("mrp_qty")), -20)

View File

@@ -122,8 +122,11 @@ class MultiLevelMrp(models.TransientModel):
)
if direction == "out":
mrp_date = res.get("mrp_date")
if self._exclude_considering_estimate_demand_and_other_sources_strat(
product_mrp_area, mrp_date
if (
self._exclude_considering_estimate_demand_and_other_sources_strat(
product_mrp_area, mrp_date
)
and not res["production_id"]
):
return False
return res