How to access logged in user's group in a view in Odoo? - odoo

I want to show a field read-only for all users of group named Manager (having read and update rights for that model). They must not be able to update a field called 'x_name'.
I am using odoo web client (Gui) and don't have access of xml file. I am only able to use the GUI so please suggest a solution for working this out through GUI.

Go to Settings -> User Interface -> Views and create a view, give it the following contents:
<record id="give_an_id" model="ir.ui.view">
<field name="name">give_a_name</field>
<field name="model">your.model</field>
<field name="inherit_id" ref="module.the_id_of_the_view_that_field_is_on" />
<field name="groups_id" eval="[(6, 0, [ref('module.the_id_of_the_group_for_which_you_want_the_field_hidden') ])]" />
<field name="arch" type="xml">
<field name="x_name" position="attributes">
<attribute name="readonly">1</attribute>
</field>
</field>
</record>
So what happens here is that the above view gets activated only when the user belongs in groups_id more here.

You can achieve it by inheriting a view, also you can create a new inherited view from the GUI and add group id for that view.
Enable Debug mode.
Go to Settings > Technical > Views > Create new view
Add All the field like which view you want to inherit, view type
Add Group name inside the Access rights
Inside the architecture add :
<field name="your_field_name" position="attributes">
<attribute name="readonly">1</attribute>
</field>

Related

Set field to readonly if currently edited user has higher privelage

So my goal is to have group of users that are able to add new users but they should not have other admin privelages.
The way I want to solve it is by having group with permissions to only add users and another group with all the admin right. For this to be scure I need to prevent users in the first group from editing users in the second group.
I have module with this code:
<record model="ir.ui.view" id="view_user_readonly" >
<field name="name">res.users.form.readonly</field>
<field name="model">res.users</field>
<field name="inherit_id" ref="base.view_users_form"/>
<field name="arch" type="xml">
<xpath expr="//field[#name='login']" position="attributes">
<attribute name="readonly">True</attribute>
</xpath>
</field>
</record>
And it sets field to readonly for all the users. Now I would like to change is so that it is readonly when user we are trying to edit has the group base.group_system and we don't.
I tried adding code based on anwsers from the internet like this:
<record model="ir.ui.view" id="view_user_readonly" >
<field name="name">res.users.form.readonly</field>
<field name="model">res.users</field>
<field name="inherit_id" ref="base.view_users_form"/>
<field name="arch" type="xml">
<xpath expr="//field[#name='login']" position="attributes">
<attribute name="readonly">True</attribute>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="view_user_readonly_settings">
<field name="name">res.users.form.readonly.settings</field>
<field name="model">res.users</field>
<field name="inherit_id" ref="custom_user_fields.view_user_readonly" />
<field name="groups_id" eval="[(6, 0, [ref('base.group_system')])]"/>
<field name="arch" type="xml">
<xpath expr="//field[#name='login']" position="attributes">
<attribute name="readonly">False</attribute>
</xpath>
</field>
</record>
But it does not work as intended. It restrict everyone without base.group_system from editing and I need to allow other users to edit this field in some cases (for example while creating new users). Or if it is possible - set this field to readonly only when user we are editing have "base.group_system" and we don't.
#EDIT
Internal users should not be able to edit other users. Manager (user with group Access Rights - group_erp_manager) should be able to edit Internal users and other managers but not admins. Admin (user with group Settings - group_system) should have access to edit everyone.
If by editing you mean stop the user from editing any field
you really have a lot of cases, because you need to check
for example:
1. manager cannot create an admin user
2. manger cannot make him self admin but can create other manager or normal users
I created a application for this but really it's not with now
it's in work.
Okay i'm going to try a simple solution that allow a manager
to edit any user but stop him with error message if he is trying to edit a admin.
#api.multi
def check_editing_previlage(self):
""" check if users is allowed to edit this record."""
# admin can do what ever he wants
if self.env.user.has_group('base.group_system'):
return True
if self.env.user.has_group('base.group_erp_manager'):
# 1. admin can create a user
if isinstance(self.id, models.NewId):
return True
# 2. he is not allowed to edit and admin
if self.has_group('base.group_system'):
return False
# 3. he is allowed to edit this users
return True
# other user are not allowed to edit any user
return False
#api.mutli
def write(self, vals):
for rec in self:
if not rec.check_editing_previlage():
# show a nice error that tells the user that he is not allowed to edit
# this user
raise exceptions.ValidationError(_('''You are not allowed to edit user %s contact your manager
if you think that is an error.
''') % rec.name)
# continute the editing otherwise
return super(ClassName, self).write(vals)
The problem with this solution is that a manager can make him self or another use an admin .
In order for you to stop this you need to check what are the groups that are added
and removed and raise an exception if a non admin user is trying
to add or remove an admin previlage. you can post another question and specify the what
Odoo version you are using.
I think that you need admin permissions for some users as we have already and for some users only create permission not edit. If you need users with the group 'group_system' only create permission not edit , then please follow the below code:
<record model="ir.ui.view" id="view_user_readonly_settings">
<field name="name">res.users.form.readonly.settings</field>
<field name="model">res.users</field>
<field name="inherit_id" ref="custom_user_fields.view_user_readonly" />
<field name="groups_id" eval="[(6, 0, [ref('base.group_system')])]"/>
<field name="arch" type="xml">
<xpath expr="//form" position="attributes">
<attribute name="create">1</attribute>
<attribute name="edit">0</attribute>
</xpath>
</field>
users with the group 'group_system' will only have create permission with Some login (editable). They cannot edit old records.

Hide fields in odoo9 openerp

I want hide fields for user in odoo 9. For example, hide Deadline in Project > Task module.
Only administrator can see this fields.
Any solution how create group etc. hide_only_admin_see and in field add this line.
<field name="date_deadline" groups="hide_only_admin_see" />
I'm find in source groups="base.group_no_one", groups="base.group_user"
but don't understand is it possible create my own group, when add to fiels that only Manager can see this...
Here is my solution:
https://postimg.org/image/rvxi74f51/
https://postimg.org/image/b87h1dlhv/
https://postimg.org/image/5mzst1wtz/
ID from file add to field etc: groups="export.res_groups_84"
On odoo 8, you forbid access to a field to all users (except configuration permissions) in that way:
<field name="date_deadline" position="attributes">
<attribute name="groups">base.group_system</attribute>
</field>
To create new group of permissions,
on odoo 8, you can create record for new category like:
<record model="ir.module.category" id="xxx">
<field name="name">Name of new category of permissions</field>
<field name="sequence">200</field>
</record>
You can create new records for groups permission on res_groups:
<record model="res.groups" id="hide_only_admin_see">
<field name="category_id" ref="XXXX"/>
<field name="name">Usuario</field>
</record>
On category_id you must write the ir_module_category you are creating / overridiing.
After this, you have to create a line on your ir.model.access.csv to give correct permissions to the model you want, something like:
"access_project.issue","project_issue access","model_project_issue","hide_only_admin_see",1,0,0,0
Finally, go to the line and override like:
<field name="date_deadline" groups="your_custom_module.hide_only_admin_see" />

What is the use of ir.ui.menu in OpenERP 7.0?

I am new to OpenERP and I wish to know about that what is model="ir.ui.menu" in OpenERP. Like this there are many other models also there.
For eg:
model="ir.ui.view"
model="ir.actions.act_window"
Can any one explain all this?
With the ir.ui.menu model you can create new menu items. You can use the menuitem tag, it is shortcut:
<record id="menu_human_readable_name" model="ir.ui.menu" >
<field name="name">Human readable name</field>
<field name="sequence" eval="10" />
<field name="action" ref="action_name" />
<field name="parent_id" ref="base.menu_custom" />
</record>
And you have a small explanation of the ir.actions.act_window model in the Odoo documentation. You can assign the id of this kind of action in the field action of the ir.ui.menu model
The most common action type, used to present visualisations of a model
through views: a window action defines a set of view types (and
possibly specific views) for a model (and possibly specific record of
the model).
<record id="action_human_readable_name_act_window" model="ir.actions.act_window">
<field name="type">ir.actions.act_window</field>
<field name="name">Human readable name</field>
<field name="res_model">model.name</field>
<field name="view_mode">tree,form</field>
<field name="view_type">form</field>
<field name="target">current</field>
<field name="domain">[]</field>
<field name="context">{}</field>
<field name="search_view_id" ref="ir.ui.view" />
</record>
The ir.ui.view is used for the views where you show the field or tree list
You have more information in the Odoo Documentation:
Views define the way the records of a model are displayed. Each type
of view represents a mode of visualization (a list of records, a graph
of their aggregation, …). Views can either be requested generically
via their type (e.g. a list of partners) or specifically via their id.
For generic requests, the view with the correct type and the lowest
priority will be used (so the lowest-priority view of each type is the
default view for that type).
<record model="ir.ui.view" id="view_id">
<field name="name">view.name</field>
<field name="model">object_name</field>
<field name="priority" eval="16"/>
<field name="arch" type="xml">
<!-- view content: <form>, <tree>, <graph>, ... -->
[...]
<field name="field_name" />
[...]
</field>
</record>
Menus and Actions
Menus are records in the ir.ui.menu table. In order to create a new menu entry, you can directly create a record using the record tag.
<record id="menu_external_id" model="ir.ui.menu">
<field name="name">New Menu</field>
<field name="action" ref="action_external_id"/>
<field name="sequence" eval="<integer value>" />
<field name="parent_id" ref="parent_menu_external_id"/>
</record>
There is a shortcut by using the menuitem tag that you should use preferentially. It offers a flexible way to easily define the menu entry along with icons and other fields.
<menuitem id="menu_external_id"
name="New Menu"
action="action_external_id"
icon="ICON_NAME"
groups="groupname"
sequence="<integer value>"
parent="parent_menu_external_id"
/>
If you remove parent/parent_id from menu/menuitem then it becames top level menu.
Actions
action specifies the identifier of the attached action defined in the action table (ir.actions.act_window). This field is not mandatory : you can define menu elements without associating actions to them.
This is useful when defining custom icons for menu elements that will act as folders. This is how custom icons for “Projects” or “Human Resources” in OpenERP are defined).
The actions define the behavior of the system in response to the actions of the users ; login of a new user, double-click on an invoice, click on the action button, ...
There are different types of simple actions:
Window: Opening of a new window
Report: The printing of a report
- Custom Report: The personalized reports
- RML Report: The XSL:RML reports
Execute: The execution of a method on the server side
Group: Gather some actions in one group
The actions are used for the following events:
User connection.
The user clicks on a menu.
The user clicks on the icon ‘print’ or ‘action’.
<record id="action_external_id" model="ir.actions.act_window">
<field name="name">action.name</field>
<field name="view_id" ref="view_external_id" />
<field name="domain">[('field','operator','value')]</field>
<field name="context">{'key':value}</field>
<field name="res_model">Model Name</field>
<field name="view_type">form|tree</field>
<field name="view_mode">form,tree|tree,form|form|tree</field>
<field name="target">new/current</field>
</record>
I hope you will easily understand my explanation below:
"ir.ui.menu" is a model which is mapped as ir_ui_menu table of database that stores data of menus in Odoo (OpenERP). Every menu in Odoo (OpenERP) is inserted via xml file and stored in database. Also, "ir.ui.view" stores view data (such as form, tree, and search views) and "ir.actions.act_window" stores action data.
Conclusion: Mostly (not all), models inside OpenERP are manifestation of tables inside database.
http://useopenerp.com/v8/model/ir-ui-view#pagetop
https://www.odoo.com/documentation/8.0/reference/actions.html#window-actions-ir-actions-act-window
See the above references for detail.
hope this will help you.

How to make field readonly based on group and status?

I want to make field readonly based on group, and status. Like I have two groups:
Manager Group
User Group
If I give User Group to any user and then change Status to Done, then field will be readonly for this user.
Hope I was able to make it clear to understand. Thanks.
Create a functional field of type boolean. If the logged in user is under user group and state is done, then return true. Then in the view, specify attrs="{'readonly':[('boolean_field_name','=',True)]}"
OR
First create your form view. Then inherit the view also specify the groups. for example in sale order form view, i want to make the customer reference field readonly for group user when state is not in draft or sent.
<record id="view_order_form_cust_ref_readonly" model="ir.ui.view">
<field name="name">sale.order.form.readonly.cust</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="groups_id" eval="[(6, 0, [ref('base.group_user') ])]"/>
<field name="arch" type="xml">
<field name='client_order_ref'" position="attributes">
<attribute name="attrs">{'readonly':[('state','not in',['draft','sent'])]}</attribute>
</field>
</field>
</record>
you can apply access rule on field level in OpenERP, like in py
'name': fields.char('Name', size=128, required=True, select=True,
read=['base.group_user'] ),
And for status in xml:
<field name="name " attrs="{'readonly': [('state','=','done')]}"/>
There is another sweet way to achieve this. Create one functional field and in that check for group assigned to that user and do not store that field. In View use that field in attrs.
Let say in product you don't want to allow any user to modify Internal Reference if user does not belongs to Product Modify group.
Create one group.
<data noupdate="1" >
<record model="res.groups" id="group_product_modify">
<field name="name">Product Modify</field>
<field name="users" eval="[(4, ref('base.user_root'))]"/>
</record>
</data>
Python file
class product_template(models.Model):
_inherit="product.template"
#api.one
def set_access_for_product(self):
self.able_to_modify_product = self.env['res.users'].has_group('product_extended_ecom_ept.group_product_modify')
able_to_modify_product = fields.Boolean(compute=set_access_for_product, string='Is user able to modify product?')
XMl file should be looking like,
<record model="ir.ui.view" id="product_template_update_internal_code_ept">
<field name="name">Product Template extension</field>
<field name="inherit_id" ref="product.product_template_only_form_view"/>
<field name="model">product.template</field>
<field name="priority" eval="50" />
<field name="arch" type="xml">
<field name="default_code" position="before">
<field name="able_to_modify_product" invisible="1" />
</field>
<field name="default_code" position="attributes">
<attribute name="attrs">{'readonly' : [('able_to_modify_product','=',False)]}</attribute>
</field>
</field>
</record>
In case if you are using Odoo web client(GUI) instead of code then there is a bit unorthodox way to do it.
Just make a copy of the field which will contain same value as the original one(giving original field name in Related Field under Advanced Properties) and mark it as read-only.
Then you can hide original field from the users which cannot edit that field and hide the copy field from those who can edit by using groups attribute.

OpenERP always displays inherited view instead of original

Original views:
<record id='view_1' model='ir.ui.view'>
<field name="name">view.name</field>
<field name="model">my.object</field>
<field name="priority" eval="17"/>
<field name="type">form</field>
<field name="arch" type="xml">
...
</field>
</record>
inherited view from the original:
<record id='view_2' model='ir.ui.view'>
<field name="name">view.name</field>
<field name="model">my.object</field>
<field name="priority" eval="10"/>
<field name="inherit_id" ref="view_1"/>
<field name="type">form</field>
<field name="arch" type="xml">
...
</field>
</record>
So what happens is OpenERP always displays the inherited view ignoring the priority value. Is this expected behaviour, or there's something else I am missing?
If this is the expected behaviour, then please read further :-)
I have my.second.object with many2one field to my.object, and when I want to create my.object from this field, I want to open a bit different form view of my.object. I am trying to create a different view just for that purpose, but as you see it doesn't work so easily (or does it?).
Any help is appreciated.
Yes it is the expected behavior. The priority of a view only serves to select the main view to use when no specific view was requested. Inherited views are "patch views" that act like children of the view they inherit from, and may never be selected as "main views". They always apply on top of their parent view when that view is displayed.
If you want an alternative view for a certain model you should define a new stand-alone view that does not inherit from any other. If that view is meant to be used only in the context of the view of my.second.object, there are two common tricks to make OpenERP use it:
Define it inline in the form view of my.second.object, as a child of the <field> element. This may not work in all OpenERP clients depending on the version, and works best for declaring inline form views for o2m lines, normally.
Declare it as a stand-alone view with a low priority (e.g. 32) and put a magic context key in the many2one field of the my.second.object view that should use it. The magic key is in the form <view_type>_view_ref, and the value must be the XML ID of the desired view. This should work everywhere.
<!-- Example 1: inline form view -->
<form string="My second object">
<field name="my_object_id">
<form string="My object inline view">
<field name="name"/>
</form>
</field>
</form>
<!-- Example 2: explicitly ask for special view using magic key -->
<form string="My second object">
<field name="my_object_id" context="{'form_view_ref': 'module.my_object_form2'}"/>
</form>
For reference, have a look at this page of the OpenERP documentation that explains most of the options for making and using context-specific views.
NOTE: If you have used form_view_ref and from form view if you have
any button which is opening another form view of some other model then
it will give you error . It will try to open the same form view you
have passed in form_view_ref for another model also.
What "position" you defined in <field name="field_from_original_view">?
<record id='view_2' model='ir.ui.view'>
<field name="name">view.name</field>
<field name="model">my.object</field>
<field name="priority" eval="10"/>
<field name="inherit_id" ref="view_1"/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="field_from_original_view" position="after" (or before)>
<field name="inherit1" />
<field name="inherit2" />
<field name="inherit3" />
</field>
</field>
</record>
There may not be a possibility to make an inherited form the standard form of your model so that it will be presented automatically.
BUT If you look at a specific task --> open an inherited form view for a one2many field e.g.; there is. Set the context variable 'form_view_ref' to 'MODULE.VIEW_ID'.
<field name="myOne2ManyField" context="{'form_view_ref': 'myModule.myInheritedView'}/>
Still works with Odoo 9.0.