summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/stock/models/stock_move.py13
-rw-r--r--addons/stock/models/stock_move_line.py6
-rw-r--r--addons/stock/tests/test_move2.py39
-rw-r--r--addons/stock/tests/test_stock_flow.py2
4 files changed, 49 insertions, 11 deletions
diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py
index 7ef8306d976..b6fa82a3b19 100644
--- a/addons/stock/models/stock_move.py
+++ b/addons/stock/models/stock_move.py
@@ -466,14 +466,7 @@ class StockMove(models.Model):
def _do_unreserve(self):
if any(move.state in ('done', 'cancel') for move in self):
raise UserError(_('Cannot unreserve a done move'))
- for move in self:
- move.move_line_ids.unlink()
- if move.procure_method == 'make_to_order' and not move.move_orig_ids:
- move.state = 'waiting'
- elif move.move_orig_ids and not all(orig.state in ('done', 'cancel') for orig in move.move_orig_ids):
- move.state = 'waiting'
- else:
- move.state = 'confirmed'
+ self.mapped('move_line_ids').unlink()
return True
def _push_apply(self):
@@ -1136,7 +1129,9 @@ class StockMove(models.Model):
elif move.reserved_availability and move.reserved_availability <= move.product_uom_qty:
move.state = 'partially_available'
else:
- if move.move_orig_ids:
+ if move.procure_method == 'make_to_order' and not move.move_orig_ids:
+ move.state = 'waiting'
+ elif move.move_orig_ids and not all(orig.state in ('done', 'cancel') for orig in move.move_orig_ids):
move.state = 'waiting'
else:
move.state = 'confirmed'
diff --git a/addons/stock/models/stock_move_line.py b/addons/stock/models/stock_move_line.py
index c5d712b8bc4..ba9383473ef 100644
--- a/addons/stock/models/stock_move_line.py
+++ b/addons/stock/models/stock_move_line.py
@@ -348,7 +348,11 @@ class StockMoveLine(models.Model):
if ml.product_id.type == 'product' and not ml.location_id.should_bypass_reservation() and not float_is_zero(ml.product_qty, precision_digits=precision):
self.env['stock.quant']._update_reserved_quantity(ml.product_id, ml.location_id, -ml.product_qty, lot_id=ml.lot_id,
package_id=ml.package_id, owner_id=ml.owner_id, strict=True)
- return super(StockMoveLine, self).unlink()
+ moves = self.mapped('move_id')
+ res = super(StockMoveLine, self).unlink()
+ if moves:
+ moves._recompute_state()
+ return res
def _action_done(self):
""" This method is called during a move's `action_done`. It'll actually move a quant from
diff --git a/addons/stock/tests/test_move2.py b/addons/stock/tests/test_move2.py
index 30868ec2dae..43a92522339 100644
--- a/addons/stock/tests/test_move2.py
+++ b/addons/stock/tests/test_move2.py
@@ -608,6 +608,45 @@ class TestPickShip(TestStockCommon):
picking_client.action_confirm()
self.assertEqual(len(picking_client.move_lines), 2, 'Moves should not be merged')
+ def test_mto_cancel_move_line(self):
+ """ Create a pick ship situation. Then process the pick picking
+ with a backorder. Then try to unlink the move line created on
+ the ship and check if the picking and move state are updated.
+ Then validate the backorder and unlink the ship move lines in
+ order to check again if the picking and state are updated.
+ """
+ picking_pick, picking_client = self.create_pick_ship()
+ location = self.env['stock.location'].browse(self.stock_location)
+
+ # make some stock
+ self.env['stock.quant']._update_available_quantity(self.productA, location, 10.0)
+ picking_pick.move_lines.quantity_done = 5.0
+ backorder_wizard_values = picking_pick.button_validate()
+ backorder_wizard = self.env[(backorder_wizard_values.get('res_model'))].browse(backorder_wizard_values.get('res_id'))
+ backorder_wizard.process()
+
+ self.assertTrue(picking_client.move_line_ids, 'A move line should be created.')
+ self.assertEqual(picking_client.move_line_ids.product_uom_qty, 5, 'The move line should have 5 unit reserved.')
+
+ # Directly delete the move lines on the picking. (Use show detail operation on picking type)
+ # Should do the same behavior than unreserve
+ picking_client.move_line_ids.unlink()
+
+ self.assertEqual(picking_client.move_lines.state, 'waiting', 'The move state should be waiting since nothing is reserved and another origin move still in progess.')
+ self.assertEqual(picking_client.state, 'waiting', 'The picking state should not be ready anymore.')
+
+ picking_client.action_assign()
+
+ back_order = self.env['stock.picking'].search([('backorder_id', '=', picking_pick.id)])
+ back_order.move_lines.quantity_done = 5
+ back_order.button_validate()
+
+ self.assertEqual(picking_client.move_lines.reserved_availability, 10, 'The total quantity should be reserved since everything is available.')
+ picking_client.move_line_ids.unlink()
+
+ self.assertEqual(picking_client.move_lines.state, 'confirmed', 'The move should be confirmed since all the origin moves are processed.')
+ self.assertEqual(picking_client.state, 'confirmed', 'The picking should be confirmed since all the moves are confirmed.')
+
class TestSinglePicking(TestStockCommon):
def test_backorder_1(self):
diff --git a/addons/stock/tests/test_stock_flow.py b/addons/stock/tests/test_stock_flow.py
index d625d9227f9..022e319f95f 100644
--- a/addons/stock/tests/test_stock_flow.py
+++ b/addons/stock/tests/test_stock_flow.py
@@ -1796,6 +1796,6 @@ class TestStockFlow(TestStockCommon):
move_with_ancestors._do_unreserve()
other_move._do_unreserve()
- self.assertEquals(move_mto_alone.state, "waiting")
+ self.assertEquals(move_mto_alone.state, "draft")
self.assertEquals(move_with_ancestors.state, "waiting")
self.assertEquals(other_move.state, "confirmed")