[FIX] mrp: division by 0 when computing the production capacity

Steps to reproduce
==================

- Create a BOM
- Add a line with a product of type product
- Set the quantity to 0
- Save and click on overview

-> ServerError: Division by 0

Cause of the issue
==================

Lines with a quantity of 0 should be excluded from the computation

opw-3053167

closes odoo/odoo#104980

X-original-commit: b0f5170252ed73d31543b8d1dcf114ae6f0b65bc
Signed-off-by: Adrien Widart <awt@odoo.com>
Signed-off-by: Hubert Van De Walle <huvw@odoo.com>
This commit is contained in:
Hubert Van de Walle (huvw)
2022-11-04 13:00:55 +01:00
parent c144ac4cf0
commit a11033d42c
2 changed files with 51 additions and 2 deletions
@@ -3,7 +3,7 @@
import json
from odoo import api, fields, models, _
from odoo.tools import float_compare, float_round, format_date
from odoo.tools import float_compare, float_round, format_date, float_is_zero
from datetime import timedelta
class ReportBomStructure(models.AbstractModel):
@@ -23,7 +23,10 @@ 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', bom_data.get('components', []))
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]
return min(producibles) * bom_data['bom']['product_qty'] if producibles else 0
+46
View File
@@ -980,6 +980,52 @@ class TestBoM(TestMrpCommon):
self.assertAlmostEqual(report_values['lines']['bom_cost'], 2.92)
def test_bom_report_capacity_with_quantity_of_0(self):
uom_unit = self.env.ref('uom.product_uom_unit')
location = self.env.ref('stock.stock_location_stock')
target = self.env['product.product'].create({
'name': 'Target',
'type': 'product',
})
product_one = self.env['product.product'].create({
'name': 'Component one',
'type': 'product',
})
self.env['stock.quant']._update_available_quantity(product_one, location, 3.0)
product_two = self.env['product.product'].create({
'name': 'Component two',
'type': 'product',
})
self.env['stock.quant']._update_available_quantity(product_two, location, 4.0)
bom = self.env['mrp.bom'].create({
'product_tmpl_id': target.product_tmpl_id.id,
'product_uom_id': self.uom_unit.id,
'product_qty': 1.0,
'type': 'phantom',
'bom_line_ids': [
Command.create({
'product_id': product_one.id,
'product_qty': 0,
'product_uom_id': uom_unit.id,
}),
Command.create({
'product_id': product_two.id,
'product_qty': 1,
'product_uom_id': uom_unit.id,
})
]
})
report_values = self.env['report.mrp.report_bom_structure']._get_report_data(bom_id=bom.id)
# The first product shouldn't affect the producible quantity because the target needs none of it
# So with 4 of the second product available, we can produce 4 items
self.assertEqual(report_values["lines"]["producible_qty"], 4)
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