[Odoo 10] Technical Documentation -Part 2-

Alhamdulillah kita bisa melanjutkan kembali tutorial ini. Sebelum kita praktek untuk membuat object, menu, dll. Sebaiknya kita review kembali teori dan penjelasan materi terkait.

Setiap class di odoo dia akan menginherite super class model, class model inilah kunci dari ORM yang ada di Odoo. Diantara attribute yang dimiliki oleh class model ini adalah :

_name : untuk membuat sebuah object atau table di database
# contoh : _name = “sale.order”

_description : memberikan informasi singkat mengenai object atau model
# contoh : _description = “Sales Orders”

_rec_name : jika kita tidak memiliki field ‘name’, maka isikan attribute ini dengan field penggantinya. Secara default, field ‘name’ akan digunakan sebagai nilai pada method name_get() (field many2one)
# contoh : _rec_name = ‘complete_name’

_inherit : untuk inheritance object terkait. Biasanya kita gunakan untuk custom baik penambahan field maupun override method
# contoh : _inherit = “stock.move”

_inherits : untuk ‘pendelegasian’ object terkait. Contohnya adalah object ‘res.users’ yang menginherits object ‘res.partner’. Ketika membuat user, maka partner (customer/supplier) juga akan tercipta otomatis (tidak sebaliknya) dengan tambahan sebuah field ‘jembatan’ antara ‘res.user’ dan ‘res.partner’ yaitu ‘partner_id’ seperti contoh berikut
# contoh : _inherits = {‘res.partner’: ‘partner_id’}

_order : untuk proses sorting, isi dengan nama salah satu field. Jika tidak diisi maka defaultnya field ‘id’
# contoh : _order = ‘date desc’

_sql_constraints : untuk membuat unik nilai suatu field
# contoh : _sql_constraints = [(‘code_uniq’, ‘unique (code)’, ‘The code of the account must be unique !’)]

_constraints : untuk membuat pengecekan nilai suatu field dengan method python yang kita bikin
# contoh : _constraints = [(_check_required_if_provider, ‘Required fields not filled’, [])]

Semenjak api baru, attribute _constraint digantikan dengan decorator @api.constrains(‘nama_field’), contohnya : @api.constrains(‘line_ids’). Selain itu, pada api baru ini, attribute _columns untuk mendefinisikan field telah dihapus. Sedangkan _defaults juga telah dihapus dan dimasukan ke attribute field

Jika kita ingin membuat duplikasi dari object yang sudah ada tetapi dengan nama yang berbeda, maka gunakan attribute _inherit dan _name secara bersamaan. Contohnya :


class AnggotaPerpustakaan(models.Model):
    _inherit = 'res.partner'
    _name = 'anggota.perpustakaan'

Setelah kita membuat object, langkah selanjutnya adalah membuat field atau column dari object tersebut. Odoo menyediakan berbagai jenis field, diantaranya :


# Char = Field free character, biasanya digunakan untuk inputan string. Contoh : 
name = fields.Char(string='Order Reference', required=True, copy=False, readonly=True)

# Boolean = Field ini bernilai True atau False, berbentuk cekbox pada list/form. Contoh :
sale_ok = fields.Boolean('Can be Sold', default=True, help="Check if the product can be selected in a sales order line.")
     
# Integer = Field dengan nilai bilangan bulat. Contoh : 
sequence = fields.Integer('Sequence', default=1)
 
# Float = Field dengan nilai bilangan decimal. Contoh : 
discount = fields.Float(string='Discount (%)', digits=dp.get_precision('Discount'))

# Monetary = Field dengan nilai bilangan decimal (khusus keuangan) dan otomatis dengan simbol currencynya (dalam 1 field). Contoh : 
amount = fields.Monetary(currency_field='currency_id')
         
# Text = Field untuk inputan text berbentuk paragraf. Contoh : 
term = fields.Text('Terms and conditions')

# Selection = Field berbentuk combobox/dropdown yang nilainya telah ditentukan dengan hardcode. Contoh : 
state = fields.Selection([('draft', 'Draft'),('done', 'Done')], required=True)

# Html = Field seperti text dengan tambahan formating seperti html
note = fields.Html('Note')

# Date = Field inputan tanggal. Contoh : 
date_invoice = fields.Date(string='Invoice Date')
 
# Datetime = Field inputan tanggal dan waktu. Contoh : 
date_done = fields.Datetime(string="Closed On")
     
# Binary = Field untuk menyimpan sebuah data file, biasanya digunakan untuk image. Contoh : 
data_file = fields.Binary(string='Bank Statement File')
  
# Many2One = Sama seperti field selection tetapi nilainya diambil dari sebuah object/tabel. Contoh : 
partner_id = fields.Many2one('res.partner', string='Customer', change_default=True, index=True, track_visibility='always')
     
# One2Many = Field berbentuk tabel pada sebuah form. Contoh : 
order_line = fields.One2many('sale.order.line', 'order_id', string='Order Lines')
 
# Many2Many = Field berbentuk tabel pada sebuah form (mirip one2many) dengan pengisian nilainya seperti field many2one. Contoh :
tag_ids = fields.Many2many('crm.lead.tag', 'crm_lead_tag_rel', 'lead_id', 'tag_id', string='Tags')
    
# Reference = Sama seperti field many2one tetapi object/tabel relasinya bebas untuk memilih (tampilan ada 2 combobox, milih object & milih recordnya). Contoh : 
document_id = fields.Reference(selection=_get_document_types, string='Source Document', required=True)

Seperti contoh diatas, ada perbedaan pada api yang baru ini, yaitu tidak adanya field compute & field related seperti di versi sebelumnya. Karna field compute & field related telah di masukan menjadi attribute sebuah field, jadi semua field diatas bisa dijadikan field compute & field related dengan menambahkan attribute compute atau related. Disana juga ada tambahan attribute default, seperti penjelasan sebelumnya.

Ada beberapa field yang tercipta otomatis (default) ketika kita membuat object, walaupun kita tidak mendefiniskan field tersebut, diantara field itu adalah :

id = berisi sequence record (auto increment)
create_date = berisi tanggal record dibuat
create_uid = berisi user yang membuat record
write_date = berisi tanggal terakhir record di update
write_uid = berisi user yang mengedit record terakhir kali

Jika kita tidak mengingingkannya, maka kita bisa ‘mematikan’ field tersebut dengan memberikan attribute model _log_access = False

Ada juga spesial field yang bisa kita tambahkan, yaitu field ‘Active’, yang bernilai boolean (defaultnya True). Secara default, semua record yang ditampilkan bernilai True, jika kita ingin menghide sebuah record, maka set field ‘Active’ menjadi False. Contoh definisinya seperti ini :

active = fields.Boolean(‘Active’, default=True) # Pada versi 10, sebagian form ada kotak “Archive / Active” untuk mengedit field ini

Jika kita perhatikan contoh diatas, setiap field memiliki attribute sebagaimana model, diantara attribute yang dimiliki field adalah :

string — (string) berfungsi sebagai label pada GUI. Jika tidak di set, maka ORM memberikan label dari nama aslinya (db) dengan capital.

size — (integer) berfungsi memberikan batasan jumlah karakter (khusus field Char)

help — (string) berfungsi memberikan tooltip jika cursor di dekatkan

readonly — (boolean) jika bernilai True, maka field tidak dapat di edit manual

required — (boolean) jika bernilai True, maka field akan bersifat mandatory (wajib di isi)

index — (integer) berfungsi untuk memberikan index pada database, mempercepat proses searching tetapi menambah alokasi database. Pengganti attribute select pada versi sebelumnya

default — (sesuai tipe field) berfungsi memberikan nilai default (baik static maupun dinamis -dengan method-) saat user akan membuat record

states — (dictionary) berfungsi untuk membuat readonly, required, & invisible suatu field berdasarkan nilai field statenya

domain — (list) memberikan filter dari nilai yang dipilih (biasa digunakan field relasi -many2one dan many2many-). Seperti fungsi ‘where’ pada sql select

digits — (tuple) untuk menentukan banyaknya digit decimal pada field float dan monetary

groups — (string) memberikan akses suatu field kepada group terkait

copy — (boolean) jika bernilai True, maka akan memberikan value yang sama pada saat record di duplikasi

translate — (boolean) jika bernilai True, maka label field terkait dapat di terjemahkan

selection — (list) untuk menentukan nilai pilihan baik static maupun dinamic (dengan method) pada field selection atau field reference

change_default — (boolean) jika bernilai True, maka field ini bisa memberikan nilai default field lain (dengan setting khusus)

track_visibility — (‘always’, ‘onchange’) membuat log history (message) yang biasanya terdapat di bawah setiap form untuk proses tracking. Jika diisi ‘always’ maka setiap ada perubahan apapun pada field lain, maka ia tetap membuat log nya (walaupun nilai field ini tidak berubah), sedangkan ‘onchange’ akan membuat log jika HANYA field ini yang mengalami perubahan nilainya

company_dependent — (boolean) jika bernilai True, maka value dari field ini bisa berbeda nilai per company. Pengganti attribute property pada versi sebelumnya

related — (string) field duplikasi dari object/tabel lain. Field dengan attribute ini akan selalu mengupdate nilai jika ada perubahan nilai pada field aslinya (sinkronisasi)

compute — (string) berfungsi memberikan nilai suatu field dari sebuah method

inverse — jika attribute ‘compute’ biasa digunakan untuk mengisi nilai field ini berdasarkan parameter dari field lain, sedangkan attribute ‘inverse’ melakukan fungsi sebaliknya, yaitu mengisi nilai field lain dari nilai field ini

store — (boolean) jika bernilai True, maka value akan di simpan pada database, biasa digunakan berpasangan dengan attribute related dan compute

ondelete — (‘set null’, ‘restrict’, ‘cascade’) digunakan pada field many2one, jika bernilai ‘cascade’ maka record (yang mengandung field ini) akan ikut terhapus jika record yang dipilih dari object referensinya dihapus, jika bernilai ‘restrict’ maka record pada object referensinya tidak akan bisa dihapus sebelum record yang mengandung field ini dihapus, jika bernilai ‘setnull’ maka field akan otomatis bernilai null jika record pada object referensinya dihapus

search — memberikan proses search pada field lain yang berhubungan dengan field ini (biasanya field yang terkait dari attribute compute atau inverse) -seperti domain-

Ada yang baru pada versi api ini dalam mengoverride field, ketika kita ingin menambahkan attribute sebuah field dari parent class, kita cukup menginherite parent class dan memberikan nama & type yang sama, sebagaimana field pada parent class tersebut. Lalu kita sisipkan HANYA attribute yang ingin ditambahkan, contoh :


class Parent(models.Model):
    _name = 'orang.tua'
    state = fields.Selection([('draft', 'Draft'),('done', 'Done')], required=True)

class Child(models.Model):
    _inherit = 'orang.tua'
    state = fields.Selection(help="Ini attribut tambahan dari class anak")

Pada contoh diatas, kita hanya menambahkan attribute help, tanpa harus mengcopas keseluruhan attribute parent.

Setelah kita mempelajari berbagai attribute model dan field. Maka selanjutnya adalah pembahasan tentang method suatu class atau model. Method dan attribute adalah dua hal yang tidak bisa kita pisahkan (keduanya saling melengkapi). Jika kita analogikan dengan sebuah object mobil, maka attribute seperti warna, merk, tahun pembuatan, dll. Sedangkan method seperti maju(), mundur(), berhenti(), dst. Diantara method yang dimiliki oleh class model adalah :

a. search()
Sama seperti fungsi select pada SQL, bedanya pada hasil yang diberikan. Contoh :


partner = self.env('res.partner').search([('is_company', '=', True), ('customer', '=', True)])
print partner # res.partner(7, 18, 12, 14, 17, 20)

partner = self.env('res.partner').search([('is_company', '=', True), ('customer', '=', True)], limit=3)
print partner # res.partner(7, 18, 12)

print partner[0].id # 7
print partner[0].name # Agrolait
print partner[1].id, partner[1].name # 18, Asustek

b. create()
Method ini berfungsi untuk membuat sebuah record pada object tertentu. Method ini membutuhkan parameter value (dictionary) berisi masing-masing field object tersebut beserta nilainya. Contoh :


self.env('res.partner').create({'name': 'Umar'})

c. write()
Method ini berfungsi untuk mengupdate satu atau beberapa field dari sebuah object. Parameter yang diperlukan adalah id dari record terkait dan value (dictionary) dari field-field yang akan diupdate. Contoh :


partner = self.env('res.partner').search([('name', '=', 'Umar')], limit=1)
partner.write({'name': 'Abdullah', 'street': 'Jl. Gunung Salak'})

d. unlink()
Method ini digunakan untuk mendelete record pada object. Contoh :


partner = self.env('res.partner').browse([13, 14])
partner.unlink()

e. copy()
Method yang digunakan untuk menduplicate sebuah record yang menghasilkan record dengan nilai default (atau kita set) dari masing-masing field.


partner = self.env('res.partner').browse([15])
partner.copy()
# ATAU
partner.copy({'name': 'Ukasyah'})

f. browse()
Method yang berfungsi untuk mengambil sebuah record dan digunakan sebagai object, dengannya kita bisa mengexplore semua field dan relasi antar table pada database tersebut ‘tanpa batas’. Contoh :


partner = self.env('res.partner').browse([7, 18, 12])
print partner # res.partner(7, 18, 12)
print partner[0].account_receivable_id.company_id.currency_id.name # USD

g. read()
Method yang memiliki fungsi sama seperti fungsi select pada SQL. Contoh :


partner = self.env('res.partner').browse([33, 34, 35])

data = partner.read(['nama'])
print data # [{'name': 'Ali'}, {'name': 'Abdurrahman'}, {'name': 'Uwais'}]

data = partner.read()
print data # [{'name': 'Ali', 'street': 'Jl. Danau Toba', 'city': 'Bekasi'}, {'name': 'Abdurrahman', 'street': 'Jl. Pisang Ambon', 'city': 'Depok'}, {'name': 'Uwais', 'street': 'Jl. Ahmad Yani', 'city': 'Jakarta'}]

h. ref()
Method yang memiliki fungsi mendapatkan record dari id xml. Contoh :


address_form_id = self.env.ref('base.res_partner_1')
print address_form_id # res.partner(7)  

Diantara perbedaan dengan api yang lama adalah :

1. Telah hilangnnya parameter cr, uid, dan ids pada method. Semuanya digantikan dengan environment (self.env), termasuk ‘self.pool.get’

2. Return dari method diatas mayoritas adalah recordset, terutama untuk method search() -sebelumnya hanya return list integer-, jika kita biasa menggunakan method search() dan browse() bersamaan, maka dengan api yang baru ini, kita cukup menggunakan method search() saja

3. Method read() bisa kita gunakan untuk ‘membaca’ beberapa field yang kita inginkan saja, tidak seperti sebelumnya yang mereturn semua field dari record yang kita baca

4. Karna hilangnya parameter ids yang biasa digunakan untuk read(), write(), copy(), dan unlink(). Maka pastikan kita harus membuat recordset terlebih dahulu, sebelum memanggil method tersebut. Biasanya dengan search() atau browse()

Saran dan kritik yang membangun selalu di tunggu…
Semoga bermanfaat ….

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s