Odoo, can't have two different siblings objects in the same view - odoo

I have a class named detail_base, and two other classes name flight_detail and tour_detail, the last two classes inherits from the first one, like this:
class DetailBase(models.Model):
_name = 'detail_base'
fee = fields.Monetary('Fee')
passenger = fields.Char('Passenger')
class FlightDetail(models.Model):
_name = 'flight_detail'
_inherits = 'detail_base'
passport = fields.Char('Passport')
class TourDetail(models.Model):
_name = 'tour_detail'
_inherits = 'detail_base'
age = fields.Integer('Tourist Age')
The problem is when I call the flight_detail and tour_detail in the same view, the browser can't handle the common attributes of both classes, If I assign 5 to tour_detail.fee, that number will be stored into flight_detail.fee.
It seems the problem is related to the attributes with the same name of different objects being siblings.
I will appreciate any help.

You should either use _inherit
class DetailBase(models.AbstractModel):
_name = 'detail_base'
fee = fields.Monetary('Fee')
passenger = fields.Char('Passenger')
class FlightDetail(models.Model):
_name = 'flight_detail'
_inherit = 'detail_base'
passport = fields.Char('Passport')
class TourDetail(models.Model):
_name = 'tour_detail'
_inherit = 'detail_base'
age = fields.Integer('Tourist Age')
which should either create 3 database tables (detail_base as Model) or 2 database tables (AbstractModel).
Or you use _inherits like:
class DetailBase(models.Model):
_name = 'detail_base'
fee = fields.Monetary('Fee')
passenger = fields.Char('Passenger')
class FlightDetail(models.Model):
_name = 'flight_detail'
_inherits = {'detail_base': 'base_id'}
passport = fields.Char('Passport')
base_id = fields.Many2one('detail_base', required=True, ondelete='cascade')
class TourDetail(models.Model):
_name = 'tour_detail'
_inherit = {'detail_base': 'base_id'}
age = fields.Integer('Tourist Age')
base_id = fields.Many2one('detail_base', required=True, ondelete='cascade')
That will create 3 tables, and fee and passenger will be stored in detail_base table. Odoo will get it from there, because it is a sort of delegation inheritence.

use inherit:
1- inherit without _name :
inherit = 'model.name'
new_field = fields...
this add this field to the model.name
2- inherit with _name:
inherit = 'model.name'
_name = 'new.model'
here will create a new tabel in database with the same structure of model.name.
inherits: The delegation inheritance.
best example is res.users and res.partners user is a partener so when we create a res.users record we must create a res.partener that hold commun field like name, email, address ... and information related to users like passowrd and login are stored in res.users model and with type of inheritence you can access field of res.partener directly without having to create a related field. you can do user_record.name or .email or .address this will not be a problem.
i like to think of it as one2one relation.
_inherits = {model.name : many2one_field_id }
_name = 'new.model'
# m2o field should be required and ondelete = cascade
many2one_field_id = fields.Many2one('model.name', string='Label', required=True, ondelete="cascade")
so when you create a record of new.model all field that are in model.name will be stored in model.name.

Related

Create an empty selection to be inherited

I have created a parent model, which has a Selection field.
This pattern must be inherited from classes that offer a service, so in the child classes I use fields.Selection(selection_add = ....). Is it possible to create, in the parent class, an "empty" selection that will only fill with the selection fields of the models that inherit it?
Ex
class GenericService(models.Model):
_name = 'generic.service'
selection_type = fields.Selection(
[('select_type', _("Select an Account")),],default='select_type',
string=_("Service Type"),
required=True
class SpecificService(model.Model):
_inherit = 'generic.service'
selection_type = fields.Selection(
selection_add=[('sftp','SFTP')],
)
I would like to avoid adding a default field on the generic model selection, my alternative is to create a method that controls the insertion, but I would like to know if it could be avoided.
If you inherit like that _inherit without _name. Then you end up only with 1 model generic.service And all selection_add=[] added selections.
If you add
class GenericService(models.Model):
_name = 'generic.service'
selection_types = fields.Selection([], string="Service Type")
class SpecificServiceA(model.Model):
_inherit = 'generic.service'
selection_type = fields.Selection(
selection_add=[('sftp','SFTP')], required=True
)
class SpecificServiceB(model.Model):
_inherit = 'generic.service'
selection_type = fields.Selection(
selection_add=[('https','HTTPS')], required=True
)
you end up with model named "generic.service" and selections [('sftp','SFTP'), ('https','HTTPS')]
I believe strings and selection names are added automatically to translation list. no need for _()
You can also use Odoo's mixin feature, which is a bit like abstract types/classes. Following an example in context of your requirments:
class ServiceMixin(models.AbstractModel):
_name = "service.mixin"
def _get_type_selection(self):
""" Returns a 2-tuple list for type_selection field
Meant to be extended by inheriting models."""
return []
type_selection = fields.Selection(
selection="_get_type_selection", string="Type")
class ServiceA(models.Model):
_name = "service.a"
_inherit = ["service.mixin"]
def _get_type_selection(self):
""" Returns a 2-tuple list for type_selection field"""
return [('a', 'A'), ('b', 'B')]
class ServiceB(models.Model):
_name = "service.b"
_inherit = ["service.mixin"]
def _get_type_selection(self):
""" Returns a 2-tuple list for type_selection field"""
return [('a', 'A'), ('c', 'C')]
In database that will lead to 2 new tables: service_a and service_b. So you have really 2 new Odoo models, which aren't dependend on eachother.

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

how can I inherit of inherited model and view in odoo/openerp

I need help to set default value of purchase_ok field at product_template class in purchase module
thanks
You can simply set the default attribute like this:
class ProductTemplate(models.Model):
_inherit = 'product.template'
purchase_ok = fields.Boolean(
string='Selectable on purchase operations',
default=True,
)
Or you can use a lambda function like this:
class ProductTemplate(models.Model):
_inherit = 'product.template'
purchase_ok = fields.Boolean(
string='Selectable on purchase operations',
default=lambda self: self._get_default_purchase_ok(),
)
#api.model
def _get_default_purchase_ok(self):
value = True
# some operations
return value

Access child model class from parent model class object in Odoo8

Is there a way to access child model class object from parent model class object or now what child model class does this parent model class object has?
Here are my model classes:
class Content(models.Model):
_name = 'content'
title = fields.Char(string='Title', required=False)
summary = fields.Char(string='Summary', required=False)
description = fields.Char(string='Description', required=False)
class Video(models.Model):
_name = 'video'
_inherits = {'content': 'content_id'}
duration = fields.Float(string='Duration', required=False)
class Image(models.Model):
_name = 'image'
_inherits = {'content': 'content_id'}
width = fields.Float(string='Width', required=False)
height = fields.Float(string='Height', required=False)
If I have an object of "Content" class say "content1" that has a child object "image1", is there a way to access that "image1" object from "content1" object or now that type of "content1" is "Image"?
Content can have many child classes in future so I don't want to query all the child classes.
In Odoo you can travel bi-direction but your models should have configured like that,
class Content(models.Model):
_name = 'content'
_rec_name='title'
title = fields.Char(string='Title', required=False)
summary = fields.Char(string='Summary', required=False)
description = fields.Char(string='Description', required=False)
video_ids : fields.One2many('video','content_id','Video')
image_ids : fields.One2many('image','content_id','Video')
class Video(models.Model):
_name = 'video'
_inherit = 'content'
duration = fields.Float(string='Duration', required=False)
content_id = fields.Many2one('content','Content')
class Image(models.Model):
_name = 'image'
_inherit = 'content'
width = fields.Float(string='Width', required=False)
height = fields.Float(string='Height', required=False)
content_id = fields.Many2one('content','Content')
And you can access functionality of child classes by calling in this way.
for video in content1.video_ids:
## you can access properties of child classes like... video.duration
for image in content1.image_ids:
print image.width
Similarly you can call the method of child classes the same way.
If your aim is to do something else then specify it with example.