1
votes

I've created a new group named accountant. If an user of this group opens the res.partner form for example, he must be able to read all, but only modify some specific fields (the ones inside the tab Accountancy, for example).

So I set the permissions create, write, unlink, read to 0, 1, 0, 1 in the res.partner model for the accountant group.

The problem: if I'm an user of the accountant group and I go to the form of res.partner, I will see the Edit button, if I click on it, I will be able to modify any field I want (and I should not, only the ones inside the tab).

So I thought to duplicate the menuitem (put the attribute groups="accountant" to the copy) and the form (put all fields readonly except for the content of the tab).

The problem: if I'm an user of a group over accountant group (with accountant in its implied_ids list), I will see both menuitems (the one which takes to the normal form and the one which takes to the duplicated form with the readonly fields).

Is it possible to create a menuitem which opens a specific set of views depending on the group of the user who is clicking on the mentioned menuitem? Any ideas of how can I succesfully implement this?

2

2 Answers

2
votes

I was googling a lot and there are many people who ask this same question in Odoo forums, but nobody gives them an answer.

Finally, I found this workaround, which in my case worked perfectly: the method field_view_get, which is in every single model, gets the XML view just before returning it to be shown. This means that you can manipulate the view from Python code in whatever way you want.

You only must know how to use a library like lxml to modify the string variable with the XML code. I put my example:

RES.PARTNER model (Here we must use etree from lxml library)

@api.model
def fields_view_get(self, view_id=None, view_type='form', toolbar=False,
                    submenu=False):
    res = super(res_partner, self).fields_view_get(
        view_id=view_id, view_type=view_type, toolbar=toolbar,
        submenu=submenu)

    checking_obj = self.env['my.own.checkings']
    doc = etree.XML(res['arch'])

    if checking_obj.belongs_to_accountant_group():
        doc.set('create', 'false')
        doc.set('delete', 'false')
        doc.set('edit', 'true')

    if view_type == 'form':
        accounting_pages = doc.xpath("//page[@name='accounting']")
        accounting_page = accounting_pages[0] if accounting_pages \
            else False

        if accounting_page is not False:
            if checking_obj.belongs_to_accountant_group():
                all_fields = doc.xpath("//field")
                for field in all_fields:
                    if accounting_page not in field.iterancestors():
                        checking_obj.set_modifiers(field,
                                                   {'readonly': True, })

    res['arch'] = etree.tostring(doc)
    return res

AUXILIAR CUSTOMIZED model (named MY.OWN.CHECKINGS) (Here we must use json library)

def update_json_data(self, json_data=False, update_data={}):
    ''' It updates JSON data. It gets JSON data, converts it to a Python
    dictionary, updates this, and converts the dictionary to JSON data
    again. '''
    dict_data = json.loads(json_data) if json_data else {}
    dict_data.update(update_data)
    return json.dumps(dict_data, ensure_ascii=False)

def set_modifiers(self, element=False, modifiers_upd={}):
    ''' It updates the JSON modifiers with the specified data to indicate
    if a XML tag is readonly or invisible or not. '''
    if element is not False:  # Do not write only if element:
        modifiers = element.get('modifiers') or {}
        modifiers_json = self.update_json_data(
            modifiers, modifiers_upd)
        element.set('modifiers', modifiers_json)

def is_accountant(self):
    return self.env.ref(
        'my_module.group_accountant').id in \
        self.env.user.groups_id.mapped('id')

This way you can make readonly some fields depending on the group of the current user.

1
votes

You cannot make few or some of the fields as 'readonly' in odoo based on the groups. If you need to do it, you can use the custom module 'smile_model_access_extension'.

For loading appropriate view on menu click you can create record of 'ir.actions.act_window' (view_ids) field of 'ir.action', where you can specify the sequence and type of view to be loaded when the menu action is performed. In your case you can specify the specific 'form view' for your action.