Inherited model many2one picking a wrong field value - odoo

I am trying to reference form_serial_no field of formdownload model in my inherited model(plot.allocate). Instead of the dropdown to show the computed value of form_serial_no which is company_short_code padded with sequence e.g CCK0000006, it's showing "CCK" which is the value of company_short_code excluding the sequence. In actual fact, it's referencing company_short_code of companyname model instead of the computed value of form_serial_no of formdownload model. And in the database, form_serial_no field is showing the right record which is something like these......ABC0000008, CDG0000003 and so on. This is my question, is there any reason why form_serial_no_id Many2one field of plot.allocate model is not picking the value of form_serial_no Char field of formdownload, instead, it's picking the company_short_code Char field of companyname model?
Secondly, how can i change the status field default value of companyname model record to true when a value is picked in form_serial_no_id Many2one field of plot.allocate model?
Kindly help me look into these.
Below are my code snippet
# -*- coding: utf-8 -*-
from openerp import models, fields, api
class CompanyName(models.Model):
_name = 'companyname'
_rec_name = 'company_short_code'
company_name = fields.Char(string="Company Name", required=True)
company_short_code = fields.Char(string="Company short code", required=True)
class FormDownload(models.Model):
_name = 'formdownload'
_rec_name = 'form_serial_no'
name = fields.Many2one('companyname', string="Company Name", ondelete='cascade',
required=True)
form_serial_no = fields.Char(string="Form Serial No", readonly=True)
status = fields.Boolean(string="Status", default=False)
#api.model
def create(self, vals):
serial_no = self.env['ir.sequence'].get('formdownload.form_serial_no')
code = self.env['companyname'].browse(vals['name']).company_short_code
# capitalize company short code values
code = code.upper()
# merge code and serial number
vals['form_serial_no'] = code + serial_no
return super(FormDownload, self).create(vals)
class PlotAllocation(models.Model):
_inherit = 'plot.allocate'
form_serial_no_id = fields.Many2one('formdownload',
domain=[('status', '=', False)],
ondelete='cascade', string="Form Serial No")
#api.model
def create(self, vals):
record = self.env['formdownload'].search([('name', 'like', vals.get('name', False))]).form_serial_no
status = self.env['companyname'].search([('name', 'like', vals.get('name', False))]).status
if vals.get('form_serial_no_id') == record.id:
self.env['companyname'].write({status : True})
return super(PlotAllocation, self).create(vals)

in the view the many2one is always showing the value of the field specified in the Model class by _rec_name :
by default _rec_name = 'name'
so in reality your model is like this :
class FormDownload(models.Model):
_name = 'formdownload'
_rec_name = 'name'
so he will retreive the value of field name name is also a many2one so the value retrieved is the _rec_name of model companyname with is company_short_code:
so i you want to change the value of many2one you have to choice:
if one field is enough than specify the _rec_name = 'form_serial_no'
if you want to combined value like first && last name then override name_get method
#api.multi
def name_get(self):
"""
change the displayed value on m2o
"""
result = []
for record in self:
result.append((record.id, _(" %s %s") % (record.first_name, record.last_name)))
return result
EDITS
in create method is easy just remove all the code in create method and put this two line
rec_id = super(PlotAllocation, self).create(vals)
# create return a record you can acces it's value
rec_id.form_serial_no_id.name.status = True
return rec_id # you need to return the record

Related

Do the odoo create and write method when the save button is click

this my class in odoo
class medical_procedure_base(models.Model):
_name = 'health_administrator.medical_procedure_base'
_description = 'Medical Procedure'
name = fields.Char(string='Libellé', required=True)
code = fields.Char(string='Code', required=True)
key_letter = fields.Many2one('health_administrator.key_letter', required=True, string="Lettre clé")
medical_procedure_cat_id = fields.Many2one('health_administrator.medical_procedure_category', required=True, string="Catégorie de l'acte")
amount = fields.Integer(string="Valeur lettre clé", required=True, default=0)
_order = 'code asc'
What I want, is when i clicked on Save Button from Odoo make a search this model to get all 'Medical Procedure' that have the same key_letter id and medical_procedure_cat_id id in that model and do the odoo create or write method.
Thanks
Call super for both create and write function.
Create
#api.model
def create(self,vals):
#your code
return super(your_class_name,self).create(vals)
Write
#api.model
def write(self,vals):
#your code
return super(your_class_name,self).write(vals)
NB:Create is called when the record is created and write is called when the record is edited.

Odoo domain for Many2Many relation

Here is code:
class Car(models.Model):
_name = 'car'
parking_id = fields.Many2one('cars')
class Parking(models.Model):
_name = 'parking'
cars_ids = fields.One2many('cars', 'parking_id')
class Group(models.Model):
_name = 'group'
parking_id = fields.Many2one('parking')
cars_ids = fields.Many2many('cars', lambda self: [('parking_id', '=', self.parking_id)])
What i want is to limit records of cars when i picking it in group form by parking on that cars are.
But my code does not work. What the mistake ?
If you define the domain in python code it will not be changed after the user
select the parking_id you need to update the domain every time the user
changes the parking_id:
class Group(models.Model):
_name = 'group'
parking_id = fields.Many2one('parking')
# it's always better to define m2m field with full properties
# cars_ids = fields.Many2many('cars','group_cars_rel', 'group_id', 'car_id', 'List of cars' )
cars_ids = fields.Many2many('cars')
#api.onchange('parking_id')
def onchange_parking(self):
"""change the domain when user change parking_id"""
# you may need to empty the many2many field if the user change the parking
# if not just remove this line
self.cars_ids = [(5, 0, 0)] # remove all record from many2many
if self.parking_id:
return {'domain': {'cars_ids': [('parking_id', '=', self.parking_id.id)]}}
else:
# remove domain
return {'domain': {'cars_ids': []}}
It seems your syntax is wrong for domain, change as below:
class Group(models.Model):
_name = 'group'
parking_id = fields.Many2one('parking')
cars_ids = fields.Many2many('cars', domain=[('parking_id', '=', parking_id)])

How overwrite default function of a field in odoo new api

I have a field that call a function to get default value (in module project_forecast):
def default_user_id(self):
return self.env.user if ("default_user_id" not in self.env.context) else self.env.context["default_user_id"]
user_id = fields.Many2one('res.users', string="User", required=True,
default=default_user_id)
I create another module to inherit it and change default value of field user_id but it's not working without any error in log, how can I resolve this ?
def default_user_id(self):
return False
You're linking a method directly on field definition. So overriding the method isn't enough anymore. Just define the field user_id again with default as the only parameter and ofc your new method:
The original model:
class MyModel(models.Model):
_name = "my.model"
def default_user_id(self):
return self.env.context.get("default_user_id", self.env.user)
user_id = fields.Many2one(
comodel_name='res.users', string="User", required=True,
default=default_user_id)
The inherited model:
class MyModelInherit(models.Model):
_inherit = "my.model"
def default_user_id(self):
return self.env['res.users']
user_id = fields.Many2one(default=default_user_id)
Please check this
user_id = fields.Many2one('res.users', string='User',readonly=True, default=lambda self: self.env.user)

I am using Odoo v10 to do some task but this error is appearing

#model.py
# -*- coding: utf-8 -*-
from openerp import models, fields
class fleet_vehicle_direction(models.Model):
_name = 'fleet.vehicle.direction'
name = fields.Char(related='vehicle_id.name', string='vehicle name', store=True)
vehicle_id = fields.Many2one('fleet.vehicle', 'select vehicle name', required=True, help='select vehicle name')
Quotations_id = fields.One2many('sale.order', 'name', 'Quotation', required=True,help='select Quotation name')
The image of model when install:
Error when add a new Quotation:
You have a problem in creating your model field which is Quotations_id,the inverse name is so wrong. you can't assign name as inverse field because it's already in the sale order and the inverse field should be Many2one so to edit that you your field definition must be like that
Quotations_id = fields.One2many('sale.order', 'fleet_id', 'Quotation', required=True,help='select Quotation name')
And you have to add the fleet_id field in the sale.order model as Many2one relation like this
class SaleOrder(models.Model):
_inherit= 'sale.order
fleet_id = fields.Many2one('fleet.vehicle.direction')

How to modify many to many field in wizard?

I have model contains many to many assign_to_id, I want to modify that field in wizard form through escalte_to method when user trigger escalate button
Model:
class Incident(models.Model):
_name = 'itmangement.incident'
assigned_to_id = fields.Many2one('hr.employee', string="Assigned To",domain="[('department_id', '=', dep_id)]",required=True)
Wizard model
class Escalate(models.TransientModel):
escalated_to = fields.Many2one('hr.employee', string="Escalated To", required=True)
#api.one
def escalate(self):
incident_obj = self.env['itmangement.incident']
record = incident_obj.browse(self._context.get('active_ids'))
record.write({'state': 'escalated'})
class Escalate(models.TransientModel):
escalated_to = fields.Many2one('hr.employee', string="Escalated To", required=True)
#api.one
def escalate(self):
object_id = self.env.context.get('active_id')
for object in self.env['itmangement.incident'].browse(object_id) and self.escalated_to:
object.assigned_to_id = self.escalated_to.id