diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 45374eee18a..4f90015195c 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -681,6 +681,8 @@ class sale_order(osv.osv): :return: True """ + if not context: + context = {} procurement_obj = self.pool.get('procurement.order') sale_line_obj = self.pool.get('sale.order.line') for order in self.browse(cr, uid, ids, context=context): @@ -706,7 +708,11 @@ class sale_order(osv.osv): proc_ids.append(proc_id) #Confirm procurement order such that rules will be applied on it #note that the workflow normally ensure proc_ids isn't an empty list - procurement_obj.run(cr, uid, proc_ids, context=context) + ctx = context.copy() + ctx["no_picking_assign"] = True + procurement_obj.run(cr, uid, proc_ids, context=ctx) + #Check all moves associated and do the picking_assign + procurement_obj.group_picking_assign(cr, uid, proc_ids, context=context) #if shipping was in exception and the user choose to recreate the delivery order, write the new status of SO if order.state == 'shipping_except': @@ -1175,3 +1181,5 @@ class procurement_order(osv.osv): 'sale_line_id': fields.many2one('sale.order.line', string='Sale Order Line'), } + def group_picking_assign(self, cr, uid, proc_ids, context=None): + return True diff --git a/addons/sale_stock/sale_stock.py b/addons/sale_stock/sale_stock.py index dbe64465047..37dcd1ad8b1 100644 --- a/addons/sale_stock/sale_stock.py +++ b/addons/sale_stock/sale_stock.py @@ -453,3 +453,18 @@ class stock_picking(osv.osv): created_lines = sale_line_obj.invoice_line_create(cr, uid, sale_line_ids, context=context) invoice_line_obj.write(cr, uid, created_lines, {'invoice_id': invoice_id}, context=context) return invoice_id + + +class procurement_order(osv.osv): + _inherit = 'procurement.order' + + def group_picking_assign(self, cr, uid, proc_ids, context=None): + moves = [] + procurements = proc_ids + while procurements: + related_moves = [] + for proc in self.browse(cr, uid, procurements, context=context): + related_moves += proc.move_ids + procurements = self.search(cr, uid, [('move_dest_id', 'in', [x.id for x in related_moves])], context=context) + moves += related_moves + self.pool.get("stock.move")._group_picking_assign(cr, uid, moves, context=context) diff --git a/addons/stock/procurement.py b/addons/stock/procurement.py index 4e16dc93d2c..2db5ef24c47 100644 --- a/addons/stock/procurement.py +++ b/addons/stock/procurement.py @@ -95,7 +95,7 @@ class procurement_rule(osv.osv): class procurement_order(osv.osv): _inherit = "procurement.order" _columns = { - 'location_id': fields.many2one('stock.location', 'Procurement Location'), # not required because task may create procurements that aren't linked to a location with project_mrp + 'location_id': fields.many2one('stock.location', 'Procurement Location'), # not required because task may create procurements that aren't linked to a location with project_mrp 'move_ids': fields.one2many('stock.move', 'procurement_id', 'Moves', help="Moves created by the procurement"), 'move_dest_id': fields.many2one('stock.move', 'Destination Move', help="Move which caused (created) the procurement"), 'route_ids': fields.many2many('stock.location.route', 'stock_location_route_procurement', 'procurement_id', 'route_id', 'Preferred Routes', help="Preferred route to be followed by the procurement order. Usually copied from the generating document (SO) but could be set up manually."), diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 3cfbc13624b..deea464f060 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -344,8 +344,8 @@ class stock_quant(osv.osv): 'location_id': loc.id, 'history_ids': [(4, move.id)], # 'package_id': False - } - self.write(cr, uid, to_move[loc], vals, context=context) + } + self.write(cr, SUPERUSER_ID, to_move[loc], vals, context=context) def check_preferred_location(self, cr, uid, move, qty, context=None): '''Checks the preferred location on the move, if any returned by a putaway strategy, and returns a list of @@ -1766,6 +1766,10 @@ class stock_move(osv.osv): return {'value': result} def _picking_assign(self, cr, uid, move, context=None): + if not context: + context = {} + if context.get("no_picking_assign") and context['no_picking_assign']: + return False if move.picking_id or not move.picking_type_id: return False context = context or {} @@ -1791,6 +1795,40 @@ class stock_move(osv.osv): move.write({'picking_id': pick}) return True + def _group_picking_assign(self, cr, uid, moves, context=None): + if not context: + context = {} + if context.get("no_picking_assign") and context['no_picking_assign']: + return False + move_dict = {} + for move in moves: + group_by = (move.location_id, move.location_dest_id, move.group_id) + if not move_dict.get(group_by, False): + move_dict[group_by] = [move] + else: + move_dict[group_by].append(move) + pick_obj = self.pool.get("stock.picking") + for to_compare in move_dict.keys(): + picks = pick_obj.search(cr, uid, [ + ('group_id', '=', to_compare[2].id), + ('location_id', '=', to_compare[0].id), + ('location_dest_id', '=', to_compare[1].id), + ('state', 'in', ['draft', 'confirmed', 'waiting']), + ], context=context) + if picks: + pick = picks[0] + else: + move = move_dict[to_compare][0] + values = { + 'origin': move.origin, + 'company_id': move.company_id and move.company_id.id or False, + 'move_type': move.group_id and move.group_id.move_type or 'one', + 'partner_id': move.group_id and move.group_id.partner_id and move.group_id.partner_id.id or False, + 'picking_type_id': move.picking_type_id and move.picking_type_id.id or False, + } + pick = pick_obj.create(cr, uid, values, context=context) + self.write(cr, uid, [x.id for x in move_dict[to_compare]], {'picking_id': pick}, context=context) + def onchange_date(self, cr, uid, ids, date, date_expected, context=None): """ On change of Scheduled Date gives a Move date. @param date_expected: Scheduled Date