[FIX] stock, mrp: move with zero as initial demand

Set the following product configuration:

Storable finished product with a flexible BOM made of storable
components in manufacture + MTO:
Component choice 1 Quantity = 0
with BOM made of component 1, quantity 1 with purchase mto route
Component choice 2 Quantity = 0
with BOM made of component 2, quantity 1 with purchase mto route

Create a MO for finished product, set the "to consume" quantity of
"Component choice 1" to 1, and try to mark it as to do. The following
issue is raised: The quantity to produce must be positive!

This is because a procurement with 0 quantity will be solved in a MO
producing 0 quantity. We fix this issue by ignoring procurements with 0
quantities.

Also, this MO without initial demand is not considered assigned. We fix
this issue by considering 0 move as assigned.

task-2159374

closes odoo/odoo#45552

X-original-commit: dffb3a1f2762d6e1517eb9b7d225521f99d874d5
Signed-off-by: Simon Lejeune (sle) <sle@openerp.com>
This commit is contained in:
Simon Lejeune
2020-02-17 17:11:11 +00:00
parent 6d90d20ee9
commit 858c2e4da0
3 changed files with 24 additions and 2 deletions
@@ -255,3 +255,21 @@ class TestMultistepManufacturingWarehouse(TestMrpCommon):
self.assertEqual(production_order.state, 'confirmed')
production_order.action_cancel()
self.assertTrue(move_stock_postprod.state, 'cancel')
def test_no_initial_demand(self):
""" Test MO/picking before manufacturing/picking after manufacturing
components and move_orig/move_dest. Ensure that everything is created
correctly.
"""
with Form(self.warehouse) as warehouse:
warehouse.manufacture_steps = 'pbm_sam'
production_form = Form(self.env['mrp.production'])
production_form.product_id = self.finished_product
production_form.picking_type_id = self.warehouse.manu_type_id
production = production_form.save()
production.move_raw_ids.product_uom_qty = 0
production.action_confirm()
production.action_assign()
self.assertFalse(production.move_raw_ids.move_orig_ids)
self.assertEqual(production.state, 'confirmed')
self.assertEqual(production.reservation_state, 'assigned')
+3 -1
View File
@@ -1167,7 +1167,9 @@ class StockMove(models.Model):
move_line_vals_list.append(move._prepare_move_line_vals(quantity=missing_reserved_quantity))
assigned_moves |= move
else:
if not move.move_orig_ids:
if float_is_zero(move.product_uom_qty, precision_rounding=move.product_uom.rounding):
assigned_moves |= move
elif not move.move_orig_ids:
if move.procure_method == 'make_to_order':
continue
# If we don't need any quantity, consider the move assigned.
+3 -1
View File
@@ -11,7 +11,7 @@ from psycopg2 import OperationalError
from odoo import SUPERUSER_ID, _, api, fields, models, registry
from odoo.exceptions import UserError
from odoo.osv import expression
from odoo.tools import float_compare, float_round, frozendict, html_escape
from odoo.tools import float_compare, float_is_zero, float_round, frozendict, html_escape
from odoo.tools.misc import split_every
_logger = logging.getLogger(__name__)
@@ -399,6 +399,8 @@ class ProcurementGroup(models.Model):
procurement.values.setdefault('company_id', self.env.company)
procurement.values.setdefault('priority', '1')
procurement.values.setdefault('date_planned', fields.Datetime.now())
if float_is_zero(procurement.product_qty, precision_rounding=procurement.product_uom.rounding):
continue
rule = self._get_rule(procurement.product_id, procurement.location_id, procurement.values)
if not rule:
error = _('No rule has been found to replenish "%s" in "%s".\nVerify the routes configuration on the product.') %\