Building the addon aimed to hide button

This post describes how to build addon that will hide Update Qty On Hand button on product form

0. Pre-requisites

This article is written for Odoo 11.0. But also all steps here are suitable for Odoo 12.0.

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:

  1. Create addon. Let's name it 'stock_update_qty_restrict'

  2. Create group "Cannot Update Qty On Hand"

  3. Make button "Update Qty On Hand" invisible for group "Cannot Update Qty On Hand

    1. Find base view that have to be modified

    2. Create new view that will inherit from base view

    3. 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


  • report/: reporting models (BI/analysis), Webkit/RML print report templates


  • 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




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)



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"?>

Our 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 # for the full list  'category': 'Warehouse', 'version': '',
 # 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

  • 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:

  1. Activate developer mode 

  2. Navigate to Apps menu

  3. Update Apps List

  4. Remove filter Apps (this allows to search for addons that are not applications.

  5. Type addon name in search box and press enter.

  6. 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>
Pay attention at id attribute of record tag. It is XMLID (External Identifier). Usualy it consists of two parts: <module name>.<identifier>
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"?>
<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>
</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"?>
    <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>
<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