Odoo 18 Development Module: Struktur, File, dan Alurnya (Module Development Basics)

Pendahuluan

ERP Odoo adalah sistem ERP (Enterprise Resource Planning) berbasis open-source yang dirancang dengan arsitektur modular sehingga, setiap modul memiliki fungsi yang berbeda - beda namun, tetap terintegrasi. Arsitektur modular memungkinkan ERP Odoo untuk memberikan kebebasan bagi developer untuk menambah, mengubah, atau menghapus fitur sesuai kebutuhan tanpa mempengaruhi keseluruhan sistem.

Oleh karena itu, pemahaman yang baik terhadap struktur dasar modul serta alur development merupakan hal penting yang perlu kita ketahui sebagai ERP Odoo developer. Artikel ini akan membahas struktur modul, fungsi masing-masing direktori atau file di dalam modul ERP Odoo serta alur development modul Odoo secara garis besar.

A. Modul ERP Odoo

Modul di dalam istilah ERP Odoo adalah kumpulan beberapa fitur yang dikelompokkan berdasarkan tujuannya sehingga dapat ditambahkan, diaktifkan, atau dikembangkan. Modul ERP Odoo dibagi menjadi dua jenis, yaitu :

  • Modul default adalah modul yang development oleh ERP Odoo (contoh: CRM, Inventory, Sales).

  • Modul custom adalah modul yang development oleh pihak lain selain Odoo.

Jika kita ingin memodifikasi modul default di ERP Odoo tidak disarankan untuk development Odoo secara langsung karena, akan mengakibatkan error atau bug di Odoo. Solusi agar kita dapat development Odoo modul default adalah dengan membuat modul custom, Di dalam modul custom, kita dapat melakukan konsep OOP seperti Inheritance (Pewarisan). Sehingga kita dapat seluruh properti atau metode yang ada di dalam modul default. 

B. Struktur Modul ERP Odoo

Setiap modul ERP Odoo memiliki struktur nya masing - masing, tergantung pada kebutuhan dari dibentuknya modul tersebut, sehingga struktur dari suatu modul Odoo akan berbeda dengan struktur modul lainnya. Namun, ada struktur yang umum digunakan oleh developer dalam development Odoo. Berikut adalah contoh struktur yang umum digunakan dalam development modul Odoo: 

custom_module/
├── __init__.py
├── __manifest__.py
├── models/
│   └── __init__.py
│   └── custom_model.py
├── views/
|   └── custom_model_views.xml
├── security/
│   └── ir.model.access.csv
|   └── security.xml
├── data/
│   └── custom_model_data.xml
├── wizard/
│   └── __init__.py
│   └── custom_model_wizard.py
├── report/
│   └── __init__.py
│   └── custom_model_report.py
│   └── custom_model_report.xml
├── static/
│   └── description/
│       └── icon.png
│   └── src/
│       └── js/
│           └── custom_model.js
│           └── custom_model.css
├── i18n/ 
│   └── __init__.py 
│   └── custom_model.pot

__init__.py/

File tersebut digunakan untuk mengimpor Python package di dalam modul Odoo / folder sehingga, file tersebut wajib ada di setiap modul / folder. File tersebut dapat diletakkan di folder utama dan di dalam folder yang memiliki file Python seperti models, wizard, dan report.

Berikut adalah contoh isi dari file __init__.py :

from . import models
from . import wizards
from . import report

​__manifest__.py/

File tersebut berisi metadata modul seperti nama modul (name), versi (version), kategori modul (category), penjelasan modul (summary), nama pembuat modul (author), dependencies ke modul lainnya (depends), data yang dimuat (data), data demo (demo) dan sebagainya. 

Berikut adalah contoh isi dari file __manifest__.py :

{
  "name": "Custom Module",
  "version": "1.0",
  "category": "Custom",
  "summary": "A custom module for Odoo",
  "author": "Your Name",
  "website": "https://www.yourwebsite.com",
  "depends": ["base", "web"],
  "data": [
      "security/ir.model.access.csv",
      "views/custom_model_views.xml",
      "data/custom_model_data.xml",
      "report/custom_model_report.xml",
  ],
  "demo": [
      "demo/custom_model_demo.xml",
  ]
}

​models/

Folder tersebut digunakan untuk menyimpan file init dan file Python yang mendefinisikan model (kelas) dan logika bisnis.

Berikut adalah contoh model dari file Python:

from odoo import models, fields

class CustomModel(models.Model):
    _name = 'custom.model'
    _description = 'Custom Model'

    name = fields.Char(string="Name")
    description = fields.Text(string="Description")

​views/

Folder tersebut digunakan untuk menyimpan file XML yang berisi definisi tampilan antarmuka (UI) modul, seperti:

  • Form view

  • Tree (list) view

  • Search view

  • Menu dan action

Berikut adalah contoh view dari file XML:

<odoo>
  <record id="view_form_custom_model" model="ir.ui.view">
      <field name="name">custom.model.form</field>
      <field name="model">custom.model</field>
      <field name="arch" type="xml">
          <form string="Custom Model">
              <sheet>
                  <group>
                      <field name="name"/>
                      <field name="description"/>
                  </group>
              </sheet>
          </form>
      </field>
  </record>
</odoo>

​security/

Folder tersebut digunakan untuk menyimpan file yang berkaitan dengan hak akses pengguna terhadap model.

Berikut adalah contoh security dari file CSV:

id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_custom_model,access_custom_model,model_custom_model,group_name,1,1,1,1

​data/

Folder tersebut digunakan untuk menyimpan data - data awal atau statis yang perlu dimuat saat modul di instal. Misalnya:

  • Default configuration

  • Sequence

  • Record type ir.cron, ir.actions, dan lainnya

Berikut adalah contoh data dari file XML:

<odoo>
  <record id="custom_model_record_1" model="custom.model">
      <field name="name">Contoh Data 1</field>
  </record>
  <record id="custom_model_record_2" model="custom.model">
      <field name="name">Contoh Data 2</field>
  </record>
</odoo>

wizard/

Folder tersebut digunakan untuk menyimpan file Python (Transient Model) atau XML yang biasa digunakan untuk membuat wizard (popup form interaktif).

Berikut adalah contoh wizard dari file Python:

from odoo import models, fields, api

class CustomModelWizard(models.TransientModel):
  _name = 'custom.model.wizard'
  _description = 'Wizard untuk Custom Model'

  name = fields.Char(string='Nama')

report/

Folder tersebut digunakan untuk menyimpan file untuk membuat laporan.
Berikut adalah contoh report dari file XML:

<odoo>
    
   <!-- Template QWeb Report -->
   <template id="custom_model_report_template">
       <t t-call="web.html_container">
           <t t-foreach="docs" t-as="o">
               <t t-call="web.external_layout">
                   <div class="page">
                       <h2 style="text-align: center;">Laporan Custom Model</h2>
                       <table class="table table-sm table-bordered" style="width: 100%;">
                           <thead>
                               <tr>
                                   <th>Nama</th>
                                   <th>Tanggal Dibuat</th>
                               </tr>
                           </thead>
                           <tbody>
                               <tr>
                                   <td><t t-esc="o.name"/></td>
                                   <td><t t-esc="o.create_date.strftime('%d-%m-%Y') if o.create_date else ''"/></td>
                               </tr>
                           </tbody>
                       </table>
                   </div>
               </t>
           </t>
       </t>
   </template>

   <!-- Action Report -->
   <record id="action_custom_model_report" model="ir.actions.report">
       <field name="name">Custom Model Report</field>
       <field name="model">custom.model</field>
       <field name="report_type">qweb-pdf</field>
       <field name="report_name">custom_module.custom_model_report_template</field>
       <field name="report_file">custom_model_report</field>
       <field name="binding_model_id" ref="model_custom_model"/>
       <field name="binding_type">report</field>
   </record>

</odoo>

static/

Folder tersebut digunakan untuk menyimpan aset statis seperti gambar, file JS, CSS, dan lainnya.

Berikut adalah contoh static dari file JS:

<!-- @odoo-module -->

import { registry } from "@web/core/registry";
import { listView } from "@web/views/list/list_view";
import { ListRenderer } from "@web/views/list/list_renderer";
import { Component, onMounted } from "@odoo/owl";

export class CustomModelInfoHelper extends Component {
  static template = "custom_module.CustomModelInfoHelper";

  setup() {
      onMounted(() => {
          console.log("CustomModelInfoHelper mounted");
      });
  }
}

export class CustomModelListRenderer extends ListRenderer {
  static template = "custom_module.CustomModelListRenderer";
  static components = {
      ...ListRenderer.components,
      CustomModelInfoHelper,
  };
}

export const CustomModelListView = {
  ...listView,
  Renderer: CustomModelListRenderer,
};

registry.category("views").add("custom_model_list_view", CustomModelListView);

i18n/

Folder ini menyimpan file terjemahan (translation) untuk modul. Biasanya menggunakan ekstensi .pot, .po, atau .mo.

Berikut adalah contoh i18n dari file POT:

msgid ""
msgstr ""
"Project-Id-Version: custom_module 1.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-05-02 12:00+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: English <en@example.com>\n"
"Language: en_US\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#. module: custom_module
#: model:ir.model,name:custom_module.model_custom_model
msgid "Custom Model"
msgstr ""

#. module: custom_module
#: model:ir.actions.act_window,name:custom_module.custom_model_action
msgid "Custom Records"
msgstr ""

#. module: custom_module
#: field:custom.model,name:0
msgid "Name"
msgstr ""

C. Alur Development Modul Odoo

Berikut alur yang umum digunakan saat membuat modul baru di Odoo: 

1. Persiapan Lingkungan Development

Sebelum memulai development modul Odoo, kita perlu menginstal Odoo dengan versi yang diinginkan dan membuat virtual environment Python agar lingkungan developement stabil dan terisolasi sehingga package yang dibutuhkan Odoo tidak bercampur dengan sistem utama. Langkah tersebut memastikan proses development berjalan lancar tanpa konflik dependensi. Berikut adalah cuplikan dalam persiapan lingkungan development 


2. Membuat Modul Odoo

ERP Odoo menyediakan fitur scaffold yang sangat membantu developer dalam membuat struktur modul secara otomatis. Dengan satu perintah ./odoo-bin scaffold NAMA_MODUL PATH_MODUL, kita dapat langsung menghasilkan folder dan file dasar seperti __init__.py, __manifest__.py, serta direktori models, views, dan lainnya. Hal ini menghemat waktu dan membuat struktur modul yang konsisten. Berikut adalah contoh dalam menggunakan perintah scaffold.


3. Memodifikasi Metadata

File __manifest__.py adalah pusat informasi dari sebuah modul. Di dalamnya terdapat detail seperti nama modul, versi, dependensi, dan file data yang akan diload Odoo. Memahami dan memodifikasi file ini dengan benar adalah langkah penting agar modul bisa dikenali dan dijalankan oleh Odoo. Berikut adalah contoh dari file __manifest__.py.


4. Membuat Model atau Tampilan

Setelah struktur dasar dibuat, kita dapat mulai membuat logika bisnis di folder models/ menggunakan class Python, serta membuat antarmuka pengguna (UI) di folder views/ dengan XML. Model mendefinisikan struktur data dan perilaku, sedangkan view mengatur bagaimana data tersebut ditampilkan di UI Odoo. Berikut adalah contoh dari view di Odoo.


5. Menambahkan Hak Akses

Setiap model baru yang dibuat perlu diberikan hak akses agar dapat digunakan oleh pengguna. Hal ini dilakukan melalui file ir.model.access.csv di dalam folder security/. Tanpa konfigurasi ini, pengguna tidak akan bisa melihat, membuat, atau mengedit data dari model yang dibuat. Berikut adalah contoh dari akses di ERP Odoo.


6. Menginstal Modul dari UI / Terminal

Setelah modul dikembangkan, langkah selanjutnya adalah menginstalnya agar bisa digunakan. Proses instalasi bisa dilakukan dari antarmuka pengguna (UI) melalui modul Apps yang telah disediakan oleh ERP Odoo, atau melalui terminal dengan perintah tertentu. Hal tersebut akan memuat semua file yang telah didaftarkan dan mengaktifkan fitur modul di dalam sistem. Berikut adalah tampilan modul Apps Odoo.


7. Menguji Coba & Debug

Langkah akhir adalah melakukan pengujian dan debugging. Developer pada saat development perlu memastikan bahwa model, view, dan logika bisnis berfungsi sebagaimana mestinya. Debugging dapat dilakukan lewat log terminal, browser console, dengan menggunakan mode pengembang Odoo yang menyediakan informasi tambahan langsung di UI, atau jika menggunakan IDE (seperti Visual Studio Code) dapat menggunakan fitur debug yang tersedia di IDE tersebut. 

​Ingin pahami Odoo lebih dalam atau butuh bantuan teknis? Arkana siap membantu!

  Writer

Fadli Fatanah
Software Engineer



Share this post
Tags
Panduan Utama Dalam Customization Odoo di Perusahaan Anda