from operator import itemgetter
from itertools import groupby
-from openerp.osv import fields, osv
+from openerp.osv import fields, osv, orm
from openerp.tools.translate import _
from openerp import netsvc
from openerp import tools
_name = "stock.picking"
_inherit = ['mail.thread']
_description = "Picking List"
+ _order = "id desc"
def _set_maximum_date(self, cr, uid, ids, name, value, arg, context=None):
""" Calculates planned date if it is greater than 'value'.
ids = [ids]
for pick in self.browse(cr, uid, ids, context=context):
sql_str = """update stock_move set
- date='%s'
+ date_expected='%s'
where
picking_id=%d """ % (value, pick.id)
-
if pick.max_date:
- sql_str += " and (date='" + pick.max_date + "' or date>'" + value + "')"
+ sql_str += " and (date_expected='" + pick.max_date + "')"
cr.execute(sql_str)
return True
ids = [ids]
for pick in self.browse(cr, uid, ids, context=context):
sql_str = """update stock_move set
- date='%s'
+ date_expected='%s'
where
picking_id=%s """ % (value, pick.id)
if pick.min_date:
- sql_str += " and (date='" + pick.min_date + "' or date<'" + value + "')"
+ sql_str += " and (date_expected='" + pick.min_date + "')"
cr.execute(sql_str)
return True
if isinstance(partner, int):
partner = partner_obj.browse(cr, uid, [partner], context=context)[0]
if not partner:
- raise osv.except_osv(_('Error, no partner !'),
+ raise osv.except_osv(_('Error, no partner!'),
_('Please put a partner on the picking list if you want to generate invoice.'))
if not inv_type:
"* Waiting Availability: This state is reached when the procurement resolution is not straight forward. It may need the scheduler to run, a component to me manufactured...\n"\
"* Available: When products are reserved, it is set to \'Available\'.\n"\
"* Done: When the shipment is processed, the state is \'Done\'."),
- '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('Product 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),
'backorder_id': fields.related('picking_id','backorder_id',type='many2one', relation="stock.picking", string="Back Order of", select=True),
elif picking_type == 'out':
location_xml_id = 'stock_location_customers'
if location_xml_id:
- location_model, location_id = mod_obj.get_object_reference(cr, uid, 'stock', location_xml_id)
+ try:
+ location_model, location_id = mod_obj.get_object_reference(cr, uid, 'stock', location_xml_id)
+ self.pool.get('stock.location').check_access_rule(cr, uid, [location_id], 'read', context=context)
+ except (orm.except_orm, ValueError):
+ location_id = False
+
return location_id
def _default_location_source(self, cr, uid, context=None):
elif picking_type in ('out', 'internal'):
location_xml_id = 'stock_location_stock'
if location_xml_id:
- location_model, location_id = mod_obj.get_object_reference(cr, uid, 'stock', location_xml_id)
+ try:
+ location_model, location_id = mod_obj.get_object_reference(cr, uid, 'stock', location_xml_id)
+ self.pool.get('stock.location').check_access_rule(cr, uid, [location_id], 'read', context=context)
+ except (orm.except_orm, ValueError):
+ location_id = False
+
return location_id
def _default_destination_address(self, cr, uid, context=None):
for move in self.browse(cr, uid, ids, context=context):
if move.state == 'done':
if frozen_fields.intersection(vals):
- raise osv.except_osv(_('Operation forbidden !'),
+ raise osv.except_osv(_('Operation Forbidden!'),
_('Quantities, Units of Measure, Products and Locations cannot be modified on stock moves that have already been processed (except by the Administrator).'))
return super(stock_move, self).write(cr, uid, ids, vals, context=context)
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)
+ try:
+ source_location = mod_obj.get_object_reference(cr, uid, 'stock', location_source_id)
+ self.pool.get('stock.location').check_access_rule(cr, uid, [source_location[1]], 'read', context=context)
+ except (orm.except_orm, ValueError):
+ source_location = False
+ try:
+ dest_location = mod_obj.get_object_reference(cr, uid, 'stock', location_dest_id)
+ self.pool.get('stock.location').check_access_rule(cr, uid, [dest_location[1]], 'read', context=context)
+ except (orm.except_orm, ValueError):
+ 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 onchange_date(self, cr, uid, ids, date, date_expected, context=None):
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)
+ if ptype == 'internal':
+ new_pick_name = seq_obj.get(cr, uid,'stock.picking')
+ else :
+ 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 Sales Order
old_ptype = location_obj.picking_type_get(cr, uid, picking.move_lines[0].location_id, picking.move_lines[0].location_dest_id)
if move.picking_id:
pickings.add(move.picking_id.id)
if move.move_dest_id and move.move_dest_id.state == 'waiting':
- self.write(cr, uid, [move.move_dest_id.id], {'state': 'assigned'})
+ 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.trg_write(uid, 'stock.picking', move.move_dest_id.picking_id.id, cr)
self.write(cr, uid, ids, {'state': 'cancel', 'move_dest_id': False})
# or if it's the same as that of the secondary amount being posted.
account_obj = self.pool.get('account.account')
src_acct, dest_acct = account_obj.browse(cr, uid, [src_account_id, dest_account_id], context=context)
- src_main_currency_id = src_acct.currency_id and src_acct.currency_id.id or src_acct.company_id.currency_id.id
- dest_main_currency_id = dest_acct.currency_id and dest_acct.currency_id.id or dest_acct.company_id.currency_id.id
+ src_main_currency_id = src_acct.company_id.currency_id.id
+ dest_main_currency_id = dest_acct.company_id.currency_id.id
cur_obj = self.pool.get('res.currency')
if reference_currency_id != src_main_currency_id:
# fix credit line:
}
def _default_stock_location(self, cr, uid, context=None):
- stock_location = self.pool.get('ir.model.data').get_object(cr, uid, 'stock', 'stock_location_stock')
- return stock_location.id
+ try:
+ location_model, location_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'stock_location_stock')
+ self.pool.get('stock.location').check_access_rule(cr, uid, [location_id], 'read', context=context)
+ except (orm.except_orm, ValueError):
+ location_id = False
+ return location_id
_defaults = {
'location_id': _default_stock_location
}
def _default_lot_input_stock_id(self, cr, uid, context=None):
- lot_input_stock = self.pool.get('ir.model.data').get_object(cr, uid, 'stock', 'stock_location_stock')
- return lot_input_stock.id
+ try:
+ lot_input_stock_model, lot_input_stock_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'stock_location_stock')
+ self.pool.get('stock.location').check_access_rule(cr, uid, [lot_input_stock_id], 'read', context=context)
+ except (ValueError, orm.except_orm):
+ # the user does not have read access on the location or it does not exists
+ lot_input_stock_id = False
+ return lot_input_stock_id
def _default_lot_output_id(self, cr, uid, context=None):
- lot_output = self.pool.get('ir.model.data').get_object(cr, uid, 'stock', 'stock_location_output')
- return lot_output.id
+ try:
+ lot_output_model, lot_output_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'stock_location_output')
+ self.pool.get('stock.location').check_access_rule(cr, uid, [lot_output_id], 'read', context=context)
+ except (ValueError, orm.except_orm):
+ # the user does not have read access on the location or it does not exists
+ lot_output_id = False
+ return lot_output_id
_defaults = {
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.inventory', context=c),
# 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"""
+ return self.pool.get('stock.picking').message_post(*args, **kwargs)
+
+ def message_subscribe(self, *args, **kwargs):
+ """Send the subscribe action on stock.picking model as it uses _name in request"""
+ return self.pool.get('stock.picking').message_subscribe(*args, **kwargs)
+
+ def message_unsubscribe(self, *args, **kwargs):
+ """Send the unsubscribe action on stock.picking model to match with subscribe"""
+ return self.pool.get('stock.picking').message_unsubscribe(*args, **kwargs)
+
_columns = {
'backorder_id': fields.many2one('stock.picking.in', '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),
'state': fields.selection(
# 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"""
+ return self.pool.get('stock.picking').message_post(*args, **kwargs)
+
+ def message_subscribe(self, *args, **kwargs):
+ """Send the subscribe action on stock.picking model as it uses _name in request"""
+ return self.pool.get('stock.picking').message_subscribe(*args, **kwargs)
+
+ def message_unsubscribe(self, *args, **kwargs):
+ """Send the unsubscribe action on stock.picking model to match with subscribe"""
+ return self.pool.get('stock.picking').message_unsubscribe(*args, **kwargs)
+
_columns = {
'backorder_id': fields.many2one('stock.picking.out', '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),
'state': fields.selection(