Hi, I am working on a module and it requires to update the product stock on clicking a button which calls a function for making picking from the form. I want to know a simple code for updating the stock table directly from the user input values.
Here's the code:
from osv import osv, fields
import time
from datetime import datetime
import pooler
import decimal_precision as dp
class mass_return(osv.osv):
_name = 'mass.return'
_description = 'Mass Return of products'
_inherit = 'product.template'
def _line_total_amount(self, cr, uid, ids, field_name, arg,context):
res={}
for line in self.browse(cr,uid,ids):
res[line.id] = line.unit_sale_price*line.product_uom_qty
return res
def address_get(self, cr, uid, ids):
address_obj = self.pool.get('res.partner.address')
address_ids = address_obj.search(cr, uid, [('partner_id', 'in', ids)])
res = list((addr['id']) for addr in address_ids)
adr = dict(res)
# get the id of the (first) default address if there is one,
# otherwise get the id of the first address in the list
if res:
default_address = adr.get('default', res[0][1])
else:
default_address = False
result = {}
return result
def onchange_partner_id(self, cr, uid, ids, part):
if not part:
return {'value': {'partner_address':False}}
addr = self.pool.get('res.partner').address_get(cr, uid, [part], ['contact'])
part = self.pool.get('res.partner').browse(cr, uid, part)
pricelist = part.property_product_pricelist and part.property_product_pricelist.id or False
val = {
'partner_address': addr['contact'],
}
if pricelist:
val['pricelist_id'] = pricelist
return {'value': val}
def onchange_pricelist_id(self, cr, uid, ids, pricelist_id, return_lines, context={}):
if (not pricelist_id) or (not return_lines):
return {}
warning = {
'title': _('Pricelist Warning!'),
'message' : _('If you change the pricelist of this order (and eventually the currency), prices of existing order lines will not be updated.')
}
return {'warning': warning}
## def _product_lst_price(self, cr, uid, ids):
## res = {}
## product_uom_obj = self.pool.get('product.uom')
## for id in ids:
## res.setdefault(id, 0.0)
## for product in self.browse(cr, uid, ids, context=context):
## if 'uom' in context:
## uom = product.uos_id or product.uom_id
## res[product.id] = product_uom_obj._compute_price(cr, uid,
## uom.id, product.list_price, context['uom'])
## else:
## res[product.id] = product.list_price
## res[product.id] = (res[product.id] or 0.0) * (product.price_margin or 1.0) + product.price_extra
## return res
def _compute_price(self, cr, uid, from_uom_id, price, to_uom_id=False):
if not from_uom_id or not price or not to_uom_id:
return price
uoms = self.browse(cr, uid, [from_uom_id, to_uom_id])
if uoms[0].id == from_uom_id:
from_unit, to_unit = uoms[0], uoms[-1]
else:
from_unit, to_unit = uoms[-1], uoms[0]
if from_unit.category_id.id <> to_unit.category_id.id:
return price
amount = price * from_unit.factor
if to_uom_id:
amount = amount / to_unit.factor
return amount
def price_get(self, cr, uid, ids,product_id,context=None):
if context is None:
context = {}
pricetype_obj = self.pool.get('product.price.type')
price_type_id = pricetype_obj.search(cr, uid, [('field','=',ptype)])[0]
res = {}
product_uom_obj = self.pool.get('product.uom')
for product in self.browse(cr, uid, ids, context=context):
res[product.id] = product[ptype] or 0.0
if ptype == 'list_price':
res[product.id] = (res[product.id] * (product.price_margin or 1.0)) + \
product.price_extra
if 'uom' in context:
uom = product.uom_id or product.uos_id
res[product.id] = product_uom_obj._compute_price(cr, uid,
uom.id, res[product.id], context['uom'])
# Convert from price_type currency to asked one
if 'currency_id' in context:
# Take the price_type currency from the product field
# This is right cause a field cannot be in more than one currency
res[product.id] = self.pool.get('res.currency').compute(cr, uid, price_type_currency_id,
context['currency_id'], res[product.id],context=context)
return res
def _get_returns(self, cr, uid, ids, context=None):
result = {}
for line in self.pool.get('mass.return.line').browse(cr, uid, ids, context=context):
result[line.return_id.id] = True
return result.keys()
def product_id_change(self,cr,uid,ids,prod):
if not prod:
return{'value':{'unit_sale_price':False,'product_uom':False}}
price_unit=self.pool.get('product.product').price_get(cr,uid,[prod],['list_price'])
prod=self.pool.get('product.product').browse(cr,uid,prod)
product_uom_=self.pool.get('product.product').browse(cr,uid,prod)
val = {
'unit_sale_price':price_unit['list_price'],
'product_uom':product_uom_['name']
}
return {'value':val}
def _get_uom_id(self, cr, uid, *args):
try:
proxy = self.pool.get('ir.model.data')
result = proxy.get_object_reference(cr, uid, 'product', 'product_uom_unit')
return result[1]
except Exception, ex:
return False
## def product_id_change(self, cr, uid, ids, pricelist, product, qty=0,uom=False, partner_id=False,flag=False, context=None):
## context = context or {}
## if not partner_id:
## raise osv.except_osv(_('No Customer Defined !'), _('You have to select a customer in the form !\nPlease set one customer before choosing a product.'))
## warning={}
## product_uom_obj = self.pool.get('product.uom')
## partner_obj = self.pool.get('res.partner')
## product_obj = self.pool.get('product.product')
## context_partner={'partner_id':partner_id}
## if not product:
## return {'domain':{'product_uom': []}}
## uom2 = False
## if uom:
## uom2 = product_uom_obj.browse(cr, uid, uom)
## if product_obj.uom_id.category_id.id != uom2.category_id.id:
## uom = False
## if not flag:
## result['name'] = self.pool.get('product.product').name_get(cr, uid, [product_obj.id], context=context_partner_id)[0][1]
## domain = {}
## if not pricelist:
## warn_msg = _('You have to select a pricelist or a customer in the sales form !\n'
## 'Please set one before choosing a product.')
## warning_msgs += _("No Pricelist ! : ") + warn_msg +"\n\n"
## else:
## price = self.pool.get('product.pricelist').price_get(cr, uid, [pricelist],
## product, qty or 1.0, partner_id, {
## 'uom': uom or result.get('product_uom'),
## 'date': date_order,
## })[pricelist]
## if price is False:
## warn_msg = _("Couldn't find a pricelist line matching this product and quantity.\n"
## "You have to change either the product, the quantity or the pricelist.")
##
## warning_msgs += _("No valid pricelist line found ! :") + warn_msg +"\n\n"
## else:
## result.update({'price_unit': price})
## if warning_msgs:
## warning = {
## 'title': _('Configuration Error !'),
## 'message' : warning_msgs
## }
## return {'value': result, 'domain': domain, 'warning': warning}
_columns ={
## 'return_id':fields.integer('Return ID', readonly=True),
'name':fields.char('Reason', size=128),
'description': fields.text('Description'),
'number': fields.char('Number', size=128, help="Company internal claim unique number"),
'partner_id':fields.many2one('res.partner', 'Partner'),
'partner_address': fields.many2one('res.partner.address', 'Partner Contact', \
domain="[('partner_id','=',partner_id)]"
),
'partner_phone': fields.char('Phone', size=64),
'origin': fields.selection([('none','Not specified'),
('legal','Legal retractation'),
('cancellation','Order cancellation'),
('damaged','Damaged delivered product'),
('error','Shipping error'),
('exchange','Exchange request'),
('lost','Lost during transport'),
('other','Other')], 'Return Subject', help="To describe the line product problem"),
'active': fields.boolean('Active'),
'cause': fields.text('Root Cause'),
'return_date':fields.datetime('Date'),
'prodlot_id': fields.many2one('stock.production.lot', 'Lot',help="The serial/lot of the returned product"),
'company_id': fields.many2one('res.company', 'Company'),
'product_id':fields.many2one('product.product', 'Product',help="Returned product"),
'product_uom_qty': fields.float('Quantity (UoM)', digits_compute= dp.get_precision('Product UoS')),
'product_uom': fields.many2one('product.uom', 'Unit of Measure '),
'pricelist_id': fields.many2one('product.pricelist', 'Pricelist',help="Pricelist for current sales order."),
'unit_sale_price' :fields.float('Unit Price', digits_compute= dp.get_precision('Sale Price'),help="Unit sale price of the product."),
'subtotal':fields.function(_line_total_amount, string='Subtotal', type="float",digits_compute= dp.get_precision('Account'), store=True),
'return_location' : fields.many2one('stock.location', 'Dest. Location',help="Location where the system will stock the returned products.", select=True),
'invoice_line_id': fields.many2one('account.invoice.line', 'Invoice Line', help='The invoice line related to the returned product'),
}
_defaults={
'number': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'mass.return'),
}
def cancel(self, cr, uid, ids, context=None):
if context is None:
context = {}
data = context and context.get('active_ids', []) or []
return self.pool.get('mass.return').mass_return_cancel(cr, uid, data, context)
def button_compute(self, cr, uid, ids, context=None, set_total=False):
for line in self.browse(cr, uid, ids, context=context):
if set_total:
self.pool.get('mass.return').write(cr, uid, [line.id], {'subtotal': line.subtotal})
return True
def button_confirm(self, cr, uid, ids, context=None):
return self.write(cr, uid, ids, {'state': 'confirmed'})
##class make_picking(osv.osv):
##
## _name= 'make.picking'
## _columns={
## 'return_location' : fields.many2one('stock.location', 'Source Location',help="Location where the returned products are sent.", required=True),
## 'return_ids' : fields.many2many('mass.return', 'return_picking', 'return_picking_id', 'Return lines'),
## }
def action_make_picking(self,cr,uid,ids,context=None):
print "context", context
partner_id = 0
for picking in self.browse(cr, uid,ids):
return_id = self.pool.get('mass.return').browse(cr, uid, context['active_id'])
partner_id = return_id.partner_id.id
# location type
location = -1
if return_id.return_type == "customer":
location = return_id.partner_id.property_stock_customer.id
else:
location = return_id.partner_id.property_stock_supplier.id
# create picking
picking_id = self.pool.get('stock.picking').create(cr, uid, {
'origin': return_id.id,
'type': 'in',
'move_type': 'one', # direct
'date': time.strftime('%Y-%m-%d %H:%M:%S'),
'address_id': return_id.partner_address_id.id,
'location_dest_id': picking.return_location.id,
'return_id': return_id.id,
})
# Create picking lines
for picking_line in picking.return_id:
move_id = self.pool.get('stock.move').create(cr, uid, {
'name' : picking_line.product_id.name_template, # Motif : crm id ? stock_picking_id ?
'priority': '0',
#'create_date':
'date': time.strftime('%Y-%m-%d %H:%M:%S'),
'product_id': picking_line.product_id.id,
'quantity': picking_line.product_uom_qty,
'product_uom': picking_line.product_id.uom_id.id,
'address_id': return_id.partner_address_id.id,
# 'price_currency_id': return_id.company_id.currency_id.id, # from invoice ???
'location_dest_id': picking.return_location.id,
})
return {
'name': 'Customer Picking IN',
'view_type': 'form',
'view_mode': 'tree,form',
'view_xml_id': 'mass_return_picking_in_form',
'view_name' :'mass_return_picking_in_form',
'domain' : "[('type', '=', 'in'),('partner_id','=',%s)]"%partner_id,
'res_model': 'stock.picking',
'type': 'ir.actions.act_window',
}
def button_return(self, cr, uid, ids, context=None):
if context is None:
context = {}
data = context and context.get('active_ids', []) or []
return self.pool.get('mass.return').action_make_picking(cr, uid, data, context)
def _get_dest_loc(self, cr, uid,context):
return self.pool.get('stock.warehouse').read(cr, uid, [1],['lot_input_id'])[0]['lot_input_id'][0]
_defaults = {
'return_location' : _get_dest_loc,
}
# If "Cancel" button pressed
def action_cancel(self,cr,uid,ids,conect=None):
return {'type': 'ir.actions.act_window_close',}
mass_return()
XML:
Mass Return Tree mass.return tree Mass Return Form mass.return form Mass Returns mass.return Cancel Return mass.return form form new
↧