diff --git a/addons/sale_stock/tests/test_sale_stock.py b/addons/sale_stock/tests/test_sale_stock.py index e056c6d7d03..4b7da8a0e3c 100644 --- a/addons/sale_stock/tests/test_sale_stock.py +++ b/addons/sale_stock/tests/test_sale_stock.py @@ -1257,3 +1257,38 @@ class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon): ret_pack_sm.picking_id.action_assign() self.assertEqual(ret_pack_sm.state, 'assigned') self.assertEqual(ret_pack_sm.move_line_ids.reserved_uom_qty, 2) + + def test_mtso_and_qty_decreasing(self): + """ + First, confirm a SO that has a line with the MTO route (the product + should already be available in stock). Then, decrease the qty on the SO + line: + - The delivery should be updated + - There should not be any other picking + """ + warehouse = self.company_data['default_warehouse'] + customer_location = self.env.ref('stock.stock_location_customers') + mto_route = self.env.ref('stock.route_warehouse0_mto') + mto_route.active = True + + self.product_a.type = 'product' + self.env['stock.quant']._update_available_quantity(self.product_a, warehouse.lot_stock_id, 10) + + so = self.env['sale.order'].create({ + 'partner_id': self.partner_a.id, + 'warehouse_id': warehouse.id, + 'order_line': [(0, 0, { + 'name': self.product_a.name, + 'product_id': self.product_a.id, + 'product_uom_qty': 10, + 'product_uom': self.product_a.uom_id.id, + 'price_unit': 1, + 'route_id': mto_route.id, + })], + }) + so.action_confirm() + self.assertRecordValues(so.picking_ids, [{'location_id': warehouse.lot_stock_id.id, 'location_dest_id': customer_location.id}]) + + so.order_line.product_uom_qty = 8 + self.assertRecordValues(so.picking_ids, [{'location_id': warehouse.lot_stock_id.id, 'location_dest_id': customer_location.id}]) + self.assertEqual(so.picking_ids.move_ids.product_uom_qty, 8) diff --git a/addons/stock/models/stock_rule.py b/addons/stock/models/stock_rule.py index 0c4ae8071d6..8a13dc0b0ec 100644 --- a/addons/stock/models/stock_rule.py +++ b/addons/stock/models/stock_rule.py @@ -244,8 +244,12 @@ class StockRule(models.Model): if rule.procure_method == 'mts_else_mto': qty_needed = procurement.product_uom._compute_quantity(procurement.product_qty, procurement.product_id.uom_id) if float_compare(qty_needed, 0, precision_rounding=procurement.product_id.uom_id.rounding) <= 0: - forecasted_qties_by_loc[rule.location_src_id][procurement.product_id.id] -= qty_needed procure_method = 'make_to_order' + for move in procurement.values.get('group_id', self.env['procurement.group']).stock_move_ids: + if move.rule_id == rule and float_compare(move.product_uom_qty, 0, precision_rounding=move.product_uom.rounding) > 0: + procure_method = move.procure_method + break + forecasted_qties_by_loc[rule.location_src_id][procurement.product_id.id] -= qty_needed elif float_compare(qty_needed, forecasted_qties_by_loc[rule.location_src_id][procurement.product_id.id], precision_rounding=procurement.product_id.uom_id.rounding) > 0: procure_method = 'make_to_order'