Openerp dynamic domain filter - odoo

On my class folder a have many goods and many amounts. I need to use a domain filter on my field good_id of class amount, on that field I need to show the list of my object folder's goods.
so I create a function on my amount class (_get_folder_list_goods) that returns the list of folder's goods and I add a domain attribute on my field good_id of class amount.
here are my classes:
class folder(osv.osv):
_name = 'folder'
_columns = {
'name' : fields.char(u'Numéro',size=50, readonly=True),
'goods_ids': fields.many2many('good', 'doss_bien_rel', 'folder_id', 'good_id', 'Goods'),
'amount_id': fields.one2many('amount', 'folder_id', 'Amounts'),
....}
class good(osv.osv):
_name = 'good'
_columns = {
'name' : fields.function(_name_get_fnc, type="char", string=u''),
....}
class amount(osv.osv):
_name = 'amount'
def _get_folder_list_biens(self, cr, uid,folder_id, context={}):
liste_goods=[]
object_folder = self.pool.get('folder').browse(cr,uid,folder_id,context)
if object_folder.goods_ids:
for good in object_folder.goods_ids:
liste_goods.append(good.id)
return liste_goods
_columns = {
'folder_id': fields.many2one('folder', 'Ref folder', select=True),
'good_id':fields.many2one('good', Goos',domain="[('id', 'in', _get_folder_list_biens(folder_id))]"),
}
I got this error:
Uncaught Error: NameError: name '_get_folder_list_biens' is not defined

The domain is used on the client when the user starts to key (or lookup) and Good and it (the client) knows nothing about this method. What you need to do is create a functional field of type many2one that calls _get_folder_list_biens and returns a list of ids. Put the new functional field on your form as invisible and then make your domain ('id', 'in', my_functional_field)

Related

How to get value on one field based on two different fields

So Im creating a hotel management module . I have the option to filter rooms based on bed_type and tag. Tag contains different facilities like AC, TV etc. So an user will come and select a bed_type and the facilities he wants and in the third field it should show the rooms that have the given configuration if not available an error messages should come. SO i created a onchange function to do this , but i dint know how to include the tags in it. Im doing it on odoo v14. m
This is the model for the room
from odoo import api, fields, models, _
class HotelRoom(models.Model):
_name = 'hotel.room'
_description = 'hotel room'
_rec_name = 'room_number'
room_number = fields.Char('Room Number', required=True)
room_rent = fields.Monetary('Room Rent')
tag = fields.Many2many('hotel.tags', string='Facilities')
dormitory_count = fields.Integer('Dormitory count')
bed_type = fields.Selection([
('single', 'Single'),
('double', 'Double'),
('dormitory', 'Dormitory')
], required=True, default='other')
This is the model for the reception
class HotelAccommodation(models.Model):
_name = 'accommodation.room'
_description = 'Reception'
bed_type = fields.Selection([
('single', 'Single'),
('double', 'Double'),
('dormitory', 'Dormitory')
], required=True, string= 'Bed type')
state = fields.Selection([
('draft','Draft'),
('check-in','Check-In'),
('check-out', "Check-Out"),
('cancel','Cancel'),
], required=True, default='draft', tracking=True)
tag = fields.Many2many('hotel.tags', string='Facilities')
room_id = fields.Many2one('hotel.room', string='Room')
Using this I can filter the rooms based on the bed_type but I need to have the tags as well.I tried giving it inside the domain but its not working .
#api.onchange('bed_type')
def filter_room(self):
for rec in self:
return {'domain': {'room_id': [('bed_type', '=', rec.bed_type)]}}
You need also to add the tag field to the domain and to the onchange decorator, so the method will be called when the tag field is modified.
The method is invoked on a pseudo-record that contains the values present in the form, you do not need to loop over self.
Try the following example:
#api.onchange('bed_type', 'tag')
def filter_room(self):
return {'domain': {'room_id': [('bed_type', '=', self.bed_type), ('tag', 'in', self.tag.ids)]}}
You can use _compute fields with the store option = True
take a look https://www.odoo.com/documentation/14.0/reference/orm.html#computed-fields

How to change the default value of a property field in Odoo (old API)?

I'm trying to change the default value of some property fields such as: 'cost_method', 'product_type' and 'valuation' of the 'product' module but I can only change the non-property fields only.
What I tried:
- I created a new module and inherited the 'product.template' model and overridden the '_default' dictionary only but it didn't work.
I created new fields with the same name but of another type (selection) not property but neither did this work.
The code:
_name = "product.template"
_inherit = "product.template"
_columns = {
'cost_method': fields.selection([('average', 'Average Price'),('standard', 'Standard Price'), ('real', 'Real Price')])
,'type': fields.selection([('product', 'Stockable Product'),('consu', 'Consumable'),('service','Service')], 'Product Type', required=True, help="Consumable are product where you don't manage stock, a service is a non-material product provided by a company or an individual.")
,'company_id': fields.many2one('res.company', 'Company', required=False)
}
_defaults = {
'company_id': False
,'type' : 'product'
, 'cost_method': 'average'
, 'barcode':'555'
}
Use only _inherit="product.template". In your case you don't need the _name property.
Did you add your py. File to your __init__.py?
Did you set the correct dependencies in your __openerp__.py. In your case "product"?
Hope that helps you. Let me know.
EDIT:
I could reproduce your problem. My Code for testing
# -*- coding: utf-8 -*-
from openerp.osv import osv, fields
class product_template(osv.osv):
_name = "product.template"
_inherit = "product.template"
_columns = {
'cost_method': fields.selection([('average', 'Average Price'),('standard', 'Standard Price'),('real', 'Real Price')]),
'type': fields.selection([('product', 'Stockable Product'),('consu', 'Consumable'),('service','Service')],'Product Type', required=True, help="Consumable are product where you don't manage stock, a service is a non-material product provided by a company or an individual.") ,
'company_id': fields.many2one('res.company', 'Company', required=False)
}
_defaults = {
'company_id': False,
'type' : 'consu',
'cost_method': 'average',
'barcode':'555'
}
Here the type-field never had the consu value. In my case I could solve the problem by opening the menu Settings -> Technical Settings -> Actions -> User-defined Defaults. I deleted all entries where the name is type and modelname is product.template.
Now if I create a new product the default type is consu. Same behaviour with cost_method-field.

How to create a field for project sale orders

I have fields for a quick access of the entities related to a project. For example:
class project(models.Model):
_name = "project.project"
_description = "Project"
_inherit = 'project.project'
production_order_ids = fields.One2many('mrp.production', 'project_id', 'Production orders')
purchase_order_ids = fields.One2many('purchase.order', 'project_id', 'Purchase orders')
....
I am trying to create a sale_order_ids in the project.project model. My first try did not work:
sale_order_ids = fields.One2many('sale.order', 'project_id', string='Sale orders')
because because the field sale.order.project_id is of type account.analytic.account.
A project.project object inherits from account.analytic.account. This query should work ok if they would share the same Id, but they do not. So the navigation would be:
"project.project".analytic_account_id" -> sale.order".project_id
And the result would be the corresponding sale.order(s).
Use a computed field:
sale_order_ids = fields.One2many('sale.order', compute='_get_sale_orders', string='Sale orders')
#api.model
def _get_sale_orders(self):
for record in self:
record.sale_order_ids = self.env['sale.order'].search([('project_id', '=', record.analytic_account_id.id)]).ids

Custom field default value - populate with other entries from same field

I have created a custom module with extra fields on the product screen. I am trying to have the default value be a drop down with all of the entries already submitted to that field or the option to create a new entry (same as the default value when adding a product to a BOM).
class product_part_detail(osv.osv):
_inherit = 'product.template'
_columns = {
'x_mfrname1': fields.char('P/N'),
}
_defaults ={
'x_mfrname1': get_default_name,
}
def get_default_name(self):
return "test"
I tried creating a many2one field that refers to a field in a different table but I keep getting an error when trying to install the module. Below is the updated code that I am having issues with. Thanks in advance!
class product_part_detail(osv.osv):
_inherit = 'product.template'
_name = 'product.part.detail'
_columns = {
'x_mfrname1': fields.many2one('product.part.detail.fill', 'x_mfrname1id'),
'x_mfrname2': fields.many2one('product.part.detail.fill', 'x_mfrname1id'),
}
class product_part_detail_fill(osv.osv):
_name = 'product.part.detail.fill'
def _sel_func(self, cr, uid, context=None):
obj = self.pool.get('product.part.detail')
ids = obj.search(cr, uid, [])
res = obj.read(cr, uid, ids, ['x_mfrname1', 'x_mfrname2'], context)
res = [(r['x_mfrname1'], r['x_mfrname2']) for r in res]
return res
_columns = {
'x_mfrname1id': fields.one2many('product.part.detail', 'x_mfrname1', 'x_mfrname2', selection=_sel_func),
}
A couple of things. The idea of a drop down of the values they have previously entered requires a many2one field. You would create another model and then make x_mfrname1 a many2one to that table. As long as the user has create access on that table they will get a create option on the drop down to key new values.
One other item, as you are using the pre-8 API, the method signature of your default method should be:
def get_default_name(self, cr, uid, context=None):

One module field use to other module in openerp

I created a field name "link to opportunities" :-
module :- hr.applicant
field type:- many2many
object relation:- crm.lead
and i used in crm.lead module .
Now i want to use this field in "hr.recruitment" .
but i have tried many ways but not success. please tell me. how can use this field in other module like as crm.lead to hr.recruitment
thank you for your timing.
this code i used:-
'sale_o_ids' : fields.related('job_id', 'x_link_to_jobposition',
readonly=True,
relation='crm.lead',
string='Opportunity Name'),
Here is the example:
of many2many
class hr_job(osv.osv):
_inherit = 'hr.job'
_columns = {
'sale_ids': fields.many2many('sale.order', 'hr_job_sale_order_rel', 'job_id', 'sale_id', 'Sale order'),
}
hr_job()
Here created a many2many field of sale.order
Now i want to used the hr.job field in hr.employee.
class hr_employee(osv.osv):
_inherit = "hr.employee"
def _get_sale_order(self, cr, uid, ids, field_name, arg, context=None):
if context is None:
context = {}
result = {}
list_o = []
for order in self.browse(cr, uid, ids, context=context):
for i in order.job_id.sale_ids:
list_o.append(i.id)
result[order.id] = list_o
return result
_columns = {
'sale_order_ids': fields.function(_get_sale_order, type='many2many', relation="sale.order", string="Sale Orders"),
}
hr_employee()
So when you update in the hr.job many2many field then its updated value show in hr.employee object when in job select this job
Another method you can use related
'sale_o_ids' : fields.related('job_id', 'sale_ids',
type='many2many',
readonly=True,
relation='sale.order',
string='Available Sale Order'),
Hope this thing clear to you