[FIX] stock, purchase_stock: do not recompute draft, done, cancel moves
Usecase to reproduce: - Set a product with routes: MTO + Buy - Create and valide a SO - Cancel the delivery - Cancel the RFQ linked -> The delivery will be switch to confirmed state while it should remain cancel. It happens because the button_cancel on purchase.order call _recompute_state on move. _recompute_state modify the state to confirm, partially_available or available depending the reservation status. Howver it should never be call on 'draft', 'cancel' or 'done' moves since it would modify their state. A fix would be to filter the set of moves in order to exclude moves that are cancel, done or draft before using _recompute_state. However this is easy to forget and the issue would be probably redo in the future. A more stable fix is to add the filter in the _recompute_state directly. closes odoo/odoo#42471 Task: 2157543 X-original-commit: 0619415c17dc810aea67890cd3415c3f05dd2290 Signed-off-by: Arnold Moyaux <amoyaux@users.noreply.github.com>
This commit is contained in:
committed by
Arnold Moyaux
parent
c7b9602165
commit
e901dfe466
@@ -246,3 +246,48 @@ class TestMoveCancelPropagation(PurchaseTestCommon):
|
||||
self.assertNotEqual(pick.state, 'cancel')
|
||||
self.assertNotEqual(pack.state, 'cancel')
|
||||
self.assertNotEqual(self.picking_out.state, 'cancel')
|
||||
|
||||
def test_cancel_move_lines_operation(self):
|
||||
"""Check for done and cancelled moves. Ensure that the RFQ cancellation
|
||||
will not impact the delivery state if it's already cancelled.
|
||||
"""
|
||||
stock_location = self.env['ir.model.data'].xmlid_to_object('stock.stock_location_stock')
|
||||
customer_location = self.env['ir.model.data'].xmlid_to_object('stock.stock_location_customers')
|
||||
picking_type_out = self.env['ir.model.data'].xmlid_to_object('stock.picking_type_out')
|
||||
|
||||
partner = self.env['res.partner'].create({
|
||||
'name': 'Steve'
|
||||
})
|
||||
seller = self.env['product.supplierinfo'].create({
|
||||
'name': partner.id,
|
||||
'price': 10.0,
|
||||
})
|
||||
product_car = self.env['product.product'].create({
|
||||
'name': 'Car',
|
||||
'type': 'product',
|
||||
'route_ids': [(4, self.ref('stock.route_warehouse0_mto')), (4, self.ref('purchase_stock.route_warehouse0_buy'))],
|
||||
'seller_ids': [(6, 0, [seller.id])],
|
||||
'categ_id': self.env.ref('product.product_category_all').id,
|
||||
})
|
||||
customer_picking = self.env['stock.picking'].create({
|
||||
'location_id': stock_location.id,
|
||||
'location_dest_id': customer_location.id,
|
||||
'partner_id': partner.id,
|
||||
'picking_type_id': picking_type_out.id,
|
||||
})
|
||||
customer_move = self.env['stock.move'].create({
|
||||
'name': 'move out',
|
||||
'location_id': stock_location.id,
|
||||
'location_dest_id': customer_location.id,
|
||||
'product_id': product_car.id,
|
||||
'product_uom': product_car.uom_id.id,
|
||||
'product_uom_qty': 10.0,
|
||||
'procure_method': 'make_to_order',
|
||||
'picking_id': customer_picking.id,
|
||||
})
|
||||
customer_move._action_confirm()
|
||||
purchase_order = self.env['purchase.order'].search([('partner_id', '=', partner.id)])
|
||||
customer_move._action_cancel()
|
||||
self.assertEqual(customer_move.state, 'cancel', 'Move should be cancelled')
|
||||
purchase_order.button_cancel()
|
||||
self.assertEqual(customer_move.state, 'cancel', 'State of cancelled and done moves should not change.')
|
||||
|
||||
@@ -1494,7 +1494,9 @@ class StockMove(models.Model):
|
||||
|
||||
def _recompute_state(self):
|
||||
for move in self:
|
||||
if move.reserved_availability == move.product_uom_qty:
|
||||
if move.state in ('cancel', 'done', 'draft'):
|
||||
continue
|
||||
elif move.reserved_availability == move.product_uom_qty:
|
||||
move.state = 'assigned'
|
||||
elif move.reserved_availability and move.reserved_availability <= move.product_uom_qty:
|
||||
move.state = 'partially_available'
|
||||
|
||||
Reference in New Issue
Block a user