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.
Related
I'm using odoo 8 and I want to remove the sum of the total in the group by. Here is my .py
class report_sales_weekly(osv.osv):
_name = "report.sales.weekly"
_description = "report sales weekly"
_columns = {
'div_target_monthly':fields.float('Div Target'),
'div_achievement':fields.float('Div Achievement'),
}
def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False):
if 'div_target_monthly' in fields:
fields.remove('div_target_monthly')
return super(report_sales_weekly, self).read_group(cr, uid, domain, fields, groupby, offset, limit=limit, context=context, orderby=orderby)
report_sales_weekly()
I found this script from https://www.odoo.com/forum/help-1/how-to-remove-sum-of-total-in-group-by-29666, but I get an error when I make grouping in the list page
TypeError: read_group() got an unexpected keyword argument 'lazy'
Any help please? Thank you
The answer in the link is for openerp-7
Odoo 8 defines an optional parameter lazy, you can find an example in account module on how to override the read_group function:
def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False, lazy=True):
# Your code
return super(account_entries_report, self).read_group(cr, uid, domain, fields, groupby, offset, limit, context, orderby, lazy)
You have two errors here: offset called without offset= and bad definition of the base read_group of Odoo 8.
Can you please try with this :
class report_sales_weekly(osv.osv):
_name = "report.sales.weekly"
_description = "report sales weekly"
_columns = {
'div_target_monthly':fields.float('Div Target'),
'div_achievement':fields.float('Div Achievement'),
}
def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False, lazy=False):
if 'div_target_monthly' in fields:
fields.remove('div_target_monthly')
return super(report_sales_weekly, self).read_group(cr, uid, domain, fields, groupby, offset=offset, limit=limit, context=context, orderby=orderby, lazy=lazy)
# As stated in the comments, you can also not put offset=offset etc. but just the variables offset, limit, ... Thanks #Kenly
# Also, why this line ?
# report_sales_weekly()
Keep me updated :)
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.
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.
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
Followup question from openerp override onchange behavior without affecting base
15244031
The following code does get fired but I get server error 500 when any of the related fields has a value.
When I look at the log, it says JSON serialization issue.
TypeError: browse_record(product.mycount, 1) is not JSON serializable
Please suggest a solution.
class purchase_order_line_custom(osv.osv):
_name = 'purchase.order.line'
_inherit = 'purchase.order.line'
def onchange_product_id(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order=False, fiscal_position_id=False, date_planned=False, name=False, price_unit=False, context=None):
values = super(purchase_order_line_custom, self).onchange_product_id(cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order, fiscal_position_id, date_planned,name, price_unit, context=context)
if product_id:
product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
values['value'].update({
'qualified_name':product.qualified_name,
'product_type' : product.product_type or None,
'product_subtype' : product.product_subtype,
'count_id':product.count_id or None
})
return values
_columns={
'product_type': fields.related('product_id','product_type',type='selection', string='Product Type', selection=[('X','X'),('Y','Y'),('Z','Z')]),
'product_subtype': fields.related('product_id','product_subtype',type='char', size=64, string='Sub-Type'),
'qualified_name': fields.related('product_id','qualified_name',type='char', size=64, string='Qualified Name'),
'count_id': fields.related('product_id','count_id',type='many2one',relation='product.mycount',string='Count')
}
purchase_order_line_custom()
in the line 'count_id':product.count_id or None, I think count_id is a many2one field in product.you are trying to pass object to the count_id field in product.order.line, you need to pass product.count_id.id to get the id.