OpenERP - which field is getting the value from overridden name_get() function? - odoo

I hope this question makes sense. My goal is to display field as defined in name_get(). I have overridden name_get() function in mrp_bom class, code attached. However, I don't know which field will get return value from the function name_get(). Any insight is greatly appreciated!
class mrp_bom(osv.osv):
_inherit = 'mrp.bom'
_name = 'mrp.bom'
_columns = {
'x_nk_default_code': fields.related('product_id', 'default_code',
type='char', relation='product.product',
string='Part Number', store=True,
readonly=True),
'x_nk_class_desc': fields.related('product_id', 'categ_id', 'name',
type='char', string='Class Description',
store=True, readonly=True),
'x_nk_item_desc': fields.related('product_tmpl_id', 'name',
type='char', relation='product.template',
string='Item Description', store=True,
readonly=True),
'categ_id': fields.related('product_id', 'categ_id', type='integer',
relation='product.product', string='Categ_ID',
store=True, readonly=True),
'x_category_code': fields.related('product_id', 'categ_id',
'x_category_code', type='char', string='Class
Description', store=True, readonly=True),
}
def name_get(self, cr, user, ids, context=None):
if context is None:
context = {}
if isinstance(ids, (int, long)):
ids = [ids]
if not len(ids):
return []
def _name_get(d):
name = d.get('name','')
code = context.get('display_default_code', True) and
d.get('x_category_code',False) or False
if code:
name = '[%s] %s' % (code,name)
return (d['id'], name)
result = []
for product_category in self.browse(cr, user, ids, context=context):
mydict = {
'id': product_category.id,
'name': product_category.name,
'x_category_code':
product_category.x_category_code,
}
result.append(_name_get(mydict))
return result

The name_get method is used to display value of a record in a many2one field. For example, in a sale order line, if you select a product, the value displayed in the sale order line for the field 'product_id' must be the result of the 'name_get' on the product.product object.
There is no special field to display the result of name_get. If you need to put the result of name_get method in a field of a record, you should create with an attribute 'compute' : http://odoo-new-api-guide-line.readthedocs.org/en/latest/fields.html#computed-fields
You can find more information here : http://odoo-new-api-guide-line.readthedocs.org/en/latest/environment.html?highlight=name_get
I hope this help you.

Related

OpenERP - Field many2one, in inherited class, returning empty rows

I want to display many2one, x_categ_id, field in inherited mrp.bom class. I have defined it in _columns{..} but I am getting empty values, in the table mrp_bom, for that column, i.e. "x_categ_id". I must be missing something? Any insights are greatly appreciated.
class mrp_bom(osv.osv):
_inherit = 'mrp.bom'
_name = 'mrp.bom'
_columns = {
'x_categ_id': fields.many2one('product.category','Item Class',
required=True, change_default=True),
}
What do you actually want to display? If you want to display the contents of BOM, you can just do this:
'product_id': fields.related('bom_id', 'product_id', type="many2one",relation='product.product', readonly=True, string="Product"),
'cost_price': fields.related('product_id', 'standard_price',type="float",digits_compute=dp.get_precision('Product Price'), store=False, readonly=True, string="Cost Price"),
'margin': fields.float('Margin',digits_compute=dp.get_precision('Product Price'),required=True),
'quantity': fields.float('Quantity',digits_compute=dp.get_precision('Product Unit of Measu re'),readonly=True),
'bom_id': fields.many2one('mrp.bom', 'Bom', readonly=True)

Copy one2many field SNAFU

I need to show record from notebook project on notebook sheet , but the showed record is not according to project
My py :
class notebook_project(osv.osv):
_name = "notebook.project"
_description = "Notebook Project ID"
def onchange_project(self, cr, uid, ids, project, arg, context=None):
if project :
proj = self.pool.get('project.project').browse(cr, uid, project, context=context)
return {'value': {'name': proj.name}}
return {}
_columns = {
'name' : fields.char('Name', size=64),
'project' : fields.many2one('project.project', 'Project'),
'notebook_project_lines' : fields.one2many('notebook.project', 'notebook_project_id', 'Members Lines'),
'notebook_project_id': fields.many2one('notebook.project', 'Parent Project', ondelete='cascade', select=True),
'member' : fields.many2one('hr.employee', 'Members'),
}
notebook_project()
class notebook_sheet(osv.osv):
_name = "notebook.sheet"
_description = "Notebook Project Sheet"
def onchange_notebook_project(self, cr, uid, ids, notebook_project, context=None):
res = {}
employee_lines = []
if not notebook_project : return {}
if notebook_project :
notebook_project_obj = self.pool.get('notebook.project').browse(cr, uid, notebook_project)
for p in notebook_project_obj.notebook_project_lines:
employee_lines.append((0,0,{'notebook_sheet_lines':p.id
}))#this dict contain keys which are fields of one2many field
res['notebook_sheet_lines']=employee_lines
return res
def onchange_project(self, cr, uid, ids, project, context=None):
if project :
proj = self.pool.get('project.project').browse(cr, uid, project, context=context)
return {'value': {'name': proj.name}}
return {}
#def create(self, cr, user, vals, context={}):
#first model
# notebook_project_obj = self.pool.get('notebook.project')
#browse and get o2m fields, according to your selected project(id)
# notebook_project_lines = notebook_project_obj.browse(cr, user, ['notebook_project_id'])[0].lines
#copy first o2m model to second o2m model
# for line in notebook_project_lines :
# vals['notebook_sheet_lines'].append([0, False, {'notebook_project_lines':line.employee_id.id,}])
# return super(notebook_sheet, self).create(cr, user, vals, context)
_columns = {
'name' : fields.char('Name', size=64),
'notebook_sheet_lines' : fields.many2many('notebook.project', 'notebook_project_sheet_rel', 'notebook_project', 'notebook_project_id'),
'notebook_project': fields.many2one('notebook.project', 'Project ID',domain=[('notebook_project_id','=',False)]),
'project' : fields.many2one('project.project', 'Project'),
'member' : fields.many2one('hr.employee', 'Members'),
}
notebook_sheet()
Edited my answer , Mr. AnomA . Still not sure about many2many , please kindly check it
Do i need to change the onhange event as well ? thanks again in advance
First of all please create a link between notebook.sheet and notebook.project. Now there is no link between these 2 models. Add a many2one relation to notebook.sheet in notebook.project and then change the relation id in notebook_sheets_lines to this field.
Otherwise change the relation type of notebook_sheet_lines to many2many.
Then change the onchange_notebok_project() which will return {'value':{'notebook_sheet_lines':LIST_OF_EMPOYEEIDS}}
Also No need to add many2many in motebook_project.

Openerp - AttributeError in function of stock.picking.in

Really struggling with this one:
I have inherited from stock.picking.in and have added a few columns. I then added a function field.
In the function that the function field refers to, it works if I do not use any attribute from the stock.picking.in object. The moment I use any value from the object, it starts giving 'AttributeError: ' and some attribute at random. It doesn't specify any other reasons or causes.
Code:
class stock_picking_custom(osv.osv):
_name = 'stock.picking.in'
_inherit = 'stock.picking.in'
_table = "stock_picking"
def calc_royalty(self, cr, uid, ids, field_name, arg, context=None):
if not ids: return {}
res = {}
for line in self.browse(cr, uid, ids, context=context):
res[line.id] = 0 #line.royalty_rate * line.loading_netweight
return res
_columns = {
'loading_netweight': fields.float('Net weight at loading', digits=(16,2), help="Net weight at loading (interior weight)"),
'royalty_date': fields.date('Royalty Issue date'),
'royalty_number' : fields.char('Royalty Number', size=64),
'royalty_rate' : fields.float('Royalty Rate (p. ton)', digits=(16,2)),
'royalty_amount' : fields.function(calc_royalty, type='float', digits=(16,2), string='Royalty Amount', store=True, select=True)
}
stock_picking_custom()
I have commented out the line that I want to use. The moment I put this line back in the code, it would give attribute error on royalty_date (for example) which is not even mentioned in the function.
Please guide.
EDIT: I tried the exact same code with purchase.order and it works perfectly. What is different about stock.picking.in?
Thanks
Ok, found the answer in stock module in delivery addon. So this is a framework limitation issue related to inheritance order etc.
Sharing here in case someone ends up in a similar situation.
To solve, I repeated the same fields in stock.picking and stock.picking.in. Then I called the calc function of the picking class from the picking.in class.
Code:
class stock_picking_custom(osv.osv):
_name = 'stock.picking'
_inherit = 'stock.picking'
def calc_royalty(self, cr, uid, ids, field_name, arg, context=None):
if not ids: return {}
res = {}
for line in self.browse(cr, uid, ids, context=context):
res[line.id] = line.royalty_rate * line.loading_netweight
return res
_columns = {
'loading_netweight': fields.float('Net weight at loading', digits=(16,2), help="Net weight at loading (interior weight)"),
'royalty_date': fields.date('Royalty Issue date'),
'royalty_number' : fields.char('Royalty Number', size=64),
'royalty_rate' : fields.float('Royalty Rate (p. ton)', digits=(16,2)),
'royalty_amount' : fields.function(calc_royalty, type='float', digits=(16,2), string='Royalty Amount', store=True, select=True)
}
stock_picking_custom()
class stock_picking_in_custom(osv.osv):
_name = 'stock.picking.in'
_inherit = 'stock.picking.in'
_table = "stock_picking"
def calc_royalty(self, cr, uid, ids, field_name, arg, context=None):
return self.pool.get('stock.picking').calc_royalty(cr,uid,ids,field_name,arg,context=context)
_columns = {
'loading_netweight': fields.float('Net weight at loading', digits=(16,2), help="Net weight at loading (interior weight)"),
'royalty_date': fields.date('Royalty Issue date'),
'royalty_number' : fields.char('Royalty Number', size=64),
'royalty_rate' : fields.float('Royalty Rate (p. ton)', digits=(16,2)),
'royalty_amount' : fields.function(calc_royalty, type='float', digits=(16,2), string='Royalty Amount', store=True, select=True)
}
stock_picking_in_custom()
I did not get much time to spend on it but I came to know that line is coming with stock.picking.in object and fields, you defined, are stored in stock_picking table that's why it may going to search that field with stock.picking.in, not getting and error is coming.
There may be issue with fields defined in object and table, but not sure.

One module field use to other module in openerp

I created a field name "link to opportunities" :-
module :- hr.applicant
field type:- many2many
object relation:- crm.lead
and i used in crm.lead module .
Now i want to use this field in "hr.recruitment" .
but i have tried many ways but not success. please tell me. how can use this field in other module like as crm.lead to hr.recruitment
thank you for your timing.
this code i used:-
'sale_o_ids' : fields.related('job_id', 'x_link_to_jobposition',
readonly=True,
relation='crm.lead',
string='Opportunity Name'),
Here is the example:
of many2many
class hr_job(osv.osv):
_inherit = 'hr.job'
_columns = {
'sale_ids': fields.many2many('sale.order', 'hr_job_sale_order_rel', 'job_id', 'sale_id', 'Sale order'),
}
hr_job()
Here created a many2many field of sale.order
Now i want to used the hr.job field in hr.employee.
class hr_employee(osv.osv):
_inherit = "hr.employee"
def _get_sale_order(self, cr, uid, ids, field_name, arg, context=None):
if context is None:
context = {}
result = {}
list_o = []
for order in self.browse(cr, uid, ids, context=context):
for i in order.job_id.sale_ids:
list_o.append(i.id)
result[order.id] = list_o
return result
_columns = {
'sale_order_ids': fields.function(_get_sale_order, type='many2many', relation="sale.order", string="Sale Orders"),
}
hr_employee()
So when you update in the hr.job many2many field then its updated value show in hr.employee object when in job select this job
Another method you can use related
'sale_o_ids' : fields.related('job_id', 'sale_ids',
type='many2many',
readonly=True,
relation='sale.order',
string='Available Sale Order'),
Hope this thing clear to you

Openerp Comparing another object field value with an object field

I have this:
class events_places(osv.osv):
"""Places for events"""
_name = 'oevents.places'
_columns = {
'name': fields.char('Name',size=35, help='Place\'s name', required = True),
'description': fields.char('Description',size=50, help='Place\'s description'),
'street': fields.char('Street',size=35, help='Place\'s street', required = True),
'number': fields.integer('Local number', help='Place\'s local number', required = True),
'zip': fields.char('Zip Code', size=5, help='Place\'s Zip code', required = True),
'city': fields.char('City',size=20, help='Place\'s city', required = True),
'country': fields.many2one('res.country', 'Country', help='Place\'s country'),
'state': fields.many2one('res.country.state','State', help='Place\'s state'),
'inWinter': fields.boolean('Active in winter', store = True, help='Place\'s province'),
}
_defaults = {
'inWinter' : True,
}
class events_events(osv.osv):
"""Client's contacts"""
_name = 'oevents.events'
_columns = {
'name': fields.char('Name',size=20, help='Event\'s name', required = True),
'place': fields.many2one('oevents.places','Place', help='Event\'s location', required = True),
'artist': fields.many2one('oevents.artists','Artist', help='Artist\'s performing in the event.', required = True),
'client': fields.many2one('res.partner','Client', help='Event\'s clients.', required = True),
'date': fields.date('Date', help='Event\'s date.', required = True),
'type': fields.selection([('children','Children\'s'),('private','Private'),('concert','Concert')],'Event type', help='Type of event this artist can do'),
}
_defaults = {
'type' : 'private'
}
When I want to create an event, there's a place related field. The event has a date, but it shouldn't let me create the event in a a winter date if the related place field in the event has the field inWinter unchecked.
How can I do that? I need to create a function or constraint which gets place inWinter field and compare it with the date, but I don't know how to do it. Any suggestions?
Thanks in advance!
You can override create & write method. In those methods just check whether "inWinter" is True or False.
def create() method will be called when new record will be created.
def create(self, cr, uid, vals, context=None):
if vals.get('place'):
event_brw = self.pool.get('oevents.places').browse(cr, uid, vals.get('place'), context=context)
#if inWinter is True
if event_brw.inWinter:
raise osv.except_osv('Error ! ', 'You can not create an event in winter.')
return super(oevents_events, self).create(cr, uid, vals, context)
def write() method will be called when record will be modified.
def write(self, cr, uid, ids, vals, context=None):
if vals.get('place'):
event_brw = self.pool.get('oevents.places').browse(cr, uid, vals.get('place'), context=context)
#if inWinter is True
if event_brw.inWinter:
raise osv.except_osv('Error ! ', 'You can not create an event in winter.')
return super(oevents_events, self).write(cr, uid, ids, vals, context)
you have to write an on_change function on 'date' field, where you raise an error if given date is in winter months and isWinter is false.
Of course, yo have to define range date for iswinter an put on_change in field definition in your xml view.
you should use constraints. grep addons folder for _constraints and _sql_contraints and you'll find a lot of examples.
Go for _constraints= , Is not at all good idea to call create and write.