Set one2many values through onchange in odoo 9 - odoo

How to set value for one2many field in odoo 9?
I've a one2many field login_details and its onchange function below:
#api.onchange('login_details')
def check_contact(self):
return {
'value':{'login_details': [(6,0, [])]}
}
But there is no effect on GUI? Help please

This may help you, and make sure that the field login_details is not readonly.
#api.onchange('login_details')
def check_contact(self):
# add your own code
res=[(0, 0, {'first_field': value1,
'second_field': value2,
})]
self.login_details = res

Odoo cut off the onchange values changes for o2m and m2m fields as you could see at:
https://github.com/odoo/odoo/blob/9.0/openerp/models.py#L6108-L6112
You could read there a comment saying that: At the moment, the client does not support updates on a *2many field. This statement is false
To get it working you will need to do something like I have proposed at:
https://www.odoo.com/forum/help-1/question/one2many-onchange-in-odoo-91362#answer-91400
Check and Try specifically the onchange redefined method to get it working

Related

Odoo ORM api onchange not working on many2many - odoo 13

Odoo ORM api onchange not working on many2many - odoo 13.
Trying to update sale_line's m2m field when product is changed in form view. It's not working.
#api.onchange("product_id")
def _fetch_mf_ids(self):
for rec in self:
rec.mf_ids = [
(6, 0, [x.id for x in rec.product_id.mf_ids])
]
Getting non-stored values for this m2m rec in sale_order_line when I print rec.mf_ids
product.mf.pgm(<NewId origin=5>, <NewId origin=7>)
Actually in onchange method you will generally get this issue of (<NewId origin=5>, <NewId origin=7>) so to get the values use
rec._origin.mf_ids
you will get the field values

How to get values in onchange with sudo()

I have added one onchange method, in that onchange method I have used sudo() while accessing many2one field.
But with sudo(), I am not able to get record's values with sudo.
So how can I get values of onchange record (<odoo.models.NewId object at 0x7fba62f7b3d8>) with sudo().
Here is sample code :
#api.onchange('product_id')
def onchange_product_id(self):
for record in self:
print(record.product_id)
print(record.sudo().product_id)
Actual result :
product.product(13,)
product.product()
Expected result :
product.product(13,)
product.product(13,)
That's because the recordset doesn't exist outside the current transaction. So your current user can see the contents but other users can't.
The code looks good to me, in fact, if you see path_to_v12/addons/hr_expense/models/hr_expense.py lines 563-567, you'll see a similar code:
#api.onchange('employee_id')
def _onchange_employee_id(self):
self.address_id = self.employee_id.sudo().address_home_id
self.department_id = self.employee_id.department_id
self.user_id = self.employee_id.expense_manager_id or
self.employee_id.parent_id.user_id

How to fill a field by date now from a click of a button

I want to fill a field by date now from a click of a button of the action
class sale_inheritd(models.Model):
_inherit = 'sale.order'
#api.multi
def action_sale_temporary(self):
for order in self:
self.env['project.project'].search([('project_id', '=', 'related_project_id')]).write({'temporary_reception_date':datetime.date.today()})
order.write({'state': 'temporary'})
What is the problem with this function?
I didn't understand the domain that you have passed to search method but if you want to fill a field with type Date:
.write({'temporary_reception_date':fields.Date.today()})
and for Datetime field:
.write({'temporary_reception_date':fields.Datetime.now()})
Note: and don't use self to access a field inside the loop exm: self.related_project_id use order.related_project_id instead or you most likely will have Singleton Error
EDITS: as #CZoellner said it's better to fields.Date.context_today(self) because that will prevent problems with user timezones
From your question it is not clear what are you trying to accomplish.
Your search method you search for project_id[looks like many2one field] equals to a string.
If it is many2one field then pass id to get correct result.
Also make sure self.env['project.project'].search([('project_id', '=', 'related_project_id')]) returns a single record only else it will lead to singleton error.
If there is only one record returned by search method then there is no issue in writing to the record like you did.

Odoo: get type of field by name

in odoo you can get value of field by it's str name:
exm:
name = getattr(self, 'name')
what i want now is to know the type of field name is it :
fields.Char, fields.Many2one, fields.Many2many .....
so what i need is something like this
gettype(self, 'user_id')
is there a way to now what is the type of field in odoo?
You can search from ir.model.fields model.
ir_model_obj=self.env['ir.model.fields']
ir_model_field=ir_model_obj.search([('model','=',model),('name','=',field)])
field_type=ir_model_field.ttype
if field_type=='many2one':
print "do operation"
This may help you.
Odoo provides this information in the _fields attribute, I think It's better because every thing happens In the Python side no need for contacting the database, especially In my case my model have more than 30 fields :
for name, field in self._fields.iteritems():
if not isinstance(field, (fields.Many2one, fields.Many2many, fields.One2many)):
# logic go here
If you you want to verify just one fields:
if not isinstance(self._fields[field_name], (fields.Many2one, ...)): # do something

How to update one2many in customers from accounting invoice

I have created an one2many to customer form. So, when I am validating (button validate) an invoice I am trying to pass some values in that one2many. I have tried many ways and followed odoo forums, but I am having trouble to do that. Using following code:
My one2many field is 'customer_status' in 'res.partner' :
#api.multi
#api.model
def invoice_validate(self):
customer_obj=self.env['res.partner']
customer_id=customer_obj.search([('id','=',self.partner_id.id)])
customer_line=customer_obj.browse(customer_id)
dd = {'policy_number': self.policy_no,}
customer_stat_add = customer_obj.write([customer_line.id],{
'customer_status': [(0, 0, dd)]
})
state_change = self.write({'state': 'open'})
return state_change, customer_stat_add
It gives me this error:
ValueError: "invoice_validate() takes exactly 2 arguments (1 given)" while evaluating
u'invoice_validate()'
Thanks.
buttons w/ new api need #api.multi and if you want to work on a single object you can use self.ensure_one();
#api.multi
def foo(self):
self.ensure_one()
print self.my_field
Also, you don't need to browse object as you already get browse objects w/ new api.
Bear in mind that if that feature is an odoo base feature you must call super().method_name to not break anything ;)