This question has been flagged
3 Replies
25521 Views

My goal is to build a domain filter (group rule) to achieve the following scenario:

We have 2 groups G1 & G2, users of G1 can see records created by any member of G1, but not records created by G2 members and vice versa. If user u1 is a member of both G1 & G2, then u1 can see records created by both groups users. Administrator can see all records.

Avatar
Discard
Author Best Answer

Thanks to Nishant for giving us a good solution. however, this solution is more flexible.

def _groups_id(self, cr, uid, context=None):
    all_groups=self.pool.get('res.groups')
    all_categ =self.pool.get('ir.module.category')
    all_users =self.pool.get('res.users')
    # You need to replace 'Fleet' with your module name. e.g Warehous, Sales ...etc
    c_ids = all_categ.search(cr,uid,[('name','=','Fleet')])
    fleet_g_ids = all_groups.search(cr,uid,[('category_id','in',c_ids)])
    if not fleet_g_ids: return False
    user_group = all_users.browse(cr, uid, uid,context=context).groups_id
    user_group_ids = [ r.id for r in user_group]

    vals = []
    for fg_id in fleet_g_ids:
        if fg_id in user_group_ids:
            vals.append(fg_id)

    if not vals: return False
    return [(6, 0, vals)]


_columns = {
    'groups_id': fields.many2many('res.groups', 'fleet_vehicle_group_rel', 'vid', 'gid', 'Vehicle'),
            }

_defaults = {
    'groups_id': _groups_id,
    }

The domain filter (Groups Rule):

[('groups_id','in',[g.id for g in user.groups_id])]

This will completely solve the scenario, also you don't have to change the source code each time you add/remove a group.

Regards..%

Avatar
Discard

Well, I will try this solution as soon as possible...But I think that you figured out this approach because of the answer I posted .. And you unvoted it and remove the correct answer sign as well.. Thank you for showing this gratitude.

Author

1- I have mentioned you at the beginning of the post.and offered my thanks.

2- I didn't removed my vote, just the best answer sign.(you still have my vote)

3- I gave you two arbitrary votes on some of your answers in return (at the time i did so).

4- This is a better and more flexibile approach for others to follow.

And i still offer my best thanks and regards..%

Thank you for that , Thankyou.

Getting me an error : Uncaught Error: Expected "]", got "(name)"

Best Answer

Hey Man Dont use the Functional field on the record rules , they wont help you, because record use applies to the record(Direct from the Database) And the functional fields are calculated when the records are shown, so they wont help you in achieveing what you are looking for.Instead try this:

_columns={
     'g1_group':fields.many2one('res.groups', string='G1 Group'),
     'g2_group':fields.many2one('res.groups', string='G2 Group'),
}

def _g1_group(self, cr, uid, context=None):
    all_groups=self.pool.get('res.groups')
    all_users =self.pool.get('res.users')
    g1_ids = all_groups.search(cr,uid,[('name','=','G1 Group')])
    if not g1_ids: return False
    if not g1_ids in all_users.browse(cr, uid, uid,context=context).groups_id:
        return False
    edit_group = all_groups.browse(cr, uid, g1_ids[0],context=context).id
    return edit_group

def _g2_group(self, cr, uid, context=None):
    all_groups=self.pool.get('res.groups')
    all_users =self.pool.get('res.users')
    g2_ids = all_groups.search(cr,uid,[('name','=','G2 Group')])
    if not g2_ids: return False
    if not g2_ids in all_users.browse(cr, uid, uid,context=context).groups_id:
        return False
    edit_group = all_groups.browse(cr, uid, g2_ids[0],context=context).id
    return edit_group

_defaults = {
    'g1_group':lambda self, cr, uid, context:self._g1_group( cr, uid, context=None)
    'g2_group':lambda self, cr, uid, context:self._g2_group( cr, uid, context=None)
}

In the Record rule check Whether the entered user is in the group so that he can see the records.

[('g1_group','in',[g.id for g in user.groups_id])]

to check for the g2 group:

[('g2_group','in',[g.id for g in user.groups_id])]

I hope this may help you.

Avatar
Discard
Author

Thanks Nishant, your suggested code solved the problem, but one final thing to discuss before marking the question as solved.

We need to add new field+method+default_value into the source code along with a rule for each new group in the future, as well as no user can be a member for two groups at the same time.

Can we think of a more flexible approach?

Well, You can add a user in different groups,And a user can be a member of two or more groups at a time, for example lets say g1_group=1 and g2_group=2 so it will check [(1,'in',[1,2,3,45,24])] in record rule.[1,2,3,45,24] is the id of other groups of the user.Well this is the default way, you can check the Setting--->Security---->Record Rules then there "Discussion group" object, there they are doing the same thing.Otherwise: You need to override def fnct_search for the functional field.Due to lack of documentation I did not able to achieve what I was looking for,

Author

yes you are right, user can be a member of multiple groups with no problems. however, we still need to write codes each time we decide to add a new group.

I will try to improve the code to gain more flexibility, and post back here.

Thanks again..%

this is exactly what i need, can you put the steps to follow, i mean do i need to create a module with .py file, xml and so.

my goal is to do this on account.invoice, res.partner and product.product . I hope that I make myself clear. thank you for your help.

Best Answer

if you set the store=True the domain will filter you data from database. So delete the store=True , you will get the _search_user_ids..!!

Avatar
Discard
Author

Thanks for trying to help, but _search_user_ids..!! didn't get called.