Halo teman-temen pengembang Odoo!

Para pengembang modul Odoo pasti sudah akrab dengan konsep model pada Odoo. Model adalah salah satu fitur penting yang digunakan untuk mengatur dan mengelola data dalam modul Odoo.

Mengenal model Odoo

Model Odoo adalah salah satu fitur penting yang digunakan untuk mengelola dan mengatur data dalam sistem. Secara sederhana, model dapat diartikan sebagai sebuah template atau rancangan yang digunakan untuk menentukan jenis data apa saja yang akan disimpan ke dalam database dan hubungan antar data tersebut. Model dapat digunakan untuk mengorganisir data dari berbagai modul, seperti pada modul penjualan, pembelian, inventaris, dan lain sebagainya.

Setiap model Odoo memiliki elemen penting, yaitu field, record, dan method. Field adalah kolom atau atribut pada model yang digunakan untuk menyimpan data. Record adalah baris atau instance pada model yang merepresentasikan satu set data yang tersimpan dalam field-field tersebut. Method adalah fungsi atau prosedur yang digunakan untuk memanipulasi data pada model.

Model Odoo dibuat menggunakan bahasa pemrograman Python. Kamu dapat membuat model baru atau menyesuaikan model yang sudah ada sesuai dengan kebutuhan modul yang sedang dikembangkan. Model berperan sebagai perantara antara obyek pada antarmuka pengguna dan database penyimpanan data.

Ketika kamu membuat sebuah modul atau fitur baru pada Odoo, kamu harus menentukan tabel dan kolom-kolom apa saja yang akan digunakan untuk menyimpan data yang diperlukan. Hal tersebut dilakukan melalui file model. File model ini berisi definisi tabel-tabel tersebut, seperti nama tabel, nama kolom, tipe data, relasi antar tabel, dan banyak lagi.

Misalnya, jika kamu ingin membuat modul untuk menyimpan data pelanggan baru, maka kamu perlu membuat sebuah file model yang akan mendefinisikan tabel untuk menyimpan data pelanggan tersebut. Tabel tersebut dapat berisi data seperti nama pelanggan, alamat, nomor telepon, dan sebagainya. Struktur tabel tersebut dapat kamu tentukan menggunakan file model.

Model Odoo merupakan sebuah ORM (Object-Relational Mapping) layer yang bertugas untuk menghubungkan antara struktur database dan kode aplikasi Odoo. ORM layer ini memudahkan programmer dalam memanipulasi data tanpa perlu mengetahui detail struktur database secara langsung.

Sebagai ORM layer, programmer dapat mengakses data, dengan menggunakan bahasa pemrograman Python, dan melakukan manipulasi data seperti pengambilan, penyimpanan, pengeditan, dan penghapusan data dengan mudah. Hal tersebut dapat dilakukan karena ORM layer ini menyediakan API yang sudah terstruktur. Oleh karena itu, kamu tidak perlu lagi menggunakan query SQL secara manual dan dapat mempercepat proses pengembangan aplikasi. Selain memudahkan pengembangan aplikasi, ORM layer juga memudahkan dalam melakukan debugging dan maintenance.

Membedah model Odoo

Atribut

Baiklah, berikut ini adalah contoh sederhana sebuah model Odoo. Dari contoh tersebut, saya akan coba untuk menjelaskan semudah mungkin untuk kamu. Saya akan memecah dan menjelaskan kode tersebut sehingga lebih mudah diikuti penjelasannya.

from odoo import fields, models

class ProductTemplate(models.Model):
   _name = 'product.template'

   name = fields.Char(string='Product Name', required=True)
   list_price = fields.Float(string='Price')
   description = fields.Text(string='Description')

Baiklah, mari kita mulai dari baris pertama.

from odoo import fields, models

Baris tersebut meminta program untuk mengimpor modul fields dan models dari paket odoo untuk digunakan di dalam model yang kita kembangkan. Modul models digunakan untuk membuat kelas model, sedangkan modul fields digunakan untuk mendefinisikan tipe data dari tiap-tiap atribut model.

Kemudian, kita mendefinisikan kelas model ProductTemplate yang merupakan turunan dari kelas models.Model.

class ProductTemplate(models.Model):

Untuk memudahkan penggunaan, usahakan nama kelas model kita samakan dengan nama tabel database yang akan digunakan.

_name = 'product.template'

Pada definisi kelas model, kita menggunakan atribut _name untuk menentukan nama tabel database yang sesuai dengan kelas model tersebut.

name = fields.Char(string='Product Name', required=True)
list_price = fields.Float(string='Price')
description = fields.Text(string='Description')

Ketiga baris tersebut mendefinisikan atribut model. Pada contoh tersebut, kita mendefinisikan atribut name, list_price, dan description. Setiap atribut model diinisialisasi dengan obyek field dari modul fields.

Atribut name didefinisikan dengan tipe data Char yang merepresentasikan sebuah string dengan panjang yang tidak terbatas. Atribut tersebut juga diberi label “Product Name”. Karena kita mewajibkan agar atribut tersebut harus diisi oleh pengguna ketika menyimpan data maka kita menetapkan nilai dari argumen required menjadi True.

Atribut list_price didefinisikan sebagai tipe data Float, yang merepresentasikan sebuah bilangan pecahan. Atribut tersebut juga diberi label “Price”.

Atribut description didefinisikan sebagai tipe data Text, yang merepresentasikan sebuah teks dengan panjang yang tidak terbatas. Atribut tersebut juga diberi label “Description”.

Kita ambil contoh baris name = fields.Char(string='Product Name', required=True) dan kita telaah lebih detail lagi.

name merupakan nama dari atribut model tersebut. Nama atribut juga digunakan sebagai nama kolom pada tabel database.

fields.Char mendefinisikan tipe data dari atribute tersebut. Pada contoh ini, tipe data didefinisikan menggunakan kelas Char dari modul fields. Untuk tipe data lainnya, dapat dilihat di Dokumentasi Odoo bagian Referensi ORM API .

Selain tipe data Char, berikut ini adalah tipe data yang didukung oleh Odoo.

  • Boolean
  • Char
  • Float
  • Integer
  • Binary
  • Html
  • Image
  • Monetary
  • Selection
  • Text
  • Date
  • Datetime

Argumen string='Product Name' mendefinisikan label untuk atribute name ketika ditampilkan di interface pengguna. Pada contoh ini, atribute name akan diberi label “Product Name” ketika ditampilkan di interface pengguna.

Selanjutnya adalah argumen required=True. Argumen tersebut menentukan bahwa atribute name harus diisi ketika membuat obyek baru dari kelas model ProductTemplate. Jika atribute name tidak diisi, maka akan muncul pesan error saat mencoba menyimpan obyek baru tersebut.

Metode

Selain pendefinisian atribut, file model juga berisi metode-metode yang digunakan dalam pengelolaan data. Mari kita kembangkan contoh di atas dengan kebutuhan untuk menentukan diskon sebuah produk secara otomatis.

Dari kode sebelumnya, kita dapat mengembangkannya menjadi kode berikut ini.

from odoo import api, fields, models

class ProductTemplate(models.Model):
   _name = 'product.template'

   name = fields.Char(string='Product Name', required=True)
   list_price = fields.Float(string='Price')
   description = fields.Text(string='Description')
   discount = fields.Float(string='Discount', compute='compute_discount')

   @api.depends('list_price')
   def compute_discount(self):
      for record in self:
         record.discount = record.list_price * 0.1

Kali ini, saya hanya akan menjelaskan kode tambahannya saja karena selebihnya masih sama. Perbedaan dari kode sebelumnya adalah sebagai berikut.

@@ -1,4 +1,4 @@
-from odoo import fields, models
+from odoo import api, fields, models
 
 class ProductTemplate(models.Model):
     _name = 'product.template'
@@ -6,3 +6,9 @@
     name = fields.Char(string='Product Name', required=True)
     list_price = fields.Float(string='Price')
     description = fields.Text(string='Description')
+    discount = fields.Float(string='Discount', compute='compute_discount')
+
+    @api.depends('list_price')
+    def compute_discount(self):
+        for record in self:
+            record.discount = record.list_price * 0.1

Baik, mari kita lanjutkan artikel ini. Saya akan menjelaskan kode-kode yang sudah kita tambahkan.

Saya menambah atribut baru bernama discount untuk menyimpan data diskon kita. Saya menggunakan satu argumen baru yaitu compute. Argumen tersebut menunjukan bahwa nilai dari discount akan dihitung menggunakan method compute_discount.

Method compute_discount didekorasi dengan @api.depends('list_price'), yang menandakan bahwa atribut discount bergantung pada atribut list_price. Ketika atribut list_price diubah, maka method ini akan dipanggil untuk menghitung diskon berdasarkan harga produk dan menyimpan hasilnya di atribut discount.

Karena kita membutuhkan dekorasi @api.depends maka saya mengimpor modul api dari paket odoo seperti ditunjukan pada baris pertama.

from odoo import api, fields, models

Dalam method compute_discount, kita melakukan iterasi pada semua record dan menghitung diskon menggunakan rumus list_price * 0.1, yang menunjukkan bahwa diskon diberikan sebesar 10% dari harga produk. Hasil diskon kemudian disimpan di atribut discount.

Di Odoo, ketika sebuah atribut didefinisikan dengan compute maka atribut tersebut akan dianggap sebagai atribut yang dihitung (computed field) dan nilainya tidak disimpan dalam database. Nilai atribut tersebut akan dihitung setiap kali dibutuhkan.

Penutup

Demikian pembahasan tentang file model Odoo. Karena sudah terlalu panjang, saya cukupkan pembahasannya. Kita lanjutkan di artikel lainnya. Dari artikel ini, diharapkan kamu sudah memiliki gambaran awal tentang file model untuk pengembangan modul Odoo.

Pesan dari saya berkaitan tentang ORM layer.

Jangan sekali-kali menggunakan kursor database secara langsung jika ORM layer dapat melakukan hal yang sama!

Dengan menggunakan kursor database secara langsung, kamu sama saja bypassing semua fitur ORM yang disediakan. Selain itu, hal tersebut juga membuat kode yang kamu tulis menjadi lebih sulit dimengerti dan memperbesar kemungkinan penulisan kode yang kurang aman.