deal with many2many field in odoo - python

I have two models skills and res_users.
I want that each user can have many skills and also each skill can have many users on it. I tried to do that but without success.
This is my skills:
class technicians_skills(osv.osv):
_name = 'skills'
_description = 'Technicians Skills'
_columns = {
'name': fields.char(string='name', size=50),
'description': fields.text(string="description"),
'member_ids': fields.many2many('res.users', 'skill', string='Technicians')
}
and this is the users :
class res_users(osv.osv):
_inherit = 'res.users'
_columns = {
'skill': fields.many2many('skills', relation='skills.rel', column1='name', column2='skill', string='Skill'),
}
and I want to know the skills of each user, but when I call this :
test = http.request.env['skills.rel'].search([])
It shows me this error
KeyError: 'skills.rel'

You need to specify all key words in your declaration to create the same relation tables
fields.many2many(
comodel_name='model.name',
relation='valid_postgres_name',
colum1='current_model_m2o_field_name',
column2='comodel_m2o_name',
string='Label')
And in the other definition keep the same name of the relation but inverse the other keyword.
In skills
user_ids = fields.many2many('re.users', 'user_skill_rel','user_id','skill_id', 'Users')
In users
skill_ids = fields.many2many('skills', 'user_skill_rel', 'skill_id', 'user_id', 'Skills')
See how i inversed the definition only the relation is the same.
Keep the same names of columns
EDITS:
don't execute search on relation because they are not models. you need to execute the search on the model then access the many2many fields.
Let say you want to get skill of the current user.
self.env.user.skill_ids # this will return the list of the skills for the current user
if you want to get the skills of more than one user.
result = self.env['res.users'].search([your_domain]])
# if you need to show user information then it's skill
for rec in result:
# use loop
rec.name # user name
rec.skill_ids
# but if you want to get the list of skill and you don't need users
skills = result.mapped('skills_ids') # mapped will return all the skills without duplication

Related

Odoo, how to hide an item from many2one field?

Odoo-10
My .py
class komMo(models.Model):
_name = 'kom.mo'
mo_id = fields.Integer(string='Code mo') #this is just the recognition number
name = fields.Char(string='Name mo')
parent_id = fields.Many2one('kom.mo')
I want to hide the option(example) from the drop list ('parent_id'), if that is the name of the object itself
So when I'm going to edit an 'example', I do not want to be offered as an option in the field 'parent_id'
When I create a new 'example2' it's all good, because only the existing items are displayed in the drop-down list.
If I was not clear please tell me.
my .xml file was pretty basic i did not add any options or attributes
Just add this domain to the field domain="[('id', '!=', id)]". That will remove the object for its own form.
You can also use odoo's nested set system for parent child relationship, which has great benefit in resolving parent child relationship query, by setting _parent_store = True in models definition, and adding parent_left, parent_right fields, you can the also use #api.constraint on parent_id calling odoo Models _check_recursion to ensure that there is no recursive parent child relationship creation.
For example on odoo Product category model:
class ProductCategory(models.Model):
_name = "product.category"
_description = "Product Category"
_parent_name = "parent_id"
_parent_store = True
_parent_order = 'name'
_rec_name = 'complete_name'
_order = 'parent_left'
parent_id = fields.Many2one('product.category', 'Parent Category', index=True, ondelete='cascade')
parent_left = fields.Integer('Left Parent', index=1)
parent_right = fields.Integer('Right Parent', index=1)
#api.constrains('parent_id')
def _check_category_recursion(self):
if not self._check_recursion():
raise ValidationError(_('Error ! You cannot create recursive categories.'))
return True

Odoo10 : How can I automatically get the value for partner when customer number is given?

I am creating a module something like call log. In that i need to search the customer number and get the Partner information or have to link the partner automatically.
the following are the codes, somebody please help me.
class model_call(models.Model):
_inherit = 'res.partner'
_name = 'model.call'
_description = 'call logs'
""" *************** Base Fields ******************* """
name = fields.Char(string='Topic')
customer_number = fields.Char(string='Customer Number', track_visiility='onchange', onchange='get_partner(customer_number)')
#-------------------------------------------------
# apis
#-------------------------------------------------
#api.onchange('customer_number')
def get_partner(self, customer_number):
if customer_number:
customer = self.env['res.partner'].search([('customer_number', '=', record.phone)])
return customer
#------------------------------------------------------
customer = fields.Many2one('res.partner', string='Customer', track_visibility='onchange',index=True, help="Linked partner (optional). Usually created when converting the lead.",)
Your onchange isn't correct. You don't need parameters and have to return a dictionary or nothing. The dictionary is only needed for field filtering changes and warning messages. Value changes like yours are made "directly":
#api.onchange('customer_number')
def get_partner(self):
if self.customer_number:
customer = self.env['res.partner'].search(
[('customer_number', '=', self.phone)]) # shouldn't it be self.customer_number?
self.customer = customer
And try to stick to the Odoo Guidelines and change the field customer to customer_id.

Generate input fields based on a input and store it properly

I have a field called subjects that asks users how many subjects do they have and based on the number they input I want to generate the input fields of same number. And How and where do I store those inputs.
MODELS.PY
#this field will determine how many input fields to generate
subjects = models.IntegerField()
VIEWS.PY
def generate_forms(request):
no_of_fields = request.GET.get('subjects')
if no_of_fields:
#generate other inupts
#save it in the database
Besides generating the input, how do I save those data in the database.
Thanks in advance
If you use postgres you can use django postgres specefic models fields(Like ArrayField).django specefic fields documention
For another databases you can create model for your subjects and for each subject you can insert new data in Subject model.
class Subject(models.Model):
desc = models.CharField(max_length=50)
other_filed = models.ForeignKey(OtherModel)
def generate_forms(request):
other_field = 1
subjects = request.GET.get('subjects')
if subjects and subjects != '':
for subject in subjects:
Subject.objects.create(desc=subject, other_field=other_field)

ODOO 10 many2many

I have a problem in ODOO 10 with a many2many relationship.
I have extended res.partner this way:
class ResPartner(models.Model):
x_bagsdesign = fields.Many2many('product.product',string='Bags Design',relation='bags_design_manufactur')
then I have extended also product.template model:
class product_template_fields(models.Model):
_inherit = 'product.template'
x_traders_stock = fields.Many2many(
'res.partner', string='Traders with access to stock',relation='xtradstock_res_partner_rel')
#api.multi
def write(self, vals):
record = super(product_template_fields, self).write(vals)
for singletrader in self.x_traders_stock:
singletrader.x_bagsdesign = [(4,self.id)]
return record
This way every time a new x_traders_stock is inserted in product.template, a new x_bags_design is also created in res.partner.
BUT.. when I save a new record in product.template I get an sql error:
bad query: INSERT INTO bags_design_manufactur (res_partner_id, product_product_id)
(SELECT a, b FROM unnest(ARRAY[1]) AS a, unnest(ARRAY[7]) AS b)
EXCEPT (SELECT res_partner_id, product_product_id FROM bags_design_manufactur WHERE res_partner_id IN (1))
I don't understand where the EXCEPT part of the sql query is coming from and how to prevent it. If anyone can help I would be grateful.. thanks!
The error message is a bit different from expected, but I can fix some problems in your code. First of all you have to take into account that a product.product object is a variant of a product.template object, so you can have in a database many product.product objects pointing to the same product.template (e.g. a product.template is a T-shirt and a product.product is a T-shirt colour red size M). This means that you can't try to set the ID of a product.template in a field which is expecting the ID of a product.product, as you're doing here:
singletrader.x_bagsdesign = [(4,self.id)]
Of course, that mistake will not give you the message error you are receiving, there must be something wrong in other part of your code (I guess related to bags_design_manufactur model).
However, to fix the problem I told you above, you should write this:
class product_template_fields(models.Model):
_inherit = 'product.template'
x_traders_stock = fields.Many2many(
comodel_name='res.partner',
string='Traders with access to stock',
relation='xtradstock_res_partner_rel'
)
#api.multi
def write(self, vals):
result = super(product_template_fields, self).write(vals)
for prod_templ in self:
products = self.env['product.product'].search([
('product_tmpl_id', '=', prod_templ.id),
])
for singletrader in prod_templ.x_traders_stock:
singletrader.write({
'x_bagsdesign': [(4, product.id) for product in products],
})
return result
EDIT
product.product inherits from product.template by delegation, this means that every field you create in product.template model is going to be available in product.product objects, so when you are creating the Many2many field x_traders_stock in product.template, you're creating it in product.product too, so you don't need to add records each time a x_trader is generated. Instead you should change your models:
class ResPartner(models.Model):
x_bagsdesign_prod_templ = fields.Many2many(
comodel_name='product.template',
column1='partner_id',
column2='product_tmpl_id',
string='Bags Design',
relation='xtradstock_res_partner_rel'
)
class ProductTemplate(models.Model):
_inherit = 'product.template'
x_traders_stock = fields.Many2many(
comodel_name='res.partner',
column1='product_tmpl_id',
column2='partner_id',
string='Traders with access to stock',
relation='xtradstock_res_partner_rel'
)
And then, if you want to access to the product.product objects a partner has, you can do it this way:
any_partner.x_bagsdesign_prod_templ.mapped('product_variant_ids')
If you preferred it, you could even create a new related field in res.partner which brought the product.product objects a partner has.

Get field value of inherited model Odoo 8

Hello to all I have been developing module under Odoo 8. I have a class "hrEmployee" with "_inherit=hr.employee" , now in my hrEmployee there is a One2many field having relation with another model "hr.employee.visa". I want to get the field values of the "hrEmployee" with onchange function defined on the field of "hr.employee.visa". Like when I change field value of "hrEmployee", I can get the field value entered on the current form (hrEmployee). How am I able to achieve this in Odoo v8? My Python code is shown below:
class hrEmployee(models.Model):
_inherit = "hr.employee"
diwan_no = fields.Char('Diwan No', size=30, help='Diwan Number')
zeo_number = fields.Char('ZEO Number',size=30, help='ZEO Number')
visas_ids = fields.One2many('hr.employee.visas', 'employee_id', 'Visas')
class hr_employee_visas(models.Model):
_name='hr.employee.visas'
employee_id = fields.Many2one("hr.employee.visas", "Employee" )
#api.onchange('visas_number')
#api.depends( 'visas_number')
def _visa_num(self):
cr=self._cr
uid=self._uid
ids=self._ids
for id in ids:
obj1=self.pool.get('hr.employee').browse(cr,uid,id,context=None)
print obj1.name_related
visas_sponsor = fields.Char('Sponsor')
visas_states = fields.Selection([('apply','Apply'),('active','Active'),('expire','Expire'),('cancel','Cancelled')], string='State' )
visas_number = fields.Char('Visa No', help='Visa Number')
I tried to use self.pool.get browse but it gives me "False" . Plz guide me or point me my mistake. Hopes for suggestion
Try following,
class hr_employee_visas(models.Model):
_name='hr.employee.visas'
employee_id = fields.Many2one("hr.employee", "Employee" )
#api.onchange('visas_number')
#api.depends( 'visas_number')
def _visa_num(self):
for obj in self:
print obj.employee_id.name
Here is the mistake
employee_id = fields.Many2one("hr.employee.visas", "Employee" )
You need to set hr.employee here.
No need to write both of the decorators together, in case of any changes into the visas_number field this method will be called, you can use any of the single decorator for this.

Categories

Resources