Odoo Help


how to use functional field in record rule?

Nishant Kashyap
on 7/18/13, 10:02 AM 1,939 views

I am trying to achieve that all the users that are Hr managers should be allowed to see the records. I have created a Functional Field:

def list_HRM(self, cr, uid, ids, field_name, arg, context):
         attribute = {}
        hr_managers = self.pool.get('hr.employee').search(cr, uid, ['&', ('department_id.name', '=', 'Human Resources'), ('manager', '=', True)], context=context)
        hr_managers_uid = []
        for record in hr_managers:
            hr_managers_uid.append(self.pool.get('hr.employee').browse(cr, uid, record, context=context).user_id.id)
        record = self.browse(cr, uid, ids)[0]
        attribute[record.id] = str(uid in hr_managers_uid or uid==1)
        return attribute

    'hr_managers_func' : fields.function(list_HRM, type='char', method=True, string='List of HR Managers'),

In .xml file:

<field name="always_true" invisible="1"/>
<field name="hr_managers_func" invisible="1"/>

In Record Rule:


I used field 'always_true' because of the record rule condition format i.e. [('field_name','operator',values)]. I thought that rule will evaluate the functional field using eval but unfortunately eval is not working on the record rule , I am getting this error:

NameError: name 'eval' is not defined

I could not think of more than this. I saw few forum somewhat similar to my problem, they were using the related field to avoid the functional field in the record, but here I have to check whether the current user belong to hr managers or not . I have tried explaining this in the best possible way, Looking forward for some reply.


Axel Mendoza

--Axel Mendoza--
| 7 7 8
Camaguey, Cuba
--Axel Mendoza--

DevOps - Full stack - Software Architect - Developer - Technology Integrator

I could help you to develop anything and solve complex problems based on technologies, integrations and tricky stuffs mostly in Python with OpenERP/Odoo, Zato, Django and many others frameworks programming languages and technologies.

I offers consulting services to anyone with an unanswered questions or needs for customizations. Think about it, maybe it's better to have an expert to solve your issues and projects than having a full time employee trying to understand what to do an how

Reach me at aekroft@gmail.com

Axel Mendoza
On 9/16/15, 4:03 AM

thx for comment, I didn't read this before, I'll check it.

Tarek Mohamed Ibrahim
on 9/16/15, 5:14 AM

Tarek Mohamed Ibrahim

--Tarek Mohamed Ibrahim--
Tarek Mohamed Ibrahim
| 5 3 7
Gîza, Egypt
--Tarek Mohamed Ibrahim--

I am an old VFP developer on ERP

I have moved to 2p since Nov-2014 and started developing with Python on Odoo.



Tarek Mohamed Ibrahim
On 9/16/15, 2:53 AM

Your request is to allow only managers to see the states hod_depart, hr_review

I'll achieved this differently, using the idea of the search function related to the function field. 

I don't have your status list, so I applied my logic on crm_lead table with the condition that employees in sales dep. can see all priorities, while others can see up to priority 3.

I replaced the word 'manager' with 'sales' to agree with the example I'm describing, the logic is the same. I created a module for this example and tested it, here is the module:

import community
"name" : "Community Examples",
"author" : "Tarek Mohamed Ibrahim",
"category" : "Examples",
"licence" : "AGPL-3",
"depends" : ['hr','crm'
"data" : [
"demo" : [],
"installable": True,
"auto_install": False,
"application": False,


class crm_lead(osv.osv): 
     _inherit = 'crm.lead'
     #changing this method , but actually it works like a dummy function, the one which is really works is the search method
     def _get_list_sales(self, cr, uid, ids, field_name, arg, context):
         attribute = {}
         hr_sales = self.pool.get('hr.employee').search(cr, uid, [('department_id.name', '=', 'Sales')], context=context)
         hr_sales_uid = []
         for record in hr_sales:
             hr_sales_uid.append(self.pool.get('hr.employee').browse(cr, uid, record, context=context).user_id.id)
         record = self.browse(cr, uid, ids)[0]
         attribute[record.id] = str(uid in hr_sales_uid or uid==1)
         return attribute

     def list_sales_search(self, cr, uid, obj, name, args, context=None):
         if not args:
             return []

         #get the uid from the passed value
         uid = args[0][2]

         #get some code from lst_HRM to evaluate the current uid
         hr_sales = self.pool.get('hr.employee').search(cr, uid, [('department_id.name', '=', 'Sales')], context=context)
         hr_sales_uid = []
         for record in hr_sales:
             hr_sales_uid.append(self.pool.get('hr.employee').browse(cr, uid, record, context=context).user_id.id)
         is_sales = uid in hr_sales_uid or uid==1

         #build a query
         if is_sales:
             query = "select id from crm_lead"
             query = "select id from crm_lead where priority<'4'"

         #execute the query
         res = cr.fetchall()
         if not res:
             return [('id','=','0')]
             return [('id','in', [x[0] for x in res])]

         _columns = {
                 'list_sales' : fields.function(_get_list_sales, type='char', method=True, string='List of HR Sales',fnct_search=list_sales_search),


I defined the function field in crm_lead as the rule is going to be applied on this class

here is the rule

<?xml version="1.0" encoding="utf-8"?> 
     <data noupdate="0">
         <record model="ir.rule" id="ir_rule_sales_crm_leads">
             <field name="name">filter leadss</field>
             <field name="model_id" ref="crm.model_crm_lead"/>
             <field name="domain_force">[('list_sales','=',user.id)]</field>
             <field name="perm_read" eval="True"/>
             <field name="perm_write" eval="True"/>
             <field name="perm_unlink" eval="True"/>
             <field name="perm_create" eval="True"/>

The thing that one can say it is not logical is the expression


which indicates that I'm going to equate the user.id value with the result of the function field list_sales, but the point is that I used a feature in the search function related to the function field to return a list of records ids based on the input sent to the function, which in our case is the user.id.

This could be generalized by sending any tuple, or even a dictionary, to the search function and doing any calculations. This could be achieved by replacing the user.id parameter with any tuple, or dictionary and receiving all needed values in the search function body by indexes

One more thing, I can use the 'operator' placeholder also to send any other parameters, as I didn't use the operator in the function.

Pls copy the code and create a module to test it and then you can borrow the logic to your own case, you need to adjust the indentation.

I think this idea is new, my first knowledge of the search function got from the link:  https://www.odoo.com/nl_NL/forum/help-1/question/how-to-implement-fnct-search-29984

I hope this search is useful.

Your Answer

Please try to give a substantial answer. If you wanted to comment on the question or answer, just use the commenting tool. Please remember that you can always revise your answers - no need to answer the same question twice. Also, please don't forget to vote - it really helps to select the best questions and answers!

About This Community

This platform is for beginners and experts willing to share their Odoo knowledge. It's not a forum to discuss ideas, but a knowledge base of questions and their answers.


Odoo Training Center

Access to our E-learning platform and experience all Odoo Apps through learning videos, exercises and Quizz.

Test it now

Question tools

1 follower(s)


Asked: 7/18/13, 10:02 AM
Seen: 1939 times
Last updated: 9/27/15, 3:42 AM