diff --git a/mrp_restrict_lot/__init__.py b/mrp_restrict_lot/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/mrp_restrict_lot/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/mrp_restrict_lot/__manifest__.py b/mrp_restrict_lot/__manifest__.py new file mode 100644 index 000000000..a58e4597c --- /dev/null +++ b/mrp_restrict_lot/__manifest__.py @@ -0,0 +1,17 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "MRP Restrict Lot", + "version": "14.0.1.0.0", + "category": "Manufacturing", + "author": "Akretion,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/manufacture", + "license": "AGPL-3", + "maintainers": ["florian-dacosta"], + "development_status": "Beta", + "depends": [ + "stock_restrict_lot", + "mrp", + ], + "installable": True, +} diff --git a/mrp_restrict_lot/models/__init__.py b/mrp_restrict_lot/models/__init__.py new file mode 100644 index 000000000..55eae1720 --- /dev/null +++ b/mrp_restrict_lot/models/__init__.py @@ -0,0 +1 @@ +from . import stock_rule diff --git a/mrp_restrict_lot/models/stock_rule.py b/mrp_restrict_lot/models/stock_rule.py new file mode 100644 index 000000000..d92d9ad77 --- /dev/null +++ b/mrp_restrict_lot/models/stock_rule.py @@ -0,0 +1,37 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models + + +class StockRule(models.Model): + _inherit = "stock.rule" + + def _prepare_mo_vals( + self, + product_id, + product_qty, + product_uom, + location_id, + name, + origin, + company_id, + values, + bom, + ): + vals = super()._prepare_mo_vals( + product_id, + product_qty, + product_uom, + location_id, + name, + origin, + company_id, + values, + bom, + ) + lot_id = values.get("restrict_lot_id") + if lot_id: + vals["lot_producing_id"] = lot_id + lot = self.env["stock.production.lot"].browse(lot_id) + vals["name"] = lot.name + return vals diff --git a/mrp_restrict_lot/readme/CONTRIBUTORS.rst b/mrp_restrict_lot/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..0bddb053a --- /dev/null +++ b/mrp_restrict_lot/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Florian da Costa diff --git a/mrp_restrict_lot/readme/DESCRIPTION.rst b/mrp_restrict_lot/readme/DESCRIPTION.rst new file mode 100644 index 000000000..4ce98a6c0 --- /dev/null +++ b/mrp_restrict_lot/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Propagate a specific lot to the Manufacturing Order (on the final product) diff --git a/mrp_restrict_lot/readme/USAGE.rst b/mrp_restrict_lot/readme/USAGE.rst new file mode 100644 index 000000000..74df36fdb --- /dev/null +++ b/mrp_restrict_lot/readme/USAGE.rst @@ -0,0 +1,6 @@ +Typically used with module sale_order_lot_generator. +- Create a sale order for a product to produce and configured with automatic lot generation. +- Confirm the sale order +The lot will be affected to the created manufacturing order + +Other module than sale_order_lot_generator could implement other uses cases for this module diff --git a/mrp_restrict_lot/tests/__init__.py b/mrp_restrict_lot/tests/__init__.py new file mode 100644 index 000000000..73b7135b6 --- /dev/null +++ b/mrp_restrict_lot/tests/__init__.py @@ -0,0 +1 @@ +from . import test_manufaturing_lot diff --git a/mrp_restrict_lot/tests/test_manufaturing_lot.py b/mrp_restrict_lot/tests/test_manufaturing_lot.py new file mode 100644 index 000000000..17f18170b --- /dev/null +++ b/mrp_restrict_lot/tests/test_manufaturing_lot.py @@ -0,0 +1,51 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.tests.common import SavepointCase + + +class TestRestrictLot(SavepointCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.customer_loc = cls.env.ref("stock.stock_location_customers") + cls.warehouse = cls.env.ref("stock.warehouse0") + cls.panel_wood_prd = cls.env.ref("mrp.product_product_wood_panel") + manufacture_route = cls.env.ref("mrp.route_warehouse0_manufacture") + mto_route = cls.env.ref("stock.route_warehouse0_mto") + mto_route.write({"active": True}) + # ensure full make to order and not mts or mto + mto_route.rule_ids.write({"procure_method": "make_to_order"}) + cls.panel_wood_prd.write( + {"route_ids": [(4, manufacture_route.id, 0), (4, mto_route.id, 0)]} + ) + cls.out_picking_type = cls.env.ref("stock.picking_type_out") + + def test_manufacturing_lot(self): + lot = self.env["stock.production.lot"].create( + { + "name": "lot1", + "product_id": self.panel_wood_prd.id, + "company_id": self.warehouse.company_id.id, + } + ) + + group = self.env["procurement.group"].create({"name": "My test delivery"}) + move = self.env["stock.move"].create( + { + "product_id": self.panel_wood_prd.id, + "location_id": self.warehouse.lot_stock_id.id, + "location_dest_id": self.customer_loc.id, + "product_uom_qty": 1, + "product_uom": self.panel_wood_prd.uom_id.id, + "name": "test", + "procure_method": "make_to_order", + "warehouse_id": self.warehouse.id, + "restrict_lot_id": lot.id, + "picking_type_id": self.out_picking_type.id, + "group_id": group.id, + } + ) + move._action_confirm() + mo = move.move_orig_ids.production_id + self.assertEqual(mo.lot_producing_id.id, lot.id) + self.assertEqual(mo.name, lot.name)