[FIX] some fixes and cleaning
bzr revid: fp@openerp.com-20130729214443-r3t4gnlisvp8hwyk
This commit is contained in:
parent
115c47b226
commit
da89a60702
|
@ -57,11 +57,15 @@ class procurement_group(osv.osv):
|
|||
_order = "id desc"
|
||||
_columns = {
|
||||
'name': fields.char('Reference', required=True),
|
||||
'move_type': fields.selection([
|
||||
('direct', 'Partial'), ('one', 'All at once')],
|
||||
'Delivery Method', required=True),
|
||||
'partner_id': fields.many2one('res.partner', string = 'Partner'), #Sale should pass it here
|
||||
'procurement_ids': fields.many2one('procurement.order', 'group_id', 'Procurements'),
|
||||
}
|
||||
_defaults = {
|
||||
'name': lambda self, cr, uid, c: self.pool.get('ir.sequence').get(cr, uid, 'procurement.group') or ''
|
||||
'name': lambda self, cr, uid, c: self.pool.get('ir.sequence').get(cr, uid, 'procurement.group') or '',
|
||||
'move_type': lambda self, cr, uid, c: 'one'
|
||||
}
|
||||
|
||||
class procurement_rule(osv.osv):
|
||||
|
|
|
@ -44,9 +44,9 @@ class stock_incoterms(osv.osv):
|
|||
_name = "stock.incoterms"
|
||||
_description = "Incoterms"
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64, required=True, help="Incoterms are series of sales terms.They are used to divide transaction costs and responsibilities between buyer and seller and reflect state-of-the-art transportation practices."),
|
||||
'code': fields.char('Code', size=3, required=True, help="Code for Incoterms"),
|
||||
'active': fields.boolean('Active', help="By unchecking the active field, you may hide an INCOTERM without deleting it."),
|
||||
'name': fields.char('Name', size=64, required=True, help="Incoterms are series of sales terms. They are used to divide transaction costs and responsibilities between buyer and seller and reflect state-of-the-art transportation practices."),
|
||||
'code': fields.char('Code', size=3, required=True, help="Incoterm Standard Code"),
|
||||
'active': fields.boolean('Active', help="By unchecking the active field, you may hide an INCOTERM you will not use."),
|
||||
}
|
||||
_defaults = {
|
||||
'active': True,
|
||||
|
@ -126,16 +126,11 @@ class stock_location(osv.osv):
|
|||
}
|
||||
def get_removal_strategy(self, cr, uid, location, product, context=None):
|
||||
return None
|
||||
# categ = product.categ_id
|
||||
# while (not categ.removal_strategy_id) and categ.parent_id:
|
||||
# categ = categ.parent_id
|
||||
# return categ and categ.removal_strategy_id or None
|
||||
|
||||
#----------------------------------------------------------
|
||||
# Quants
|
||||
#----------------------------------------------------------
|
||||
|
||||
|
||||
class stock_quant(osv.osv):
|
||||
"""
|
||||
Quants are the smallest unit of stock physical instances
|
||||
|
@ -201,9 +196,6 @@ class stock_quant(osv.osv):
|
|||
self._quant_reconcile_negative(cr, uid, quant, context=context)
|
||||
return quant
|
||||
|
||||
|
||||
# FP Note: TODO: implement domain preference that tries to retrieve first with this domain
|
||||
# This will be used for reservation
|
||||
def quants_get(self, cr, uid, location, product, qty, domain=None, prefered_order=False, reservedcontext=None, context=None):
|
||||
"""
|
||||
Use the removal strategies of product to search for the correct quants
|
||||
|
@ -226,12 +218,11 @@ class stock_quant(osv.osv):
|
|||
raise osv.except_osv(_('Error!'), _('Removal strategy %s not implemented.' % (removal_strategy,)))
|
||||
return result
|
||||
|
||||
|
||||
#
|
||||
# Create a quant in the destination location
|
||||
# Create a negative quant in the source location if it's an internal location
|
||||
# Reconcile a positive quant with a negative is possible
|
||||
#
|
||||
#
|
||||
def _quant_create(self, cr, uid, qty, move, context=None):
|
||||
# FP Note: TODO: compute the right price according to the move, with currency convert
|
||||
# QTY is normally already converted to main product's UoM
|
||||
|
@ -311,12 +302,10 @@ class stock_quant(osv.osv):
|
|||
def _price_update(self, cr, uid, quant, newprice, context=None):
|
||||
self.write(cr, uid, [quant.id], {'cost': newprice}, context=context)
|
||||
|
||||
|
||||
def quants_unreserve(self, cr, uid, move, context=None):
|
||||
cr.execute('update stock_quant set reservation_id=NULL where reservation_id=%s', (move.id,))
|
||||
return True
|
||||
|
||||
|
||||
#
|
||||
# Implementation of removal strategies
|
||||
# If it can not reserve, it will return a tuple (None, qty)
|
||||
|
@ -358,6 +347,17 @@ class stock_quant(osv.osv):
|
|||
def _location_owner(self, cr, uid, quant, location, context=None):
|
||||
return location and (location.usage == 'internal') and location.company_id or False
|
||||
|
||||
def _check_location(self, cr, uid, ids, context=None):
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
if record.location_id.usage == 'view':
|
||||
raise osv.except_osv(_('Error'), _('You cannot move product %s to a location of type view %s.')% (record.product_id.name, record.location_id.name))
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_location, 'You cannot move products to a location of the type view.', ['location_id'])
|
||||
]
|
||||
|
||||
|
||||
#----------------------------------------------------------
|
||||
# Stock Picking
|
||||
#----------------------------------------------------------
|
||||
|
@ -392,12 +392,13 @@ class stock_picking(osv.osv):
|
|||
return res
|
||||
|
||||
def create(self, cr, user, vals, context=None):
|
||||
context = context or {}
|
||||
if ('name' not in vals) or (vals.get('name') in ('/', False)):
|
||||
sequence_id = self.pool.get('stock.picking.type').browse(cr, user, vals['picking_type_id'], context=context).sequence_id.id
|
||||
ptype_id = vals.get('picking_type_id', context['default_picking_type_id'])
|
||||
sequence_id = self.pool.get('stock.picking.type').browse(cr, user, ptype_id, context=context).sequence_id.id
|
||||
vals['name'] = self.pool.get('ir.sequence').get_id(cr, user, sequence_id, 'id', context=context)
|
||||
return super(stock_picking, self).create(cr, user, vals, context)
|
||||
|
||||
|
||||
# The state of a picking depends on the state of its related stock.move
|
||||
# draft: the picking has no line or any one of the lines is draft
|
||||
# done, draft, cancel: all lines are done / draft / cancel
|
||||
|
@ -422,29 +423,19 @@ class stock_picking(osv.osv):
|
|||
res[pick.id] = order_inv[min(lst)]
|
||||
else:
|
||||
res[pick.id] = order_inv[max(lst)]
|
||||
print 'Returning', res
|
||||
return res
|
||||
|
||||
def _get_pickings(self, cr, uid, ids, context=None):
|
||||
res = set()
|
||||
for move in self.browse(cr, uid, ids, context=context):
|
||||
if move.picking_id:
|
||||
if move.picking_id:
|
||||
res.add(move.picking_id.id)
|
||||
return list(res)
|
||||
|
||||
def _get_pack_operation_exist(self, cr, uid, ids, field_name, arg, context=None):
|
||||
res = {}
|
||||
for pick in self.browse(cr, uid, ids, context=context):
|
||||
res[pick.id] = False
|
||||
if pick.pack_operation_ids:
|
||||
res[pick.id] = True
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Reference', size=64, select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
|
||||
'origin': fields.char('Source Document', size=64, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="Reference of the document", select=True),
|
||||
'backorder_id': fields.many2one('stock.picking', 'Back Order of', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True),
|
||||
#'type': fields.selection([('out', 'Sending Goods'), ('in', 'Getting Goods'), ('internal', 'Internal')], 'Shipping Type', required=True, select=True, help="Shipping type specify, goods coming in or going out."),
|
||||
'note': fields.text('Notes', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
|
||||
'move_type': fields.selection([('direct', 'Partial'), ('one', 'All at once')], 'Delivery Method', required=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="It specifies goods to be deliver partially or all at once"),
|
||||
'state': fields.function(_state_get, type="selection", store = {'stock.picking': (lambda self, cr, uid, ids, ctx: ids, ['move_type', 'move_lines'], 20), 'stock.move': (_get_pickings, ['state'], 20)}, selection = [
|
||||
|
@ -464,37 +455,31 @@ class stock_picking(osv.osv):
|
|||
),
|
||||
'min_date': fields.function(get_min_max_date, multi="min_max_date",
|
||||
store={'stock.move': (_get_pickings, ['state'], 20)}, type='datetime', string='Scheduled Time', select=1, 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, multi="min_max_date",
|
||||
store={'stock.move': (_get_pickings, ['state'], 20)}, type='datetime', string='Max. Expected Date', select=2),
|
||||
'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)]}),
|
||||
'move_lines': fields.one2many('stock.move', 'picking_id', 'Internal Moves', states={'done': [('readonly', True)], 'cancel': [('readonly', True)]}),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
|
||||
'company_id': fields.many2one('res.company', 'Company', required=True, select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
|
||||
'pack_operation_ids': fields.one2many('stock.pack.operation', 'picking_id', string='Related Packing Operations'),
|
||||
|
||||
# Used to search a product on pickings
|
||||
'picking_type_id': fields.many2one('stock.picking.type', 'Picking Type', required=True),
|
||||
|
||||
# Used to search on pickings
|
||||
'product_id': fields.related('move_lines', 'product_id', type='many2one', relation='product.product', string='Product'),#?
|
||||
'location_id': fields.related('move_lines', 'location_id', type='many2one', relation='stock.location', string='Location', readonly=True),
|
||||
'location_dest_id': fields.related('move_lines', 'location_dest_id', type='many2one', relation='stock.location', string='Destination Location', readonly=True),
|
||||
'group_id': fields.related('move_lines', 'group_id', type='many2one', relation='procurement.group', string='Procurement Group', readonly=True),
|
||||
#Picking type will be on the picking itself instead
|
||||
'picking_type_id': fields.many2one('stock.picking.type', 'Picking Type', required=True),
|
||||
#related('move_lines', 'picking_type_id', type='many2one', relation='stock.picking.type', string="Picking Type", readonly=True),
|
||||
'rule_id': fields.related('move_lines', 'rule_id', type='many2one', relation='procurement.rule', string="Procurement Rule", readonly=True),
|
||||
'pack_operation_exist': fields.function(_get_pack_operation_exist, type='boolean', string='Pack Operation Exists?', help='technical field for attrs in view'),
|
||||
}
|
||||
_defaults = {
|
||||
'name': lambda self, cr, uid, context: '/',
|
||||
#TODO: not a good solution => we need to remove the partner_id from stock move for internal moves
|
||||
'partner_id': lambda self, cr, uid, context: self.pool.get('stock.move')._default_destination_address(cr, uid, context=context),
|
||||
'state': 'draft',
|
||||
'move_type': 'direct',
|
||||
'move_type': 'one',
|
||||
'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)
|
||||
}
|
||||
_sql_constraints = [
|
||||
('name_uniq', 'unique(name, company_id)', 'Reference must be unique per Company!'),
|
||||
('name_uniq', 'unique(name, company_id)', 'Reference must be unique per company!'),
|
||||
]
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
|
@ -509,24 +494,12 @@ class stock_picking(osv.osv):
|
|||
default['backorder_id'] = False
|
||||
return super(stock_picking, self).copy(cr, uid, id, default, context)
|
||||
|
||||
|
||||
def action_confirm(self, cr, uid, ids, context=None):
|
||||
""" Confirms picking.
|
||||
@return: True
|
||||
"""
|
||||
proc_group = self.pool.get("procurement.group")
|
||||
pickings = self.browse(cr, uid, ids, context=context)
|
||||
todo = []
|
||||
for picking in pickings:
|
||||
#If no procurement group, create one
|
||||
new_proc = False
|
||||
if not picking.group_id:
|
||||
new_proc = proc_group.create(cr, uid, {'name': picking.name}, context=context)
|
||||
for picking in self.browse(cr, uid, ids, context=context):
|
||||
for r in picking.move_lines:
|
||||
if r.state == 'draft':
|
||||
todo.append(r.id)
|
||||
if not r.group_id and new_proc:
|
||||
self.pool.get("stock.move").write(cr, uid, [r.id], {'group_id': new_proc}, context=context)
|
||||
if len(todo):
|
||||
self.pool.get('stock.move').action_confirm(cr, uid, todo, context=context)
|
||||
return True
|
||||
|
@ -540,7 +513,7 @@ class stock_picking(osv.osv):
|
|||
self.action_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.'))
|
||||
raise osv.except_osv(_('Warning!'),_('No product available.'))
|
||||
self.pool.get('stock.move').action_assign(cr, uid, move_ids)
|
||||
return True
|
||||
|
||||
|
@ -553,19 +526,6 @@ class stock_picking(osv.osv):
|
|||
self.pool.get('stock.move').force_assign(cr, uid, move_ids)
|
||||
return True
|
||||
|
||||
def draft_force_assign(self, cr, uid, ids, *args):
|
||||
""" Confirms picking directly from draft state.
|
||||
@return: True
|
||||
"""
|
||||
return self.action_confirm(cr, uid, ids)
|
||||
|
||||
def draft_validate(self, cr, uid, ids, context=None):
|
||||
""" Validates picking directly from draft state.
|
||||
@return: True
|
||||
"""
|
||||
self.draft_force_assign(cr, uid, ids)
|
||||
return self.action_done(cr, uid, ids, context=context)
|
||||
|
||||
def cancel_assign(self, cr, uid, ids, *args):
|
||||
""" Cancels picking and moves.
|
||||
@return: True
|
||||
|
@ -575,22 +535,6 @@ class stock_picking(osv.osv):
|
|||
self.pool.get('stock.move').cancel_assign(cr, uid, move_ids)
|
||||
return True
|
||||
|
||||
def _create_backorder(self, cr, uid, picking, context=None):
|
||||
sequence_obj = self.pool.get('ir.sequence')
|
||||
new_picking_name = picking.name
|
||||
#TODO back_order_name is False currently => find why
|
||||
back_order_name = sequence_obj.get(cr, uid, 'stock.picking') #TODO: Need to have sequence for every picking type
|
||||
self.write(cr, uid, [picking.id], {'name': back_order_name})
|
||||
backorder_id = self.copy(cr, uid, picking.id, {
|
||||
'name': new_picking_name,
|
||||
'move_lines': [], # the move_lines are linked after
|
||||
'state': 'done' # the backorder is already created as 'done' because it is created only after the action_done of stock moves
|
||||
})
|
||||
self.message_post(cr, uid, picking.id, body=_("Back order <em>%s</em> has been <b>created</b>.") % (back_order_name), context=context)
|
||||
unlink_operation_order = [(2, op.id) for op in picking.pack_operation_ids]
|
||||
self.write(cr, uid, [picking.id], {'backorder_id': backorder_id, 'pack_operation_ids': unlink_operation_order}, context=context)
|
||||
return backorder_id
|
||||
|
||||
def action_cancel(self, cr, uid, ids, context=None):
|
||||
""" Changes picking state to cancel.
|
||||
@return: True
|
||||
|
@ -598,12 +542,11 @@ class stock_picking(osv.osv):
|
|||
for pick in self.browse(cr, uid, ids, context=context):
|
||||
ids2 = [move.id for move in pick.move_lines]
|
||||
self.pool.get('stock.move').action_cancel(cr, uid, ids2, context)
|
||||
self.write(cr, uid, ids, {'state': 'cancel'})
|
||||
return True
|
||||
|
||||
def action_done(self, cr, uid, ids, context=None):
|
||||
"""Changes picking state to done by processing the Stock Moves of the Picking
|
||||
|
||||
|
||||
Normally that happens when the button "Done" is pressed on a Picking view.
|
||||
@return: True
|
||||
"""
|
||||
|
@ -622,24 +565,29 @@ class stock_picking(osv.osv):
|
|||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
move_obj = self.pool.get('stock.move')
|
||||
if context is None:
|
||||
context = {}
|
||||
context = context or {}
|
||||
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,))
|
||||
else:
|
||||
ids2 = [move.id for move in pick.move_lines]
|
||||
ctx = context.copy()
|
||||
ctx.update({'call_unlink':True})
|
||||
if pick.state != 'draft':
|
||||
#Cancelling the move in order to affect Virtual stock of product
|
||||
move_obj.action_cancel(cr, uid, ids2, ctx)
|
||||
#Removing the move
|
||||
move_obj.unlink(cr, uid, ids2, ctx)
|
||||
|
||||
ids2 = [move.id for move in pick.move_lines]
|
||||
move_obj.action_cancel(cr, uid, ids2, ctx)
|
||||
move_obj.unlink(cr, uid, ids2, ctx)
|
||||
return super(stock_picking, self).unlink(cr, uid, ids, context=context)
|
||||
|
||||
# FP Note: review all methods aboce this line for stock.picking
|
||||
# FP Note: review all methods above this line for stock.picking
|
||||
|
||||
def _create_backorder(self, cr, uid, picking, context=None):
|
||||
sequence_obj = self.pool.get('ir.sequence')
|
||||
new_picking_name = picking.name
|
||||
seq_id = picking.picking_type_id.sequence_id.id
|
||||
back_order_name = sequence_obj.get_id(cr, uid, seq_id, 'id', context=context)
|
||||
self.write(cr, uid, [picking.id], {'name': back_order_name})
|
||||
backorder_id = self.copy(cr, uid, picking.id, {
|
||||
'name': new_picking_name,
|
||||
'move_lines': [],
|
||||
})
|
||||
self.message_post(cr, uid, picking.id, body=_("Back order <em>%s</em> has been <b>created</b>.") % (back_order_name), context=context)
|
||||
unlink_operation_order = [(2, op.id) for op in picking.pack_operation_ids]
|
||||
self.write(cr, uid, [picking.id], {'backorder_id': backorder_id, 'pack_operation_ids': unlink_operation_order}, context=context)
|
||||
return backorder_id
|
||||
|
||||
def make_packaging(self, cr, uid, picking_id, todo_move_ids, context=None):
|
||||
quant_obj = self.pool.get('stock.quant')
|
||||
|
@ -797,16 +745,6 @@ class stock_picking(osv.osv):
|
|||
picking_to_package = stock_move_obj.browse(cr, uid, todo_move_ids[0], context=context).picking_id
|
||||
self.make_packaging(cr, uid, picking_to_package.id, todo_move_ids, context=context)
|
||||
|
||||
# views associated to each picking type
|
||||
def _get_view_id(self, cr, uid, type):
|
||||
"""Get the view id suiting the given type
|
||||
|
||||
@param type: the picking type as a string
|
||||
@return: view i, or False if no view found
|
||||
"""
|
||||
res = self.pool.get('ir.model.data').get_object_reference(cr, uid,
|
||||
'stock', 'view_picking_form')
|
||||
return res and res[1] or False
|
||||
|
||||
def _get_picking_for_packing_ui(self, cr, uid, context=None):
|
||||
res = self.search(cr, uid, [('state', '=', 'assigned')], limit=1, context=context)
|
||||
|
@ -894,17 +832,6 @@ class stock_production_lot(osv.osv):
|
|||
_sql_constraints = [
|
||||
('name_ref_uniq', 'unique (name, ref)', 'The combination of Serial Number and internal reference must be unique !'),
|
||||
]
|
||||
def action_traceability(self, cr, uid, ids, context=None):
|
||||
""" It traces the information of a product
|
||||
@param self: The object pointer.
|
||||
@param cr: A database cursor
|
||||
@param uid: ID of the user currently logged in
|
||||
@param ids: List of IDs selected
|
||||
@param context: A standard dictionary
|
||||
@return: A dictionary of values
|
||||
"""
|
||||
value=self.pool.get('action.traceability').action_traceability(cr,uid,ids,context)
|
||||
return value
|
||||
|
||||
|
||||
# ----------------------------------------------------
|
||||
|
@ -917,26 +844,6 @@ class stock_move(osv.osv):
|
|||
_order = 'date_expected desc, id'
|
||||
_log_create = False
|
||||
|
||||
def action_partial_move(self, cr, uid, ids, context=None):
|
||||
if context is None: context = {}
|
||||
if context.get('active_model') != self._name:
|
||||
context.update(active_ids=ids, active_model=self._name)
|
||||
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):
|
||||
|
@ -1020,7 +927,7 @@ class stock_move(osv.osv):
|
|||
|
||||
# FP Note: should we remove this?
|
||||
'partner_id': fields.many2one('res.partner', 'Destination Address ', states={'done': [('readonly', True)]}, help="Optional address where goods are to be delivered, specifically used for allotment"),
|
||||
|
||||
|
||||
|
||||
'move_dest_id': fields.many2one('stock.move', 'Destination Move', help="Optional: next stock move when chaining them", select=True),
|
||||
'move_orig_ids': fields.one2many('stock.move', 'move_dest_id', 'Original Move', help="Optional: previous stock move when chaining them", select=True),
|
||||
|
@ -1050,54 +957,37 @@ class stock_move(osv.osv):
|
|||
|
||||
# used for colors in tree views:
|
||||
'scrapped': fields.related('location_dest_id','scrap_location',type='boolean',relation='stock.location',string='Scrapped', readonly=True),
|
||||
|
||||
'picking_type_id': fields.related('picking_id', 'picking_type_id', type='many2one', relation='stock.picking.type', string="Picking type" ,readonly=True),
|
||||
|
||||
'picking_type_id': fields.related('picking_id', 'picking_type_id', type='many2one', relation='stock.picking.type', string="Picking type" ,readonly=True),
|
||||
'quant_ids': fields.many2many('stock.quant', 'stock_quant_move_rel', 'move_id', 'quant_id', 'Quants'),
|
||||
'reserved_quant_ids': fields.one2many('stock.quant', 'reservation_id', 'Reserved quants'),
|
||||
'remaining_qty': fields.function(_get_remaining_qty, type='float', string='Remaining Quantity', digits_compute=dp.get_precision('Product Unit of Measure'), states={'done': [('readonly', True)]}),
|
||||
'group_id': fields.many2one('procurement.group', 'Procurement Group'),
|
||||
'rule_id': fields.many2one('procurement.rule', 'Procurement Rule'),
|
||||
'propagate': fields.boolean('Propagate cancel and split', help='If checked, when this move is cancelled, cancel the linked move too'),
|
||||
'picking_type_id': fields.many2one('stock.picking.type', 'Picking Type', required=True),
|
||||
}
|
||||
|
||||
def _check_location(self, cr, uid, ids, context=None):
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
if (record.state=='done') and (record.location_id.usage == 'view'):
|
||||
raise osv.except_osv(_('Error'), _('You cannot move product %s from a location of type view %s.')% (record.product_id.name, record.location_id.name))
|
||||
if (record.state=='done') and (record.location_dest_id.usage == 'view' ):
|
||||
raise osv.except_osv(_('Error'), _('You cannot move product %s to a location of type view %s.')% (record.product_id.name, record.location_dest_id.name))
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_location, 'You cannot move products from or to a location of the type view.',
|
||||
['location_id','location_dest_id'])
|
||||
]
|
||||
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
if default is None:
|
||||
default = {}
|
||||
default = default.copy()
|
||||
default['procurement_group'] = False
|
||||
default['move_orig_ids'] = []
|
||||
default['quant_ids'] = []
|
||||
default['reserved_quant_ids'] = []
|
||||
default['state'] = 'draft'
|
||||
return super(stock_move, self).copy(cr, uid, id, default, context)
|
||||
|
||||
|
||||
|
||||
def _default_location_destination(self, cr, uid, context=None):
|
||||
""" Gets default address of partner for destination location
|
||||
@return: Address id or False
|
||||
"""
|
||||
context = context or {}
|
||||
if 'picking_type_id' in context and context['picking_type_id']:
|
||||
if context.get('picking_type_id', False):
|
||||
pick_type = self.pool.get('stock.picking.type').browse(cr, uid, context['picking_type_id'], context=context)
|
||||
return pick_type.location_dest_id and pick_type.location_dest_id.id or False
|
||||
return False
|
||||
|
||||
def _default_location_source(self, cr, uid, context=None):
|
||||
""" Gets default address of partner for source location
|
||||
@return: Address id or False
|
||||
"""
|
||||
context = context or {}
|
||||
if 'picking_type_id' in context and context['picking_type_id']:
|
||||
if context.get('picking_type_id', False):
|
||||
pick_type = self.pool.get('stock.picking.type').browse(cr, uid, context['picking_type_id'], context=context)
|
||||
return pick_type.location_src_id and pick_type.location_src_id.id or False
|
||||
return False
|
||||
|
@ -1107,9 +997,6 @@ class stock_move(osv.osv):
|
|||
return user.company_id.partner_id.id
|
||||
|
||||
def _default_picking_type(self, cr, uid, context=None):
|
||||
""" Gets default type of move
|
||||
@return: type
|
||||
"""
|
||||
context = context or {}
|
||||
return context.get('picking_type_id', False)
|
||||
|
||||
|
@ -1147,7 +1034,7 @@ class stock_move(osv.osv):
|
|||
'product_uos': (move.product_uos and move.product_uos.id) or move.product_uom.id,
|
||||
'location_id': move.location_id.id,
|
||||
'move_dest_id': move.id,
|
||||
'group_id': move.group_id and move.group_id.id or False,
|
||||
'group_id': move.group_id and move.group_id.id or False,
|
||||
})
|
||||
|
||||
# Check that we do not modify a stock.move which is done
|
||||
|
@ -1163,18 +1050,6 @@ class stock_move(osv.osv):
|
|||
result = super(stock_move, self).write(cr, uid, ids, vals, context=context)
|
||||
return result
|
||||
|
||||
|
||||
|
||||
def _auto_init(self, cursor, context=None):
|
||||
res = super(stock_move, self)._auto_init(cursor, context=context)
|
||||
cursor.execute('SELECT indexname \
|
||||
FROM pg_indexes \
|
||||
WHERE indexname = \'stock_move_location_id_location_dest_id_product_id_state\'')
|
||||
if not cursor.fetchone():
|
||||
cursor.execute('CREATE INDEX stock_move_location_id_location_dest_id_product_id_state \
|
||||
ON stock_move (product_id, state, location_id, location_dest_id)')
|
||||
return res
|
||||
|
||||
def onchange_quantity(self, cr, uid, ids, product_id, product_qty,
|
||||
product_uom, product_uos):
|
||||
""" On change of product quantity finds UoM and UoS quantities
|
||||
|
@ -1185,8 +1060,8 @@ class stock_move(osv.osv):
|
|||
@return: Dictionary of values
|
||||
"""
|
||||
result = {
|
||||
'product_uos_qty': 0.00
|
||||
}
|
||||
'product_uos_qty': 0.00
|
||||
}
|
||||
warning = {}
|
||||
|
||||
if (not product_id) or (product_qty <=0.0):
|
||||
|
@ -1195,8 +1070,8 @@ class stock_move(osv.osv):
|
|||
|
||||
product_obj = self.pool.get('product.product')
|
||||
uos_coeff = product_obj.read(cr, uid, product_id, ['uos_coeff'])
|
||||
|
||||
# Warn if the quantity was decreased
|
||||
|
||||
# Warn if the quantity was decreased
|
||||
if ids:
|
||||
for move in self.read(cr, uid, ids, ['product_qty']):
|
||||
if product_qty < move['product_qty']:
|
||||
|
@ -1234,8 +1109,8 @@ class stock_move(osv.osv):
|
|||
|
||||
product_obj = self.pool.get('product.product')
|
||||
uos_coeff = product_obj.read(cr, uid, product_id, ['uos_coeff'])
|
||||
|
||||
# Warn if the quantity was decreased
|
||||
|
||||
# Warn if the quantity was decreased
|
||||
for move in self.read(cr, uid, ids, ['product_uos_qty']):
|
||||
if product_uos_qty < move['product_uos_qty']:
|
||||
warning.update({
|
||||
|
@ -1285,58 +1160,34 @@ class stock_move(osv.osv):
|
|||
result['location_dest_id'] = loc_dest_id
|
||||
return {'value': result}
|
||||
|
||||
def onchange_move_type(self, cr, uid, ids, picking_type_id, context=None):
|
||||
""" On change of move type gives sorce and destination location.
|
||||
@param type: Move Type
|
||||
@return: Dictionary of values
|
||||
"""
|
||||
mod_obj = self.pool.get('ir.model.data')
|
||||
location_source_id = 'stock_location_stock'
|
||||
location_dest_id = 'stock_location_stock'
|
||||
type="internal"
|
||||
if type == 'in':
|
||||
location_source_id = 'stock_location_suppliers'
|
||||
location_dest_id = 'stock_location_stock'
|
||||
elif type == 'out':
|
||||
location_source_id = 'stock_location_stock'
|
||||
location_dest_id = 'stock_location_customers'
|
||||
source_location = mod_obj.get_object_reference(cr, uid, 'stock', location_source_id)
|
||||
dest_location = mod_obj.get_object_reference(cr, uid, 'stock', location_dest_id)
|
||||
#Check companies
|
||||
user_company = self.pool.get("res.users").browse(cr, uid, uid, context=context).company_id.id
|
||||
if source_location:
|
||||
location_company = self.pool.get("stock.location").browse(cr, uid, source_location[1], context=context).company_id
|
||||
if location_company and location_company.id != user_company:
|
||||
source_location = False
|
||||
if dest_location:
|
||||
location_company = self.pool.get("stock.location").browse(cr, uid, dest_location[1], context=context).company_id
|
||||
if location_company and location_company.id != user_company:
|
||||
dest_location = False
|
||||
return {'value': {'location_id': source_location and source_location[1] or False, 'location_dest_id': dest_location and dest_location[1] or False}}
|
||||
|
||||
def _find_or_create_picking(self, cr, uid, move, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
# TODO: Put the move in the right picking according to group_id -> should be more elaborated (draft is nok) and picking should be confirmed
|
||||
def _picking_assign(self, cr, uid, move, context=None):
|
||||
if move.picking_id or \
|
||||
move.location_id.usage in ['production', 'inventory'] or \
|
||||
move.location_dest_id.usage in ['production', 'inventory']:
|
||||
return False
|
||||
context = context or {}
|
||||
pick_obj = self.pool.get("stock.picking")
|
||||
picks = pick_obj.search(cr, uid, [('group_id', '=', move.group_id.id), ('location_id', '=', move.location_id.id),
|
||||
('location_dest_id', '=', move.location_dest_id.id), ('state', 'in', ['confirmed', 'waiting', 'draft'])], context=context)
|
||||
picks = pick_obj.search(cr, uid, [
|
||||
('group_id', '=', move.group_id and move.group_id.id or False),
|
||||
('location_id', '=', move.location_id.id),
|
||||
('location_dest_id', '=', move.location_dest_id.id),
|
||||
('state', 'in', ['confirmed', 'auto'])], context=context)
|
||||
if picks:
|
||||
pick = picks[0]
|
||||
else:
|
||||
#a picking doesn't exist yet, create a new one
|
||||
values = {'origin': move.origin,
|
||||
'company_id': move.company_id and move.company_id.id or False,
|
||||
'move_type': 'one',
|
||||
'partner_id': move.partner_id and move.partner_id.id or False,
|
||||
'date_done': move.date_expected,
|
||||
#'invoice_state': move.invoice_state
|
||||
'state': 'confirmed',
|
||||
'group_id': move.group_id and move.group_id.id or False,
|
||||
'picking_type_id': move.rule_id and move.rule_id.picking_type_id.id or False,
|
||||
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.partner_id and move.partner_id.id or False,
|
||||
'date_done': move.date_expected,
|
||||
'state': 'confirmed',
|
||||
'group_id': move.group_id and move.group_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)
|
||||
return pick
|
||||
move.write({'picking_id': pick})
|
||||
return True
|
||||
|
||||
def onchange_date(self, cr, uid, ids, date, date_expected, context=None):
|
||||
""" On change of Scheduled Date gives a Move date.
|
||||
|
@ -1363,9 +1214,7 @@ class stock_move(osv.osv):
|
|||
state = 'waiting'
|
||||
states[state].append(move.id)
|
||||
|
||||
if not move.picking_id and move.location_id.usage not in ['production', 'inventory'] and move.location_dest_id.usage not in ['production', 'inventory']:
|
||||
pick = self._find_or_create_picking(cr, uid, move, context=context)
|
||||
move.write({'picking_id': pick})
|
||||
self._picking_assign(cr, uid, move, context=context)
|
||||
|
||||
|
||||
for state, write_ids in states.items():
|
||||
|
@ -1382,9 +1231,9 @@ class stock_move(osv.osv):
|
|||
@return: True
|
||||
"""
|
||||
done = self.action_assign(cr, uid, ids, context=context)
|
||||
self.write(cr, uid, list(set(ids) - set(done)), {'state': 'assigned'})
|
||||
self.write(cr, uid, list(set(ids) - set(done)), {'state': 'assigned'})
|
||||
return True
|
||||
|
||||
|
||||
|
||||
def cancel_assign(self, cr, uid, ids, context=None):
|
||||
""" Changes the state to confirmed.
|
||||
|
@ -1414,7 +1263,7 @@ class stock_move(osv.osv):
|
|||
dp.append(str(q.id))
|
||||
domain = ['|', ('reservation_id', '=', False), ('reservation_id', '=', move.id)]
|
||||
quants = quant_obj.quants_get(cr, uid, move.location_id, move.product_id, qty, domain=domain, prefered_order = dp and ('id not in ('+','.join(dp)+')') or False, context=context)
|
||||
#Will only reserve physical quants, no negative
|
||||
#Will only reserve physical quants, no negative
|
||||
quant_obj.quants_reserve(cr, uid, quants, move, context=context)
|
||||
# the total quantity is provided by existing quants
|
||||
if all(map(lambda x:x[0], quants)):
|
||||
|
@ -1469,7 +1318,7 @@ class stock_move(osv.osv):
|
|||
if move.picking_id:
|
||||
pickings.add(move.picking_id.id)
|
||||
qty = move.product_uom_qty
|
||||
|
||||
|
||||
# for qty, location_id in move_id.prefered_location_ids:
|
||||
# quants = quant_obj.quants_get(cr, uid, move.location_id, move.product_id, qty, context=context)
|
||||
# quant_obj.quants_move(cr, uid, quants, move, location_dest_id, context=context)
|
||||
|
@ -1479,7 +1328,7 @@ class stock_move(osv.osv):
|
|||
#Will move all quants_get and as such create negative quants
|
||||
quant_obj.quants_move(cr, uid, quants, move, context=context)
|
||||
quant_obj.quants_unreserve(cr, uid, move, context=context)
|
||||
|
||||
|
||||
#
|
||||
#Check moves that were pushed
|
||||
if move.move_dest_id.state in ('waiting', 'confirmed'):
|
||||
|
@ -1499,14 +1348,11 @@ class stock_move(osv.osv):
|
|||
return True
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
ctx = context.copy()
|
||||
context = context or {}
|
||||
for move in self.browse(cr, uid, ids, context=context):
|
||||
if move.state != 'draft' and not ctx.get('call_unlink', False):
|
||||
if move.state not in ('draft', 'cancel'):
|
||||
raise osv.except_osv(_('User Error!'), _('You can only delete draft moves.'))
|
||||
return super(stock_move, self).unlink(
|
||||
cr, uid, ids, context=ctx)
|
||||
return super(stock_move, self).unlink(cr, uid, ids, context=context)
|
||||
|
||||
def action_scrap(self, cr, uid, ids, quantity, location_id, context=None):
|
||||
""" Move the scrap/damaged product into scrap location
|
||||
|
@ -1613,12 +1459,12 @@ class stock_move(osv.osv):
|
|||
|
||||
# def price_calculation(self, cr, uid, ids, quants, context=None):
|
||||
# '''
|
||||
# This method puts the right price on the stock move,
|
||||
# This method puts the right price on the stock move,
|
||||
# adapts the price on the product when necessary
|
||||
# and creates the necessary stock move matchings
|
||||
# :param quants: are quants to be reconciled and needs to be done when IN move reconciles out move
|
||||
#
|
||||
# It returns a list of tuples with (move_id, match_id)
|
||||
#
|
||||
# It returns a list of tuples with (move_id, match_id)
|
||||
# which is used for generating the accounting entries when FIFO/LIFO
|
||||
# '''
|
||||
# product_obj = self.pool.get('product.product')
|
||||
|
@ -1626,7 +1472,7 @@ class stock_move(osv.osv):
|
|||
# matching_obj = self.pool.get('stock.move.matching')
|
||||
# uom_obj = self.pool.get('product.uom')
|
||||
# quant_obj = self.pool.get('stock.quant')
|
||||
#
|
||||
#
|
||||
# product_avail = {}
|
||||
# res = {}
|
||||
# for move in self.browse(cr, uid, ids, context=context):
|
||||
|
@ -1643,9 +1489,9 @@ class stock_move(osv.osv):
|
|||
# product_uom_qty = uom_obj._compute_qty(cr, uid, move_uom, move_qty, product.uom_id.id, round=False)
|
||||
# if not product.id in product_avail:
|
||||
# product_avail[product.id] = product.qty_available
|
||||
#
|
||||
#
|
||||
# # Check if out -> do stock move matchings and if fifo/lifo -> update price
|
||||
# # only update the cost price on the product form on stock moves of type == 'out' because if a valuation has to be made without PO,
|
||||
# # only update the cost price on the product form on stock moves of type == 'out' because if a valuation has to be made without PO,
|
||||
# # for inventories for example we want to use the last value used for an outgoing move
|
||||
# if move.location_id.usage == 'internal' and move.location_dest_id.usage != 'internal':
|
||||
# fifo = (cost_method != 'lifo')
|
||||
|
@ -1658,14 +1504,14 @@ class stock_move(osv.osv):
|
|||
# for quant in quant_obj.browse(cr, uid, quants_move, context=context):
|
||||
# price_amount += quant.qty * quant.price_unit
|
||||
# amount += quant.qty
|
||||
#
|
||||
## tuples = product_obj.get_stock_matchings_fifolifo(cr, uid, [product.id], move_qty, fifo,
|
||||
#
|
||||
## tuples = product_obj.get_stock_matchings_fifolifo(cr, uid, [product.id], move_qty, fifo,
|
||||
## move_uom, move.company_id.currency_id.id, context=ctx) #TODO Would be better to use price_currency_id for migration?
|
||||
## price_amount = 0.0
|
||||
## amount = 0.0
|
||||
## #Write stock matchings
|
||||
## for match in tuples:
|
||||
## matchvals = {'move_in_id': match[0], 'qty': match[1],
|
||||
## for match in tuples:
|
||||
## matchvals = {'move_in_id': match[0], 'qty': match[1],
|
||||
## 'move_out_id': move.id}
|
||||
## match_id = matching_obj.create(cr, uid, matchvals, context=context)
|
||||
## res[move.id].append(match_id)
|
||||
|
@ -1675,11 +1521,11 @@ class stock_move(osv.osv):
|
|||
# if product_avail[product.id] >= product_uom_qty and product.cost_method in ['real']:
|
||||
# if amount > 0:
|
||||
# self.write(cr, uid, move.id, {'price_unit': price_amount / move_qty}, context=context) #Should be converted
|
||||
# product_obj.write(cr, uid, product.id, {'standard_price': price_amount / amount}, context=ctx)
|
||||
# product_obj.write(cr, uid, product.id, {'standard_price': price_amount / amount}, context=ctx)
|
||||
# else:
|
||||
# pass
|
||||
## raise osv.except_osv(_('Error'), _("Something went wrong finding quants ") + str(self.search(cr, uid, [('company_id','=', company_id), ('qty_remaining', '>', 0), ('state', '=', 'done'),
|
||||
## ('location_id.usage', '!=', 'internal'), ('location_dest_id.usage', '=', 'internal'), ('product_id', '=', product.id)],
|
||||
## raise osv.except_osv(_('Error'), _("Something went wrong finding quants ") + str(self.search(cr, uid, [('company_id','=', company_id), ('qty_remaining', '>', 0), ('state', '=', 'done'),
|
||||
## ('location_id.usage', '!=', 'internal'), ('location_dest_id.usage', '=', 'internal'), ('product_id', '=', product.id)],
|
||||
## order = 'date, id', context=context)) + str(move_qty) + str(move_uom) + str(move.company_id.currency_id.id))
|
||||
# else:
|
||||
# new_price = uom_obj._compute_price(cr, uid, product.uom_id.id, product.standard_price, move_uom)
|
||||
|
@ -1687,7 +1533,7 @@ class stock_move(osv.osv):
|
|||
# #Adjust product_avail when not average and move returned from
|
||||
# if product.cost_method != 'average':
|
||||
# product_avail[product.id] -= product_uom_qty
|
||||
#
|
||||
#
|
||||
# #Check if in => if price 0.0, take standard price / Update price when average price and price on move != standard price
|
||||
# if move.location_id.usage != 'internal' and move.location_dest_id.usage == 'internal':
|
||||
# if move.price_unit == 0.0:
|
||||
|
@ -1859,7 +1705,7 @@ class stock_inventory(osv.osv):
|
|||
'product_id': line.product_id.id,
|
||||
'product_uom': line.product_uom.id,
|
||||
'date': inv.date,
|
||||
'company_id': line.location_id.company_id.id,
|
||||
'company_id': line.location_id.company_id.id,
|
||||
}
|
||||
|
||||
if change > 0:
|
||||
|
@ -2276,7 +2122,7 @@ class stock_picking_code(osv.osv):
|
|||
_name = "stock.picking.code"
|
||||
_description = "Will group picking types for kanban view"
|
||||
_columns = {
|
||||
'name': fields.char("Picking Type", translate=True),
|
||||
'name': fields.char("Picking Type", translate=True),
|
||||
}
|
||||
|
||||
class stock_picking_type(osv.osv):
|
||||
|
@ -2337,7 +2183,7 @@ class stock_picking_type(osv.osv):
|
|||
}
|
||||
result = {}
|
||||
for field in domains:
|
||||
data = obj.read_group(cr, uid, domains[field] +
|
||||
data = obj.read_group(cr, uid, domains[field] +
|
||||
[('state', 'not in',('done','cancel','draft')), ('picking_type_id', 'in', ids)],
|
||||
['picking_type_id'], ['picking_type_id'], context=context)
|
||||
count = dict(map(lambda x: (x['picking_type_id'], x['__count']), data))
|
||||
|
@ -2379,7 +2225,7 @@ class stock_picking_type(osv.osv):
|
|||
|
||||
# Statistics for the kanban view
|
||||
'weekly_picking': fields.function(_get_picking_data,
|
||||
type='string',
|
||||
type='string',
|
||||
string='Scheduled pickings per week'),
|
||||
|
||||
'count_picking': fields.function(_get_picking_count,
|
||||
|
|
|
@ -581,15 +581,13 @@
|
|||
<field eval="12" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Internal Picking List" version="7.0">
|
||||
<field name='pack_operation_exist' invisible="1"/>
|
||||
<header>
|
||||
<button name="draft_force_assign" states="draft" string="Confirm" type="object" class="oe_highlight" groups="base.group_user"/>
|
||||
<button name="draft_validate" states="draft" string="Confirm & Total Transfer" type="object" class="oe_highlight" groups="base.group_user"/>
|
||||
<button name="force_assign" states="draft" string="Confirm" type="object" class="oe_highlight" groups="base.group_user"/>
|
||||
<!-- <button name="check_assign" states="confirmed" string="Check Availability" type="object"/> -->
|
||||
<button name="force_assign" states="confirmed" string="Force Availability" type="object" class="oe_highlight" groups="base.group_user"/>
|
||||
<button name="action_done" states="assigned" string="Total Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight"/>
|
||||
<button name="do_prepare_partial" states="assigned" string="(prepare) Partial Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight" attrs="{'invisible': [('pack_operation_exist','=',True)]}"/>
|
||||
<button name="do_partial" states="assigned" string="Partial Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight" attrs="{'invisible': [('pack_operation_exist','=',False)]}"/>
|
||||
<button name="do_prepare_partial" states="assigned" string="(prepare) Partial Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight" attrs="{'invisible': [('pack_operation_ids','<>',False)]}"/>
|
||||
<button name="do_partial" states="assigned" string="Partial Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight" attrs="{'invisible': [('pack_operation_ids','=',False)]}"/>
|
||||
<button name="%(act_stock_return_picking)d" string="Reverse Transfer" states="done" type="action" groups="base.group_user"/>
|
||||
<button name="button_cancel" states="assigned,confirmed,draft" string="Cancel Transfer" groups="base.group_user"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,assigned,done" statusbar_colors='{"shipping_except":"red","invoice_except":"red","waiting_date":"blue"}'/>
|
||||
|
@ -611,7 +609,7 @@
|
|||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Partial/Packing Operations" attrs="{'invisible': [('pack_operation_exist','=',False)]}">
|
||||
<page string="Partial/Packing Operations" attrs="{'invisible': [('pack_operation_ids','=',False)]}">
|
||||
<field name="pack_operation_ids">
|
||||
<tree editable="top">
|
||||
<field name="product_id"/>
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
import stock_traceability
|
||||
import stock_move
|
||||
import stock_inventory_merge
|
||||
import stock_fill_inventory
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.tools.translate import _
|
||||
|
||||
class action_traceability(osv.osv_memory):
|
||||
"""
|
||||
This class defines a function action_traceability for wizard
|
||||
|
||||
"""
|
||||
_name = "action.traceability"
|
||||
_description = "Action traceability "
|
||||
|
||||
def action_traceability(self, cr, uid, ids, context=None):
|
||||
""" It traces the information of a product
|
||||
@param self: The object pointer.
|
||||
@param cr: A database cursor
|
||||
@param uid: ID of the user currently logged in
|
||||
@param ids: List of IDs selected
|
||||
@param context: A standard dictionary
|
||||
@return: A dictionary of values
|
||||
"""
|
||||
lot_id = ids
|
||||
if context is None:
|
||||
context = {}
|
||||
type1 = context.get('type', 'move_history_ids2')
|
||||
field = context.get('field', 'tracking_id')
|
||||
obj = self.pool.get('stock.move')
|
||||
ids = obj.search(cr, uid, [(field, 'in',lot_id)])
|
||||
cr.execute('select id from ir_ui_view where model=%s and field_parent=%s and type=%s', ('stock.move', type1, 'tree'))
|
||||
view_ids = cr.fetchone()
|
||||
view_id = view_ids and view_ids[0] or False
|
||||
value = {
|
||||
'domain': "[('id','in',["+','.join(map(str, ids))+"])]",
|
||||
'name': ((type1=='move_history_ids2') and _('Upstream Traceability')) or _('Downstream Traceability'),
|
||||
'view_mode': 'tree',
|
||||
'view_type': 'tree',
|
||||
'res_model': 'stock.move',
|
||||
'field_parent': type1,
|
||||
'view_id': (view_id,'View'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'nodestroy':True,
|
||||
}
|
||||
return value
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
Loading…
Reference in New Issue