res[pick]['min_date'] = dt1
res[pick]['max_date'] = dt2
return res
+
+ def _get_stock_move_changes(self, cr, uid, ids, context=None):
+ '''Return the ids of pickings that should change, due to changes
+ in stock moves.'''
+ move_pool = self.pool['stock.move']
+ picking_ids = set()
+ for move_obj in move_pool.browse(cr, uid, ids, context=context):
+ if move_obj.picking_id:
+ picking_ids.add(move_obj.picking_id.id)
+ return list(picking_ids)
def create(self, cr, user, vals, context=None):
if ('name' not in vals) or (vals.get('name')=='/'):
* Transferred: has been processed, can't be modified or cancelled anymore\n
* Cancelled: has been cancelled, can't be confirmed anymore"""
),
- 'min_date': fields.function(get_min_max_date, fnct_inv=_set_minimum_date, multi="min_max_date",
- store=True, type='datetime', string='Scheduled Time', select=1, help="Scheduled time for the shipment to be processed"),
+ 'min_date': fields.function(
+ get_min_max_date,
+ fnct_inv=_set_minimum_date, multi='min_max_date',
+ store={
+ 'stock.move': (
+ _get_stock_move_changes,
+ ['date_expected'], 10,
+ )
+ },
+ type='datetime', string='Scheduled Time', select=True,
+ help="Scheduled time for the shipment to be processed"
+ ),
'date': fields.datetime('Creation Date', help="Creation date, usually the time of the order.", select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
'date_done': fields.datetime('Date of Transfer', help="Date of Completion", states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
- 'max_date': fields.function(get_min_max_date, fnct_inv=_set_maximum_date, multi="min_max_date",
- store=True, type='datetime', string='Max. Expected Date', select=2),
+ 'max_date': fields.function(
+ get_min_max_date,
+ fnct_inv=_set_maximum_date, multi='min_max_date',
+ store={
+ 'stock.move': (
+ _get_stock_move_changes,
+ ['date_expected'], 10,
+ )
+ },
+ type='datetime', string='Max. Expected Date', select=True
+ ),
'move_lines': fields.one2many('stock.move', 'picking_id', 'Internal Moves', states={'done': [('readonly', True)], 'cancel': [('readonly', True)]}),
'product_id': fields.related('move_lines', 'product_id', type='many2one', relation='product.product', string='Product'),
'auto_picking': fields.boolean('Auto-Picking', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
'origin': (invoice.origin or '') + ', ' + (picking.name or '') + (picking.origin and (':' + picking.origin) or ''),
'comment': (comment and (invoice.comment and invoice.comment + "\n" + comment or comment)) or (invoice.comment and invoice.comment or ''),
'date_invoice': context.get('date_inv', False),
- 'user_id': uid,
}
def _prepare_invoice(self, cr, uid, picking, partner, inv_type, journal_id, context=None):
context = {}
for pick in self.browse(cr, uid, ids, context=context):
if pick.state in ['done','cancel']:
- raise osv.except_osv(_('Error!'), _('You cannot remove the picking which is in %s state!')%(pick.state,))
+ # retrieve the string value of field in user's language
+ state = dict(self.fields_get(cr, uid, context=context)['state']['selection']).get(pick.state, pick.state)
+ raise osv.except_osv(_('Error!'), _('You cannot remove the picking which is in %s state!')%(state,))
else:
ids2 = [move.id for move in pick.move_lines]
ctx = context.copy()
for pick in self.browse(cr, uid, ids, context=context):
new_picking = None
complete, too_many, too_few = [], [], []
- move_product_qty, prodlot_ids, product_avail, partial_qty, product_uoms = {}, {}, {}, {}, {}
+ move_product_qty, prodlot_ids, product_avail, partial_qty, uos_qty, product_uoms = {}, {}, {}, {}, {}, {}
for move in pick.move_lines:
if move.state in ('done', 'cancel'):
continue
prodlot_ids[move.id] = prodlot_id
product_uoms[move.id] = product_uom
partial_qty[move.id] = uom_obj._compute_qty(cr, uid, product_uoms[move.id], product_qty, move.product_uom.id)
+ uos_qty[move.id] = move.product_id._compute_uos_qty(product_uom, product_qty, move.product_uos) if product_qty else 0.0
if move.product_qty == partial_qty[move.id]:
complete.append(move)
elif move.product_qty > partial_qty[move.id]:
product_avail[product.id] += qty
-
+ # every line of the picking is empty, do not generate anything
+ empty_picking = not any(q for q in move_product_qty.values() if q > 0)
for move in too_few:
product_qty = move_product_qty[move.id]
- if not new_picking:
+ if not new_picking and not empty_picking:
new_picking_name = pick.name
self.write(cr, uid, [pick.id],
{'name': sequence_obj.get(cr, uid,
'stock.picking.%s'%(pick.type)),
})
+ pick.refresh()
new_picking = self.copy(cr, uid, pick.id,
{
'name': new_picking_name,
if product_qty != 0:
defaults = {
'product_qty' : product_qty,
- 'product_uos_qty': product_qty, #TODO: put correct uos_qty
+ 'product_uos_qty': uos_qty[move.id],
'picking_id' : new_picking,
'state': 'assigned',
'move_dest_id': move.move_dest_id.id,
move_obj.write(cr, uid, [move.id],
{
'product_qty': move.product_qty - partial_qty[move.id],
- 'product_uos_qty': move.product_qty - partial_qty[move.id], #TODO: put correct uos_qty
+ 'product_uos_qty': move.product_uos_qty - uos_qty[move.id],
'prodlot_id': False,
'tracking_id': False,
})
product_qty = move_product_qty[move.id]
defaults = {
'product_qty' : product_qty,
- 'product_uos_qty': product_qty, #TODO: put correct uos_qty
+ 'product_uos_qty': uos_qty[move.id],
'product_uom': product_uoms[move.id]
}
prodlot_id = prodlot_ids.get(move.id)
self.action_move(cr, uid, [new_picking], context=context)
wf_service.trg_validate(uid, 'stock.picking', new_picking, 'button_done', cr)
wf_service.trg_write(uid, 'stock.picking', pick.id, cr)
+ delivered_pack_id = new_picking
+ self.message_post(cr, uid, new_picking, body=_("Back order <em>%s</em> has been <b>created</b>.") % (pick.name), context=context)
+ elif empty_picking:
delivered_pack_id = pick.id
- back_order_name = self.browse(cr, uid, delivered_pack_id, context=context).name
- self.message_post(cr, uid, new_picking, body=_("Back order <em>%s</em> has been <b>created</b>.") % (back_order_name), context=context)
else:
self.action_move(cr, uid, [pick.id], context=context)
wf_service.trg_validate(uid, 'stock.picking', pick.id, 'button_done', cr)
'product_id': lambda x, y, z, c: c.get('product_id', False),
}
_sql_constraints = [
- ('name_ref_uniq', 'unique (name, ref)', 'The combination of Serial Number and internal reference must be unique !'),
+ ('name_ref_uniq', 'unique (name, ref, product_id, company_id)', 'The combination of Serial Number, internal reference, Product and Company must be unique !'),
]
def action_traceability(self, cr, uid, ids, context=None):
""" It traces the information of a product
product = self.pool.get('product.product').browse(cr, uid, [prod_id], context=ctx)[0]
uos_id = product.uos_id and product.uos_id.id or False
result = {
+ 'name': product.partner_ref,
'product_uom': product.uom_id.id,
'product_uos': uos_id,
'product_qty': 1.00,
'product_uos_qty' : self.pool.get('stock.move').onchange_quantity(cr, uid, ids, prod_id, 1.00, product.uom_id.id, uos_id)['value']['product_uos_qty'],
'prodlot_id' : False,
}
- if not ids:
- result['name'] = product.partner_ref
if loc_id:
result['location_id'] = loc_id
if loc_dest_id:
pickings[move.picking_id.id] = 1
r = res.pop(0)
product_uos_qty = self.pool.get('stock.move').onchange_quantity(cr, uid, [move.id], move.product_id.id, r[0], move.product_id.uom_id.id, move.product_id.uos_id.id)['value']['product_uos_qty']
- cr.execute('update stock_move set location_id=%s, product_qty=%s, product_uos_qty=%s where id=%s', (r[1], r[0],product_uos_qty, move.id))
+ move.write({
+ 'location_id': r[1],
+ 'product_qty': r[0],
+ 'product_uos_qty': product_uos_qty,
+ })
while res:
r = res.pop(0)
return count
def setlast_tracking(self, cr, uid, ids, context=None):
- tracking_obj = self.pool.get('stock.tracking')
- picking = self.browse(cr, uid, ids, context=context)[0].picking_id
- if picking:
- last_track = [line.tracking_id.id for line in picking.move_lines if line.tracking_id]
- if not last_track:
- last_track = tracking_obj.create(cr, uid, {}, context=context)
+ assert len(ids) == 1, "1 ID expected, got %s" % (ids, )
+ tracking_obj = self.pool['stock.tracking']
+ move = self.browse(cr, uid, ids[0], context=context)
+ picking_id = move.picking_id.id
+ if picking_id:
+ move_ids = self.search(cr, uid, [
+ ('picking_id', '=', picking_id),
+ ('tracking_id', '!=', False)
+ ], limit=1, order='tracking_id DESC', context=context)
+ if move_ids:
+ tracking_move = self.browse(cr, uid, move_ids[0],
+ context=context)
+ tracking_id = tracking_move.tracking_id.id
else:
- last_track.sort()
- last_track = last_track[-1]
- self.write(cr, uid, ids, {'tracking_id': last_track})
+ tracking_id = tracking_obj.create(cr, uid, {}, context=context)
+ self.write(cr, uid, move.id,
+ {'tracking_id': tracking_id},
+ context=context)
return True
#
todo.append(move.id)
if todo:
self.action_confirm(cr, uid, todo, context=context)
- todo = []
for move in self.browse(cr, uid, ids, context=context):
if move.state in ['done','cancel']:
self._create_product_valuation_moves(cr, uid, move, context=context)
if move.state not in ('confirmed','done','assigned'):
- todo.append(move.id)
-
- if todo:
- self.action_confirm(cr, uid, todo, context=context)
-
- self.write(cr, uid, move_ids, {'state': 'done', 'date': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}, context=context)
- for id in move_ids:
- wf_service.trg_trigger(uid, 'stock.move', id, cr)
-
+ self.action_confirm(cr, uid, [move.id], context=context)
+ self.write(cr, uid, [move.id],
+ {'state': 'done',
+ 'date': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)},
+ context=context)
for pick_id in picking_ids:
wf_service.trg_write(uid, 'stock.picking', pick_id, cr)