diff --git a/setup/stock_orderpoint_origin_mrp_link/odoo/addons/stock_orderpoint_origin_mrp_link b/setup/stock_orderpoint_origin_mrp_link/odoo/addons/stock_orderpoint_origin_mrp_link new file mode 120000 index 000000000000..dc1854938b94 --- /dev/null +++ b/setup/stock_orderpoint_origin_mrp_link/odoo/addons/stock_orderpoint_origin_mrp_link @@ -0,0 +1 @@ +../../../../stock_orderpoint_origin_mrp_link \ No newline at end of file diff --git a/setup/stock_orderpoint_origin_mrp_link/setup.py b/setup/stock_orderpoint_origin_mrp_link/setup.py new file mode 100644 index 000000000000..28c57bb64031 --- /dev/null +++ b/setup/stock_orderpoint_origin_mrp_link/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/stock_orderpoint_origin/README.rst b/stock_orderpoint_origin/README.rst new file mode 100644 index 000000000000..876fdb5f4079 --- /dev/null +++ b/stock_orderpoint_origin/README.rst @@ -0,0 +1 @@ +Generated diff --git a/stock_orderpoint_origin/__init__.py b/stock_orderpoint_origin/__init__.py new file mode 100644 index 000000000000..0650744f6bc6 --- /dev/null +++ b/stock_orderpoint_origin/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/stock_orderpoint_origin/__manifest__.py b/stock_orderpoint_origin/__manifest__.py new file mode 100644 index 000000000000..e86f85a0ecfb --- /dev/null +++ b/stock_orderpoint_origin/__manifest__.py @@ -0,0 +1,13 @@ +# Copyright 2021 Open Source Integrators +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). +{ + "name": "Stock Orderpoint Replenishment demand origin details", + "summary": "Link Purchase Orders to the replenishment demand Sales Orders", + "version": "14.0.1.0.0", + "license": "LGPL-3", + "website": "https://github.com/OCA/stock-logistics-warehouse", + "author": "Open Source Integrators, Odoo Community Association (OCA)", + "category": "Warehouse", + "depends": ["purchase_stock", "sale_stock"], + "installable": True, +} diff --git a/stock_orderpoint_origin/models/__init__.py b/stock_orderpoint_origin/models/__init__.py new file mode 100644 index 000000000000..bd988e158497 --- /dev/null +++ b/stock_orderpoint_origin/models/__init__.py @@ -0,0 +1,2 @@ +from . import procurement_group +from . import purchase_order diff --git a/stock_orderpoint_origin/models/procurement_group.py b/stock_orderpoint_origin/models/procurement_group.py new file mode 100644 index 000000000000..4ab1dcb4cfb2 --- /dev/null +++ b/stock_orderpoint_origin/models/procurement_group.py @@ -0,0 +1,32 @@ +# Copyright 2021 Open Source Integrators +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from odoo import api, models + + +class ProcurementGroup(models.Model): + _inherit = "procurement.group" + + @api.model + def run(self, procurements, raise_user_error=True): + # Store the reorder source Procurement Groups + # To be used for reference and link navigation + # Also updates the Origin field of the PO + Forecast = self.env["report.stock.report_product_product_replenishment"] + new_procurements = [] + for procurement in procurements: + product = procurement.product_id + # TODO: set warehouse_id in context? + data = Forecast._get_report_data(product_variant_ids=[product.id]) + source_docs = [] + for line in data["lines"]: + if not line["document_in"] and line["document_out"]: + source_docs.append(line["document_out"]) + if source_docs: + source_groups = [x.procurement_group_id for x in source_docs] + source_names = ", ".join([x.name for x in source_docs]) + new_origin = "%s (from %s)" % (source_names, procurement.origin) + new_procurement = procurement._replace(origin=new_origin) + new_procurement.values["source_group_ids"] = source_groups + new_procurements.append(new_procurement) + return super().run(new_procurements, raise_user_error=True) diff --git a/stock_orderpoint_origin/models/purchase_order.py b/stock_orderpoint_origin/models/purchase_order.py new file mode 100644 index 000000000000..cea9e07c966e --- /dev/null +++ b/stock_orderpoint_origin/models/purchase_order.py @@ -0,0 +1,39 @@ +# Copyright 2021 Open Source Integrators +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from odoo import api, fields, models + + +class PurchaseOrder(models.Model): + _inherit = "purchase.order" + + def _get_sale_orders(self): + # Used by action_view_sale_orders, for smart button + # return self.order_line.sale_order_id + res = super()._get_sale_orders() + res |= self.order_line.source_group_ids.sale_id + return res + + +class PurchaseOrderLine(models.Model): + _inherit = "purchase.order.line" + + source_group_ids = fields.Many2many( + comodel_name="procurement.group", + string="Procurements from Forecast Report", + copy=False, + ) + + @api.model + def _prepare_purchase_order_line_from_procurement( + self, product_id, product_qty, product_uom, company_id, values, po + ): + vals = super()._prepare_purchase_order_line_from_procurement( + product_id, product_qty, product_uom, company_id, values, po + ) + # Store the reorder source Procurement Groups + # To be used for reference and link navigation + groups = values.get("source_group_ids") + if groups: + vals["source_group_ids"] = [(4, o.id) for o in groups] + return vals diff --git a/stock_orderpoint_origin/readme/CONTRIBUTORS.rst b/stock_orderpoint_origin/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000000..1d5a48b4cc71 --- /dev/null +++ b/stock_orderpoint_origin/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Daniel Reis `Open Source Integrators `_: diff --git a/stock_orderpoint_origin/readme/DESCRIPTION.rst b/stock_orderpoint_origin/readme/DESCRIPTION.rst new file mode 100644 index 000000000000..e9058d65b5f2 --- /dev/null +++ b/stock_orderpoint_origin/readme/DESCRIPTION.rst @@ -0,0 +1,14 @@ +The Inventory Replenishment menu alows to choose a route and create orders to +replenish the needed quantities of a Product. + +However the Purchase Orders created do not have the information +about the documents that generated that demand. +The Purchase Order "Origin" field will only +identify the replenishment/reorder rule that generated it. + +This feature updates the Purchase Order "Origin" field with the documents +that generated the demand, generating the demand, such as Sales Orders or Manufacturing Orders. +This is done based on the information provided by the Forecast report. + +The source demand Sales Orders are added to the Purchase Order smart button, +allowing to navigate directly to them. diff --git a/stock_orderpoint_origin/readme/USAGE.rst b/stock_orderpoint_origin/readme/USAGE.rst new file mode 100644 index 000000000000..88bdd528b5d7 --- /dev/null +++ b/stock_orderpoint_origin/readme/USAGE.rst @@ -0,0 +1,4 @@ +- Create order from the Replenishment menu, for example, using the "Order Once" button. +- Verify the Origin field of the created orders. It should include the references to the + orders generating this demand at the time of replenishment creation. +- If demand was generated from Sales Orders, the "Sale" smart button should be available. diff --git a/stock_orderpoint_origin/static/description/icon.png b/stock_orderpoint_origin/static/description/icon.png new file mode 100644 index 000000000000..3a0328b516c4 Binary files /dev/null and b/stock_orderpoint_origin/static/description/icon.png differ diff --git a/stock_orderpoint_origin_mrp_link/README.rst b/stock_orderpoint_origin_mrp_link/README.rst new file mode 100644 index 000000000000..876fdb5f4079 --- /dev/null +++ b/stock_orderpoint_origin_mrp_link/README.rst @@ -0,0 +1 @@ +Generated diff --git a/stock_orderpoint_origin_mrp_link/__init__.py b/stock_orderpoint_origin_mrp_link/__init__.py new file mode 100644 index 000000000000..0650744f6bc6 --- /dev/null +++ b/stock_orderpoint_origin_mrp_link/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/stock_orderpoint_origin_mrp_link/__manifest__.py b/stock_orderpoint_origin_mrp_link/__manifest__.py new file mode 100644 index 000000000000..f151ef9aeff1 --- /dev/null +++ b/stock_orderpoint_origin_mrp_link/__manifest__.py @@ -0,0 +1,14 @@ +# Copyright 2021 Open Source Integrators +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). +{ + "name": "Stock Orderpoint Replenishment MRP demand origin details", + "summary": "Link Purchase Orders to the replenishment demand MOs", + "version": "14.0.1.0.0", + "license": "LGPL-3", + "website": "https://github.com/OCA/stock-logistics-warehouse", + "author": "Open Source Integrators, Odoo Community Association (OCA)", + "category": "Warehouse", + "depends": ["stock_orderpoint_origin", "purchase_mrp"], + "installable": True, + "auto_intall": True, +} diff --git a/stock_orderpoint_origin_mrp_link/models/__init__.py b/stock_orderpoint_origin_mrp_link/models/__init__.py new file mode 100644 index 000000000000..9f03530643d8 --- /dev/null +++ b/stock_orderpoint_origin_mrp_link/models/__init__.py @@ -0,0 +1 @@ +from . import purchase_order diff --git a/stock_orderpoint_origin_mrp_link/models/purchase_order.py b/stock_orderpoint_origin_mrp_link/models/purchase_order.py new file mode 100644 index 000000000000..782ee9ebb26f --- /dev/null +++ b/stock_orderpoint_origin_mrp_link/models/purchase_order.py @@ -0,0 +1,41 @@ +# Copyright 2021 Open Source Integrators +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from odoo import _, api, models + + +class PurchaseOrder(models.Model): + _inherit = "purchase.order" + + @api.depends( + "order_line.move_dest_ids.group_id.mrp_production_ids", + "order_line.source_group_ids", + ) + def _compute_mrp_production_count(self): + super()._compute_mrp_production_count() + for purchase in self: + mos_to_add = purchase.order_line.source_group_ids.mrp_production_ids + purchase.mrp_production_count += len(mos_to_add) + + def action_view_mrp_productions(self): + action = super().action_view_mrp_productions() + mos_to_add = self.order_line.source_group_ids.mrp_production_ids + if mos_to_add: + if self.mrp_production_count == 1: + action = { + "res_model": "mrp.production", + "type": "ir.actions.act_window", + "view_mode": "form", + "res_id": mos_to_add.id, + } + else: + old_domain = action.get("domain") or [("id", "=", action.get("res_id"))] + new_domain = ["|", ("id", "in", mos_to_add.ids)] + old_domain + action = { + "res_model": "mrp.production", + "type": "ir.actions.act_window", + "name": _("Manufacturing Source of %s", self.name), + "domain": new_domain, + "view_mode": "tree,form", + } + return action diff --git a/stock_orderpoint_origin_mrp_link/readme/CONTRIBUTORS.rst b/stock_orderpoint_origin_mrp_link/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000000..1d5a48b4cc71 --- /dev/null +++ b/stock_orderpoint_origin_mrp_link/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Daniel Reis `Open Source Integrators `_: diff --git a/stock_orderpoint_origin_mrp_link/readme/DESCRIPTION.rst b/stock_orderpoint_origin_mrp_link/readme/DESCRIPTION.rst new file mode 100644 index 000000000000..aaff84bb7bcd --- /dev/null +++ b/stock_orderpoint_origin_mrp_link/readme/DESCRIPTION.rst @@ -0,0 +1,14 @@ +The Inventory Replenishment menu alows to choose a route and create orders to +replenish the needed quantities of a Product. + +However the Purchase Orders created do not have the information +about the documents that generated that demand. +The Purchase Order "Origin" field will only +identify the replenishment/reorder rule that generated it. + +This feature updates the Purchase Order "Origin" field with the documents +that generated the demand, generating the demand, such as Sales Orders or Manufacturing Orders. +This is done based on the information provided by the Forecast report. + +This particular extension also adds the source demand Manufacturing Orders +to the Purchase Order smart button, allowing to navigate directly to them. diff --git a/stock_orderpoint_origin_mrp_link/readme/USAGE.rst b/stock_orderpoint_origin_mrp_link/readme/USAGE.rst new file mode 100644 index 000000000000..cc68851b4b54 --- /dev/null +++ b/stock_orderpoint_origin_mrp_link/readme/USAGE.rst @@ -0,0 +1,5 @@ +- Create order from the Replenishment menu, for example, using the "Order Once" button. +- Verify the Origin field of the created orders. It should include the references to the + orders generating this demand at the time of replenishment creation. +- If demand was generated from Manufacturing Orders, the "Manufacturin" smart button + should be available. diff --git a/stock_orderpoint_origin_mrp_link/static/description/icon.png b/stock_orderpoint_origin_mrp_link/static/description/icon.png new file mode 100644 index 000000000000..3a0328b516c4 Binary files /dev/null and b/stock_orderpoint_origin_mrp_link/static/description/icon.png differ