Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions mrp_bom_assign_auto/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
===================
MRP BOM Assign Auto
===================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:68c6ea3dbba98c56e84e26543b557d40d45679f4c0cc6cadf00d2c9205440810
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |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/mrp_bom_assign_auto
: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-mrp_bom_assign_auto
: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 checks BoM and picks the first one where all its components are
available. In case not found returns odoo one by default.

**Table of contents**

.. contents::
:local:

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/manufacture/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 <https://github.com/OCA/manufacture/issues/new?body=module:%20mrp_bom_assign_auto%0Aversion:%2015.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

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

Credits
=======

Authors
~~~~~~~

* Tecnativa

Contributors
~~~~~~~~~~~~

- [Tecnativa](https://www.tecnativa.com):
- Eduardo Ezerouali


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 <https://github.com/OCA/manufacture/tree/15.0/mrp_bom_assign_auto>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
3 changes: 3 additions & 0 deletions mrp_bom_assign_auto/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Copyright 2025 Tecnativa - Eduardo Ezerouali
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
from . import models
16 changes: 16 additions & 0 deletions mrp_bom_assign_auto/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright 2025 Tecnativa - Eduardo Ezerouali
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
{
"name": "MRP BOM Assign Auto",
"version": "15.0.1.0.0",
"category": "Manufacturing",
"summary": "Auto select th first BoM that has all components available",
"website": "https://github.com/OCA/manufacture",
"author": "Tecnativa," "Odoo Community Association (OCA)",
"license": "AGPL-3",
"installable": True,
"depends": ["mrp"],
"data": [
"views/res_config_settings_views.xml",
],
}
4 changes: 4 additions & 0 deletions mrp_bom_assign_auto/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright 2025 Tecnativa - Eduardo Ezerouali
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
from . import mrp_bom
from . import res_config_settings
70 changes: 70 additions & 0 deletions mrp_bom_assign_auto/models/mrp_bom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Copyright 2025 Tecnativa - Eduardo Ezerouali
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)

from collections import defaultdict

from odoo import api, models
from odoo.tools import config, float_compare


class MrpBom(models.Model):
_inherit = "mrp.bom"

@api.model
def _bom_find(self, products, picking_type=None, company_id=False, bom_type=False):
test_condition = config["test_enable"] and not self.env.context.get(
"test_mrp_bom_assign_auto"
)
if test_condition or self.env.context.get("no_mrp_bom_assign_auto"):
return super()._bom_find(
products,
picking_type=picking_type,
company_id=company_id,
bom_type=bom_type,
)
params = self.env["ir.config_parameter"].sudo()
bom_available = defaultdict(lambda: self.env["mrp.bom"])
domain = self._bom_find_domain(
products,
picking_type=picking_type,
company_id=company_id,
bom_type=bom_type,
)
boms = self.search(domain, order="sequence, product_id, id")
bom_products = list(set(boms.bom_line_ids.mapped("product_id").ids))
type_stock_check = params.get_param(
"mrp_bom_assign_auto.bom_stock_check", "free_qty"
)
product_available = (
self.env["product.product"].browse(bom_products).read([type_stock_check])
)
product_available_map = {
rec["id"]: rec[type_stock_check] for rec in product_available
}
for bom in boms:
for line in bom.bom_line_ids:
required = line.product_qty
component = line.product_id
available = product_available_map.get(line.product_id.id)
fully_available = True
if (
float_compare(
available,
required,
precision_rounding=component.uom_id.rounding,
)
< 0
):
fully_available = False
break
if fully_available:
bom_available[products] = bom
break
if not any(bom_available.values()):
return super()._bom_find(
products,
picking_type=picking_type,
company_id=company_id,
bom_type=bom_type,
)
return bom_available
14 changes: 14 additions & 0 deletions mrp_bom_assign_auto/models/res_config_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from odoo import fields, models


class ResConfigSettings(models.TransientModel):
"""Add option for user to decide bom auto check by
virtual_available o free_qty"""

_inherit = "res.config.settings"

bom_stock_check = fields.Selection(
selection=[("virtual_available", "Vitual Available"), ("free_qty", "Free Qty")],
default="free_qty",
config_parameter="mrp_bom_assign_auto.bom_stock_check",
)
3 changes: 3 additions & 0 deletions mrp_bom_assign_auto/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- [Tecnativa](https://www.tecnativa.com):
- Eduardo Ezerouali

2 changes: 2 additions & 0 deletions mrp_bom_assign_auto/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This module checks BoM and picks the first one where all its components are
available. In case not found returns odoo one by default.
Loading