diff --git a/purchase_mrp_distribution/README.rst b/purchase_mrp_distribution/README.rst
new file mode 100644
index 000000000..3bb3e645c
--- /dev/null
+++ b/purchase_mrp_distribution/README.rst
@@ -0,0 +1,132 @@
+=========================
+Purchase MRP Distribution
+=========================
+
+..
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! This file is generated by oca-gen-addon-readme !!
+ !! changes will be overwritten. !!
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! source digest: sha256:51d9b4cab80068fcea738841c68a570388273d7cde664d9603cad40b83184c13
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+.. |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/purchase_mrp_distribution
+ :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-purchase_mrp_distribution
+ :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 allows you to buy a product that will be divided into others without
+knowing the exact quantity of the others. That quantity will be filled in the picking.
+
+**Table of contents**
+
+.. contents::
+ :local:
+
+Configuration
+=============
+
+To use this module, we will need to configure n different distribution-type Bills of
+Materials (BoM) for n products. To do this, we will follow these steps:
+
+#. Go to Manufacturing > Products > Bills of Materials
+#. Click on Create
+#. Select the product to be distributed in the receptions
+#. Select the BoM type "Distribution"
+#. In the components, add the products that can be filled in the reception (it is not
+ necessary to mark the quantity as it will default to 0)
+
+Usage
+=====
+
+To see the module's functionality:
+
+1. Create a new purchase order
+2. Add the product for which the BoM has been created
+3. Confirm the order
+4. Go to the created delivery order
+5. You will see a new button in the move that contains the product, click on it
+6. A wizard will open to define the quantity of each product to distribute
+7. By clicking on Distribute, the move lines will be added with the products from the
+ BoM
+
+Known issues / Roadmap
+======================
+
+#. The current module is not designed to handle multi-step receipts. It operates on a
+ single-step process, making it unsuitable for more complex inventory management
+ scenarios.
+#. The current module is not designed to handle multiple lots for a product.
+#. The current module is not designed to handle multiple packages for a product.
+
+Changelog
+=========
+
+This module aims to address the need to receive a generic product, but until the
+moment of reception, we do not know the quantity that we might receive of its
+specific products.
+
+Using kits was not suitable for us, because to account for a unit of the kit product,
+the quantity specified in the BoM must be received. Therefore, we opted to define a
+new type of BoM called distribution.
+
+In this way, upon receiving a unit of any product added to the BoM, it will be
+accounted for as a unit of the generic product and will be reflected in the svls as
+separate products, but they will be accounted for in the purchase line as part of the
+product.
+
+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
+~~~~~~~
+
+* Tecnaiva
+
+Contributors
+~~~~~~~~~~~~
+
+* `Tecnativa `_:
+
+ * Pedro M. Baeza
+ * Carlos Roca
+
+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/purchase_mrp_distribution/__init__.py b/purchase_mrp_distribution/__init__.py
new file mode 100644
index 000000000..aee8895e7
--- /dev/null
+++ b/purchase_mrp_distribution/__init__.py
@@ -0,0 +1,2 @@
+from . import models
+from . import wizards
diff --git a/purchase_mrp_distribution/__manifest__.py b/purchase_mrp_distribution/__manifest__.py
new file mode 100644
index 000000000..e18a27e80
--- /dev/null
+++ b/purchase_mrp_distribution/__manifest__.py
@@ -0,0 +1,20 @@
+# Copyright 2024 Tecnatva - Carlos Roca
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
+
+{
+ "name": "Purchase MRP Distribution",
+ "version": "15.0.1.0.0",
+ "author": "Tecnaiva, Odoo Community Association (OCA)",
+ "website": "https://github.com/OCA/manufacture",
+ "category": "Manufacturing",
+ "depends": ["purchase_mrp"],
+ "data": [
+ "security/ir.model.access.csv",
+ "views/mrp_bom_views.xml",
+ "views/stock_picking_views.xml",
+ "wizards/stock_move_distribution_wiz_views.xml",
+ ],
+ "license": "AGPL-3",
+ "installable": True,
+ "application": False,
+}
diff --git a/purchase_mrp_distribution/i18n/es.po b/purchase_mrp_distribution/i18n/es.po
new file mode 100644
index 000000000..3821e6f14
--- /dev/null
+++ b/purchase_mrp_distribution/i18n/es.po
@@ -0,0 +1,189 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * purchase_mrp_distribution
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 15.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-07-09 09:38+0000\n"
+"PO-Revision-Date: 2024-07-09 11:50+0200\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"Language: 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: purchase_mrp_distribution
+#: model_terms:ir.ui.view,arch_db:purchase_mrp_distribution.purchase_order_form
+msgid ""
+"A BoM of type distribution is used to select the quantities of components."
+msgstr ""
+"Una lista de materiales (BoM) de tipo distribución se utiliza para "
+"seleccionar las cantidades de componentes."
+
+#. module: purchase_mrp_distribution
+#: model_terms:ir.ui.view,arch_db:purchase_mrp_distribution.purchase_order_form
+msgid "At a Stock Transfer."
+msgstr "En una transferencia de stock."
+
+#. module: purchase_mrp_distribution
+#: model:ir.model,name:purchase_mrp_distribution.model_mrp_bom
+msgid "Bill of Material"
+msgstr "Lista de material"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_mrp_bom__type
+msgid "BoM Type"
+msgstr "Tipo de LdM"
+
+#. module: purchase_mrp_distribution
+#: model_terms:ir.ui.view,arch_db:purchase_mrp_distribution.stock_move_distribution_wiz_form
+msgid "Cancel"
+msgstr "Cancelar"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__create_uid
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__create_uid
+msgid "Created by"
+msgstr "Creado por"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__create_date
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__create_date
+msgid "Created on"
+msgstr "Creado el"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__demand_quantity
+msgid "Demand"
+msgstr "Demanda"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__display_name
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__display_name
+msgid "Display Name"
+msgstr "Nombre a mostrar"
+
+#. module: purchase_mrp_distribution
+#: model_terms:ir.ui.view,arch_db:purchase_mrp_distribution.stock_move_distribution_wiz_form
+msgid "Distribute"
+msgstr "Distribuir"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields.selection,name:purchase_mrp_distribution.selection__mrp_bom__type__distribution
+msgid "Distribution"
+msgstr "Distribución"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move__distribution_bom_id
+msgid "Distribution Bom"
+msgstr "LdM de distribución"
+
+#. module: purchase_mrp_distribution
+#: code:addons/purchase_mrp_distribution/models/stock_move.py:0
+#, python-format
+msgid "Distribution for %s"
+msgstr "Distribución para %s"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__id
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__id
+msgid "ID"
+msgstr "ID"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz____last_update
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line____last_update
+msgid "Last Modified on"
+msgstr "Última modificación el"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__write_uid
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__write_uid
+msgid "Last Updated by"
+msgstr "Última actualización por"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__write_date
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__write_date
+msgid "Last Updated on"
+msgstr "Última actualización el"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__line_ids
+msgid "Line"
+msgstr "Linea"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model,name:purchase_mrp_distribution.model_stock_move_distribution_wiz_line
+msgid "Lines of wizard to distribute product qty to diferent products"
+msgstr ""
+"Líneas del asistente para distribuir la cantidad del producto a diferentes "
+"productos"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__move_id
+msgid "Move"
+msgstr "Movimiento"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__product_id
+msgid "Product"
+msgstr "Producto"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model,name:purchase_mrp_distribution.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr "Línea de pedido de venta"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__quantity
+msgid "Quantity"
+msgstr "Cantidad"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model,name:purchase_mrp_distribution.model_stock_move
+msgid "Stock Move"
+msgstr "Movimiento de Stock"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,help:purchase_mrp_distribution.field_stock_move_distribution_wiz__demand_quantity
+msgid ""
+"This is the quantity of products from an inventory point of view. For moves "
+"in the state 'done', this is the quantity of products that were actually "
+"moved. For other moves, this is the quantity of product that is planned to "
+"be moved. Lowering this quantity does not generate a backorder. Changing "
+"this quantity on assigned moves affects the product reservation, and should "
+"be done with care."
+msgstr ""
+"Ésta es la cantidad de productos desde un punto de vista de inventario. "
+"Para movimientos en el estado 'Realizado', ésta es la cantidad de productos "
+"que se movieron realmente. Para otros movimientos, ésta es la cantidad de "
+"producto que está planeado mover. Disminuyendo esta cantidad no se genera "
+"un pedido en espera. Cambiando esta cantidad en movimientos asignados, "
+"afecta la reserva de producto, y debe ser realizado con cuidado."
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__move_uom_id
+msgid "UoM"
+msgstr "UdM"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__uom_id
+msgid "Uom"
+msgstr "UdM"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__wizard_id
+msgid "Wizard"
+msgstr "Asistente"
+
+#. module: purchase_mrp_distribution
+#: model:ir.model,name:purchase_mrp_distribution.model_stock_move_distribution_wiz
+msgid "Wizard to distribute product qty to diferent products"
+msgstr ""
+"Asistente para distribuir la cantidad de producto a diferentes productos"
diff --git a/purchase_mrp_distribution/i18n/purchase_mrp_distribution.pot b/purchase_mrp_distribution/i18n/purchase_mrp_distribution.pot
new file mode 100644
index 000000000..52d0922f4
--- /dev/null
+++ b/purchase_mrp_distribution/i18n/purchase_mrp_distribution.pot
@@ -0,0 +1,176 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * purchase_mrp_distribution
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 15.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-07-09 09:38+0000\n"
+"PO-Revision-Date: 2024-07-09 09:38+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: purchase_mrp_distribution
+#: model_terms:ir.ui.view,arch_db:purchase_mrp_distribution.purchase_order_form
+msgid ""
+"A BoM of type distribution is used to select the quantities of components."
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model_terms:ir.ui.view,arch_db:purchase_mrp_distribution.purchase_order_form
+msgid "At a Stock Transfer."
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model,name:purchase_mrp_distribution.model_mrp_bom
+msgid "Bill of Material"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_mrp_bom__type
+msgid "BoM Type"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model_terms:ir.ui.view,arch_db:purchase_mrp_distribution.stock_move_distribution_wiz_form
+msgid "Cancel"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__create_uid
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__create_uid
+msgid "Created by"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__create_date
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__create_date
+msgid "Created on"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__demand_quantity
+msgid "Demand"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__display_name
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model_terms:ir.ui.view,arch_db:purchase_mrp_distribution.stock_move_distribution_wiz_form
+msgid "Distribute"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields.selection,name:purchase_mrp_distribution.selection__mrp_bom__type__distribution
+msgid "Distribution"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move__distribution_bom_id
+msgid "Distribution Bom"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: code:addons/purchase_mrp_distribution/models/stock_move.py:0
+#, python-format
+msgid "Distribution for %s"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__id
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__id
+msgid "ID"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz____last_update
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line____last_update
+msgid "Last Modified on"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__write_uid
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__write_uid
+msgid "Last Updated by"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__write_date
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__write_date
+msgid "Last Updated on"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__line_ids
+msgid "Line"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model,name:purchase_mrp_distribution.model_stock_move_distribution_wiz_line
+msgid "Lines of wizard to distribute product qty to diferent products"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__move_id
+msgid "Move"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__product_id
+msgid "Product"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model,name:purchase_mrp_distribution.model_purchase_order_line
+msgid "Purchase Order Line"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__quantity
+msgid "Quantity"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model,name:purchase_mrp_distribution.model_stock_move
+msgid "Stock Move"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,help:purchase_mrp_distribution.field_stock_move_distribution_wiz__demand_quantity
+msgid ""
+"This is the quantity of products from an inventory point of view. For moves "
+"in the state 'done', this is the quantity of products that were actually "
+"moved. For other moves, this is the quantity of product that is planned to "
+"be moved. Lowering this quantity does not generate a backorder. Changing "
+"this quantity on assigned moves affects the product reservation, and should "
+"be done with care."
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz__move_uom_id
+msgid "UoM"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__uom_id
+msgid "Uom"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model.fields,field_description:purchase_mrp_distribution.field_stock_move_distribution_wiz_line__wizard_id
+msgid "Wizard"
+msgstr ""
+
+#. module: purchase_mrp_distribution
+#: model:ir.model,name:purchase_mrp_distribution.model_stock_move_distribution_wiz
+msgid "Wizard to distribute product qty to diferent products"
+msgstr ""
diff --git a/purchase_mrp_distribution/models/__init__.py b/purchase_mrp_distribution/models/__init__.py
new file mode 100644
index 000000000..8ef1c3daf
--- /dev/null
+++ b/purchase_mrp_distribution/models/__init__.py
@@ -0,0 +1,3 @@
+from . import mrp_bom
+from . import purchase
+from . import stock_move
diff --git a/purchase_mrp_distribution/models/mrp_bom.py b/purchase_mrp_distribution/models/mrp_bom.py
new file mode 100644
index 000000000..ba59cb9cf
--- /dev/null
+++ b/purchase_mrp_distribution/models/mrp_bom.py
@@ -0,0 +1,13 @@
+# Copyright 2024 Tecnativa - Carlos Roca
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
+
+from odoo import fields, models
+
+
+class MrpBom(models.Model):
+ _inherit = "mrp.bom"
+
+ type = fields.Selection(
+ selection_add=[("distribution", "Distribution")],
+ ondelete={"distribution": "set default"},
+ )
diff --git a/purchase_mrp_distribution/models/purchase.py b/purchase_mrp_distribution/models/purchase.py
new file mode 100644
index 000000000..0bf396ade
--- /dev/null
+++ b/purchase_mrp_distribution/models/purchase.py
@@ -0,0 +1,39 @@
+# Copyright 2024 Tecnativa - Carlos Roca
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
+
+from odoo import models
+
+
+class PurchaseOrderLine(models.Model):
+ _inherit = "purchase.order.line"
+
+ def _prepare_stock_move_vals(
+ self, picking, price_unit, product_uom_qty, product_uom
+ ):
+ res = super()._prepare_stock_move_vals(
+ picking, price_unit, product_uom_qty, product_uom
+ )
+ bom = (
+ self.env["mrp.bom"]
+ .sudo()
+ ._bom_find(
+ self.product_id, company_id=self.company_id.id, bom_type="distribution"
+ )[self.product_id]
+ )
+ if bom:
+ res["distribution_bom_id"] = bom.id
+ return res
+
+ def _get_po_line_moves(self):
+ res = super()._get_po_line_moves()
+ bom = (
+ self.env["mrp.bom"]
+ .sudo()
+ ._bom_find(
+ self.product_id, company_id=self.company_id.id, bom_type="distribution"
+ )[self.product_id]
+ )
+ res |= self.move_ids.filtered(
+ lambda m: m.product_id in bom.bom_line_ids.product_id
+ )
+ return res
diff --git a/purchase_mrp_distribution/models/stock_move.py b/purchase_mrp_distribution/models/stock_move.py
new file mode 100644
index 000000000..0888ec094
--- /dev/null
+++ b/purchase_mrp_distribution/models/stock_move.py
@@ -0,0 +1,50 @@
+# Copyright 2024 Tecnativa - Carlos Roca
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
+
+from odoo import _, fields, models
+
+
+class StockMove(models.Model):
+ _inherit = "stock.move"
+
+ distribution_bom_id = fields.Many2one("mrp.bom")
+
+ def action_open_distribution_wizard(self):
+ return {
+ "name": _("Distribution for %s") % self.product_id.display_name,
+ "type": "ir.actions.act_window",
+ "view_mode": "form",
+ "res_model": "stock.move.distribution.wiz",
+ "target": "new",
+ "context": {"active_model": "stock.move", "active_id": self.id},
+ }
+
+ def _action_done(self, cancel_backorder=False):
+ distribution_moves = self.filtered(lambda m: m.distribution_bom_id)
+ new_moves = self.env["stock.move"]
+ for move in distribution_moves:
+ cancel_move = False
+ for sml in move.move_line_ids.filtered(
+ lambda ml, move=move: ml.product_id != move.product_id
+ ):
+ # Create new moves with the corresponding product and the linked sml
+ new_moves += self.env["stock.move"].create(
+ {
+ "picking_id": sml.picking_id.id,
+ "product_id": sml.product_id.id,
+ "name": sml.product_id.display_name,
+ "purchase_line_id": move.purchase_line_id.id,
+ "product_uom": sml.product_uom_id.id,
+ "state": "assigned",
+ "location_id": sml.location_id.id,
+ "location_dest_id": sml.location_dest_id.id,
+ "price_unit": move.price_unit,
+ "move_line_ids": [(4, sml.id)],
+ }
+ )
+ cancel_move = True
+ if cancel_move:
+ move.state = "cancel"
+ return super(StockMove, self + new_moves)._action_done(
+ cancel_backorder=cancel_backorder
+ )
diff --git a/purchase_mrp_distribution/readme/CONFIGURE.rst b/purchase_mrp_distribution/readme/CONFIGURE.rst
new file mode 100644
index 000000000..3079b442e
--- /dev/null
+++ b/purchase_mrp_distribution/readme/CONFIGURE.rst
@@ -0,0 +1,9 @@
+To use this module, we will need to configure n different distribution-type Bills of
+Materials (BoM) for n products. To do this, we will follow these steps:
+
+#. Go to Manufacturing > Products > Bills of Materials
+#. Click on Create
+#. Select the product to be distributed in the receptions
+#. Select the BoM type "Distribution"
+#. In the components, add the products that can be filled in the reception (it is not
+ necessary to mark the quantity as it will default to 0)
diff --git a/purchase_mrp_distribution/readme/CONTRIBUTORS.rst b/purchase_mrp_distribution/readme/CONTRIBUTORS.rst
new file mode 100644
index 000000000..42f94d59e
--- /dev/null
+++ b/purchase_mrp_distribution/readme/CONTRIBUTORS.rst
@@ -0,0 +1,4 @@
+* `Tecnativa `_:
+
+ * Pedro M. Baeza
+ * Carlos Roca
diff --git a/purchase_mrp_distribution/readme/DESCRIPTION.rst b/purchase_mrp_distribution/readme/DESCRIPTION.rst
new file mode 100644
index 000000000..aef6ff65a
--- /dev/null
+++ b/purchase_mrp_distribution/readme/DESCRIPTION.rst
@@ -0,0 +1,2 @@
+This module allows you to buy a product that will be divided into others without
+knowing the exact quantity of the others. That quantity will be filled in the picking.
diff --git a/purchase_mrp_distribution/readme/HISTORY.rst b/purchase_mrp_distribution/readme/HISTORY.rst
new file mode 100644
index 000000000..5db4cc093
--- /dev/null
+++ b/purchase_mrp_distribution/readme/HISTORY.rst
@@ -0,0 +1,12 @@
+This module aims to address the need to receive a generic product, but until the
+moment of reception, we do not know the quantity that we might receive of its
+specific products.
+
+Using kits was not suitable for us, because to account for a unit of the kit product,
+the quantity specified in the BoM must be received. Therefore, we opted to define a
+new type of BoM called distribution.
+
+In this way, upon receiving a unit of any product added to the BoM, it will be
+accounted for as a unit of the generic product and will be reflected in the svls as
+separate products, but they will be accounted for in the purchase line as part of the
+product.
diff --git a/purchase_mrp_distribution/readme/ROADMAP.rst b/purchase_mrp_distribution/readme/ROADMAP.rst
new file mode 100644
index 000000000..40d31618b
--- /dev/null
+++ b/purchase_mrp_distribution/readme/ROADMAP.rst
@@ -0,0 +1,5 @@
+#. The current module is not designed to handle multi-step receipts. It operates on a
+ single-step process, making it unsuitable for more complex inventory management
+ scenarios.
+#. The current module is not designed to handle multiple lots for a product.
+#. The current module is not designed to handle multiple packages for a product.
diff --git a/purchase_mrp_distribution/readme/USAGE.rst b/purchase_mrp_distribution/readme/USAGE.rst
new file mode 100644
index 000000000..75de1ea2a
--- /dev/null
+++ b/purchase_mrp_distribution/readme/USAGE.rst
@@ -0,0 +1,10 @@
+To see the module's functionality:
+
+1. Create a new purchase order
+2. Add the product for which the BoM has been created
+3. Confirm the order
+4. Go to the created delivery order
+5. You will see a new button in the move that contains the product, click on it
+6. A wizard will open to define the quantity of each product to distribute
+7. By clicking on Distribute, the move lines will be added with the products from the
+ BoM
diff --git a/purchase_mrp_distribution/security/ir.model.access.csv b/purchase_mrp_distribution/security/ir.model.access.csv
new file mode 100644
index 000000000..5119cda00
--- /dev/null
+++ b/purchase_mrp_distribution/security/ir.model.access.csv
@@ -0,0 +1,3 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+purchase_mrp_distribution.access_stock_move_distribution_wiz,access_stock_move_distribution_wiz,purchase_mrp_distribution.model_stock_move_distribution_wiz,stock.group_stock_user,1,1,1,1
+purchase_mrp_distribution.access_stock_move_distribution_wiz_line,access_stock_move_distribution_wiz_line,purchase_mrp_distribution.model_stock_move_distribution_wiz_line,stock.group_stock_user,1,1,1,1
diff --git a/purchase_mrp_distribution/static/description/index.html b/purchase_mrp_distribution/static/description/index.html
new file mode 100644
index 000000000..f9a0553e8
--- /dev/null
+++ b/purchase_mrp_distribution/static/description/index.html
@@ -0,0 +1,482 @@
+
+
+
+
+
+Purchase MRP Distribution
+
+
+
+
+
Purchase MRP Distribution
+
+
+
+
This module allows you to buy a product that will be divided into others without
+knowing the exact quantity of the others. That quantity will be filled in the picking.
To use this module, we will need to configure n different distribution-type Bills of
+Materials (BoM) for n products. To do this, we will follow these steps:
+
+
Go to Manufacturing > Products > Bills of Materials
+
Click on Create
+
Select the product to be distributed in the receptions
+
Select the BoM type “Distribution”
+
In the components, add the products that can be filled in the reception (it is not
+necessary to mark the quantity as it will default to 0)
The current module is not designed to handle multi-step receipts. It operates on a
+single-step process, making it unsuitable for more complex inventory management
+scenarios.
+
The current module is not designed to handle multiple lots for a product.
+
The current module is not designed to handle multiple packages for a product.
This module aims to address the need to receive a generic product, but until the
+moment of reception, we do not know the quantity that we might receive of its
+specific products.
+
Using kits was not suitable for us, because to account for a unit of the kit product,
+the quantity specified in the BoM must be received. Therefore, we opted to define a
+new type of BoM called distribution.
+
In this way, upon receiving a unit of any product added to the BoM, it will be
+accounted for as a unit of the generic product and will be reflected in the svls as
+separate products, but they will be accounted for in the purchase line as part of the
+product.
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.
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.