diff --git a/mrp_multi_level_estimate/__manifest__.py b/mrp_multi_level_estimate/__manifest__.py index b614cd22d..cff42fa07 100644 --- a/mrp_multi_level_estimate/__manifest__.py +++ b/mrp_multi_level_estimate/__manifest__.py @@ -3,7 +3,7 @@ { "name": "MRP Multi Level Estimate", - "version": "12.0.1.1.0", + "version": "13.0.1.0.0", "development_status": "Beta", "license": "AGPL-3", "author": "ForgeFlow, Odoo Community Association (OCA)", @@ -11,13 +11,8 @@ "summary": "Allows to consider demand estimates using MRP multi level.", "website": "https://github.com/OCA/manufacture", "category": "Manufacturing", - "depends": [ - "mrp_multi_level", - "stock_demand_estimate_matrix", - ], - "data": [ - "views/product_mrp_area_views.xml", - ], + "depends": ["mrp_multi_level", "stock_demand_estimate_matrix"], + "data": ["views/product_mrp_area_views.xml"], "installable": True, "application": False, "auto_install": True, diff --git a/mrp_multi_level_estimate/models/product_mrp_area.py b/mrp_multi_level_estimate/models/product_mrp_area.py index b8091d210..0831b6db8 100644 --- a/mrp_multi_level_estimate/models/product_mrp_area.py +++ b/mrp_multi_level_estimate/models/product_mrp_area.py @@ -12,11 +12,14 @@ 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 lenght of the date ranges you " + "use in the estimates.", ) _sql_constraints = [ - ("group_estimate_days_check", "CHECK( group_estimate_days >= 0 )", - "Group Days of Estimates must be greater than or equal to zero."), + ( + "group_estimate_days_check", + "CHECK( group_estimate_days >= 0 )", + "Group Days of Estimates must be greater than or equal to zero.", + ), ] 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 3413ac7a4..b68774266 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 @@ -4,82 +4,93 @@ from datetime import datetime, timedelta from dateutil.rrule import WEEKLY + from odoo.addons.mrp_multi_level.tests.common import TestMrpMultiLevelCommon class TestMrpMultiLevelEstimate(TestMrpMultiLevelCommon): - @classmethod def setUpClass(cls): super().setUpClass() cls.estimate_obj = cls.env["stock.demand.estimate"] # Create new clean area: - cls.estimate_loc = cls.loc_obj.create({ - "name": "Test location for estimates", - "usage": "internal", - "location_id": cls.wh.view_location_id.id, - }) - cls.estimate_area = cls.mrp_area_obj.create({ - "name": "Test", - "warehouse_id": cls.wh.id, - "location_id": cls.estimate_loc.id, - }) - cls.product_mrp_area_obj.create({ - 'product_id': cls.prod_test.id, - 'mrp_area_id': cls.estimate_area.id, - 'mrp_nbr_days': 7, - }) + cls.estimate_loc = cls.loc_obj.create( + { + "name": "Test location for estimates", + "usage": "internal", + "location_id": cls.wh.view_location_id.id, + } + ) + cls.estimate_area = cls.mrp_area_obj.create( + { + "name": "Test", + "warehouse_id": cls.wh.id, + "location_id": cls.estimate_loc.id, + } + ) + cls.product_mrp_area_obj.create( + { + "product_id": cls.prod_test.id, + "mrp_area_id": cls.estimate_area.id, + "mrp_nbr_days": 7, + } + ) # Create Date Ranges: - cls.dr_type = cls.env["date.range.type"].create({ - "name": "Weeks", - "company_id": False, - "allow_overlap": False, - }) + cls.dr_type = cls.env["date.range.type"].create( + {"name": "Weeks", "company_id": False, "allow_overlap": False} + ) today = datetime.today().replace(hour=0) - generator = cls.env["date.range.generator"].create({ - "date_start": today - timedelta(days=3), - "name_prefix": "W-", - "type_id": cls.dr_type.id, - "duration_count": 1, - "unit_of_time": WEEKLY, - "count": 3}) + generator = cls.env["date.range.generator"].create( + { + "date_start": today - timedelta(days=3), + "name_prefix": "W-", + "type_id": cls.dr_type.id, + "duration_count": 1, + "unit_of_time": WEEKLY, + "count": 3, + } + ) generator.action_apply() # Create Demand Estimates: - ranges = cls.env["date.range"].search( - [("type_id", "=", cls.dr_type.id)]) + ranges = cls.env["date.range"].search([("type_id", "=", cls.dr_type.id)]) qty = 140.0 for dr in ranges: qty += 70.0 - cls._create_demand_estimate( - cls.prod_test, cls.stock_location, dr, qty) - cls._create_demand_estimate( - cls.prod_test, cls.estimate_loc, dr, qty) + cls._create_demand_estimate(cls.prod_test, cls.stock_location, dr, qty) + cls._create_demand_estimate(cls.prod_test, cls.estimate_loc, dr, qty) cls.mrp_multi_level_wiz.create({}).run_mrp_multi_level() @classmethod def _create_demand_estimate(cls, product, location, date_range, qty): - cls.estimate_obj.create({ - "product_id": product.id, - "location_id": location.id, - "product_uom": product.uom_id.id, - "product_uom_qty": qty, - "date_range_id": date_range.id, - }) + cls.estimate_obj.create( + { + "product_id": product.id, + "location_id": location.id, + "product_uom": product.uom_id.id, + "product_uom_qty": qty, + "date_range_id": date_range.id, + } + ) def test_01_demand_estimates(self): """Tests demand estimates integration.""" - estimates = self.estimate_obj.search([ - ("product_id", "=", self.prod_test.id), - ("location_id", "=", self.stock_location.id)]) + estimates = self.estimate_obj.search( + [ + ("product_id", "=", self.prod_test.id), + ("location_id", "=", self.stock_location.id), + ] + ) self.assertEqual(len(estimates), 3) - moves = self.mrp_move_obj.search([ - ("product_id", "=", self.prod_test.id), - ("mrp_area_id", "=", self.mrp_area.id), - ]) + moves = self.mrp_move_obj.search( + [ + ("product_id", "=", self.prod_test.id), + ("mrp_area_id", "=", self.mrp_area.id), + ] + ) # 3 weeks - 3 days in the past = 18 days of valid estimates: moves_from_estimates = moves.filtered(lambda m: m.mrp_type == "d") self.assertEqual(len(moves_from_estimates), 18) @@ -87,32 +98,42 @@ class TestMrpMultiLevelEstimate(TestMrpMultiLevelCommon): self.assertIn(-30.0, quantities) # 210 a week => 30.0 dayly: self.assertIn(-40.0, quantities) # 280 a week => 40.0 dayly: self.assertIn(-50.0, quantities) # 350 a week => 50.0 dayly: - plans = self.planned_order_obj.search([ - ("product_id", "=", self.prod_test.id), - ("mrp_area_id", "=", self.mrp_area.id), - ]) + plans = self.planned_order_obj.search( + [ + ("product_id", "=", self.prod_test.id), + ("mrp_area_id", "=", self.mrp_area.id), + ] + ) action = list(set(plans.mapped("mrp_action"))) self.assertEqual(len(action), 1) self.assertEqual(action[0], "buy") self.assertEqual(len(plans), 18) - inventories = self.mrp_inventory_obj.search([ - ("mrp_area_id", "=", self.estimate_area.id)]) + inventories = self.mrp_inventory_obj.search( + [("mrp_area_id", "=", self.estimate_area.id)] + ) self.assertEqual(len(inventories), 18) def test_02_group_demand_estimates(self): """Test demand grouping functionality, `nbr_days`.""" - estimates = self.estimate_obj.search([ - ("product_id", "=", self.prod_test.id), - ("location_id", "=", self.estimate_loc.id)]) + 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), - ]) - supply_plans = self.planned_order_obj.search([ - ("product_id", "=", self.prod_test.id), - ("mrp_area_id", "=", self.estimate_area.id), - ]) + moves = self.mrp_move_obj.search( + [ + ("product_id", "=", self.prod_test.id), + ("mrp_area_id", "=", self.estimate_area.id), + ] + ) + supply_plans = self.planned_order_obj.search( + [ + ("product_id", "=", self.prod_test.id), + ("mrp_area_id", "=", self.estimate_area.id), + ] + ) # 3 weeks - 3 days in the past = 18 days of valid estimates: moves_from_estimates = moves.filtered(lambda m: m.mrp_type == "d") self.assertEqual(len(moves_from_estimates), 18) diff --git a/mrp_multi_level_estimate/views/product_mrp_area_views.xml b/mrp_multi_level_estimate/views/product_mrp_area_views.xml index cf1f382b1..f614d34a3 100644 --- a/mrp_multi_level_estimate/views/product_mrp_area_views.xml +++ b/mrp_multi_level_estimate/views/product_mrp_area_views.xml @@ -1,16 +1,14 @@ - + - product.mrp.area.form - estimates product.mrp.area form - + - + - diff --git a/mrp_multi_level_estimate/wizards/mrp_multi_level.py b/mrp_multi_level_estimate/wizards/mrp_multi_level.py index 00fb355d3..83ebd1d63 100644 --- a/mrp_multi_level_estimate/wizards/mrp_multi_level.py +++ b/mrp_multi_level_estimate/wizards/mrp_multi_level.py @@ -4,8 +4,10 @@ import logging from datetime import timedelta + from odoo import api, fields, models from odoo.tools.float_utils import float_round + logger = logging.getLogger(__name__) @@ -13,14 +15,14 @@ class MultiLevelMrp(models.TransientModel): _inherit = "mrp.multi.level" @api.model - def _prepare_mrp_move_data_from_estimate( - self, estimate, product_mrp_area, date): + def _prepare_mrp_move_data_from_estimate(self, estimate, product_mrp_area, date): mrp_type = "d" origin = "fc" daily_qty = float_round( estimate.daily_qty, precision_rounding=product_mrp_area.product_id.uom_id.rounding, - rounding_method="HALF-UP") + rounding_method="HALF-UP", + ) return { "mrp_area_id": product_mrp_area.mrp_area_id.id, "product_id": product_mrp_area.product_id.id, @@ -52,8 +54,7 @@ class MultiLevelMrp(models.TransientModel): @api.model def _init_mrp_move_from_forecast(self, product_mrp_area): - res = super(MultiLevelMrp, self)._init_mrp_move_from_forecast( - product_mrp_area) + res = super(MultiLevelMrp, self)._init_mrp_move_from_forecast(product_mrp_area) if not product_mrp_area.group_estimate_days: return False today = fields.Date.today() @@ -67,9 +68,9 @@ class MultiLevelMrp(models.TransientModel): date_end = fields.Date.from_string(rec.date_range_id.date_end) delta = timedelta(days=product_mrp_area.group_estimate_days) while mrp_date <= date_end: - mrp_move_data = \ - self._prepare_mrp_move_data_from_estimate( - rec, product_mrp_area, mrp_date) + mrp_move_data = self._prepare_mrp_move_data_from_estimate( + rec, product_mrp_area, mrp_date + ) self.env["mrp.move"].create(mrp_move_data) mrp_date += delta return res