I'm trying to show a res.partner field, which is called phone into the treeview of a sale.order.
But it is not showing anything, just the name of the field without data. This is my code on sale.order
phone : fields.char('Telefono del Cliente'),
Onchange function for this field:
def onchange_phone(self, cr, uid, ids, phone, context=None):
res = {}
if phone:
obj = self.pool.get('res.partner')
browse(cr, uid, phone)
res['phone'] = obj.phone
return {'value' : res}
On res.partner the field is also called phone which is obviously the client's phone, i need to show it on the sale.order treeview, this is the code on my sale_view.xml:
<field name="phone" on_change="onchange_phone(phone)"/>
Any ideas?
Thanks in advance.
As a suggestion, If you want phone number of partner, than you should not create on_change of phone field. You can get phone number in 2 ways.
First way and best way, In sale.order, onchange_partner_id() method is their, you need to override that method and update vals with phone number of partner.
And Second way and long way, You may override create() method and write() method of sale.order.
create() method trick:
in create() method, you can take partner id from the context. For example vals.get('partner_id')
write() method trick:
in write() method, you have id of created record so you need to simply browse that record and write phone number of partner.
As Odedra suggested, you should do this like so (this is taken from sale.py file):
def onchange_partner_id(self, cr, uid, ids, part, context=None):
if not part:
return {'value': {'partner_invoice_id': False, 'partner_shipping_id': False, 'payment_term': False, 'fiscal_position': False}}
part = self.pool.get('res.partner').browse(cr, uid, part, context=context)
addr = self.pool.get('res.partner').address_get(cr, uid, [part.id], ['delivery', 'invoice', 'contact'])
pricelist = part.property_product_pricelist and part.property_product_pricelist.id or False
payment_term = part.property_payment_term and part.property_payment_term.id or False
fiscal_position = part.property_account_position and part.property_account_position.id or False
dedicated_salesman = part.user_id and part.user_id.id or uid
phone = part.phone or False
val = {
'partner_invoice_id': addr['invoice'],
'partner_shipping_id': addr['delivery'],
'payment_term': payment_term,
'fiscal_position': fiscal_position,
'user_id': dedicated_salesman,
'phone': phone,
}
if pricelist:
val['pricelist_id'] = pricelist
return {'value': val}
Note that you should not do that on base module, but instead create your own module and inherit it to sale.order model. What is more, onchange will not work on tree view (like you suggested), but you can easily show it on the tree - you have to first put it on your form with the onchange provided, then modify tree view to show phone number.
Related
In hr.holidays model for employee_id field onchange function is there but I removed that onchange function from 'employee_id' field.The main aim of that function is Auto filling of 'department_id' field of same model when the change of 'employee_id' field.
problem:
My requirement is the below code is existing in odoo v7 but i need in odoo v8.
I tried in different ways but I didn't get any result so please help me.
def onchange_employee(self, cr, uid, ids, employee_id):
result = {'value': {'department_id': False}}
if employee_id:
employee = self.pool.get('hr.employee').browse(cr, uid, employee_id)
result['value'] = {'department_id': employee.department_id.id}
return result
My odoo V8 code:
I am getting object of 'hr.employee' but I am unable to fill that object in 'department_id' field because of it is many2one field.Below is my code.
#api.onchange('employee_id')
#api.constrains('employee_id')
def joining_date(self):
if self.employee_id:
self.department_id =''
depart_obj = self.env['hr.employee'].search([('name', '=' , self.employee_id.name)])
if depart_obj:
for departments in depart_obj:
depart_new_obj = self.env['hr.employee'].browse([departments.id])
for tax in depart_new_obj.department_id:
self.department_id = [tax.id]
Why are you searching and browsing object if you have already object of self.employee_id
just set
self.department_id = self.employee_id.department_id.id
At finally I got the answer removing of [ ] .""self.department_id = tax.id""
I added 2 fields in 'sale.order.line' object. Let's say 'field1' and 'field2', those are readonly field. The value of the 2 fields will appear whenever the product is change in order line.
When I select a product, it shows the value of the two fields but when save it, the value will back 0, not stored.
Here's my code:
class sale_order_line(models.Model):
_inherit = 'sale.order.line'
field1 = fields.Float('One')
field2 = fields.Float('Two')
#api.multi
def product_id_change(self, pricelist, product, qty=0,
uom=False, qty_uos=0, uos=False, name='', partner_id=False,
lang=False, update_tax=True, date_order=False, packaging=False, fiscal_position=False, flag=False):
res = super(sale_order_line, self).product_id_change(pricelist, product, qty,
uom, qty_uos, uos, name, partner_id,
lang, update_tax, date_order, packaging, fiscal_position, flag)
if product:
one = self.search([('product_id', '=', product), ('partner_id', '=', partner_id)])
two = self.search([('product_id', '=', product), ('partner_id', '!=', partner_id)])
if customer:
field1 = one[-1]
res['value']['field1'] = field1
if other:
field2 = two[-1].
res['value']['field2'] = field2
return res
In Odoo framework we are now allowing to set readonly fields value, as well as readonly fields will not be getting in vals in create and write methods.
So if you set those readonly fields value in onchange methods then also it will not persist it's value because by nature it's readonly, it will not gives you any errors.
Purpose : The aims behind to define readonly attributes is to behave same through the all states of the record on UI and user can not change it's value and mainly define for display purpose.That is why readonly fields are not accessible for edit in onchange method.
Solution:
You need to override CREATE or WRITE method in following manner.
#api.model
def create(self, vals):
######
# WRITE YOUR LOGIC HERE AND BRING THOSE VALUE INTO VARIABLE AND THEN UPDATE IT IN VALS
VARIABLE_1 = SEARCH YOUR DATA
VARIABLE_2 = SEARCH YOUR DATA
vals.update({field1' : VARIABLE_1, 'field_2' : VARIABLE_2})
return super(sale_order_line, self).create(vals)
Update vals (record dictionary) by setting those readonly fields in to dictionary before calling super method or update those fields after calling super method.
There is an alternative solution for your problem. In Odoo Apps one module available from that system will store readonly value in the database.
Read Only ByPass
It is because readonly mode works only for display. In this case value from fields will not send to server-side.
You can override method create of sale.order.line. It should be something like this:
class sale_order_line(models.Model):
_inherit = 'sale.order.line'
#api.model
def create(self, vals):
# just example
vals[u'field1'] = 2.03
vals[u'field2'] = 3.05
return super(sale_order_line, self).create(vals)
Hope this helps you.
What is main difference between following :
self.pool['res.partner'].browse(cr, uid, partner_id, context=context)
and
self.pool.get('res.partner').browse(cr, uid, partner_id, context)
As per my understanding both returns single record of type res.partner if partner_id e.g. 1
Then why it is used like this.
if self.pool is a dictionary (I hope :) ) then self.pool['res.partner'] will raise an exception (KeyError) if the 'res.partner' is not present in that dictionary.
self.pool.get('res.partner') in the same case will return default value (which is None).
If you want to specify a different default value, you can do it like that: self.pool.get('res.partner',some_def_value).
I have a selection field in account.invoice.line named form_type. It has three selection options:
1) form_a
2) form_b
3) form_c
There is also an integer field named flag in account.invoice.line. When form_c is selected, the flag value should be set to 1; otherwise, if either form_a or form_b is selected, the flag value should be set to 0. I wrote an onchange function for the above case but it's not working. Can someone help me out? What is wrong in my code?
def onchange_form_type(self, cr, uid, ids, invoice, context=None):
val={}
flag=0
invoice = self.pool.get('account.invoice.line').browse(cr, uid, invoice)
for invoice in self.browse(cr, uid, ids, context=context):
if invoice.form_type=="form_c":
flag="1"
else:
flag="0"
print flag
val = { 'flag': flag, }
return {'value': val}
My XML code in account.invoice.line for onchange is:
<field name="form_type" on_change="onchange_form_type(form_type)"/>
In your on-change function you don't need to call the browse function of the object, because the values are not stored in the database yet. Also, you are passing the "form_type" value to the function and not the object id(as browse accepts object id).
So, below will be the on_change function, for the expected requirement:
def onchange_form_type(self, cr, uid, ids, form_type, context=None):
val={}
flag=0
if form_type == 'form_c':
flag="1"
val = { 'flag': flag }
return {'value': val}
I have a form view. I entered a value in a field. How can i retrieve that value and have it assigned to some variable in .py for making operations
For Example:
I have ActiveFrom field.I entered value 23-11-2011 to field in form view. I want to get that value dynamically in openerp. How can I do that?
I suspect you want the on_change event. It lets you trigger server-side code when the user changes a field's value. You can then change the value of other fields, or pop up a warning message.
Here's an example of how to pop up a warning from the warning module (slightly edited):
def onchange_partner_id(self, cr, uid, ids, part):
warning = {}
title = False
message = False
partner = self.pool.get('res.partner').browse(cr, uid, part)
if partner.sale_warn != 'no-message':
title = _("Warning for %s") % partner.name
message = partner.sale_warn_msg
warning = {
'title': title,
'message': message,
}
result = super(sale_order, self).onchange_partner_id(cr, uid, ids, part)
return {'value': result.get('value',{}), 'warning':warning}