[FIX] stock: merge move not always working.

Correct sort on recordset. See this commit for more
information cdd7f09
This commit is contained in:
amoyaux
2017-09-22 16:13:14 +02:00
parent 497ea3199f
commit e91fd246d2
3 changed files with 45 additions and 11 deletions
+3 -2
View File
@@ -500,11 +500,12 @@ class StockMove(models.Model):
:return: Recordset of moves passed to this method. If some of the passed moves were merged
into another existing one, return this one and not the (now unlinked) original.
"""
distinct_fields = ['price_unit', 'product_id', 'product_packaging',
distinct_fields = ['product_id', 'price_unit', 'product_packaging',
'product_uom', 'restrict_partner_id', 'scrapped', 'origin_returned_move_id']
def _keys_sorted(move):
return tuple([getattr(move, attr) for attr in distinct_fields])
return move.product_id.id, move.price_unit, move.product_packaging.id, move.product_uom.id,\
move.restrict_partner_id.id, move.scrapped, move.origin_returned_move_id.id
# Move removed after merge
moves_to_unlink = self.env['stock.move']
+36
View File
@@ -1268,6 +1268,42 @@ class TestSinglePicking(TestStockCommon):
self.assertEqual(receipt.move_lines.origin.count('MPS'), 1, 'Origin not merged together or duplicated')
self.assertEqual(receipt.move_lines.origin.count('PO0001'), 1, 'Origin not merged together or duplicated')
def test_merge_moves_3(self):
""" Create 2 moves without initial_demand and already a
quantity done. Check that we still have only 2 moves after
validation.
"""
receipt = self.env['stock.picking'].create({
'location_id': self.supplier_location,
'location_dest_id': self.stock_location,
'partner_id': self.partner_delta_id,
'picking_type_id': self.picking_type_in,
})
move_1 = self.MoveObj.create({
'name': self.productA.name,
'product_id': self.productA.id,
'product_uom_qty': 0,
'product_uom': self.productA.uom_id.id,
'picking_id': receipt.id,
'location_id': self.supplier_location,
'location_dest_id': self.stock_location,
'origin': 'MPS'
})
move_2 = self.MoveObj.create({
'name': self.productB.name,
'product_id': self.productB.id,
'product_uom_qty': 0,
'product_uom': self.productB.uom_id.id,
'picking_id': receipt.id,
'location_id': self.supplier_location,
'location_dest_id': self.stock_location,
'origin': 'PO0001'
})
move_1.quantity_done = 5
move_2.quantity_done = 5
receipt.button_validate()
self.assertEqual(len(receipt.move_lines), 2, 'Moves were not merged')
def test_merge_chained_moves(self):
""" Imagine multiple step delivery. Two different receipt picking for the same product should only generate
1 picking from input to QC and another from QC to stock. The link at the end should follow this scheme.
+6 -9
View File
@@ -112,7 +112,7 @@ class TestStockFlow(TestStockCommon):
# ----------------------------------------------------------------------
# Check total no of move lines of incoming shipment. move line e disappear from original picking to go in backorder.
self.assertEqual(len(picking_in.move_lines), 6, 'Wrong number of move lines.')
self.assertEqual(len(picking_in.move_lines), 4, 'Wrong number of move lines.')
# Check incoming shipment state.
self.assertEqual(picking_in.state, 'done', 'Incoming shipment state should be done.')
# Check incoming shipment move lines state.
@@ -120,12 +120,10 @@ class TestStockFlow(TestStockCommon):
self.assertEqual(move.state, 'done', 'Wrong state of move line.')
# Check product A done quantity must be 3 and 1
moves = self.MoveObj.search([('product_id', '=', self.productA.id), ('picking_id', '=', picking_in.id)])
a_done_qty = [move.product_uom_qty for move in moves]
self.assertEqual(set(a_done_qty), set([1.0, 3.0]), 'Wrong move quantity for product A.')
self.assertEqual(moves.product_uom_qty, 4.0, 'Wrong move quantity for product A.')
# Check product B done quantity must be 4 and 1
moves = self.MoveObj.search([('product_id', '=', self.productB.id), ('picking_id', '=', picking_in.id)])
b_done_qty = [move.product_uom_qty for move in moves]
self.assertEqual(set(b_done_qty), set([4.0, 1.0]), 'Wrong move quantity for product B.')
self.assertEqual(moves.product_uom_qty, 5.0, 'Wrong move quantity for product B.')
# Check product C done quantity must be 7
c_done_qty = self.MoveObj.search([('product_id', '=', self.productC.id), ('picking_id', '=', picking_in.id)], limit=1).product_uom_qty
self.assertEqual(c_done_qty, 7.0, 'Wrong move quantity of product C (%s found instead of 7)' % (c_done_qty))
@@ -254,7 +252,7 @@ class TestStockFlow(TestStockCommon):
# check outgoing shipment status.
self.assertEqual(picking_out.state, 'done', 'Wrong state of outgoing shipment.')
# check outgoing shipment total moves and and its state.
self.assertEqual(len(picking_out.move_lines), 5, 'Wrong number of move lines')
self.assertEqual(len(picking_out.move_lines), 4, 'Wrong number of move lines')
for move in picking_out.move_lines:
self.assertEqual(move.state, 'done', 'Wrong state of move line.')
back_order_out = self.PickingObj.search([('backorder_id', '=', picking_out.id)])
@@ -372,7 +370,7 @@ class TestStockFlow(TestStockCommon):
# ----------------------------------------------------------------------
# Check total no of move lines.
self.assertEqual(len(back_order_in.move_lines), 4, 'Wrong number of move lines')
self.assertEqual(len(back_order_in.move_lines), 3, 'Wrong number of move lines')
# Check incoming shipment state must be 'Done'.
self.assertEqual(back_order_in.state, 'done', 'Wrong state of picking.')
# Check incoming shipment move lines state must be 'Done'.
@@ -383,8 +381,7 @@ class TestStockFlow(TestStockCommon):
self.assertEqual(movesA.product_uom_qty, 10, "Wrong move quantity of product A (%s found instead of 10)" % (movesA.product_uom_qty))
# Check product C done quantity must be 3.0, 1.0, 2.0
movesC = self.MoveObj.search([('product_id', '=', self.productC.id), ('picking_id', '=', back_order_in.id)])
c_done_qty = [move.product_uom_qty for move in movesC]
self.assertEqual(set(c_done_qty), set([3.0, 3.0]), 'Wrong quantity of moves product C.')
self.assertEqual(movesC.product_uom_qty, 6.0, 'Wrong quantity of moves product C.')
# Check product D done quantity must be 5.0 and 3.0
movesD = self.MoveObj.search([('product_id', '=', self.productD.id), ('picking_id', '=', back_order_in.id)])
d_done_qty = [move.product_uom_qty for move in movesD]