diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index bc945d7ee06..281a0504410 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -819,14 +819,6 @@ class stock_picking(osv.osv):
self.pool.get('stock.move').force_assign(cr, uid, move_ids, context=context)
return True
- def cancel_assign(self, cr, uid, ids, context=None):
- """ Cancels picking for the moves that are in the assigned state
- @return: True
- """
- for pick in self.browse(cr, uid, ids, context=context):
- move_ids = [x.id for x in pick.move_lines if x not in ['done', 'cancel']]
- self.pool.get('stock.move').cancel_assign(cr, uid, move_ids, context=context)
- return True
def action_cancel(self, cr, uid, ids, context=None):
for pick in self.browse(cr, uid, ids, context=context):
@@ -1307,6 +1299,7 @@ class stock_move(osv.osv):
'price_unit': fields.float('Unit Price', help="Technical field used to record the product cost set by the user during a picking confirmation (when costing method used is 'average price' or 'real'). Value given in company currency and in product uom."), # as it's a technical field, we intentionally don't provide the digits attribute
'company_id': fields.many2one('res.company', 'Company', required=True, select=True),
+ 'split_from': fields.many2one('stock.move', string="Move Split From", select=True),
'backorder_id': fields.related('picking_id', 'backorder_id', type='many2one', relation="stock.picking", string="Back Order of", select=True),
'origin': fields.char("Source"),
'procure_method': fields.selection([('make_to_stock', 'Make to Stock'), ('make_to_order', 'Make to Order')], 'Procurement Method', required=True, help="Make to Stock: When needed, the product is taken from the stock or we wait for replenishment. \nMake to Order: When needed, the product is purchased or produced."),
@@ -1697,11 +1690,6 @@ class stock_move(osv.osv):
"""
return self.write(cr, uid, ids, {'state': 'assigned'})
- def cancel_assign(self, cr, uid, ids, context=None):
- """ Changes the state to confirmed.
- @return: True
- """
- return self.write(cr, uid, ids, {'state': 'confirmed'})
def check_tracking(self, cr, uid, move, lot_id, context=None):
""" Checks if serial number is assigned to stock move or not and raise an error if it had to.
@@ -1961,7 +1949,8 @@ class stock_move(osv.osv):
'move_dest_id': False,
'reserved_quant_ids': [],
'restrict_lot_id': restrict_lot_id,
- 'restrict_partner_id': restrict_partner_id
+ 'restrict_partner_id': restrict_partner_id,
+ 'split_from': move.id,
}
if context.get('source_location_id'):
defaults['location_id'] = context['source_location_id']
diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml
index 524773eff2e..6b0a91014ce 100644
--- a/addons/stock/stock_view.xml
+++ b/addons/stock/stock_view.xml
@@ -852,6 +852,7 @@
+
diff --git a/addons/stock/wizard/stock_return_picking.py b/addons/stock/wizard/stock_return_picking.py
index c16c0d51230..e58a635c10a 100644
--- a/addons/stock/wizard/stock_return_picking.py
+++ b/addons/stock/wizard/stock_return_picking.py
@@ -62,18 +62,30 @@ class stock_return_picking(osv.osv_memory):
record_id = context and context.get('active_id', False) or False
pick_obj = self.pool.get('stock.picking')
pick = pick_obj.browse(cr, uid, record_id, context=context)
+ quant_obj = self.pool.get("stock.quant")
+ move_obj = self.pool.get("stock.move")
if pick:
if pick.state != 'done':
raise osv.except_osv(_('Warning!'), _("You may only return pickings that are Done!"))
- for line in pick.move_lines:
- qty = line.product_uom_qty
- if line.returned_move_ids:
- for returned_move in line.returned_move_ids:
- if returned_move.product_id.id == line.product_id.id:
- qty -= returned_move.product_uom_qty
-
- if qty > 0:
- result1.append({'product_id': line.product_id.id, 'quantity': qty, 'move_id': line.id})
+ #Check if chained moves are not done already. In the mean time, sum the quants in that location
+ all_moves = []
+ quants = []
+ for move in pick.move_lines:
+ if move.move_dest_id:
+ #Backorder moves
+ moves = move_obj.search(cr, uid, [('split_from', '=', move.move_dest_id.id)], context=context)
+ moves = [move.move_dest_id] + move_obj.browse(cr, uid, moves, context=context)
+ if all([x.state in ['done'] for x in moves]):
+ raise osv.except_osv(_('Warning!'), _('You can not reverse when the chained moves are done!'))
+ #Search quants
+ quant_search = quant_obj.search(cr, uid, ['&', '&', ('history_ids', 'in', move.id), ('qty', '>', 0.0),
+ ('location_id', '=', move.location_dest_id.id), ], context=context)
+ #('reservation_id.origin_returned_move_id', '!=', move.id)
+ quants += [(move.id, x) for x in quant_obj.browse(cr, uid, quant_search, context=context)]
+
+ for quant in quants:
+ result1.append({'product_id': quant[1].product_id.id, 'quantity': quant[1].qty, 'move_id': quant[0]})
+
if len(result1) == 0:
raise osv.except_osv(_('Warning!'), _("No products to return (only lines in Done state and not fully returned yet can be returned)!"))
if 'product_return_moves' in fields:
@@ -95,13 +107,18 @@ class stock_return_picking(osv.osv_memory):
#Create new picking for returned products
pick_type_id = pick.picking_type_id.return_picking_type_id and pick.picking_type_id.return_picking_type_id.id or pick.picking_type_id.id
+ # Cancel assignment of existing chained assigned moves
+ moves_to_unreserve = [x.move_dest_id.id for x in pick.move_lines if x.move_dest_id and x.move_dest_id.state == "assigned"]
+ if moves_to_unreserve:
+ move_obj.do_unreserve(cr, uid, moves_to_unreserve, context=context)
+
new_picking = pick_obj.copy(cr, uid, pick.id, {
'move_lines': [],
'picking_type_id': pick_type_id,
'state': 'draft',
'origin': pick.name,
},context=context)
-
+
for data_get in data_obj.browse(cr, uid, data['product_return_moves'], context=context):
move = data_get.move_id
if not move: