[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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user