Odoo is an open-source solution, and it consists of different business modules. A developer can modify or integrate the business workflows with Odoo. For developing Odoo modules we have certain guidelines which will help the developers to improve the Odoo code quality. We can go through these guidelines in this blog.
Module Structure
In Odoo development, we can add new business logic or we can extend the existing Odoo business logic. We can create new modules for this. There are different directories for a module.\
Directories
Each of the directories has different files, each file has its own functionalities.
data/:
Demo or data files will be included in the data directory. XML is used for creating data or demo files.
The syntax is:
<odoo>
<data noupdate=”1”>
<!-- Only loaded when installing the module <operation/>
</data>
</odoo>
<odoo>
<data>
<!-- (Re)Loaded at install and update <operation/>
</data>
</odoo>
models/:
Inside the model directory, we can see different model files and an __init__.py. These are python files.
_name is one of the important attributes of models, it defines the name of the table. Models are database tables. ‘.’ in the model name will replace ‘_’ for the table name. Moreover, we can define different types of fields and functions for each model and we can extend or create the models for development.
For example:
test_model.py
from Odoo import fields, models
class ModelTest(models.Model):
_name = "model.test"
_description = "Model Test "
name = fields.Char(string=”name”)
We want to import all the model files in __init__.py file.
For example:
__init__.py
from. import test_model
controllers/:
In the case of Odoo for the front-end modules, we can use controllers. All controllers will be defined in this directory. __init__.py file is also defined inside the controller for importing all python files inside the controller.
For example:
main.py
from odoo import http
from odoo.http import request
class Product(http.Controller):
@http.route('/products', type='http', auth='public', website=True)
def my_products(self , **kwargs):
products = request.env[product.product].sudo().search([])
return request.render('my_module.product_details_page', {'product_details':
products})
__init__.py
from . import main
views/:
Views directory contains XML files for views and templates. Views are the visualization of records. We can define views for how to display the records for the end-user. The developer can also do different customization in views. There are different view types in Odoo such as, tree, form, activity, kanban, and many more.
The syntax is:
<record id="model_view_id" model="ir.ui.view">
<field name="name">NAME</field>
<field name="model">MODEL</field>
<field name="arch" type="xml">
<VIEW_TYPE>
<VIEW_SPECIFICATIONS/>
</VIEW_TYPE>
</field>
</record>
static/:
All web assets are included in the status directory. We have an src directory inside the static directory. JS, CSS, SCSS, img, and many more are the different files for the web interface, these are defined corresponding directories like JS, CSS, SCSS, img, and many more under the src directory.
In Odoo 15 the assets paths will be added on the __manifest__.py.
For Example:
'assets': {
'web.assets_backend': [
'calendar/static/src/scss/calendar.scss',
'calendar/static/src/js/base_calendar.js',
'calendar/static/src/js/calendar_renderer.js',
'calendar/static/src/js/calendar_controller.js',
'calendar/static/src/js/calendar_model.js',
'calendar/static/src/js/calendar_view.js',
'calendar/static/src/js/systray_activity_menu.js',
'calendar/static/src/js/services/calendar_notification_service.js',
],
'web.qunit_suite_tests': [
'calendar/static/tests/**/*',
],
'web.assets_qweb': [
'calendar/static/src/xml/base_calendar.xml',
],
},
security/:
All security-related files are included in this directory. We can create different users and can set permissions to them separately. And also possible to set different rules for security.
Access rights
ir.model.access.csv files are defined for setting the access rights. All-access rights consist of model, group, and different permissions such as reading, write, create, unlink.
For Example:
Id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_calendar_alarm,calendar.alarm,model_calendar_alarm,base.group_user,1,1,1,1
Record rules
We can also set some rules for our records. These rules are related to the model ir.rule. domain_force is used for restricting the accesses based on the domain condition.
For Example:
<record id="survey_survey_rule_survey_user_read" model="ir.rule">
<field name="name">Survey: officer: read all</field>
<field name="model_id" ref="survey.model_survey_survey"/>
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('group_survey_user'))]"/>
<field name="perm_unlink" eval="0"/>
<field name="perm_write" eval="0"/>
<field name="perm_read" eval="1"/>
<field name="perm_create" eval="0"/>
</record>
wizard/:
The wizard directory contains XML and python files that are related to wizards. Wizards are actually dynamic forms for user interaction. In the case of the wizard, we extend the TransientModel. Wizards are not stored permanently on the database, it is removed after a certain time. For opening the wizards we set the target as new on window actions.
<record id="wizard_example" model="ir.actions.act_window">
<field name="name">Wizard Example</field>
<field name="res_model">wizard.model</field>
<field name="view_mode">form</field>
<field name="target">new</field>
<field name="binding_model_id" ref="model_context_model_ref"/>
</record>
report/:
All the files that relate to reports will be included in the report directory. We can create different reports in Odoo. A report contains 2 elements:
ir.actions.report: which defines different parameters for the report.
<record id="action_account_original_vendor_bill" model="ir.actions.report">
<field name="name">Original Bills</field>
<field name="model">account.move</field>
<field name="binding_model_id" ref="model_account_move"/>
<field name="report_type">qweb-pdf</field>
<field name="report_name">account.report_original_vendor_bill</field>
<field name="report_file">account.report_original_vendor_bill</field>
<field name="attachment">'original_vendor_bill.pdf'</field>
<field name="attachment_use">True</field>
<field name="binding_view_types">list</field>
</record>
Qweb view: We can render the reports using different elements in qweb.
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="web.external_layout">
<div class="page">
<h2>Report title</h2>
</div>
</t>
</t>
</t>
test/:
When we create python files, we can also create unit tests for the module.
When creating a module we have to create two important files directly inside the main directory, ie, __manifest__.py and __init_.py.
__manifest__.py:
This file consists of a single dictionary containing all module descriptions.
For Example:
{
'name': 'Maintenance',
'version': '1.0',
'sequence': 100,
'category': 'Manufacturing/Maintenance',
'description': """
Track equipments and maintenance requests""",
'depends': ['mail'],
'summary': 'Track equipment and manage maintenance requests',
'website': 'https://www.odoo.com/app/maintenance',
'data': [
'security/maintenance.xml',
'security/ir.model.access.csv',
'data/maintenance_data.xml',
'data/mail_data.xml',
'views/maintenance_views.xml',
'views/mail_activity_views.xml',
'data/maintenance_cron.xml',
],
'demo': ['data/maintenance_demo.xml'],
'installable': True,
'application': True,
'assets': {
'web.assets_backend': [
'maintenance/static/src/**/*',
],
},
'license': 'LGPL-3',
}
__init_.py :
Here we import all python directories. I.e. ,
from . import models
from . import controllers
These are the most important guidelines for creating a module in Odoo 15