Override many2one with many2many - odoo

I try to override many2one field with many2many
property_product_pricelist = fields.Many2many('product.pricelist',
string="Sale Pricelist",
help="This pricelist will be used, instead of the default one, for sales to the current partner")
and i get this error when try to save values
File "/home//workspace/odoo-9.0/openerp/models.py", line 5384, in _browse
env.prefetch[cls._name].update(ids)
TypeError: unhashable type: 'list'
also i tryid like this
property_product_pricelist = fields.Many2many('product.pricelist', column1='partner_id', column2='pricelist_id')
but get
ProgrammingError: column product_pricelist_res_partner_rel.pricelist_id does not exist
LINE 1: SELECT product_pricelist_res_partner_rel.pricelist_id, produ...

Best solution I came up with.
create a many2many field totally new
write an onchange method which sets the value of the original field (here the many2one) to the new many2many field
multiply_pricelists_ids = fields.Many2many(
'product.pricelist', string='Multiply Pricelists')
#api.onchange('property_product_pricelist')
#api.multi
def pricelist_change(self):
self.multiply_pricelists_ids = self.property_product_pricelist

Related

How can I find out the difference between when user changes fields and when field fills automatically from record on the table in onchange function?

I have a many2one field as A and one2many field as A_details that A_details has filter base on A,
A = fields.Many2one(comodel_name="headertable")
A_details = fields.One2many(comodel_name="detailtable")
and in the xml I pass the A value with context in A_detail to filter it
<field name="A_detail" context="{'parent_id': A,}"/>
now I want to delete A_detail's records when user changes the A value, so I use onchange decorator on A field like this:
#api.onchange('A')
def _delete_selected_records(self):
for rec in self.A_details:
self.A_details = [(3, rec.id, 0)]
this function workes correctly to create mode but the problem occurs when I open the record from tree view and while A field is getting value from model Onchanged decorator call the _delete_selected_records function and it delete all the A_detail's records, That's why I want to check in this function that if user change the A, delete the A_detail's records else if system sets value to field do nothing... how can I handle this???
You should add a check if A is deleted or not meaning if A is False then do X:
#api.onchange('A')
def _delete_selected_records(self):
for rec in self:
if rec.A is False:
rec.A_details = [(3, rec.id, 0)] # You can you .unlink() btw
else:
continue
This way even if the function is triggered by let's say a user accidentally putting cursor on the field in the view or something you won't risk deleting anything unless the correct condition is met.

Set one2many values through onchange in odoo 9

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

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 10 Traverse Many2many field

I have the following for loop where account_move_id is a Many2one field:
...
for line in payment.move_line_ids + expense_sheet.account_move_id.line_ids:
...
I have modified account_move_id making it a Many2many field. Hence when I run the code I get an "expected singleton" exception in the for loop line.
Given that now account_move_id is a Many2many field, how could I get all line_ids from all account_move_ids of expense_sheet?
Thanks,
I don't where is the problem exactly but when you get this error most likely you where trying to acces a field but in recordSet that contains more than one record.
When you use decorator api.multi self in the method can contains more than one record so to avoid this error always loop through self.
for rec in self:
# here rec will alawys contain just one record
rec.some_field
so this error can happen in one2many field basically check where did you acces a field or method in a recordSet
You can use mapped() to gather a certain field from all records in a recordset.
How could I get all line_ids from all account_move_id of expense_sheet?
# If account_move_id is a recordset, mapped will get line_ids for all of them
line_ids = expense_sheet.account_move_id.mapped('line_ids')

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 ;)