How to update a field in Model B using onchange in the field of model A ? Odoo 12 - odoo

What i'm trying to achieve is ,When updating a field in model A ,i needs to update a field in model B using onchange method
_name = 'Model_A'
health_profile = fields.Many2one('health.profile', domain="[('partner_id', '=', partner_id)]", string="Health Profile")
#api.onchange('health_profile')
def get_health_profile_specialist(self):
ctx = self.health_profile.id
res = self.env['model_B'].browse(ctx)
return res.update({'specialist_name': self.specialist_name})

From what I understand there is no need to modify the field with an onchange. You can directly check the value in the model A field, you could directly use a related field
health_profile = fields.Many2one('health.profile', domain="[('partner_id', '=', partner_id)]", string="Health Profile")
specialist_id = fields.Many2one('<yourmodel>', related='health_profile.specialist_id')
Maybe you should explain yourself better.

Related

odoo 8 Count attachment and show in list view

I have odoo 8. I want to count the attachment from ir_attachment and and show it in stock.production.lot. Here is my .py
class stock_production_lot(models.Model):
_inherit='stock.production.lot'
#api.multi
def get_attachment_info(self):
for lot in self:
so_line_ids = self.env['ir.attachment'].search([('res_id','=',lot.id)])
for pick in so_line_ids:
pick.count_attachment = 0
if pick.datas_fname:
pick.count_attachment = len(pick.datas_fname)
count_attachment = fields.Float(string='Total Attachment', compute='get_attachment_info')
and this the view
<field name="count_attachment" />
Thanks
It's difficult to answer, because the information in your question are a bit poor. But let me try to answer it in a general way with a general example how i would do it.
Let's say you want a count of all attachments of model stock.picking (Delivery Nots, Slips, Receipts, and so on).
So you need to add a computed field, which could be stored, but it's difficult to trigger a recalculation of this field, because attachments are related to records indirectly (no real foreign keys used in database).
class StockPicking(models.Model):
_inherit = 'stock.picking'
attachment_count = fields.Integer(compute="_compute_attachment_count")
#api.multi
def _compute_attachment_count(self):
for picking in self:
domain = [('res_id', '=', picking.id),
('res_model', '=', self._name)]
picking.attachment_count = self.search_count(domain)
And also add the new field to a view of model stock.picking.
Now let's pretend that you don't only want the attachments of the pickings but also of their move lines, too.
Just "count" them and add that count to the previous one:
#api.multi
def _compute_attachment_count(self):
for picking in self:
domain = [('res_id', '=', picking.id),
('res_model', '=', self._name)]
picking_count = self.search_count(domain)
if picking.move_lines:
domain_move = [('res_id', 'in', picking.move_lines.ids),
('res_model', '=', picking.move_lines._name)]
picking_count += picking.move_lines.search_count(domain_move)
picking.attachment_count = picking_count
Thank you for the respone. I have got the answer
#api.one
def count_attachments(self):
obj_attachment = self.env['ir.attachment']
for record in self:
record.count_attachment = 0
attachment_ids = obj_attachment.search([('res_model','=',self._name),('res_id','=',record.id)])
if attachment_ids:
record.count_attachment = len(attachment_ids)

How to create a record for field using many2one in Odoo 13?

I have 3 models. I used One2many field o put the tree view of model 3 in form view of model 1 and 2.
1/ bao_hiem.py with one2many field:
lstd_baohiem = fields.One2many('lich.su', 'name')
thamchieu = fields.Char('Tham chiếu')
2/ dieu_chinh.py with one2many field:
lstd_dieuchinh = fields.One2many('lich.su', 'name')
thamchieu = fields.Char('Tham chiếu')
And 3/ lich_su.py with many2one field:
name = fields.Many2one('bao.hiem')
name_id = fields.Many2one('bao.hiem')
thamchieu = fields.Char('Tham chiếu')
I want to pass the values (eg: 'name', 'thamchieu') from dieu_chinh.py to lich_su.py and auto record with all those values via a button. So that, in the user's form view of model 1 and 2 can show the recorded value also, called the activity history of 1 user.
The code for the button like this:
def chapthuan(self):
giatri_lstd = self.env['lich.su']
gt = {
'name' : self.name.id,
'thamchieu' : self.thamchieu,
'thoigian' : self.thoigian
}
list_lstd_dieuchinh=[]
for line in self.lstd_dieuchinh :
art = {}
art['name'] = line.name.id
art['lstd_dieuchinh'] = line.lstd_dieuchinh
art['thamchieu'] = line.thamchieu
art['thoigian'] = line.thoigian
list_lstd_dieuchinh.append((0, 0, art))
gt.update({ # add the list of command to gt
'thamchieu': list_lstd_dieuchinh
})
giatri_lstd = giatri_lstd.create(gt)
return True
After click the button 'chapthuan', it can pass the value and create the record with the field 'name', 'date'. But with the field: 'thamchieu' which has relation many2one with model2 is still not worked.
I must select manually in the form view of the user.
So how to create a record with many2one field?
Please help!
Thank you
https://www.odoo.com/documentation/13.0/reference/orm.html#create-update
You are trying to create records by (0, 0, {values}) to name_id by the way of x2many field.
But name_id is Many2one field. That's your programming error.
But the error log you showed happened when you are trying to remove a record that already links to another record. So what I said above is not the main problem... Anyway, I'm a little confused with your code, it looks not so good

Is it possible to change the value of a selection field dynamically in Odoo 10?

I would like to have my selections depend on the value of a Char field, for instance, a Char field defined as such:
my_char = fields.Char("Enter Something", readonly = False)
so I suppose the selection field should call a function, something like "_get_value"
my_selection = fields.Selection(selection = ' _get_value')
#api.model
def _get_value(self):
my_list = [('key1','value1')]
#no idea how to assign the value of my_char to value1
return my_list
Eventually, I would like to have the selections in the drop down list vary as the user input different strings in my_char.
Is this achievable in Odoo? Because if it's not, I should better start reorganizing my structure. Thanks a lot.
As far is i know, it isn't possible with field type Selection. But you can use a Many2one field for such a behaviour.
class MySelectionModel(model.Models):
_name = "my.selection.model"
name = fields.Char()
class MyModel(models.Model):
_name = "my.model"
my_char = fields.Char()
my_selection_id = fields.Many2one(
comodel_name="my.selection.model", string="My Selection")
#api.onchange("my_char")
def onchange_my_char(self):
return {'domain': {'my_selection_id': [('name', 'ilike', self.my_char)]}}
Or without a onchange method:
my_selection_id = fields.Many2one(
comodel_name="my.selection.model", string="My Selection",
domain="[('name', 'ilike', my_char)]")
To let the Many2one field look like a selection, add the widget="selection" on that field in the form view.
How the domain should look like, should be decided by you. Here it is just an example.
No need to write method here. Just declare the dictionary to a variable and call it in selection field.
VAR_LIST = [('a','ABC'),
('p','PQR'),
('x','XYZ')]
my_selection = fields.Selection(string="Field Name",VAR_LIST)

how get id with onchange for filtering

how can i retrieve the value of a many2one field or its ID from another model
for exemple:
class Contrat(models.Model):
_name = 'facturation.contrat'
contrat_parent_id = fields.Many2one('facturation.contrat', string='Numéro Contrat Client',
domain=[('is_prestataire', '=', False)])
class Lot(models.Model):
contrat_id = fields.Many2one('facturation.contrat', ondelete='cascade')
articlecontrat_ids = fields.Many2many('facturation.articleouvrage',string='Article Lot')
91/5000
i want that when i change contrat_parent_id i get it back to use it and filter my articles for field 'articlecontrat_ids'
here you need to use onchange event i'm assuming that facturation.articleouvrage have a m2o field named contrat_id
# in onchange event always put the name of the field that trigger the event
#api.onchange('contrat_parent_id ')
def onchange_contrat(self):
"""update the domain when we change the contrat"""
if self.contrat_parent_id :
# always check if the field is not empty
# return the domain like this but i don't know what you need exactly
return {'domain': {'articlecontrat_ids ' : [('contrat_id ', '=', self.contrat_parent_id.contract.id)]}}
else: # remove the domain
return {'domain': {'articlecontrat_ids ' : []}}
if you want to remove all records when user change the contrat_id but i think you make the user ungry
to reselect all this records.
self.articlecontrat_ids = [(5, 0, 0)]

Copy last value in new tree view row odoo 9

When click on Add an Item in tree view, I want in new row copy value from last inserted row.
Eg. if field name = 'Text' in new row I need in field name string 'Text'
Any simple solution?
If you want to load default value from a database then follow this method.
You can achieve it by overriding default_get method and in that, you need to write your logic.
#api.model
def default_get(self,fields):
res = super(class_name, self).default_get(fields)
last_rec = self.search([], order='id desc', limit=1)
if last_rec:
res.update({'your_field_name':last_rec.field_value})
return res
While you click on add an item it will fill the new record with its default value and in default value we have written last record's value it it's there.
If you want to load default value from list view (last added value in a list) then it's a bit tricky work, for that you can do something like as follow.
Add one field in the parent form.
last_added_value = fields.Char("Last Added Value")
Create onchange method for that field.
#api.onchange('field_name')
def onchange_fieldname(self):
# there must be many2one field of parent model, use it here.
self.parent_model_field.last_added_value = self.field_name
And in xml field, you need to write like this.
<field name="one2many_field" context="{'default_field_name' : parent.last_added_value}">
<tree string="Title" editable="bottom">
<field name="field_name"/>
</tree>
</field>
You also need to write default_get method.
#api.model
def default_get(self,fields):
res = super(class_name, self).default_get(fields)
last_rec = self.search([('parent_field_id','=',self.parent_field_id.id)], order='id desc', limit=1)
if last_rec:
res.update({'your_field_name':last_rec.field_value})
return res