'active': True,
}
-stock_incoterms()
class stock_journal(osv.osv):
_name = "stock.journal"
'user_id': lambda s, c, u, ctx: u
}
-stock_journal()
#----------------------------------------------------------
# Stock Location
_parent_order = 'posz,name'
_order = 'parent_left'
- # TODO: implement name_search() in a way that matches the results of name_get!
-
def name_get(self, cr, uid, ids, context=None):
# always return the full hierarchical name
res = self._complete_name(cr, uid, ids, 'complete_name', None, context=context)
uom_rounding = self.pool.get('product.product').browse(cr, uid, product_id, context=context).uom_id.rounding
if context.get('uom'):
uom_rounding = uom_obj.browse(cr, uid, context.get('uom'), context=context).rounding
- prodlot_id = context.get('prodlot_id', False)
-
- locations_ids = self.search(cr, uid, [('location_id', 'child_of', ids)])
- if locations_ids:
- # Fetch only the locations in which this product has ever been processed (in or out)
- cr.execute("""SELECT l.id FROM stock_location l WHERE l.id in %s AND
- EXISTS (SELECT 1 FROM stock_move m WHERE m.product_id = %s
- AND (NOT BOOL(%s) OR m.prodlot_id=%s)
- AND ((state = 'done' AND m.location_dest_id = l.id)
- OR (state in ('done','assigned') AND m.location_id = l.id)))
- """, (tuple(locations_ids), product_id, prodlot_id, prodlot_id or None))
- locations_ids = [i for (i,) in cr.fetchall()]
- for id in locations_ids:
+ for id in self.search(cr, uid, [('location_id', 'child_of', ids)]):
if lock:
try:
# Must lock with a separate select query because FOR UPDATE can't be used with
cr.execute("SAVEPOINT stock_location_product_reserve")
cr.execute("""SELECT id FROM stock_move
WHERE product_id=%s AND
- (NOT BOOL(%s) OR prodlot_id=%s) AND
(
(location_dest_id=%s AND
location_id<>%s AND
location_dest_id<>%s AND
state in ('done', 'assigned'))
)
- FOR UPDATE of stock_move NOWAIT""", (product_id, prodlot_id, prodlot_id or None, id, id, id, id), log_exceptions=False)
+ FOR UPDATE of stock_move NOWAIT""", (product_id, id, id, id, id), log_exceptions=False)
except Exception:
# Here it's likely that the FOR UPDATE NOWAIT failed to get the LOCK,
# so we ROLLBACK to the SAVEPOINT to restore the transaction to its earlier
WHERE location_dest_id=%s AND
location_id<>%s AND
product_id=%s AND
- (NOT BOOL(%s) OR prodlot_id=%s) AND
state='done'
GROUP BY product_uom
""",
- (id, id, product_id, prodlot_id, prodlot_id or None))
+ (id, id, product_id))
results = cr.dictfetchall()
cr.execute("""SELECT product_uom,-sum(product_qty) AS product_qty
FROM stock_move
WHERE location_id=%s AND
location_dest_id<>%s AND
product_id=%s AND
- (NOT BOOL(%s) OR prodlot_id=%s) AND
state in ('done', 'assigned')
GROUP BY product_uom
""",
- (id, id, product_id, prodlot_id, prodlot_id or None))
+ (id, id, product_id))
results += cr.dictfetchall()
total = 0.0
results2 = 0.0
continue
return False
-stock_location()
class stock_tracking(osv.osv):
"""
return self.pool.get('action.traceability').action_traceability(cr,uid,ids,context)
-stock_tracking()
#----------------------------------------------------------
# Stock Picking
return res
def create(self, cr, user, vals, context=None):
- if ('name' not in vals) or (vals.get('name')=='/'):
+ if ('name' not in vals) or (vals.get('name')=='/') or (vals.get('name') == False):
seq_obj_name = self._name
vals['name'] = self.pool.get('ir.sequence').get(cr, user, seq_obj_name)
new_id = super(stock_picking, self).create(cr, user, vals, context)
""" Changes state of picking to available if all moves are confirmed.
@return: True
"""
- wf_service = netsvc.LocalService("workflow")
for pick in self.browse(cr, uid, ids):
if pick.state == 'draft':
- wf_service.trg_validate(uid, 'stock.picking', pick.id, 'button_confirm', cr)
+ self.signal_button_confirm(cr, uid, [pick.id])
move_ids = [x.id for x in pick.move_lines if x.state == 'confirmed']
if not move_ids:
raise osv.except_osv(_('Warning!'),_('Not enough stock, unable to reserve the products.'))
""" Confirms picking directly from draft state.
@return: True
"""
- wf_service = netsvc.LocalService("workflow")
for pick in self.browse(cr, uid, ids):
if not pick.move_lines:
raise osv.except_osv(_('Error!'),_('You cannot process picking without stock moves.'))
- wf_service.trg_validate(uid, 'stock.picking', pick.id,
- 'button_confirm', cr)
+ self.signal_button_confirm(cr, uid, [pick.id])
return True
def draft_validate(self, cr, uid, ids, context=None):
context['currency_id'] = move_currency_id
qty = uom_obj._compute_qty(cr, uid, product_uom, product_qty, product.uom_id.id)
- if product.id not in product_avail:
- # keep track of stock on hand including processed lines not yet marked as done
+ if product.id in product_avail:
+ product_avail[product.id] += qty
+ else:
product_avail[product.id] = product.qty_available
if qty > 0:
move_currency_id, product_price)
new_price = uom_obj._compute_price(cr, uid, product_uom, new_price,
product.uom_id.id)
- if product_avail[product.id] <= 0:
- product_avail[product.id] = 0
+ if product.qty_available <= 0:
new_std_price = new_price
else:
# Get the standard price
{'price_unit': product_price,
'price_currency_id': product_currency})
- product_avail[product.id] += qty
-
-
for move in too_few:
product_qty = move_product_qty[move.id]
# At first we confirm the new picking (if necessary)
if new_picking:
- wf_service.trg_validate(uid, 'stock.picking', new_picking, 'button_confirm', cr)
+ self.signal_button_confirm(cr, uid, [new_picking])
# Then we finish the good picking
self.write(cr, uid, [pick.id], {'backorder_id': new_picking})
self.action_move(cr, uid, [new_picking], context=context)
- wf_service.trg_validate(uid, 'stock.picking', new_picking, 'button_done', cr)
+ self.signal_button_done(cr, uid, [new_picking])
wf_service.trg_write(uid, 'stock.picking', pick.id, cr)
delivered_pack_id = new_picking
back_order_name = self.browse(cr, uid, delivered_pack_id, context=context).name
self.message_post(cr, uid, ids, 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)
+ self.signal_button_done(cr, uid, [pick.id])
delivered_pack_id = pick.id
delivered_pack = self.browse(cr, uid, delivered_pack_id, context=context)
default.update(date=time.strftime('%Y-%m-%d %H:%M:%S'), move_ids=[])
return super(stock_production_lot, self).copy(cr, uid, id, default=default, context=context)
-stock_production_lot()
class stock_production_lot_revision(osv.osv):
_name = 'stock.production.lot.revision'
'date': fields.date.context_today,
}
-stock_production_lot_revision()
# ----------------------------------------------------
# Move
"""
if not prod_id:
return {}
- user = self.pool.get('res.users').browse(cr, uid, uid)
- lang = user and user.lang or False
+ lang = False
if partner_id:
addr_rec = self.pool.get('res.partner').browse(cr, uid, partner_id)
if addr_rec:
res_obj = self.pool.get('res.company')
location_obj = self.pool.get('stock.location')
move_obj = self.pool.get('stock.move')
- wf_service = netsvc.LocalService("workflow")
new_moves = []
if context is None:
context = {}
})
new_moves.append(self.browse(cr, uid, [new_id])[0])
if pickid:
- wf_service.trg_validate(uid, 'stock.picking', pickid, 'button_confirm', cr)
+ self.signal_button_confirm(cr, uid, [pickid])
if new_moves:
new_moves += self.create_chained_picking(cr, uid, new_moves, context)
return new_moves
pickings[move.picking_id.id] = 1
continue
if move.state in ('confirmed', 'waiting'):
- ctx = context.copy()
- ctx.update({'uom': move.product_uom.id})
- if move.prodlot_id:
- ctx.update({'prodlot_id': move.prodlot_id.id})
# Important: we must pass lock=True to _product_reserve() to avoid race conditions and double reservations
- res = self.pool.get('stock.location')._product_reserve(cr, uid, [move.location_id.id], move.product_id.id, move.product_qty, context=ctx, lock=True)
+ res = self.pool.get('stock.location')._product_reserve(cr, uid, [move.location_id.id], move.product_id.id, move.product_qty, {'uom': move.product_uom.id}, lock=True)
if res:
#_product_available_test depends on the next status for correct functioning
#the test does not work correctly if the same product occurs multiple times
return True
if context is None:
context = {}
+ wf_service = netsvc.LocalService("workflow")
pickings = set()
for move in self.browse(cr, uid, ids, context=context):
if move.state in ('confirmed', 'waiting', 'assigned', 'draft'):
if move.move_dest_id and move.move_dest_id.state == 'waiting':
self.write(cr, uid, [move.move_dest_id.id], {'state': 'confirmed'})
if context.get('call_unlink',False) and move.move_dest_id.picking_id:
- wf_service = netsvc.LocalService("workflow")
wf_service.trg_write(uid, 'stock.picking', move.move_dest_id.picking_id.id, cr)
self.write(cr, uid, ids, {'state': 'cancel', 'move_dest_id': False})
if not context.get('call_unlink',False):
if all(move.state == 'cancel' for move in pick.move_lines):
self.pool.get('stock.picking').write(cr, uid, [pick.id], {'state': 'cancel'})
- wf_service = netsvc.LocalService("workflow")
for id in ids:
wf_service.trg_trigger(uid, 'stock.move', id, cr)
return True
product_obj = self.pool.get('product.product')
currency_obj = self.pool.get('res.currency')
uom_obj = self.pool.get('product.uom')
- wf_service = netsvc.LocalService("workflow")
if context is None:
context = {}
res = cr.fetchall()
if len(res) == len(move.picking_id.move_lines):
picking_obj.action_move(cr, uid, [move.picking_id.id])
- wf_service.trg_validate(uid, 'stock.picking', move.picking_id.id, 'button_done', cr)
+ picking_obj.signal_button_done(cr, uid, [move.picking_id.id])
return [move.id for move in complete]
-stock_move()
class stock_inventory(osv.osv):
_name = "stock.inventory"
self.write(cr, uid, [inv.id], {'state': 'cancel'}, context=context)
return True
-stock_inventory()
class stock_inventory_line(osv.osv):
_name = "stock.inventory.line"
result = {'product_qty': amount, 'product_uom': uom, 'prod_lot_id': False}
return {'value': result}
-stock_inventory_line()
#----------------------------------------------------------
# Stock Warehouse
'lot_output_id': _default_lot_output_id,
}
-stock_warehouse()
#----------------------------------------------------------
# "Empty" Classes that are used to vary from the original stock.picking (that are dedicated to the internal pickings)
#override in order to redirect the check of acces rules on the stock.picking object
return self.pool.get('stock.picking').check_access_rule(cr, uid, ids, operation, context=context)
- def _workflow_trigger(self, cr, uid, ids, trigger, context=None):
- #override in order to trigger the workflow of stock.picking at the end of create, write and unlink operation
- #instead of it's own workflow (which is not existing)
- return self.pool.get('stock.picking')._workflow_trigger(cr, uid, ids, trigger, context=context)
+ def create_workflow(self, cr, uid, ids, context=None):
+ # overridden in order to trigger the workflow of stock.picking at the end of create,
+ # write and unlink operation instead of its own workflow (which is not existing)
+ return self.pool.get('stock.picking').create_workflow(cr, uid, ids, context=context)
+
+ def delete_workflow(self, cr, uid, ids, context=None):
+ # overridden in order to trigger the workflow of stock.picking at the end of create,
+ # write and unlink operation instead of its own workflow (which is not existing)
+ return self.pool.get('stock.picking').delete_workflow(cr, uid, ids, context=context)
- def _workflow_signal(self, cr, uid, ids, signal, context=None):
- #override in order to fire the workflow signal on given stock.picking workflow instance
- #instead of it's own workflow (which is not existing)
- return self.pool.get('stock.picking')._workflow_signal(cr, uid, ids, signal, context=context)
+ def step_workflow(self, cr, uid, ids, context=None):
+ # overridden in order to trigger the workflow of stock.picking at the end of create,
+ # write and unlink operation instead of its own workflow (which is not existing)
+ return self.pool.get('stock.picking').step_workflow(cr, uid, ids, context=context)
+
+ def signal_workflow(self, cr, uid, ids, signal, context=None):
+ # overridden in order to fire the workflow signal on given stock.picking workflow instance
+ # instead of its own workflow (which is not existing)
+ return self.pool.get('stock.picking').signal_workflow(cr, uid, ids, signal, context=context)
def message_post(self, *args, **kwargs):
"""Post the message on stock.picking to be able to see it in the form view when using the chatter"""
#override in order to redirect the check of acces rules on the stock.picking object
return self.pool.get('stock.picking').check_access_rule(cr, uid, ids, operation, context=context)
- def _workflow_trigger(self, cr, uid, ids, trigger, context=None):
- #override in order to trigger the workflow of stock.picking at the end of create, write and unlink operation
- #instead of it's own workflow (which is not existing)
- return self.pool.get('stock.picking')._workflow_trigger(cr, uid, ids, trigger, context=context)
-
- def _workflow_signal(self, cr, uid, ids, signal, context=None):
- #override in order to fire the workflow signal on given stock.picking workflow instance
- #instead of it's own workflow (which is not existing)
- return self.pool.get('stock.picking')._workflow_signal(cr, uid, ids, signal, context=context)
+ def create_workflow(self, cr, uid, ids, context=None):
+ # overridden in order to trigger the workflow of stock.picking at the end of create,
+ # write and unlink operation instead of its own workflow (which is not existing)
+ return self.pool.get('stock.picking').create_workflow(cr, uid, ids, context=context)
+
+ def delete_workflow(self, cr, uid, ids, context=None):
+ # overridden in order to trigger the workflow of stock.picking at the end of create,
+ # write and unlink operation instead of its own workflow (which is not existing)
+ return self.pool.get('stock.picking').delete_workflow(cr, uid, ids, context=context)
+
+ def step_workflow(self, cr, uid, ids, context=None):
+ # overridden in order to trigger the workflow of stock.picking at the end of create,
+ # write and unlink operation instead of its own workflow (which is not existing)
+ return self.pool.get('stock.picking').step_workflow(cr, uid, ids, context=context)
+
+ def signal_workflow(self, cr, uid, ids, signal, context=None):
+ # overridden in order to fire the workflow signal on given stock.picking workflow instance
+ # instead of its own workflow (which is not existing)
+ return self.pool.get('stock.picking').signal_workflow(cr, uid, ids, signal, context=context)
def message_post(self, *args, **kwargs):
"""Post the message on stock.picking to be able to see it in the form view when using the chatter"""