Module or addon is a directory that contains certain files that can add or remove odoo features. For example, the ‘sale’ module for sales features, ‘purchase’ for purchases and others. Odoo has provided a fairly complete module that we can install and use immediately in the default odoo installation. If it’s still lacking we can download the free or paid modules on the Odoo apps store, github, or other websites, or if there are no modules/addons available according to our needs, we can create our own module.
This article is the first part of the Odoo Module Development Tutorial series on my blog. In this series, I will discuss how to create an odoo module/addon for beginners. They range from the simplest ones to the slightly more complicated ones.
To follow this article, make sure you have installed odoo on your computer. You must able to install modules/addons, add custom modules/addons to your odoo installation, restart the odoo service, and enter the debug/developer mode. Please read this article to learn how to do that on the Windows operating system. Or read this article if you are a Linux user.
To create a module/addon we must create a directory with any name as you desired, as long as it does not contain spaces or special characters. For example the custom_sale. Use underscore ( _ ) to separate each word, if the name of the module that you want is more than one word. You can put this directory anywhere. But you have to modify the odoo configuration in the odoo.conf file, then enter the name of the parent directory of your module. Please read the tutorial on how to install odoo on Windows or Linux to find out how to do this, where the link can be found in the previous paragraph. If you have trouble adding your custom module directory by modifying the odoo configuration in the odoo.conf file, put your custom module directory (in this article the custom_sale directory) in the same directory where the original odoo module/addon is located, which is a directory that contains directories such as account, sale, purchase, point_of_sale etc. Usually this directory is located in odoo_installation_path/odoo-server/addons.
Then create a file with the name of __manifest__.py in that directory, with the contents like below.
{ "name": "Custom Sale", # any text "author": "Ngasturi", # any text "website": "https://en.ngasturi.id", # any text "version": "1.0.0", # any text "license": "LGPL-3", # choose between GPL-2, GPL-3, AGPL-3, LGPL-3, OEEL-1, OPL-1, or Other proprietary "installable": True # must True }
When opened from the Sublime text editor, the directory will look like the image below.

Restart your odoo service, enter debug/developer mode, then open the Apps menu. Make sure that the Update Apps List menu is exist. If not, there are 2 possibilities, the first is that you may not be logged in as an administrator or you have not entered the debug/developer mode. Click the Update Apps List menu, a dialog will appear, click the Update button and wait for it to finish.
Search the directory or module name that you have created in the apps menu, like the image below.

If the directory/module name that you have created appears when you search it, like in the picture above, it means that you have successfully created a custom module/addon for odoo. CONGRATULATION !!! 🙂 If not, you have to be patient and repeat this tutorial from the beginning, good luck.
To create a custom module/addon for odoo, we only need to create a directory and a python file, named __manifest__.py. Easy enough, right ? Of course, with just a directory and a python file, the module that we create will have no use at all. To provide the functionality to the custom module that we have created, we have to create a few more files, the number of files, and the types of files depending on the function of the module that we are going to create.
As a case study, we will try to create a module that adds the name of the broker/middleman in the Sales menu, below the Salesperson field. Enter the Apps menu again then install the Sales or sale_management module. Then edit the __manifest__.py file that we have created to add the dependencies to the sale module. Like in the code below.
{ "name": "Custom Sale", # any text "author": "Ngasturi", # any text "website": "https://en.ngasturi.id", # any text "version": "1.0.0", # any text "depends": [ "sale", # depedency to sales module ], "license": "LGPL-3", # choose between GPL-2, GPL-3, AGPL-3, LGPL-3, OEEL-1, OPL-1, or Other proprietary "installable": True # must True }
When we want to change the features of an existing module, make sure we have inserted the name of the module/directory in the depends section in the __manifest__.py file in our custom module. If not, there will be a possibility that our module will not run properly, for example it cannot access fields and so on. You may ask why in the __manifest__.py file I insert the sale module in the dependencies section, even though in the previous paragraph I asked you to install the sale_management module. I do this because the sale module is a module where the main function of the sales feature is written, while the sale_management module is also inherit to the sale module. I want to show you that in one sales feature, not all code is written in one module. Odoo sometimes breaks the code of a feature (in this example it is a sales feature) into several modules. Please see the list of odoo 14 modules/addons on the github page and count the modules that have names with the sale_ prefix such as the sale_coupon module and others. Include the modules with the website_sale_ prefix. But if you want to write the sale_management module as a dependency in the __manifest__.py file that’s fine too.
The next step, still in the custom_sale directory, create a python file with the name of custom_sale.py or with another name according to your wishes, with the following contents:
# -*- coding: utf-8 -*- # import the default odoo module from odoo import api, fields, models, exceptions, _ # create a new class # the class name is up to you, but must inherit to Model class class sale_order(models.Model): # use _inherit if we want to override the existing class # the sale.order model is exist in the original odoo code # if the model does not exist or the module not yet installed # it will cause an error _inherit = 'sale.order' # create a new database table column with varchar data type and mandatory # we will discuss the other data type in another article middleman = fields.Char("Middleman", required=True)
Then create another python file with the name of __init__.py to import the python file that we have created above. Because in this tutorial the file name that I create is custom_sale.py, then I can use the code below to import the file in the __init__.py file.
# import the python file that we have created from . import custom_sale
Create an xml file with any name, but in this tutorial I use the custom_sale_view.xml file name with the following content:
<?xml version="1.0"?> <odoo> <data> <!-- above code is odoo default code --> <!-- display the new Middleman field below the Salesperson field --> <record id="view_order_form_inherit" model="ir.ui.view"> <field name="name">sale.order.form</field> <field name="model">sale.order</field> <field name="inherit_id" ref="sale.view_order_form"/> <field name="arch" type="xml"> <field name="user_id" position="after"> <field name="middleman" /> </field> </field> </record> <!-- below code is odoo default code --> </data> </odoo>
The final step, update the __manifest__.py file and insert the xml file name above to the data section. So the final contents of the __manifest__.py file will look like in the code below.
{ "name": "Custom Sale", # any text "author": "Ngasturi", # any text "website": "https://en.ngasturi.id", # any text "version": "1.0.0", # any text "depends": [ "sale", # depedency to sales module ], "data": [ "custom_sale_view.xml" ], "license": "LGPL-3", # choose between GPL-2, GPL-3, AGPL-3, LGPL-3, OEEL-1, OPL-1, or Other proprietary "installable": True # must True }
Restart your odoo service. Please remember when you make any changes to any file you must restart the odoo service.
After the odoo service has finished restarting, open the Apps menu then find the directory/module name that you have created, then click the Install or Upgrade button. If you have followed this tutorial correctly and the custom module/addon that you created has no errors, when you open the Sales menu precisely in the Other Info tab you will see a field with the name of Middleman as shown below.

Please fill the field with any text then save it by pressing the Save button.
Congratulation on successfully creating your first odoo custom module/addon, which really has a purpose or functionality. Easy right ? With just a directory consisting of three python files and an xml file, you have successfully added a new field to the Sales menu.
Download the Source Code