[FIX] mrp: compute the right producible qty with same components

Steps to reproduce:
- In Manufacturing, create a the following BoM
  - Product: P1
  - Components:
    - 2 x P2
    - 2 x P2
- Set the quantity in stock for P2 to 2
- Open the Overview from the BoM

Issue:
The 'Ready to Produce' column will indicate 1, as it checks line by line
how much product there is in stock compared to what is required for this
line.
To avoid this, we just need to sum the quantities required by products.

closes odoo/odoo#134890

X-original-commit: b8fda0bdb2238cba21a4541f4292da04003704cf
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
This commit is contained in:
clesgow
2023-09-08 16:48:02 +00:00
parent 9b42ab531d
commit f8c1927b5b
2 changed files with 31 additions and 5 deletions
@@ -5,6 +5,7 @@ import json
from odoo import api, fields, models, _
from odoo.tools import float_compare, float_round, format_date, float_is_zero
from datetime import timedelta
from collections import defaultdict
class ReportBomStructure(models.AbstractModel):
_name = 'report.mrp.report_bom_structure'
@@ -23,11 +24,14 @@ class ReportBomStructure(models.AbstractModel):
@api.model
def _compute_current_production_capacity(self, bom_data):
# Get the maximum amount producible product of the selected bom given each component's stock levels.
stockable_components = filter(
lambda c: c['product'].detailed_type == 'product'
and not float_is_zero(c['base_bom_line_qty'], precision_digits=c['uom'].rounding),
bom_data.get('components', []))
producibles = [float_round(comp['quantity_available'] / comp['base_bom_line_qty'], precision_digits=0, rounding_method='DOWN') for comp in stockable_components]
components_qty_to_produce = defaultdict(lambda: 0)
components_qty_available = {}
for comp in bom_data.get('components', []):
if comp['product'].type != 'product' or float_is_zero(comp['base_bom_line_qty'], precision_digits=comp['uom'].rounding):
continue
components_qty_to_produce[comp['product_id']] += comp['base_bom_line_qty']
components_qty_available[comp['product_id']] = comp['quantity_available']
producibles = [float_round(components_qty_available[p_id] / qty, precision_digits=0, rounding_method='DOWN') for p_id, qty in components_qty_to_produce.items()]
return min(producibles) * bom_data['bom']['product_qty'] if producibles else 0
@api.model
+22
View File
@@ -1018,6 +1018,28 @@ class TestBoM(TestMrpCommon):
# So with 4 of the second product available, we can produce 4 items
self.assertEqual(report_values["lines"]["producible_qty"], 4)
def test_bom_report_capacity_with_duplicate_components(self):
location = self.env.ref('stock.stock_location_stock')
self.env['stock.quant']._update_available_quantity(self.product_2, location, 2.0)
bom = self.env['mrp.bom'].create({
'product_tmpl_id': self.product_3.product_tmpl_id.id,
'product_qty': 1,
'bom_line_ids': [
Command.create({
'product_id': self.product_2.id,
'product_qty': 2,
}),
Command.create({
'product_id': self.product_2.id,
'product_qty': 2,
})
]
})
report_values = self.env['report.mrp.report_bom_structure']._get_report_data(bom_id=bom.id)
# Total quantity of components is 4, so shouldn't be able to produce a single one.
self.assertEqual(report_values['lines']['producible_qty'], 0)
def test_validate_no_bom_line_with_same_product(self):
"""
Cannot set a BOM line on a BOM with the same product as the BOM itself