[14.0] stock_available_mrp: improve performance by using standard field

This commit is contained in:
Cédric Pigeon
2021-10-01 17:25:23 +02:00
parent 5dc3fc08a1
commit 08a708a649

View File

@@ -3,7 +3,7 @@
from collections import Counter
from odoo import api, fields, models
from odoo import api, models
from odoo.fields import first
from odoo.tools import float_round
@@ -11,44 +11,14 @@ from odoo.tools import float_round
class ProductProduct(models.Model):
_inherit = "product.product"
bom_id = fields.Many2one(
comodel_name="mrp.bom", compute="_compute_bom_id", string="BOM"
)
@api.depends("virtual_available", "bom_id", "bom_id.product_qty")
@api.depends("virtual_available", "bom_ids", "bom_ids.product_qty")
def _compute_available_quantities(self):
super()._compute_available_quantities()
def _get_bom_id_domain(self):
"""
Real multi domain
:return:
"""
return [
"|",
("product_id", "in", self.ids),
"&",
("product_id", "=", False),
("product_tmpl_id", "in", self.mapped("product_tmpl_id.id")),
]
@api.depends("product_tmpl_id")
def _compute_bom_id(self):
bom_obj = self.env["mrp.bom"]
boms = bom_obj.search(self._get_bom_id_domain(), order="sequence, product_id")
for product in self:
product.bom_id = product.bom_id
product_boms = boms.filtered(
lambda b: b.product_id == product
or (not b.product_id and b.product_tmpl_id == product.product_tmpl_id)
)
if product_boms:
product.bom_id = first(product_boms)
def _compute_available_quantities_dict(self):
res, stock_dict = super()._compute_available_quantities_dict()
# compute qty for product with bom
product_with_bom = self.filtered("bom_id")
product_with_bom = self.filtered("bom_ids")
if not product_with_bom:
return res, stock_dict
@@ -83,8 +53,7 @@ class ProductProduct(models.Model):
for product in product_with_bom:
# Need by product (same product can be in many BOM lines/levels)
exploded_components = exploded_boms[product.id]
component_needs = product._get_components_needs(
exploded_components)
component_needs = product._get_components_needs(exploded_components)
if not component_needs:
# The BoM has no line we can use
potential_qty = immediately_usable_qty = 0.0
@@ -97,21 +66,20 @@ class ProductProduct(models.Model):
for component, need in component_needs.items()
]
)
potential_qty = product.bom_id.product_qty * components_potential_qty
bom_id = first(product.bom_ids)
potential_qty = bom_id.product_qty * components_potential_qty
potential_qty = potential_qty > 0.0 and potential_qty or 0.0
# We want to respect the rounding factor of the potential_qty
# Rounding down as we want to be pesimistic.
potential_qty = product.bom_id.product_uom_id._compute_quantity(
potential_qty = bom_id.product_uom_id._compute_quantity(
potential_qty,
product.bom_id.product_tmpl_id.uom_id,
bom_id.product_tmpl_id.uom_id,
rounding_method="DOWN",
)
res[product.id]["potential_qty"] = potential_qty
immediately_usable_qty = (
potential_qty if product.bom_id.type != "phantom" else 0
)
immediately_usable_qty = potential_qty if bom_id.type != "phantom" else 0
res[product.id]["immediately_usable_qty"] += immediately_usable_qty
return res, stock_dict
@@ -160,15 +128,12 @@ class ProductProduct(models.Model):
for product in self:
lines_done = []
bom_lines = [
(product.bom_id, bom_line, product, 1.0)
for bom_line in product.bom_id.bom_line_ids
(first(product.bom_ids), bom_line, product, 1.0)
for bom_line in first(product.bom_ids).bom_line_ids
]
while bom_lines:
(current_bom,
current_line,
current_product,
current_qty) = bom_lines[0]
(current_bom, current_line, current_product, current_qty) = bom_lines[0]
bom_lines = bom_lines[1:]
if current_line._skip_bom_line(current_product):
@@ -176,8 +141,8 @@ class ProductProduct(models.Model):
line_quantity = current_qty * current_line.product_qty
sub_bom = current_line.product_id.bom_id
if sub_bom.type == 'phantom':
sub_bom = first(current_line.product_id.bom_ids)
if sub_bom.type == "phantom":
product_uom = current_line.product_uom_id
converted_line_quantity = product_uom._compute_quantity(
line_quantity / sub_bom.product_qty,
@@ -200,7 +165,7 @@ class ProductProduct(models.Model):
line_quantity = float_round(
line_quantity,
precision_rounding=rounding,
rounding_method='UP',
rounding_method="UP",
)
lines_done.append((current_line, line_quantity))