return False
return canceled
- def _get_order_picking_key(self, cr, uid, order, order_data, order_line, pickings_dict, context=None):
- """Allows to partition a sale over several pickings: just override it and return
- a unique key for the given parameters. If key changes, a new picking will be created.
- :params order: the sale order
- :params order_data: a place holder to store data while iterating the order lines
- :params line: the sale order line
- :params pickings_dict: the current dictionary of key / picking_id for this order
- :return: unique key for those parameters
- :rtype: string
- """
- return "default"
-
- def _create_order_picking(self, cr, uid, order, order_data, line, picking_dict, picking_vals, context=None):
- picking_vals['name'] = self.pool.get('ir.sequence').get(cr, uid, 'stock.picking.out')
- return self.pool.get('stock.picking').create(cr, uid, picking_vals)
-
- def _create_line_move(self, cr, uid, order, order_data, line, move_vals, context=None):
- return self.pool.get('stock.move').create(cr, uid, move_vals)
-
- def _create_line_procurement(self, cr, uid, order, order_data, line, move_id, proc_vals, context=None):
- return self.pool.get('procurement.order').create(cr, uid, proc_vals)
- def action_ship_create(self, cr, uid, ids, *args):
- wf_service = netsvc.LocalService("workflow")
- move_obj = self.pool.get('stock.move')
- proc_obj = self.pool.get('procurement.order')
- for order in self.browse(cr, uid, ids, context={}):
- output_id = order.shop_id.warehouse_id.lot_output_id.id
- proc_ids = []
- pickings = {}
- order_data = {} #a place holder to store data while iteraing the lines if needed
+ def _prepare_proc(self, cr, uid, order, line, move_id, date_planned, *args):
+ return {
+ 'name': line.name,
+ 'origin': order.name,
+ 'date_planned': date_planned,
+ 'product_id': line.product_id.id,
+ 'product_qty': line.product_uom_qty,
+ 'product_uom': line.product_uom.id,
+ 'product_uos_qty': (line.product_uos and line.product_uos_qty)\
+ or line.product_uom_qty,
+ 'product_uos': (line.product_uos and line.product_uos.id)\
+ or line.product_uom.id,
+ 'location_id': order.shop_id.warehouse_id.lot_stock_id.id,
+ 'procure_method': line.type,
+ 'move_id': move_id,
+ 'property_ids': [(6, 0, [x.id for x in line.property_ids])],
+ 'company_id': order.company_id.id,
+ 'sale_line_id': line.id,
+ }
- for line in order.order_line:
- date_planned = datetime.strptime(order.date_order, '%Y-%m-%d') + relativedelta(days=line.delay or 0.0)
- date_planned = (date_planned - timedelta(days=order.company_id.security_lead)).strftime('%Y-%m-%d %H:%M:%S')
- if line.state == 'done':
- continue
- move_id = False
- if line.product_id and line.product_id.product_tmpl_id.type in ('product', 'consu'):
- location_id = order.shop_id.warehouse_id.lot_stock_id.id
- picking_key = self._get_order_picking_key(cr, uid, order, order_data, line, pickings, *args)
- picking_id = pickings.get(picking_key, False)
+ def _prepare_move(self, cr, uid, order, line, picking_id, date_planned, *args):
+ location_id = order.shop_id.warehouse_id.lot_stock_id.id
+ output_id = order.shop_id.warehouse_id.lot_output_id.id
+ return {
+ 'name': line.name[:64],
+ 'picking_id': picking_id,
+ 'product_id': line.product_id.id,
+ 'date': date_planned,
+ 'date_expected': date_planned,
+ 'product_qty': line.product_uom_qty,
+ 'product_uom': line.product_uom.id,
+ 'product_uos_qty': line.product_uos_qty,
+ 'product_uos': (line.product_uos and line.product_uos.id)\
+ or line.product_uom.id,
+ 'product_packaging': line.product_packaging.id,
+ 'address_id': line.address_allotment_id.id or order.partner_shipping_id.id,
+ 'location_id': location_id,
+ 'location_dest_id': output_id,
+ 'sale_line_id': line.id,
+ 'tracking_id': False,
+ 'state': 'draft',
+ #'state': 'waiting',
+ 'note': line.notes,
+ 'company_id': order.company_id.id,
+ 'price_unit': line.product_id.standard_price or 0.0
+ }
+
+
+
+ def _prepare_picking(self, cr, uid, order, *args):
+ pick_name = self.pool.get('ir.sequence').get(cr, uid, 'stock.picking.out')
+ return {
+ 'name': pick_name,
+ 'origin': order.name,
+ 'type': 'out',
+ 'state': 'auto',
+ 'move_type': order.picking_policy,
+ 'sale_id': order.id,
+ 'address_id': order.partner_shipping_id.id,
+ 'note': order.note,
+ 'invoice_state': (order.order_policy=='picking' and '2binvoiced') or 'none',
+ 'company_id': order.company_id.id,
+ }
+
+
+ def _create_pickings_an_procurements(self, cr, uid, order, order_lines, picking_id=False, *args):
+ proc_ids = []
+ for line in order_lines:
+ if line.state == 'done':
+ continue
+
+ date_planned = datetime.strptime(order.date_order, '%Y-%m-%d') + relativedelta(days=line.delay or 0.0)
+ date_planned = (date_planned - timedelta(days=order.company_id.security_lead)).strftime('%Y-%m-%d %H:%M:%S')
+
+ if line.product_id:
+ if line.product_id.product_tmpl_id.type in ('product', 'consu'):
if not picking_id:
- picking_id = self._create_order_picking(cr, uid, order, order_data, line, pickings, {
- 'origin': order.name,
- 'type': 'out',
- 'state': 'auto',
- 'move_type': order.picking_policy,
- 'sale_id': order.id,
- 'address_id': order.partner_shipping_id.id,
- 'note': order.note,
- 'invoice_state': (order.order_policy=='picking' and '2binvoiced') or 'none',
- 'company_id': order.company_id.id,
- }, *args)
- pickings[picking_key] = picking_id
-
- move_id = self._create_line_move(cr, uid, order, order_data, line, {
- 'name': line.name[:64],
- 'picking_id': picking_id,
- 'product_id': line.product_id.id,
- 'date': date_planned,
- 'date_expected': date_planned,
- 'product_qty': line.product_uom_qty,
- 'product_uom': line.product_uom.id,
- 'product_uos_qty': line.product_uos_qty,
- 'product_uos': (line.product_uos and line.product_uos.id)\
- or line.product_uom.id,
- 'product_packaging': line.product_packaging.id,
- 'address_id': line.address_allotment_id.id or order.partner_shipping_id.id,
- 'location_id': location_id,
- 'location_dest_id': output_id,
- 'sale_line_id': line.id,
- 'tracking_id': False,
- 'state': 'draft',
- 'note': line.notes,
- 'company_id': order.company_id.id,
- 'price_unit': line.product_id.standard_price or 0.0
- }, *args)
-
- if line.product_id:
- proc_id = self._create_line_procurement(cr, uid, order, order_data, line, move_id, {
- 'name': line.name,
- 'origin': order.name,
- 'date_planned': date_planned,
- 'product_id': line.product_id.id,
- 'product_qty': line.product_uom_qty,
- 'product_uom': line.product_uom.id,
- 'product_uos_qty': (line.product_uos and line.product_uos_qty)\
- or line.product_uom_qty,
- 'product_uos': (line.product_uos and line.product_uos.id)\
- or line.product_uom.id,
- 'location_id': order.shop_id.warehouse_id.lot_stock_id.id,
- 'procure_method': line.type,
- 'move_id': move_id,
- 'property_ids': [(6, 0, [x.id for x in line.property_ids])],
- 'company_id': order.company_id.id,
- 'sale_line_id': line.id,
- }, *args)
- proc_ids.append(proc_id)
- self.pool.get('sale.order.line').write(cr, uid, [line.id], {'procurement_id': proc_id})
- if order.state == 'shipping_except':
- for pick in order.picking_ids:
- for move in pick.move_lines:
- if move.state == 'cancel':
- mov_ids = move_obj.search(cr, uid, [('state', '=', 'cancel'),('sale_line_id', '=', line.id),('picking_id', '=', pick.id)])
- if mov_ids:
- for mov in move_obj.browse(cr, uid, mov_ids):
- move_obj.write(cr, uid, [move_id], {'product_qty': mov.product_qty, 'product_uos_qty': mov.product_uos_qty})
- proc_obj.write(cr, uid, [proc_id], {'product_qty': mov.product_qty, 'product_uos_qty': mov.product_uos_qty})
-
- val = {}
-
- for k, picking_id in pickings.items():
- wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr)
-
- for proc_id in proc_ids:
- wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_confirm', cr)
+ picking_id = self.pool.get('stock.picking').create(cr, uid, self._prepare_picking(cr, uid, order, args))
+ move_id = self.pool.get('stock.move').create(cr, uid, self._prepare_move(cr, uid, order, line, picking_id, date_planned, args))
+ else: #a service has no stock move
+ move_id = False
+
+ proc_id = self.pool.get('procurement.order').create(cr, uid, self._prepare_proc(cr, uid, order, line, move_id, date_planned, args))
+ proc_ids.append(proc_id)
+
+ if order.state == 'shipping_except': #deals with potentially cancelled shipments FIXME seems broken, see below
+ for pick in order.picking_ids:
+ for move in pick.move_lines:
+ if move.state == 'cancel':
+ mov_ids = self.pool.get('stock.move').search(cr, uid, [('state', '=', 'cancel'),('sale_line_id', '=', line.id),('picking_id', '=', pick.id)])
+ if mov_ids:
+ for mov in move_obj.browse(cr, uid, mov_ids):
+ #FIXME: the following seems broken: what if move_id doesn't exist? What if there are several mov_ids? Shouldn't that be a sum?
+ self.pool.get('stock.move').write(cr, uid, [move_id], {'product_qty': mov.product_qty, 'product_uos_qty': mov.product_uos_qty})
+ self.pool.get('procurement.order').write(cr, uid, [proc_id], {'product_qty': mov.product_qty, 'product_uos_qty': mov.product_uos_qty})
- if order.state == 'shipping_except':
- val['state'] = 'progress'
- val['shipped'] = False
+ wf_service = netsvc.LocalService("workflow")
+ if picking_id:
+ wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr)
- if (order.order_policy == 'manual'):
- for line in order.order_line:
- if (not line.invoiced) and (line.state not in ('cancel', 'draft')):
- val['state'] = 'manual'
- break
- self.write(cr, uid, [order.id], val)
+ for proc_id in proc_ids:
+ wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_confirm', cr)
+
+ val = {}
+ if order.state == 'shipping_except':
+ val['state'] = 'progress'
+ val['shipped'] = False
+
+ if (order.order_policy == 'manual'):
+ for line in order.order_line:
+ if (not line.invoiced) and (line.state not in ('cancel', 'draft')):
+ val['state'] = 'manual'
+ break
+ self.write(cr, uid, [order.id], val)
+ return True
+
+ def action_ship_create(self, cr, uid, ids, *args):
+ for order in self.browse(cr, uid, ids, context={}):
+ self._create_pickings_an_procurements(cr, uid, order, [line for line in order.order_line], False, args)
return True
def action_ship_end(self, cr, uid, ids, context=None):