From 2d16599860fc28bb832e313c0b84927656b928b0 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Tue, 28 Jan 2014 11:58:09 +0100 Subject: [PATCH] [WIP] Should take into account chained moves when doing return picking bzr revid: jco@openerp.com-20140128105809-eyqsxr9q4laks86o --- addons/stock/stock.py | 17 ++-------- addons/stock/stock_view.xml | 1 + addons/stock/wizard/stock_return_picking.py | 37 +++++++++++++++------ 3 files changed, 31 insertions(+), 24 deletions(-) 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: