0. Pre-requisites
This article is written for Odoo 11.0. But also all steps here are suitable for Odoo 12.0 and above.
1. The Goal
Our goal is to hide button "Update Qty On Hand" that is present on product form when addon 'stock' (Inventory) is installed.
This button looks like:
And we want to hide this button from some group of users.
2. The Plan
We have to create new group. Let's call it "Cannot Update Qty On Hand".
We have to make button "Update Qty On Hand" invisible for users that are in group "Cannot Update Qty On Hand".
So we need to do following steps:
Create addon. Let's name it 'stock_update_qty_restrict'
Create group "Cannot Update Qty On Hand"
Make button "Update Qty On Hand" invisible for group "Cannot Update Qty On Hand
Find base view that have to be modified
Create new view that will inherit from base view
Apply groups attribute on button defined in base view
3. Create addon
Useful links:
Basically Odoo addon is a directory with following content:
controllers/: contains controllers (http routes)
data/: data xml
demo/: demo xml
examples/: external files lib/, ...
models/: model definitions
__init__.py
report/: reporting models (BI/analysis), Webkit/RML print report templates
__init__.py
security/: Securitu data
ir.model.access.csv
security.xml
static/: contains the web assets, separated into css/, js/, img/,
templates/: if you have several web templates and several backend views you can split them here
views/: contains the views and templates, and QWeb report print templates
wizards/: wizard model and views
__init__.py
__init__.py
__manifest__.py
Thus to create new addon we need to create directory. The name of directory is system name of addon.
So, let's create new directory stock_update_qty_restrict with following content:
security/
security.xml
views/
product_template.xml contains views for product.template model (Products)
product_product.xml contains views for product.product model (Variants)
__init__.py
__manifest__.py
Empty xml files must contain following code (add this snippet to security.xml, product_template.xml, product_product.xml files):
<?xml version="1.0" encoding="utf-8"?> <odoo> </odoo>
Our __manifest__.py file must look like:
{ 'name': "Restrict Update Qty On Hand Button", 'summary': """
Restrict access to Qty On Hand Button on product form """, 'author': "Your name",
# Categories can be used to filter modules in modules listing # Check https://github.com/odoo/odoo/blob/11.0/odoo/addons/base/module/module_data.xml # for the full list 'category': 'Warehouse', 'version': '11.0.0.0.1',
# any module necessary for this one to work correctly 'depends': [
'stock', ], # always loaded 'data': [ 'security/security.xml', 'views/product_template.xml',
'views/product_product.xml', ], }
Notes about __manifest__.py:
depends section contains list of addons that are required to make our addon work correctly.
data section lists all xml files that have to be loaded on module install/update.
After these steps done, we need to place this addon on odoo's addons_path (one of directories listed in addons_path configuration parametr)
When addon is available to Odoo, update list of addons available for Odoo and install your addon:
Navigate to Apps menu
Update Apps List
Remove filter Apps (this allows to search for addons that are not applications.
Type addon name in search box and press enter.
Install addon
This addon in current state is empty and do nothing. We need to install it to be sure that Odoo can find it and that addon is correct.
You can check addon created at this step on our github demo repository or check commit
4. Create group to hide button for
Useful links:
To add new user group we have to add new record in res.groups model. For this purpose we can user record tag in xml.
We can find system name of model by looking into models list via menu *Settings / Technical / Database Structure / Models*:
See Model field.
By opening model, we can see list of it's fields. And we can sort those fields by *Required* to find all required fields for this model.
Groups require only name field.
So, adding new group via xml will look like (file security/security.xml):
<record model="res.groups" id="group_cannot_update_qty_on_hand"> <field name="name">Cannot Update Qty On Hand</field>
</record>
Usually, it is not required to specify module name when creating new record via xml. In this case name of module, that contains this xml, will be used as first part of XMLID.
In our case fill xmlid of group will look like: stock_update_qty_restrict.group_cannot_update_qty_on_hand
One more note about XMLID - pay attention that it is prefixed with group_, that means that this XMLID references user group. This is required for better readability of code.
So, after module update you could see new user group:
You can check addon state at this step on our github demo repository or check commit
5. Make button "Update Qty On Hand" invisible for group "Cannot Update Qty On Hand
Useful links:
In order to make button invisible for some group of users or contrary to make it visible only for specific group of users we need to modify groups attribute of button tag in view.
First, we need to find base view that defines our button. We know only following information: it is introduced in Warehouse (stock) addon, it is related to Product model.
Thus we can search for Update Qty On Hand in module stock. The odoo code is located on GitHub. We can view source code of Warehouse addon via this link. Buttons definitions usualy located in views and our button is related to Product model. Thus, obviously, we need to search in file views/product_views.xml.
So, our button is defined in following views:
stock.product_product_view_form_easy_inherit_stock (model product.product [Product Variant ])
stock.product_form_view_procurement_button (model product.product [Product Variant ])
product_template_form_view_procurement_button (model product.template [Product ])
To achieve our goal we need to modify all these views. The xpath xml tag is used to declare modification of parent views. Check useful links at the begining of section to get more information.
In few words xpath tag have two required attributes: expr and position. First attribute (expr) contains XPath Expression to find XML Node to be modified. Second attribute (position) specify way of modification. Position supports following values:
before
after
attributes
replace
inside
The XPath tag works by placing its content in specified position.
In our case we need only attributes position, because we need to modify attribute of button.
So, let's do a bit of code (file views/product_template.xml):
<?xml version="1.0" encoding="utf-8"?> <odoo>
<record model="ir.ui.view" id="product_template_form_view_procurement_button">
<field name="model">product.template</field>
<field name="inherit_id" ref="stock.product_template_form_view_procurement_button"/>
<field name="arch" type="xml">
<xpath expr="//button[@name='%(stock.action_view_change_product_quantity)d']" position="attributes">
<attribute name="groups">!stock_update_qty_restrict.group_cannot_update_qty_on_hand</attribute>
</xpath>
</field>
</record> </odoo>
Update your fiile views/product_template.xml with code above and update your module. Test that this button will not be visible (on product template form view) for users that have group Cannot Update Qty On Hand.
Now i will describe step by step what is done via this view definition.
Because Odoo Views have inheritance (which means extension in this case), any change to base views have to be done by creating new view that extends base view. See <field name="inherit_id" ref="stock.product_template_form_view_procurement_button"/> line, which means that our new view inherits (extends) base view.
Next point is XPath expression, which means find button with name %(stock.action_view_change_product_quantity)d and change attributes of this button. This XPath tag changes only one attribute of button - groups that is responsible for visibility of button depending on grous of current user. The Exclamation Sign ('!') at the begining of group's XMLID means NOT (user must not have specified group to see this button). If we want to make this button visible only for specified group, we have to remove this exclamation sign.
So, let's finish our task making button Update Qty On Hand invisible for our group on product variant forms too.
<?xml version="1.0" encoding="utf-8"?> <odoo> <record model="ir.ui.view" id="product_product_view_form_easy_inherit_stock"> <field name="model">product.product</field> <field name="inherit_id" ref="stock.product_product_view_form_easy_inherit_stock"/> <field name="arch" type="xml"> <xpath expr="//button[@name='%(stock.action_view_change_product_quantity)d']" position="attributes"> <attribute name="groups">!stock_update_qty_restrict.group_cannot_update_qty_on_hand</attribute> </xpath> </field> </record>
<record model="ir.ui.view" id="product_form_view_procurement_button"> <field name="model">product.product</field> <field name="inherit_id" ref="stock.product_form_view_procurement_button"/> <field name="arch" type="xml"> <xpath expr="//button[@name='%(stock.action_view_change_product_quantity)d']" position="attributes"> <attribute name="groups">!stock_update_qty_restrict.group_cannot_update_qty_on_hand</attribute> </xpath> </field> </record> </odoo>
Update our addon, enable Product Variants and check that it works for product variants too.
You can check addon state at this step on our github demo repository or check commit