"""
prod_id = context and context.get('product_id', False)
+ if not prod_id:
+ return dict([(i, {}.fromkeys(field_names, 0.0)) for i in ids])
+
product_product_obj = self.pool.get('product.product')
cr.execute('select distinct product_id, location_id from stock_move where location_id in %s', (tuple(ids), ))
'stock_virtual_value': fields.function(_product_value, method=True, type='float', string='Virtual Stock Value', multi="stock", digits_compute=dp.get_precision('Account')),
'company_id': fields.many2one('res.company', 'Company', select=1, help='Let this field empty if this location is shared between all companies'),
'scrap_location': fields.boolean('Scrap Location', help='Check this box to allow using this location to put scrapped/damaged goods.'),
+ 'valuation_in_account_id': fields.many2one('account.account', 'Stock Input Account',domain = [('type','=','other')], help='This account will be used to value stock moves that have this location as destination, instead of the stock output account from the product.'),
+ 'valuation_out_account_id': fields.many2one('account.account', 'Stock Output Account',domain = [('type','=','other')], help='This account will be used to value stock moves that have this location as source, instead of the stock input account from the product.'),
}
_defaults = {
'active': True,
context['compute_child'] = False
if not product_ids:
- product_ids = product_obj.search(cr, uid, [])
+ product_ids = product_obj.search(cr, uid, [], context={'active_test': False})
products = product_obj.browse(cr, uid, product_ids, context=context)
products_by_uom = {}
_defaults = {
'active': 1,
'name': make_sscc,
- 'date': time.strftime('%Y-%m-%d %H:%M:%S'),
+ 'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
}
def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=100):
'state': fields.selection([
('draft', 'Draft'),
('auto', 'Waiting'),
- ('confirmed', 'Confirmed'),
- ('assigned', 'Available'),
+ ('confirmed', 'Waiting Availability'),
+ ('assigned', 'Ready to Process'),
('done', 'Done'),
('cancel', 'Cancelled'),
], 'State', readonly=True, select=True,
'move_type': 'direct',
'type': 'in',
'invoice_state': 'none',
- 'date': time.strftime('%Y-%m-%d %H:%M:%S'),
+ 'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.picking', context=c)
}
def action_process(self, cr, uid, ids, context=None):
+ if context is None: context = {}
+ partial_id = self.pool.get("stock.partial.picking").create(
+ cr, uid, {}, context=dict(context, active_ids=ids))
return {
'name':_("Products to Process"),
'view_mode': 'form',
'view_id': False,
'view_type': 'form',
'res_model': 'stock.partial.picking',
+ 'res_id': partial_id,
'type': 'ir.actions.act_window',
'nodestroy': True,
'target': 'new',
'domain': '[]',
- 'context': {
- 'active_id': ids[0],
- 'active_ids':ids
- }
+ 'context': dict(context, active_ids=ids)
}
def copy(self, cr, uid, id, default=None, context=None):
if res:
picking_obj = self.browse(cr, uid, res, context=context)
for move in picking_obj.move_lines:
- move_obj.write(cr, uid, [move.id], {'tracking_id': False,'prodlot_id':False})
+ move_obj.write(cr, uid, [move.id], {'tracking_id': False,'prodlot_id':False, 'move_history_ids2': [(6, 0, [])], 'move_history_ids': [(6, 0, [])]})
return res
def onchange_partner_in(self, cr, uid, context=None, partner_id=None):
""" Validates picking directly from draft state.
@return: True
"""
- if context is None:
- context = {}
wf_service = netsvc.LocalService("workflow")
self.draft_force_assign(cr, uid, ids)
for pick in self.browse(cr, uid, ids, context=context):
move_ids = [x.id for x in pick.move_lines]
self.pool.get('stock.move').force_assign(cr, uid, move_ids)
wf_service.trg_write(uid, 'stock.picking', pick.id, cr)
- context.update({'active_ids':ids})
- return {
- 'name': 'Make Picking',
- 'view_type': 'form',
- 'view_mode': 'form',
- 'res_model': 'stock.partial.picking',
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'nodestroy': True,
- 'context':context
- }
+ return self.action_process(
+ cr, uid, ids, context=context)
def cancel_assign(self, cr, uid, ids, *args):
""" Cancels picking and moves.
@return: True
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,))
- elif pick.state in ['confirmed','assigned', 'draft']:
+ else:
ids2 = [move.id for move in pick.move_lines]
ctx = context.copy()
ctx.update({'call_unlink':True})
complete, too_many, too_few = [], [], []
move_product_qty = {}
prodlot_ids = {}
+ product_avail = {}
for move in pick.move_lines:
if move.state in ('done', 'cancel'):
continue
- partial_data = partial_datas.get('move%s'%(move.id), False)
- assert partial_data, _('Missing partial picking data for move #%s') % (move.id)
+ partial_data = partial_datas.get('move%s'%(move.id), {})
product_qty = partial_data.get('product_qty',0.0)
move_product_qty[move.id] = product_qty
product_uom = partial_data.get('product_uom',False)
move_currency_id = move.company_id.currency_id.id
context['currency_id'] = move_currency_id
qty = uom_obj._compute_qty(cr, uid, product_uom, product_qty, product.uom_id.id)
+
+ if product.id in product_avail:
+ product_avail[product.id] += qty
+ else:
+ product_avail[product.id] = product.qty_available
+
if qty > 0:
new_price = currency_obj.compute(cr, uid, product_currency,
move_currency_id, product_price)
else:
# Get the standard price
amount_unit = product.price_get('standard_price', context)[product.id]
- new_std_price = ((amount_unit * product.qty_available)\
- + (new_price * qty))/(product.qty_available + qty)
-
+ new_std_price = ((amount_unit * product_avail[product.id])\
+ + (new_price * qty))/(product_avail[product.id] + qty)
# Write the field according to price type field
product_obj.write(cr, uid, [product.id], {'standard_price': new_std_price})
{'price_unit': product_price,
'price_currency_id': product_currency})
- if not move.returned_price:
- move_obj.write(cr, uid, [move.id], {'returned_price': move.price_unit})
for move in too_few:
product_qty = move_product_qty[move.id]
if new_picking:
move_obj.write(cr, uid, [c.id for c in complete], {'picking_id': new_picking})
- for move in complete:
- if prodlot_ids.get(move.id):
- move_obj.write(cr, uid, move.id, {'prodlot_id': prodlot_ids[move.id]})
+ for move in complete:
+ if prodlot_ids.get(move.id):
+ move_obj.write(cr, uid, [move.id], {'prodlot_id': prodlot_ids[move.id]})
for move in too_many:
product_qty = move_product_qty[move.id]
defaults = {
if pick.min_date:
msg= _(' for the ')+ datetime.strptime(pick.min_date, '%Y-%m-%d %H:%M:%S').strftime('%m/%d/%Y')
state_list = {
- 'confirmed': _("is scheduled") + msg +'.',
+ 'confirmed': _('is scheduled %s.') % msg,
'assigned': _('is ready to process.'),
'cancel': _('is cancelled.'),
'done': _('is done.'),
- 'draft':_('is in draft state.'),
+ 'auto': _('is waiting.'),
+ 'draft': _('is in draft state.'),
}
res = data_obj.get_object_reference(cr, uid, 'stock', view_list.get(pick.type, 'view_picking_form'))
context.update({'view_id': res and res[1] or False})
'move_ids': fields.one2many('stock.move', 'prodlot_id', 'Moves for this production lot', readonly=True),
}
_defaults = {
- 'date': time.strftime('%Y-%m-%d %H:%M:%S'),
+ 'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'name': lambda x, y, z, c: x.pool.get('ir.sequence').get(y, z, 'stock.lot.serial'),
'product_id': lambda x, y, z, c: c.get('product_id', False),
}
'indice': fields.char('Revision Number', size=16),
'author_id': fields.many2one('res.users', 'Author'),
'lot_id': fields.many2one('stock.production.lot', 'Production lot', select=True, ondelete='cascade'),
- 'company_id': fields.related('lot_id','company_id',type='many2one',relation='res.company',string='Company',store=True),
+ 'company_id': fields.related('lot_id','company_id',type='many2one',relation='res.company',string='Company', store=True, readonly=True),
}
_defaults = {
_order = 'date_expected desc, id'
_log_create = False
+ def action_partial_move(self, cr, uid, ids, context=None):
+ if context is None: context = {}
+ partial_id = self.pool.get("stock.partial.move").create(
+ cr, uid, {}, context=context)
+ return {
+ 'name':_("Products to Process"),
+ 'view_mode': 'form',
+ 'view_id': False,
+ 'view_type': 'form',
+ 'res_model': 'stock.partial.move',
+ 'res_id': partial_id,
+ 'type': 'ir.actions.act_window',
+ 'nodestroy': True,
+ 'target': 'new',
+ 'domain': '[]',
+ 'context': context
+ }
+
+
def name_get(self, cr, uid, ids, context=None):
res = []
for line in self.browse(cr, uid, ids, context=context):
_columns = {
'name': fields.char('Name', size=64, required=True, select=True),
'priority': fields.selection([('0', 'Not urgent'), ('1', 'Urgent')], 'Priority'),
- 'create_date': fields.datetime('Creation Date', readonly=True),
- 'date': fields.datetime('Date', required=True, help="Move date: scheduled date until move is done, then date of actual move processing", readonly=True),
- 'date_expected': fields.datetime('Scheduled Date', states={'done': [('readonly', True)]},required=True, help="Scheduled date for the processing of this move"),
+ 'create_date': fields.datetime('Creation Date', readonly=True, select=True),
+ 'date': fields.datetime('Date', required=True, select=True, help="Move date: scheduled date until move is done, then date of actual move processing", readonly=True),
+ 'date_expected': fields.datetime('Scheduled Date', states={'done': [('readonly', True)]},required=True, select=True, help="Scheduled date for the processing of this move"),
'product_id': fields.many2one('product.product', 'Product', required=True, select=True, domain=[('type','<>','service')],states={'done': [('readonly', True)]}),
'product_qty': fields.float('Quantity', digits_compute=dp.get_precision('Product UoM'), required=True,states={'done': [('readonly', True)]}),
'state': fields.selection([('draft', 'Draft'), ('waiting', 'Waiting'), ('confirmed', 'Not Available'), ('assigned', 'Available'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', readonly=True, select=True,
help='When the stock move is created it is in the \'Draft\' state.\n After that, it is set to \'Not Available\' state if the scheduler did not find the products.\n When products are reserved it is set to \'Available\'.\n When the picking is done the state is \'Done\'.\
\nThe state is \'Waiting\' if the move is waiting for another one.'),
- 'price_unit': fields.float('Unit Price', digits_compute= dp.get_precision('Account'), help="Technical field used to record the product cost set by the user during a picking confirmation (when average price costing method is used)"),
+ 'price_unit': fields.float('Unit Price', digits_compute= dp.get_precision('Purchase Price'), help="Technical field used to record the product cost set by the user during a picking confirmation (when average price costing method is used)"),
'price_currency_id': fields.many2one('res.currency', 'Currency for average price', help="Technical field used to record the currency chosen by the user during a picking confirmation (when average price costing method is used)"),
'company_id': fields.many2one('res.company', 'Company', required=True, select=True),
'partner_id': fields.related('picking_id','address_id','partner_id',type='many2one', relation="res.partner", string="Partner", store=True, select=True),
# used for colors in tree views:
'scrapped': fields.related('location_dest_id','scrap_location',type='boolean',relation='stock.location',string='Scrapped', readonly=True),
- 'returned_price': fields.float('Returned product price', digits_compute= dp.get_precision('Sale Price')),
}
_constraints = [
(_check_tracking,
except:
pass
if context.get('address_in_id', False):
- return self.pool.get('res.partner.address').browse(cr, uid, context['address_in_id'], context).partner_id.property_stock_supplier.id
+ part_obj_add = self.pool.get('res.partner.address').browse(cr, uid, context['address_in_id'], context=context)
+ if part_obj_add.partner_id:
+ return part_obj_add.partner_id.property_stock_supplier.id
return False
_defaults = {
'priority': '1',
'product_qty': 1.0,
'scrapped' : False,
- 'date': time.strftime('%Y-%m-%d %H:%M:%S'),
+ 'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.move', context=c),
- 'date_expected': time.strftime('%Y-%m-%d %H:%M:%S'),
+ 'date_expected': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
}
def write(self, cr, uid, ids, vals, context=None):
+ if isinstance(ids, (int, long)):
+ ids = [ids]
if uid != 1:
frozen_fields = set(['product_qty', 'product_uom', 'product_uos_qty', 'product_uos', 'location_id', 'location_dest_id', 'product_id'])
for move in self.browse(cr, uid, ids, context=context):
if default is None:
default = {}
default = default.copy()
+ default.update({'move_history_ids2': [], 'move_history_ids': []})
return super(stock_move, self).copy(cr, uid, id, default, context=context)
def _auto_init(self, cursor, context=None):
'date': picking.date,
})
return pick_id
+ def create_chained_picking(self, cr, uid, moves, context=None):
+ 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 = {}
+ seq_obj = self.pool.get('ir.sequence')
+ for picking, todo in self._chain_compute(cr, uid, moves, context=context).items():
+ ptype = todo[0][1][5] and todo[0][1][5] or location_obj.picking_type_get(cr, uid, todo[0][0].location_dest_id, todo[0][1][0])
+ if picking:
+ # name of new picking according to its type
+ new_pick_name = seq_obj.get(cr, uid, 'stock.picking.' + ptype)
+ pickid = self._create_chained_picking(cr, uid, new_pick_name, picking, ptype, todo, context=context)
+ # Need to check name of old picking because it always considers picking as "OUT" when created from Sale Order
+ old_ptype = location_obj.picking_type_get(cr, uid, picking.move_lines[0].location_id, picking.move_lines[0].location_dest_id)
+ if old_ptype != picking.type:
+ old_pick_name = seq_obj.get(cr, uid, 'stock.picking.' + old_ptype)
+ self.pool.get('stock.picking').write(cr, uid, [picking.id], {'name': old_pick_name}, context=context)
+ else:
+ pickid = False
+ for move, (loc, dummy, delay, dummy, company_id, ptype) in todo:
+ new_id = move_obj.copy(cr, uid, move.id, {
+ 'location_id': move.location_dest_id.id,
+ 'location_dest_id': loc.id,
+ 'date_moved': time.strftime('%Y-%m-%d'),
+ 'picking_id': pickid,
+ 'state': 'waiting',
+ 'company_id': company_id or res_obj._company_default_get(cr, uid, 'stock.company', context=context) ,
+ 'move_history_ids': [],
+ 'date': (datetime.strptime(move.date, '%Y-%m-%d %H:%M:%S') + relativedelta(days=delay or 0)).strftime('%Y-%m-%d'),
+ 'move_history_ids2': []}
+ )
+ move_obj.write(cr, uid, [move.id], {
+ 'move_dest_id': new_id,
+ 'move_history_ids': [(4, new_id)]
+ })
+ new_moves.append(self.browse(cr, uid, [new_id])[0])
+ if pickid:
+ wf_service.trg_validate(uid, 'stock.picking', pickid, 'button_confirm', cr)
+ if new_moves:
+ new_moves += self.create_chained_picking(cr, uid, new_moves, context)
+ return new_moves
+
def action_confirm(self, cr, uid, ids, context=None):
""" Confirms stock move.
@return: List of ids.
"""
moves = self.browse(cr, uid, ids, context=context)
self.write(cr, uid, ids, {'state': 'confirmed'})
- 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")
-
- def create_chained_picking(self, cr, uid, moves, context=None):
- new_moves = []
- if context is None:
- context = {}
- seq_obj = self.pool.get('ir.sequence')
- for picking, todo in self._chain_compute(cr, uid, moves, context=context).items():
- ptype = todo[0][1][5] and todo[0][1][5] or location_obj.picking_type_get(cr, uid, todo[0][0].location_dest_id, todo[0][1][0])
- if picking:
- # name of new picking according to its type
- new_pick_name = seq_obj.get(cr, uid, 'stock.picking.' + ptype)
- pickid = self._create_chained_picking(cr, uid, new_pick_name, picking, ptype, todo, context=context)
- # Need to check name of old picking because it always considers picking as "OUT" when created from Sale Order
- old_ptype = location_obj.picking_type_get(cr, uid, picking.move_lines[0].location_id, picking.move_lines[0].location_dest_id)
- if old_ptype != picking.type:
- old_pick_name = seq_obj.get(cr, uid, 'stock.picking.' + old_ptype)
- self.pool.get('stock.picking').write(cr, uid, picking.id, {'name': old_pick_name}, context=context)
- else:
- pickid = False
- for move, (loc, dummy, delay, dummy, company_id, ptype) in todo:
- new_id = move_obj.copy(cr, uid, move.id, {
- 'location_id': move.location_dest_id.id,
- 'location_dest_id': loc.id,
- 'date_moved': time.strftime('%Y-%m-%d'),
- 'picking_id': pickid,
- 'state': 'waiting',
- 'company_id': company_id or res_obj._company_default_get(cr, uid, 'stock.company', context=context) ,
- 'move_history_ids': [],
- 'date': (datetime.strptime(move.date, '%Y-%m-%d %H:%M:%S') + relativedelta(days=delay or 0)).strftime('%Y-%m-%d'),
- 'move_history_ids2': []}
- )
- move_obj.write(cr, uid, [move.id], {
- 'move_dest_id': new_id,
- 'move_history_ids': [(4, new_id)]
- })
- new_moves.append(self.browse(cr, uid, [new_id])[0])
- if pickid:
- wf_service.trg_validate(uid, 'stock.picking', pickid, 'button_confirm', cr)
- if new_moves:
- create_chained_picking(self, cr, uid, new_moves, context)
- create_chained_picking(self, cr, uid, moves, context)
+ self.create_chained_picking(cr, uid, moves, context)
return []
def action_assign(self, cr, uid, ids, *args):
@return: True
"""
self.write(cr, uid, ids, {'state': 'confirmed'})
+
+ # fix for bug lp:707031
+ # called write of related picking because changing move availability does
+ # not trigger workflow of picking in order to change the state of picking
+ wf_service = netsvc.LocalService('workflow')
+ for move in self.browse(cr, uid, ids, context):
+ if move.picking_id:
+ wf_service.trg_write(uid, 'stock.picking', move.picking_id.id, cr)
return True
#
"""
product_obj=self.pool.get('product.product')
accounts = product_obj.get_product_accounts(cr, uid, move.product_id.id, context)
- acc_src = accounts['stock_account_input']
- acc_dest = accounts['stock_account_output']
+ if move.location_id.valuation_out_account_id:
+ acc_src = move.location_id.valuation_out_account_id.id
+ else:
+ acc_src = accounts['stock_account_input']
+
+ if move.location_dest_id.valuation_in_account_id:
+ acc_dest = move.location_dest_id.valuation_in_account_id.id
+ else:
+ acc_dest = accounts['stock_account_output']
+
acc_variation = accounts.get('property_stock_variation', False)
journal_id = accounts['stock_journal']
if not acc_variation:
raise osv.except_osv(_('Error!'), _('There is no inventory variation account defined on the product category: "%s" (id: %d)') % \
(move.product_id.categ_id.name, move.product_id.categ_id.id,))
-
return journal_id, acc_src, acc_dest, acc_variation
def _get_reference_accounting_values_for_valuation(self, cr, uid, move, context=None):
move_obj = self.pool.get('account.move')
for j_id, move_lines in account_moves:
move_obj.create(cr, uid,
- {'name': move.name,
+ {
'journal_id': j_id,
'line_id': move_lines,
'ref': move.picking_id and move.picking_id.name})
todo = []
for move in self.browse(cr, uid, ids, context=context):
- #print 'DONE MOVE', move.id, move.product_id.name, move.move_dest_id.id, move.state, move.move_dest_id and move.move_dest_id.state
if move.state=="draft":
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']:
prodlot_id = partial_datas and partial_datas.get('move%s_prodlot_id' % (move.id), False)
if prodlot_id:
self.write(cr, uid, [move.id], {'prodlot_id': prodlot_id}, context=context)
+ if move.state not in ('confirmed','done','assigned'):
+ todo.append(move.id)
- self.write(cr, uid, move_ids, {'state': 'done', 'date_planned': time.strftime('%Y-%m-%d %H:%M:%S')}, context=context)
+ if todo:
+ self.action_confirm(cr, uid, todo, context=context)
+
+ self.write(cr, uid, move_ids, {'state': 'done', 'date': time.strftime('%Y-%m-%d %H:%M:%S')}, context=context)
for id in move_ids:
wf_service.trg_trigger(uid, 'stock.move', id, cr)
'tracking_id': move.tracking_id.id,
'prodlot_id': move.prodlot_id.id,
}
+ if move.location_id.usage <> 'internal':
+ default_val.update({'location_id': move.location_dest_id.id})
new_move = self.copy(cr, uid, move.id, default_val)
res += [new_move]
'state': move.state,
'location_id': location_id or move.location_id.id,
}
- if (not move.prodlot_id.id) and (move.product_id.track_production and location_id):
- # IF product has checked track for production lot, move lines will be split by 1
- res += self.action_split(cr, uid, [move.id], quantity, split_by_qty=1, context=context)
- else:
- current_move = self.copy(cr, uid, move.id, default_val)
- res += [current_move]
+ current_move = self.copy(cr, uid, move.id, default_val)
+ res += [current_move]
update_val = {}
update_val['product_qty'] = quantity_rest
update_val['product_uos_qty'] = uos_qty_rest
else:
quantity_rest = quantity
uos_qty_rest = uos_qty
- if (not move.prodlot_id.id) and (move.product_id.track_production and location_id):
- res += self.action_split(cr, uid, [move.id], quantity_rest, split_by_qty=1, context=context)
- else:
- res += [move.id]
- update_val = {
+ res += [move.id]
+ update_val = {
'product_qty' : quantity_rest,
'product_uos_qty' : uos_qty_rest,
'location_id': location_id or move.location_id.id
- }
- self.write(cr, uid, [move.id], update_val)
+ }
+ self.write(cr, uid, [move.id], update_val)
product_obj = self.pool.get('product.product')
for new_move in self.browse(cr, uid, res, context=context):
for (id, name) in product_obj.name_get(cr, uid, [new_move.product_id.id]):
- message = _('Product ') + " '" + name + "' "+ _("is consumed with") + " '" + str(new_move.product_qty) + "' "+ _("quantity.")
+ message = _("Product '%s' is consumed with '%s' quantity.") %(name, new_move.product_qty)
self.log(cr, uid, new_move.id, message)
self.action_done(cr, uid, res)
defaults.update(prodlot_id=prodlot_id)
new_move = self.copy(cr, uid, move.id, defaults)
complete.append(self.browse(cr, uid, new_move))
- self.write(cr, uid, move.id,
+ self.write(cr, uid, [move.id],
{
'product_qty' : move.product_qty - product_qty,
'product_uos_qty':move.product_qty - product_qty,
for move in too_many:
- self.write(cr, uid, move.id,
+ self.write(cr, uid, [move.id],
{
'product_qty': move.product_qty,
'product_uos_qty': move.product_qty,
}
_defaults = {
- 'date': time.strftime('%Y-%m-%d %H:%M:%S'),
+ 'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'state': 'draft',
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.inventory', context=c)
}
move_ids = []
for line in inv.inventory_line_id:
pid = line.product_id.id
- product_context.update(uom=line.product_uom.id,date=inv.date)
+ product_context.update(uom=line.product_uom.id, date=inv.date, prodlot_id=line.prod_lot_id.id)
amount = location_obj._product_get(cr, uid, line.location_id.id, [pid], product_context)[pid]
change = line.product_qty - amount
'location_id': line.location_id.id,
'location_dest_id': location_id,
})
- if lot_id:
- value.update({
- 'prodlot_id': lot_id,
- 'product_qty': line.product_qty
- })
move_ids.append(self._inventory_line_hook(cr, uid, line, value))
- message = _('Inventory') + " '" + inv.name + "' "+ _("is done.")
+ message = _("Inventory '%s' is done.") %(inv.name)
self.log(cr, uid, inv.id, message)
self.write(cr, uid, [inv.id], {'state': 'confirm', 'move_ids': [(6, 0, move_ids)]})
return True
- def action_cancel(self, cr, uid, ids, context=None):
+ def action_cancel_draft(self, cr, uid, ids, context=None):
""" Cancels the stock move and change inventory state to draft.
@return: True
"""
for inv in self.browse(cr, uid, ids, context=context):
- self.pool.get('stock.move').action_cancel(cr, uid, [x.id for x in inv.move_ids], context)
- self.write(cr, uid, [inv.id], {'state': 'draft'})
+ self.pool.get('stock.move').action_cancel(cr, uid, [x.id for x in inv.move_ids], context=context)
+ self.write(cr, uid, [inv.id], {'state':'draft'}, context=context)
return True
def action_cancel_inventary(self, cr, uid, ids, context=None):
""" Cancels both stock move and inventory
@return: True
"""
+ move_obj = self.pool.get('stock.move')
+ account_move_obj = self.pool.get('account.move')
for inv in self.browse(cr, uid, ids, context=context):
- self.pool.get('stock.move').action_cancel(cr, uid, [x.id for x in inv.move_ids], context)
- self.write(cr, uid, [inv.id], {'state':'cancel'})
+ move_obj.action_cancel(cr, uid, [x.id for x in inv.move_ids], context=context)
+ for move in inv.move_ids:
+ account_move_ids = account_move_obj.search(cr, uid, [('name', '=', move.name)])
+ if account_move_ids:
+ account_move_data_l = account_move_obj.read(cr, uid, account_move_ids, ['state'], context=context)
+ for account_move in account_move_data_l:
+ if account_move['state'] == 'posted':
+ raise osv.except_osv(_('UserError'),
+ _('You can not cancel inventory which has any account move with posted state.'))
+ account_move_obj.unlink(cr, uid, [account_move['id']], context=context)
+ self.write(cr, uid, [inv.id], {'state': 'cancel'}, context=context)
return True
stock_inventory()
class stock_inventory_line(osv.osv):
_name = "stock.inventory.line"
_description = "Inventory Line"
+ _rec_name = "inventory_id"
_columns = {
'inventory_id': fields.many2one('stock.inventory', 'Inventory', ondelete='cascade', select=True),
'location_id': fields.many2one('stock.location', 'Location', required=True),
'product_id': fields.many2one('product.product', 'Product', required=True, select=True),
'product_uom': fields.many2one('product.uom', 'Product UOM', required=True),
'product_qty': fields.float('Quantity', digits_compute=dp.get_precision('Product UoM')),
- 'company_id': fields.related('inventory_id','company_id',type='many2one',relation='res.company',string='Company',store=True, select=True),
+ 'company_id': fields.related('inventory_id','company_id',type='many2one',relation='res.company',string='Company',store=True, select=True, readonly=True),
'prod_lot_id': fields.many2one('stock.production.lot', 'Production Lot', domain="[('product_id','=',product_id)]"),
'state': fields.related('inventory_id','state',type='char',string='State',readonly=True),
}
@return: Dictionary of changed values
"""
if not product:
- return {}
- if not uom:
- prod = self.pool.get('product.product').browse(cr, uid, [product], {'uom': uom})[0]
- uom = prod.uom_id.id
+ return {'value': {'product_qty': 0.0, 'product_uom': False}}
+ obj_product = self.pool.get('product.product').browse(cr, uid, product)
+ uom = uom or obj_product.uom_id.id
amount = self.pool.get('stock.location')._product_get(cr, uid, location_id, [product], {'uom': uom, 'to_date': to_date})[product]
result = {'product_qty': amount, 'product_uom': uom}
return {'value': result}