How to Use System Parameter to Store the Application Configuration in Odoo

System parameter in odoo is a model with a key value pair format that is used to store the application configuration. System parameter are only used to store the configuration, the real implementation must be manually programmed in each model as needed.

The model of the system parameter is a ir.config_parameter. System parameter are usually used to enable or disable a certain feature, store the default values ​​etc. Since the system parameter is only for storing the configuration, it doesn’t specify a limit for its use, so we can use the system parameter freely for anything in our odoo application.

Create System Parameter

There are several ways to create a system parameter. First, we can create it through the user interface. Logged in as an administrator and enter the debug mode, then go to the Settings >> Technical >> Parameters >> System Parameters menu. Then click the Create button.

In the key field, we can fill any text, as long as it is unique per database. Always try to use lowercase letters and avoid spaces or special characters.

In the value field, the data type that we can use is string, so we can fill this field with any value as long as we can process it in python. My advice, fill this field with text in integer format, comma sparated value, or JSON without spaces if we want to process this field further with python.

The second way is to create a system parameter from the module, so that when the module is installed, the system parameter is automatically created, the user does not need to create it manually. Here is an example how to do it.

<record id="allowed_warehouse_parameter" model="ir.config_parameter">
    <field name="key">allowed_warehouse</field>
    <field name="value">2,5,9</field>
</record>

In addition, we can also place the system parameter in the Configuration or the Settings form, make it easier for users to access.

To do this, first, we have to create a model that inherit to the res.config.settings model. Then create a field with the data type of Char and place the key name of the system parameter that you want in the config_parameter as shown below.

# -*- coding: utf-8 -*-

from odoo import api, fields, models, _

class ResConfigSettings(models.TransientModel):
    _inherit = 'res.config.settings'

    allowed_warehouse = fields.Char(string='Allowed Warehouse', config_parameter='allowed_warehouse')

Then insert those field into the Configuration form by inherit its view, in this example I will insert the allowed_warehouse field above into the Sales Configuration form.

<record id="res_config_settings_view_form" model="ir.ui.view">
    <field name="name">res.config.settings.view.form.inherit.sale</field>
    <field name="model">res.config.settings</field>
    <field name="priority" eval="10"/>
    <field name="inherit_id" ref="sale.res_config_settings_view_form" />
    <field name="arch" type="xml">
        <xpath expr="//div[@id='sale_ebay']" position="after">
            <h2 class="mt32">New Configuration</h2>
            <div class="row mt16 o_settings_container">
                <div class="col-12 col-lg-6 o_setting_box">
                    <div class="o_setting_right_pane">
                        <label for="allowed_warehouse"/>
                        <div class="text-muted">
                            <field name="allowed_warehouse" />
                        </div>                                
                    </div>
                </div>
            </div>
        </xpath>
    </field>
</record>

When we go to the Sales >> Configuration >> Settings menu, we can fill the value of allowed_warehouse system parameter above like the image below. If we click the Save button, what we insert will be stored in the ir.config_parameter model or system parameter.

Read System Parameter

To read the system parameter we just need to call the get_param method of the ir.config_parameter model. The first argument is the key of the system parameter that we want to access, the second argument is optional, which is the default value that will be returned if the key of the system parameter that we access is not exist in the database. This is an example of how to use the system parameter to limit warehouse access in sales order by overriding the create and write methods.

# -*- coding: utf-8 -*-

from odoo import api, fields, models, exceptions, _

class SaleOrder(models.Model):
    _inherit = 'sale.order'

    @api.model
    def create(self, vals):
        # read the system parameter with key of 'allowed_warehouse'
        # if not exist, it will return an empty string
        # then split based on the comma character to convert it into a list

        allowed_warehouse = self.env['ir.config_parameter'].get_param('allowed_warehouse', '').split(',')
        
        # because the list value is stored in string, convert it to an integer
        allowed_warehouse = list(map(lambda x: int(x), allowed_warehouse))

        # check the warehouse field that selected by the user, is it in the list of warehouses that are allowed or not
        if vals.get('warehouse_id', False) not in allowed_warehouse:
            raise exceptions.ValidationError('You are not allowed to create the sales order in this warehouse !')


        return super(SaleOrder, self).create(vals)


    def write(self, vals):
        # read the system parameter with key of 'allowed_warehouse'
        # if not exist, it will return an empty string
        # then split based on the comma character to convert it into a list

        allowed_warehouse = self.env['ir.config_parameter'].get_param('allowed_warehouse', '').split(',')

        # because the list value is stored in string, convert it to an integer
        allowed_warehouse = list(map(lambda x: int(x), allowed_warehouse))

        # check the warehouse field that selected by the user, is it in the list of warehouses that are allowed or not
        if vals.get('warehouse_id', False) not in allowed_warehouse:
            raise exceptions.ValidationError('You are not allowed to create the sales order in this warehouse !')


        return super(SaleOrder, self).write(vals)

From the code above, if user select the warehouse that not exist in the allowed_warehouse system parameter, an error will occur like image below.

Change the Value of System Parameter

To change the value of system parameter we can use the set_param method. The first argument is the key of the system parameter that we want to change. The second argument is the value. This is an example of how to change the value of the system parameter to record how many Sales Order that were deleted.

def unlink(self):        
    for rec in self:
        deleted = int(self.env['ir.config_parameter'].get_param('deleted_sale_order', '0')) + 1
        self.env['ir.config_parameter'].set_param('deleted_sale_order', deleted)

    return super(SaleOrder, self).unlink()

In my opinion it is better if you know some of the default odoo system parameter. The first is web.base.url. Fill this system parameter with your server address, for example https://ngasturi.id:8069. This system parameter is used as a basis when we create a url to our server. For example, when we create an email template with code like this,

<p>
    Follow <a href="${'/my/order'}"> this link </a> to see your order detail
</p>

When a customer receives an email, the href in the code above will be translated into https://ngasturi.id:8069/my/order automatically. So that when we change the website domain we don’t need to change the email template code.

This system parameter is also used as the address to load the bootstrap and css files used in the report. So if your pdf report looks messed, there could be something wrong with this system parameter.

There are cases that the value of web.base.url system parameter will change automatically, without we realizing it. To prevent this, it’s a good idea to add the web.base.url.freeze system parameter with the value of True.

Download the Source Code

Related Article

Leave a Reply

Your email address will not be published. Required fields are marked *