From af7bd8755c9cc79a4a65ec9e1c0fe9512cb8b9fe Mon Sep 17 00:00:00 2001 From: pilarvargas-tecnativa Date: Fri, 3 May 2024 13:38:30 +0200 Subject: [PATCH] [ADD] stock_replenishment_mrp_bom_selection: New module TT48984 --- .../stock_replenishment_mrp_bom_selection | 1 + .../setup.py | 6 + .../README.rst | 100 ++++ .../__init__.py | 2 + .../__manifest__.py | 17 + .../i18n/es.po | 209 ++++++++ .../stock_replenishment_mrp_bom_selection.pot | 201 ++++++++ .../models/__init__.py | 1 + .../models/stock_warehouse_orderpoint.py | 31 ++ .../readme/CONTEXT.rst | 6 + .../readme/CONTRIBUTORS.rst | 4 + .../readme/DESCRIPTION.rst | 3 + .../readme/USAGE.rst | 5 + .../security/ir.model.access.csv | 5 + .../static/description/index.html | 445 ++++++++++++++++++ .../tests/__init__.py | 1 + ...t_stock_replenishment_mrp_bom_selection.py | 72 +++ .../wizard/__init__.py | 2 + .../wizard/material_availability_wizard.py | 59 +++ .../material_availability_wizard_views.xml | 28 ++ ...k_warehouse_orderpoint_replenish_wizard.py | 133 ++++++ ...ouse_orderpoint_replenish_wizard_views.xml | 55 +++ 22 files changed, 1386 insertions(+) create mode 120000 setup/stock_replenishment_mrp_bom_selection/odoo/addons/stock_replenishment_mrp_bom_selection create mode 100644 setup/stock_replenishment_mrp_bom_selection/setup.py create mode 100644 stock_replenishment_mrp_bom_selection/README.rst create mode 100644 stock_replenishment_mrp_bom_selection/__init__.py create mode 100644 stock_replenishment_mrp_bom_selection/__manifest__.py create mode 100644 stock_replenishment_mrp_bom_selection/i18n/es.po create mode 100644 stock_replenishment_mrp_bom_selection/i18n/stock_replenishment_mrp_bom_selection.pot create mode 100644 stock_replenishment_mrp_bom_selection/models/__init__.py create mode 100644 stock_replenishment_mrp_bom_selection/models/stock_warehouse_orderpoint.py create mode 100644 stock_replenishment_mrp_bom_selection/readme/CONTEXT.rst create mode 100644 stock_replenishment_mrp_bom_selection/readme/CONTRIBUTORS.rst create mode 100644 stock_replenishment_mrp_bom_selection/readme/DESCRIPTION.rst create mode 100644 stock_replenishment_mrp_bom_selection/readme/USAGE.rst create mode 100644 stock_replenishment_mrp_bom_selection/security/ir.model.access.csv create mode 100644 stock_replenishment_mrp_bom_selection/static/description/index.html create mode 100644 stock_replenishment_mrp_bom_selection/tests/__init__.py create mode 100644 stock_replenishment_mrp_bom_selection/tests/test_stock_replenishment_mrp_bom_selection.py create mode 100644 stock_replenishment_mrp_bom_selection/wizard/__init__.py create mode 100644 stock_replenishment_mrp_bom_selection/wizard/material_availability_wizard.py create mode 100644 stock_replenishment_mrp_bom_selection/wizard/material_availability_wizard_views.xml create mode 100644 stock_replenishment_mrp_bom_selection/wizard/stock_warehouse_orderpoint_replenish_wizard.py create mode 100644 stock_replenishment_mrp_bom_selection/wizard/stock_warehouse_orderpoint_replenish_wizard_views.xml diff --git a/setup/stock_replenishment_mrp_bom_selection/odoo/addons/stock_replenishment_mrp_bom_selection b/setup/stock_replenishment_mrp_bom_selection/odoo/addons/stock_replenishment_mrp_bom_selection new file mode 120000 index 000000000..d651a8fbb --- /dev/null +++ b/setup/stock_replenishment_mrp_bom_selection/odoo/addons/stock_replenishment_mrp_bom_selection @@ -0,0 +1 @@ +../../../../stock_replenishment_mrp_bom_selection \ No newline at end of file diff --git a/setup/stock_replenishment_mrp_bom_selection/setup.py b/setup/stock_replenishment_mrp_bom_selection/setup.py new file mode 100644 index 000000000..28c57bb64 --- /dev/null +++ b/setup/stock_replenishment_mrp_bom_selection/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/stock_replenishment_mrp_bom_selection/README.rst b/stock_replenishment_mrp_bom_selection/README.rst new file mode 100644 index 000000000..fad3a4f75 --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/README.rst @@ -0,0 +1,100 @@ +===================================== +Stock Replenishment MRP BoM Selection +===================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:ea77f5ab29a72f3762a1a209c394d7f956762b97b0945b4d432e6f979ac0a109 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmanufacture-lightgray.png?logo=github + :target: https://github.com/OCA/manufacture/tree/15.0/stock_replenishment_mrp_bom_selection + :alt: OCA/manufacture +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/manufacture-15-0/manufacture-15-0-stock_replenishment_mrp_bom_selection + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/manufacture&target_branch=15.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module adds a wizard for replenishment cases that have the product manufacturing route +marked as a route. This wizard allows to establish which quantity to create and with which +bill of materials to manufacture it. + +**Table of contents** + +.. contents:: + :local: + +Use Cases / Context +=================== + +You may have several ways to manufacture a product, using different raw materials, and +for deciding which one to choose, you need to have all the information available in +the same screen (raw material availability, production times, etc). + +This module eases this through a wizard displaying the information and allowing to select +discrete quantities to produce for each combination. + +Usage +===== + +# Go to "Inventory / Operations / Replenishment" +# Create or use a registry that has the manufacturing route defined +# Click on "Order once", the wizard should open +# Set the quantity and the list with which you want to produce this quantity of product. +# On confirmation, the relevant production orders will be created. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Tecnativa + +Contributors +~~~~~~~~~~~~ + +* `Tecnativa `_: + + * Pedro Baeza + * Pilar Vargas + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/manufacture `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_replenishment_mrp_bom_selection/__init__.py b/stock_replenishment_mrp_bom_selection/__init__.py new file mode 100644 index 000000000..9b4296142 --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizard diff --git a/stock_replenishment_mrp_bom_selection/__manifest__.py b/stock_replenishment_mrp_bom_selection/__manifest__.py new file mode 100644 index 000000000..5297ea5fa --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2024 Tecnativa - Pilar Vargas +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +{ + "name": "Stock Replenishment MRP BoM Selection", + "version": "15.0.1.0.0", + "license": "AGPL-3", + "author": "Tecnativa, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/manufacture", + "depends": ["stock", "mrp"], + "data": [ + "security/ir.model.access.csv", + "wizard/material_availability_wizard_views.xml", + "wizard/stock_warehouse_orderpoint_replenish_wizard_views.xml", + ], + "installable": True, + "development_status": "Beta", +} diff --git a/stock_replenishment_mrp_bom_selection/i18n/es.po b/stock_replenishment_mrp_bom_selection/i18n/es.po new file mode 100644 index 000000000..a9dfd8033 --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/i18n/es.po @@ -0,0 +1,209 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_replenishment_mrp_bom_selection +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-05-15 07:50+0000\n" +"PO-Revision-Date: 2024-05-15 09:53+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: es_ES\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.0.1\n" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__bom_id +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard__bom_id +msgid "Bill of Materials" +msgstr "Lista de materiales" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__bom_line_ids +msgid "Bom Line" +msgstr "Línea de lista de materiales" + +#. module: stock_replenishment_mrp_bom_selection +#: model_terms:ir.ui.view,arch_db:stock_replenishment_mrp_bom_selection.material_availability_wizard_view +msgid "Close" +msgstr "Cerrar" + +#. module: stock_replenishment_mrp_bom_selection +#: model_terms:ir.ui.view,arch_db:stock_replenishment_mrp_bom_selection.stock_warehouse_orderpoint_replenish_wizard_view_form +msgid "Confirm" +msgstr "Confirmar" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__create_uid +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard__create_uid +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line__create_uid +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__create_date +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard__create_date +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line__create_date +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__create_date +msgid "Created on" +msgstr "Creado en" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,help:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__product_uom_id +msgid "Default unit of measure used for all stock operations." +msgstr "Unidad de medida por defecto utilizada para todas las operaciones de stock." + +#. module: stock_replenishment_mrp_bom_selection +#: model_terms:ir.ui.view,arch_db:stock_replenishment_mrp_bom_selection.stock_warehouse_orderpoint_replenish_wizard_view_form +msgid "Discard" +msgstr "Descartar" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__display_name +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard__display_name +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line__display_name +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__display_name +msgid "Display Name" +msgstr "Nombre mostrado" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__id +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard__id +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line__id +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__id +msgid "ID" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard____last_update +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard____last_update +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line____last_update +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard____last_update +msgid "Last Modified on" +msgstr "Última modificación en" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__write_uid +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard__write_uid +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line__write_uid +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__write_uid +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__write_date +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard__write_date +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line__write_date +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__write_date +msgid "Last Updated on" +msgstr "Última actualización en" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model,name:stock_replenishment_mrp_bom_selection.model_bom_line_wizard +msgid "Manufacture BOM line" +msgstr "Linea de fabricación de la lista de materiales" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model,name:stock_replenishment_mrp_bom_selection.model_material_availability_wizard +msgid "Material Availability Wizard" +msgstr "Asistente de disponibilidad de material" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model,name:stock_replenishment_mrp_bom_selection.model_material_availability_wizard_line +msgid "Material Availability Wizard Line" +msgstr "Línea del Asistente de Disponibilidad de Material" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__max_production_qty +msgid "Maximum Production Quantity" +msgstr "Máxima Cantidad de Producción" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model,name:stock_replenishment_mrp_bom_selection.model_stock_warehouse_orderpoint +msgid "Minimum Inventory Rule" +msgstr "Regla de inventario mínimo" + +#. module: stock_replenishment_mrp_bom_selection +#: code:addons/stock_replenishment_mrp_bom_selection/wizard/stock_warehouse_orderpoint_replenish_wizard.py:0 +#, python-format +msgid "Nothing to produce." +msgstr "Nada para producir." + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__orderpoint_id +msgid "Orderpoint" +msgstr "Punto de pedido" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line__product_id +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__product_id +msgid "Product" +msgstr "Producto" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__product_tmpl_id +msgid "Product Template" +msgstr "Plantilla de producto" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__production_time +#, fuzzy +#| msgid "Product Template" +msgid "Production Time" +msgstr "Plantilla de producto" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard__product_ids +#, fuzzy +#| msgid "Product" +msgid "Products" +msgstr "Producto" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line__product_qty_available +msgid "Quantity Available" +msgstr "Cantidad disponible" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__qty_to_produce +msgid "Quantity to produce" +msgstr "Cantidad a producir" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard__replenish_wizard_id +msgid "Replenish Wizard" +msgstr "Asistente de Reposición" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model,name:stock_replenishment_mrp_bom_selection.model_stock_warehouse_orderpoint_replenish_wizard +msgid "Stock warehouse orderpoint replenish wizard" +msgstr "Asistente de reposición de pedidos de almacén" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__qty_to_order +msgid "To Order" +msgstr "A producir" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__total_qty_to_produce +#, fuzzy +#| msgid "Quantity to produce" +msgid "Total Quantity to Produce" +msgstr "Cantidad a producir" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__product_uom_id +msgid "Unit of Measure" +msgstr "Unidad de medida" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__wizard_id +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line__wizard_id +msgid "Wizard" +msgstr "Asistente" diff --git a/stock_replenishment_mrp_bom_selection/i18n/stock_replenishment_mrp_bom_selection.pot b/stock_replenishment_mrp_bom_selection/i18n/stock_replenishment_mrp_bom_selection.pot new file mode 100644 index 000000000..8c6ce434f --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/i18n/stock_replenishment_mrp_bom_selection.pot @@ -0,0 +1,201 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_replenishment_mrp_bom_selection +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-05-15 07:50+0000\n" +"PO-Revision-Date: 2024-05-15 07:50+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__bom_id +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard__bom_id +msgid "Bill of Materials" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__bom_line_ids +msgid "Bom Line" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model_terms:ir.ui.view,arch_db:stock_replenishment_mrp_bom_selection.material_availability_wizard_view +msgid "Close" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model_terms:ir.ui.view,arch_db:stock_replenishment_mrp_bom_selection.stock_warehouse_orderpoint_replenish_wizard_view_form +msgid "Confirm" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__create_uid +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard__create_uid +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line__create_uid +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__create_uid +msgid "Created by" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__create_date +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard__create_date +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line__create_date +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__create_date +msgid "Created on" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,help:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__product_uom_id +msgid "Default unit of measure used for all stock operations." +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model_terms:ir.ui.view,arch_db:stock_replenishment_mrp_bom_selection.stock_warehouse_orderpoint_replenish_wizard_view_form +msgid "Discard" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__display_name +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard__display_name +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line__display_name +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__display_name +msgid "Display Name" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__id +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard__id +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line__id +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__id +msgid "ID" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard____last_update +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard____last_update +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line____last_update +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard____last_update +msgid "Last Modified on" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__write_uid +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard__write_uid +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line__write_uid +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__write_date +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard__write_date +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line__write_date +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__write_date +msgid "Last Updated on" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model,name:stock_replenishment_mrp_bom_selection.model_bom_line_wizard +msgid "Manufacture BOM line" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model,name:stock_replenishment_mrp_bom_selection.model_material_availability_wizard +msgid "Material Availability Wizard" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model,name:stock_replenishment_mrp_bom_selection.model_material_availability_wizard_line +msgid "Material Availability Wizard Line" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__max_production_qty +msgid "Maximum Production Quantity" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model,name:stock_replenishment_mrp_bom_selection.model_stock_warehouse_orderpoint +msgid "Minimum Inventory Rule" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: code:addons/stock_replenishment_mrp_bom_selection/wizard/stock_warehouse_orderpoint_replenish_wizard.py:0 +#, python-format +msgid "Nothing to produce." +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__orderpoint_id +msgid "Orderpoint" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line__product_id +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__product_id +msgid "Product" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__product_tmpl_id +msgid "Product Template" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__production_time +msgid "Production Time" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard__product_ids +msgid "Products" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line__product_qty_available +msgid "Quantity Available" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__qty_to_produce +msgid "Quantity to produce" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard__replenish_wizard_id +msgid "Replenish Wizard" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model,name:stock_replenishment_mrp_bom_selection.model_stock_warehouse_orderpoint_replenish_wizard +msgid "Stock warehouse orderpoint replenish wizard" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__qty_to_order +msgid "To Order" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_stock_warehouse_orderpoint_replenish_wizard__total_qty_to_produce +msgid "Total Quantity to Produce" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__product_uom_id +msgid "Unit of Measure" +msgstr "" + +#. module: stock_replenishment_mrp_bom_selection +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_bom_line_wizard__wizard_id +#: model:ir.model.fields,field_description:stock_replenishment_mrp_bom_selection.field_material_availability_wizard_line__wizard_id +msgid "Wizard" +msgstr "" diff --git a/stock_replenishment_mrp_bom_selection/models/__init__.py b/stock_replenishment_mrp_bom_selection/models/__init__.py new file mode 100644 index 000000000..5024fb8c7 --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/models/__init__.py @@ -0,0 +1 @@ +from . import stock_warehouse_orderpoint diff --git a/stock_replenishment_mrp_bom_selection/models/stock_warehouse_orderpoint.py b/stock_replenishment_mrp_bom_selection/models/stock_warehouse_orderpoint.py new file mode 100644 index 000000000..b46d79e88 --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/models/stock_warehouse_orderpoint.py @@ -0,0 +1,31 @@ +# Copyright 2024 Tecnativa - Pilar Vargas +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models + + +class StockWarehouseOrderpoint(models.Model): + _inherit = "stock.warehouse.orderpoint" + + def action_replenish(self): + # The wizard is only necessary if the production route is marked and the product + # has defined BOMs. + if ( + self.route_id == self.env.ref("mrp.route_warehouse0_manufacture") + and self.product_id.bom_ids + ): + # In to use the info button, it is necessary to create the wizard + replenish_wizard = self.env[ + "stock.warehouse.orderpoint.replenish.wizard" + ].create({"orderpoint_id": self.id}) + replenish_wizard_id = replenish_wizard.id + return { + "name": "Replenish", + "type": "ir.actions.act_window", + "view_mode": "form", + "res_model": "stock.warehouse.orderpoint.replenish.wizard", + "res_id": replenish_wizard_id, + "target": "new", + "context": {"default_orderpoint_id": self.id}, + } + return super().action_replenish() diff --git a/stock_replenishment_mrp_bom_selection/readme/CONTEXT.rst b/stock_replenishment_mrp_bom_selection/readme/CONTEXT.rst new file mode 100644 index 000000000..ca0d9b780 --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/readme/CONTEXT.rst @@ -0,0 +1,6 @@ +You may have several ways to manufacture a product, using different raw materials, and +for deciding which one to choose, you need to have all the information available in +the same screen (raw material availability, production times, etc). + +This module eases this through a wizard displaying the information and allowing to select +discrete quantities to produce for each combination. diff --git a/stock_replenishment_mrp_bom_selection/readme/CONTRIBUTORS.rst b/stock_replenishment_mrp_bom_selection/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..e70fbc47a --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/readme/CONTRIBUTORS.rst @@ -0,0 +1,4 @@ +* `Tecnativa `_: + + * Pedro Baeza + * Pilar Vargas diff --git a/stock_replenishment_mrp_bom_selection/readme/DESCRIPTION.rst b/stock_replenishment_mrp_bom_selection/readme/DESCRIPTION.rst new file mode 100644 index 000000000..943d6763a --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/readme/DESCRIPTION.rst @@ -0,0 +1,3 @@ +This module adds a wizard for replenishment cases that have the product manufacturing route +marked as a route. This wizard allows to establish which quantity to create and with which +bill of materials to manufacture it. diff --git a/stock_replenishment_mrp_bom_selection/readme/USAGE.rst b/stock_replenishment_mrp_bom_selection/readme/USAGE.rst new file mode 100644 index 000000000..3bfc3392e --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/readme/USAGE.rst @@ -0,0 +1,5 @@ +# Go to "Inventory / Operations / Replenishment" +# Create or use a registry that has the manufacturing route defined +# Click on "Order once", the wizard should open +# Set the quantity and the list with which you want to produce this quantity of product. +# On confirmation, the relevant production orders will be created. diff --git a/stock_replenishment_mrp_bom_selection/security/ir.model.access.csv b/stock_replenishment_mrp_bom_selection/security/ir.model.access.csv new file mode 100644 index 000000000..8be2700ad --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/security/ir.model.access.csv @@ -0,0 +1,5 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +stock_replenishment_mrp_bom_selection.access_stock_warehouse_orderpoint_replenish_wizard,access_stock_warehouse_orderpoint_replenish_wizard,stock_replenishment_mrp_bom_selection.model_stock_warehouse_orderpoint_replenish_wizard,stock.group_stock_manager,1,1,1,1 +stock_replenishment_mrp_bom_selection.access_bom_line_wizard,access_bom_line_wizard,stock_replenishment_mrp_bom_selection.model_bom_line_wizard,stock.group_stock_manager,1,1,1,1 +stock_replenishment_mrp_bom_selection.access_material_availability_wizard,access_material_availability_wizard,stock_replenishment_mrp_bom_selection.model_material_availability_wizard,stock.group_stock_manager,1,1,1,1 +stock_replenishment_mrp_bom_selection.access_material_availability_wizard_line,access_material_availability_wizard_line,stock_replenishment_mrp_bom_selection.model_material_availability_wizard_line,stock.group_stock_manager,1,1,1,1 diff --git a/stock_replenishment_mrp_bom_selection/static/description/index.html b/stock_replenishment_mrp_bom_selection/static/description/index.html new file mode 100644 index 000000000..7b493c56f --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/static/description/index.html @@ -0,0 +1,445 @@ + + + + + + +Stock Replenishment MRP BoM Selection + + + +
+

Stock Replenishment MRP BoM Selection

+ + +

Beta License: AGPL-3 OCA/manufacture Translate me on Weblate Try me on Runboat

+

This module adds a wizard for replenishment cases that have the product manufacturing route +marked as a route. This wizard allows to establish which quantity to create and with which +bill of materials to manufacture it.

+

Table of contents

+ +
+

Use Cases / Context

+

You may have several ways to manufacture a product, using different raw materials, and +for deciding which one to choose, you need to have all the information available in +the same screen (raw material availability, production times, etc).

+

This module eases this through a wizard displaying the information and allowing to select +discrete quantities to produce for each combination.

+
+
+

Usage

+

# Go to “Inventory / Operations / Replenishment” +# Create or use a registry that has the manufacturing route defined +# Click on “Order once”, the wizard should open +# Set the quantity and the list with which you want to produce this quantity of product. +# On confirmation, the relevant production orders will be created.

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Tecnativa
  • +
+
+
+

Contributors

+
    +
  • Tecnativa:
      +
    • Pedro Baeza
    • +
    • Pilar Vargas
    • +
    +
  • +
+
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/manufacture project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/stock_replenishment_mrp_bom_selection/tests/__init__.py b/stock_replenishment_mrp_bom_selection/tests/__init__.py new file mode 100644 index 000000000..8c2cf2921 --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/tests/__init__.py @@ -0,0 +1 @@ +from . import test_stock_replenishment_mrp_bom_selection diff --git a/stock_replenishment_mrp_bom_selection/tests/test_stock_replenishment_mrp_bom_selection.py b/stock_replenishment_mrp_bom_selection/tests/test_stock_replenishment_mrp_bom_selection.py new file mode 100644 index 000000000..31d9f66af --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/tests/test_stock_replenishment_mrp_bom_selection.py @@ -0,0 +1,72 @@ +# Copyright 2021 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +from odoo import exceptions +from odoo.tests.common import Form, TransactionCase + + +class TestStockReplenishmentMrpBomSelection(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + # Product with bill of materials + cls.product = cls._create_product_template(cls, "Test product") + cls.product_c1 = cls._create_product_template(cls, "Test c1") + cls.product_c2 = cls._create_product_template(cls, "Test c2") + cls.product_c3 = cls._create_product_template(cls, "Test c3") + cls.product_c4 = cls._create_product_template(cls, "Test c4") + cls.mrp_bom_1 = cls._create_mrp_bom(cls, cls.product_c1, cls.product_c2) + cls.mrp_bom_2 = cls._create_mrp_bom(cls, cls.product_c3, cls.product_c4) + cls.manufacturing_route_id = cls.env.ref("mrp.route_warehouse0_manufacture") + + def _create_product_template(self, name): + product_form = Form(self.env["product.template"]) + product_form.name = name + product_form.detailed_type = "product" + return product_form.save() + + def _create_mrp_bom(self, component1, component2): + mrp_bom_form = Form(self.env["mrp.bom"]) + mrp_bom_form.product_tmpl_id = self.product + with mrp_bom_form.bom_line_ids.new() as line_form: + line_form.product_id = component1.product_variant_ids[0] + with mrp_bom_form.bom_line_ids.new() as line_form: + line_form.product_id = component2.product_variant_ids[0] + return mrp_bom_form.save() + + def test_stock_replenishment_mrp_bom_selection(self): + orderpoint_form = Form( + self.env["stock.warehouse.orderpoint"], + view="stock.view_warehouse_orderpoint_tree_editable", + ) + orderpoint_form.product_id = self.product.product_variant_ids[0] + orderpoint_form.qty_to_order = 500 + order = orderpoint_form.save() + # If no route is set it will not open the wizard + with self.assertRaises(exceptions.RedirectWarning): + order.action_replenish() + # If the defined route is manufacturing it will open the wizard. + order.route_id = self.manufacturing_route_id + action = order.action_replenish() + wizard = self.env[action["res_model"]].browse(action["res_id"]) + self.assertEqual(wizard.orderpoint_id, order) + self.assertEqual(len(wizard.product_id.bom_ids), 2) + self.assertEqual(wizard.qty_to_order, 500) + # Have 100 produced with each production list, finally there should be 300 left + # to be produced. + wizard.bom_line_ids[0].qty_to_produce = 100 + wizard.bom_line_ids[1].qty_to_produce = 100 + wizard.action_confirm() + self.assertEqual(order.qty_to_order, 300) + # Check that 2 production orders have been created. + mrp_production_orders = self.env["mrp.production"].search( + [("product_id", "=", self.product.product_variant_ids[0].id)] + ) + self.assertEqual(len(mrp_production_orders), 2) + # Check that all the products have been added to the production orders. + mrp_bom_1_product_ids = self.mrp_bom_1.bom_line_ids.product_id.ids + mrp_bom_2_product_ids = self.mrp_bom_2.bom_line_ids.product_id.ids + production_product_ids = mrp_production_orders.move_raw_ids.product_id.ids + for product_id in mrp_bom_1_product_ids: + self.assertIn(product_id, production_product_ids) + for product_id in mrp_bom_2_product_ids: + self.assertIn(product_id, production_product_ids) diff --git a/stock_replenishment_mrp_bom_selection/wizard/__init__.py b/stock_replenishment_mrp_bom_selection/wizard/__init__.py new file mode 100644 index 000000000..a6a0fd9fe --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/wizard/__init__.py @@ -0,0 +1,2 @@ +from . import material_availability_wizard +from . import stock_warehouse_orderpoint_replenish_wizard diff --git a/stock_replenishment_mrp_bom_selection/wizard/material_availability_wizard.py b/stock_replenishment_mrp_bom_selection/wizard/material_availability_wizard.py new file mode 100644 index 000000000..27d2fbbf0 --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/wizard/material_availability_wizard.py @@ -0,0 +1,59 @@ +# Copyright 2024 Tecnativa - Pilar Vargas +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class MaterialAvailabilityWizard(models.TransientModel): + _name = "material.availability.wizard" + _description = "Material Availability Wizard" + + replenish_wizard_id = fields.Many2one("stock.warehouse.orderpoint.replenish.wizard") + bom_id = fields.Many2one("mrp.bom", string="Bill of Materials") + product_ids = fields.One2many( + comodel_name="material.availability.wizard.line", + inverse_name="wizard_id", + string="Products", + compute="_compute_product_ids", + store=True, + readonly=False, + ) + + @api.depends("bom_id") + def _compute_product_ids(self): + for wizard in self: + lines_vals = [] + for line in wizard.bom_id.bom_line_ids: + lines_vals.append( + ( + 0, + 0, + { + "product_id": line.product_id.id, + "product_qty_available": line.product_id.qty_available, + }, + ) + ) + wizard.product_ids = lines_vals + + def action_close(self): + return { + "name": "Replenish", + "type": "ir.actions.act_window", + "view_mode": "form", + "res_model": "stock.warehouse.orderpoint.replenish.wizard", + "res_id": self.replenish_wizard_id.id, + "target": "new", + "context": { + "default_orderpoint_id": self.replenish_wizard_id.orderpoint_id.id + }, + } + + +class MaterialAvailabilityWizardLine(models.TransientModel): + _name = "material.availability.wizard.line" + _description = "Material Availability Wizard Line" + + wizard_id = fields.Many2one("material.availability.wizard") + product_id = fields.Many2one("product.product", string="Product") + product_qty_available = fields.Float(string="Quantity Available") diff --git a/stock_replenishment_mrp_bom_selection/wizard/material_availability_wizard_views.xml b/stock_replenishment_mrp_bom_selection/wizard/material_availability_wizard_views.xml new file mode 100644 index 000000000..a963ce554 --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/wizard/material_availability_wizard_views.xml @@ -0,0 +1,28 @@ + + + material.availability.wizard.view + material.availability.wizard + +
+ + + + + + + + + + +
+
+
+
+
+
diff --git a/stock_replenishment_mrp_bom_selection/wizard/stock_warehouse_orderpoint_replenish_wizard.py b/stock_replenishment_mrp_bom_selection/wizard/stock_warehouse_orderpoint_replenish_wizard.py new file mode 100644 index 000000000..52dfdc760 --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/wizard/stock_warehouse_orderpoint_replenish_wizard.py @@ -0,0 +1,133 @@ +# Copyright 2024 Tecnativa - Pilar Vargas +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models +from odoo.exceptions import UserError +from odoo.tools import float_is_zero + + +class StockWarehouseOrderpointReplenishWizard(models.TransientModel): + _name = "stock.warehouse.orderpoint.replenish.wizard" + _description = "Stock warehouse orderpoint replenish wizard" + + orderpoint_id = fields.Many2one("stock.warehouse.orderpoint") + qty_to_order = fields.Float(related="orderpoint_id.qty_to_order") + product_id = fields.Many2one("product.product", related="orderpoint_id.product_id") + product_tmpl_id = fields.Many2one( + "product.template", related="product_id.product_tmpl_id" + ) + total_qty_to_produce = fields.Float( + compute="_compute_total_qty_to_produce", + string="Total Quantity to Produce", + ) + qty_remaining_to_produce = fields.Float( + compute="_compute_qty_remaining_to_produce", + string="Quantity Remaining to Produce", + store=True, + ) + bom_line_ids = fields.One2many( + comodel_name="bom.line.wizard", + inverse_name="wizard_id", + compute="_compute_bom_line_ids", + store=True, + readonly=False, + ) + + @api.depends("bom_line_ids.qty_to_produce") + def _compute_total_qty_to_produce(self): + for wizard in self: + wizard.total_qty_to_produce = sum( + wizard.bom_line_ids.mapped("qty_to_produce") + ) + + @api.depends("total_qty_to_produce", "qty_to_order") + def _compute_qty_remaining_to_produce(self): + for wizard in self: + wizard.qty_remaining_to_produce = ( + wizard.qty_to_order - wizard.total_qty_to_produce + ) + + @api.depends("orderpoint_id") + def _compute_bom_line_ids(self): + self.bom_line_ids = None + lines_vals = [] + boms = self.product_id.bom_ids.filtered( + lambda x: not x.product_id or x.product_id == self.product_id + ) + for line in boms: + lines_vals.append( + ( + 0, + 0, + { + "wizard_id": self.id, + "bom_id": line.id, + }, + ) + ) + self.bom_line_ids = lines_vals + + def action_confirm(self): + pd = self.env["decimal.precision"].precision_get("Product Unit of Measure") + if float_is_zero(self.total_qty_to_produce, precision_digits=pd): + raise UserError(_("Nothing to produce.")) + for line in self.bom_line_ids.filtered(lambda x: x.qty_to_produce > 0): + self.orderpoint_id.qty_to_order = line.qty_to_produce + self.orderpoint_id.bom_id = line.bom_id + self.orderpoint_id._procure_orderpoint_confirm(company_id=self.env.company) + self.orderpoint_id.bom_id = False + self.orderpoint_id.qty_to_order = self.qty_remaining_to_produce + return True + + +class BomLineWizard(models.TransientModel): + _name = "bom.line.wizard" + _description = "Manufacture BOM line" + + wizard_id = fields.Many2one( + comodel_name="stock.warehouse.orderpoint.replenish.wizard" + ) + bom_id = fields.Many2one("mrp.bom", string="Bill of Materials") + qty_to_produce = fields.Float(string="Quantity to produce") + max_production_qty = fields.Float( + string="Maximum Production Quantity", compute="_compute_max_production_qty" + ) + product_uom_id = fields.Many2one( + comodel_name="uom.uom", + related="bom_id.product_tmpl_id.uom_id", + readonly=True, + ) + production_time = fields.Float(compute="_compute_production_time") + + @api.depends("bom_id") + def _compute_max_production_qty(self): + for line in self: + max_qty = float("inf") + for bom_line in line.bom_id.bom_line_ids: + available_qty = bom_line.product_id.qty_available / bom_line.product_qty + if available_qty < 0: + max_qty = 0 + break + max_qty = min(max_qty, available_qty) + line.max_production_qty = max_qty + + @api.depends("bom_id") + def _compute_production_time(self): + for line in self: + production_time = sum( + operation.time_cycle for operation in line.bom_id.operation_ids + ) + line.production_time = production_time + + def action_material_availability_popup(self): + return { + "type": "ir.actions.act_window", + "name": "Availability of raw materials", + "res_model": "material.availability.wizard", + "view_mode": "form", + "target": "new", + "context": { + "default_bom_id": self.bom_id.id, + "default_replenish_wizard_id": self.wizard_id.id, + }, + } diff --git a/stock_replenishment_mrp_bom_selection/wizard/stock_warehouse_orderpoint_replenish_wizard_views.xml b/stock_replenishment_mrp_bom_selection/wizard/stock_warehouse_orderpoint_replenish_wizard_views.xml new file mode 100644 index 000000000..4b3a0d89b --- /dev/null +++ b/stock_replenishment_mrp_bom_selection/wizard/stock_warehouse_orderpoint_replenish_wizard_views.xml @@ -0,0 +1,55 @@ + + + + stock.warehouse.orderpoint.replenish.wizard.view.form + stock.warehouse.orderpoint.replenish.wizard + +
+ + + + + + + + + + + + + + +