Kalau anda adalah orang yang baru mengenal Odoo dan tertarik utk mempelajari
teknikalnya, tapi bingung harus mulai dari mana? Nah dalam tutorial ini saya ingin
memberikan tips langkah-langkah yang harus dilakukan untuk mulai mempelajari
Odoo dan langsung praktek membuat addons. Adapun pembahasan yang akan saya
sampaikan kurang lebih ada 8 poin, yaitu :
Hal pertama yang harus dilakukan tentu saja adalah menginstal odoo (versi 10).
Boleh menggunakan OS apa saja, tapi saya sarankan pakai linux. Karena dalam
tutorial ini saya menggunakan linux (Ubuntu 16.04). Anda bisa menginstalnya
dengan mengikuti tutorial ini Cara Install Odoo 10 di Ubuntu 14.04
LTS ataupun bisa cari tutorial lain di google.
Kedua, jika odoo nya sudah jalan silahkan coba buat database baru (gunakan data
dummy dengan men-centang checkbox Load demonstration data saat create database)
dan instal beberapa addons default. Saran saya instal 3 addons yang sering dipakai
yaitu Purchase Management, Inventory Management dan Sales. Kemudian coba
explore penggunaan dari masing-masing addons. Mulai dari pembelian barang, cek
ketersediaan barang di gudang dan melakukan penjualan.
Ketiga, siapkan folder baru untuk menyimpan custom addons, karena kita akan
praktek membuat addons sendiri dan ubah konfigurasi odoo agar custom addons
dapat terbaca di apps. Foldernya kita kasih nama custom_addons dan simpan di
dalam folder odoo, kalau anda menginstalnya dari blog saya maka folder odoo ada di
/home/nama_user_ubuntu/odoo-10.0. Kemudian edit konfigurasi dengan
membuka terminal dan ketikkan sudo nano /etc/odoo-server.conf sampai terbuka
tampilan berikut.
Ubah bagian addons_path jadi addons_path = /home/miftah/odoo-
10.0/addons,/home/miftah/odoo-10.0/custom_addons (jangan pakai spasi setelah koma)
Konfigurasi sudah selesai dan anda sudah siap untuk membuat custom addons.
Keempat, install IDE yang anda suka utk mulai melakukan coding, saya sendiri
menggunakan sublime text.
Kelima, install pgadmin III untuk menampilkan isi database postgresql, dengan
syntax :
Sekarang silahkan buat folder baru di dalam folder custom_addons yang sudah
kita buat sebelumnya di part 1 /home/miftah/odoo/custom_addons, beri nama
new_addons. Kemudian buat satu file baru di dalam folder new_addons dan beri
nama __manifest__.py
File manifest berfungsi untuk mendeklarasikan python package sebagai modul
Odoo dan menentukan metadata modul. Penulisan file ini menggunakan single
dictionary yang berisi beberapa key dan value, yang mana setiap key
menunjukkan metadata modul.
Selanjutnya edit file __manifest__.py dan isi dengan {} atau agar lebih lengkap
isi dengan code berikut :
{
"name" : "New Addons",
"version" : "1.0",
"author" : "Miftahussalam",
"website" : "http://miftahussalam.com",
"category" : "New Module",
"summary" : "Ini adalah addons baru",
"description" : """
Latihan membuat addons baru di odoo 10
""",
"depends" : [
"base",
],
"data" : [
],
"demo" : [],
"test" : [],
"images" : [],
"qweb" : [],
"css" : [],
"application" : True,
"installable" : True,
"auto_install" : False,
}
Kemudian save dan sampai sini seharusnya addons sudah bisa terbaca di menu
apps. Silahkan jalankan service odoo (atau restart jika sebelumnya sudah
dijalankan) kemudian masuk ke menu Apps di browser, jangan lupa Aktifkan
Developer Mode agar muncul menu Update Apps List di submenu Apps.
Setelah itu update apps list dengan mengklik menu Update Apps List > Update
dan ketikkan new addons di kolom pencarian (pojok kanan atas), kemudian
enter. Jika berhasil maka akan muncul addons dengan nama New Addons sesuai
dengan nama addons yang kita buat.
Sampai sini maka addons sudah dapat terbaca di menu Apps, akan tetapi belum
bisa diinstal. Untuk menginstalnya maka kita harus menambahkan file baru
dengan nama __init__.py di dalam folder new_addons (sejajar dengan file
__manifest__.py). Biarkan file tersebut kosong, tidak perlu diisi.
Jika sudah, silahkan restart kembali service nya dan update apps list kemudian
instal addons nya
Selamat, anda sudah bisa membuat addons baru dan berhasil menginstalnya
Jika anda bertanya, “Lalu apa maksud dari isi file __manifest__.py”? Berikut
penjelasannya :
bikin modul untuk diinstal. Kalau anda tahu, please let me know hehe
auto_install : tipe boolean (default: False), modul akan otomatis diinstal
jika semua modul dependencies nya terinstal. Dan jika modul tersebut
tidak mempunyai dependencies (baris/key depends nya kosong) maka
modul tersebut akan diinstal ketika create database
Diantara informasi metadata tersebut ada yang ditampilkan di interface odoo ada
juga yang tidak.
Sebenarnya masih ada lagi beberapa key metadata yang bisa dipakai dalam file
__manifest__.py tersebut, seperti maintainer, external_dependencies, license,
dll. Akan tetapi kita tidak perlu memasukkan semuanya, bahkan jika kita hanya
mengisi kurung kurawal {} pun modul tetap bisa terbaca di menu Apps. Selain itu
kita juga bisa mengisi key dan value baru yang tidak ada formatnya dari odoo,
asalkan sesuai dengan penulisan dictionary. Misalnya ‘nomor hp’:
‘085123456789’, ‘contributors’: ‘Miftah, Heru dan Ajeng’. Tambahan key value
tersebut tidak akan menyebabkan modul jadi error, tapi juga tidak akan
menambahkan efek apapun terhadap modul.
Jika anda masih belum berhasil menginstalnya, silahkan download addons yang
sudah saya buat berikut ini https://bitbucket.org/miftahussalam/new-
addons/get/f01b87fb260f.zip
Di bawah ini saya juga membuat tutorial dalam bentuk video yang berhubungan
dengan tutorial part 2 ini, silahkan disimak.
https://youtu.be/5R1Jtt4VZs8
Belajar Odoo Untuk Pemula [Part 3/8]
Posted on22 February 2018
by Miftahussalam
4 Commentson Belajar Odoo Untuk Pemula [Part 3/8]
Seperti yang sudah saya sampaikan sebelumnya, di part 3 ini saya akan memberikan
addons tentang puskesmas yang sudah saya siapkan di sini. Silahkan didownload
dan dicopy ke folder custom_addons, uninstall dan hapus saja addons new_addons
yang sudah ditambahkan sebelumnya. Jangan lupa restart dan update apps list
setiap ada penambahan addons. Jika sudah selesai copy, silahkan instal semua
addons tersebut. Addons puskesmas ini dibuat khusus untuk tutorial ini
Semua menu yang ditambahkan dari addons tersebut disimpan di menu Puskesmas.
Menu-menu tersebut dikelompokkan jadi dua, yaitu master data dan transaksi.
Master data terdiri dari dokter, pasien, poli dan obat. Sementara transaksi terdiri
dari pendaftaran, pemeriksaan dan pembayaran.
Perbedaan master data dan transaksi secara fungsional saya rasa anda sudah faham,
jadi tidak perlu dijelaskan lagi. Namun secara teknis di odoo ada perbedaan yaitu
transaksi menggunakan workflow sementara master data tidak (workflow akan
dibahas di part 7). Proses di puskesmas ini diawali dari penginputan data dokter,
poli dan obat. Jika ada pasien yang datang maka input data pasien saat mendaftar
(kalau sebelumnya sudah pernah berobat maka tidak perlu diinput lagi). Kemudian
admin puskesmas mengisi data pendaftaran, selanjutnya pasien menunggu antrian
untuk dipanggil dokter. Jika sudah dipanggil maka pasien masuk ke ruang dokter
dan melengkapi data pemeriksaan termasuk memberikan resep obat kepada pasien
untuk ditebus di bagian obat. Setelah itu pasien menuju bagian obat untuk
mengambil dan membayar obat. Di sana admin bagian obat melakukan validasi data
pembayaran dan proses transaksi di puskesmas sudah selesai.
Silahkan anda explore penggunaannya lebih lanjut, dan untuk melihat contoh
penginputannya mari simak video berikut :
Komposisi Module/Addons
Setiap modul odoo yang kita buat dapat berisi penambahan proses, attribute,
tampilan, dll ataupun mengubah proses yang sudah ada, memperluas bahkan
menghapus beberapa tampilan default yang dirasa tidak perlu. Jadi setiap ingin
menambahkan atau mengubah proses default kita harus membuat modul baru dan
sangat tidak dianjurkan mengubah langsung pada modul aslinya.
Dan setiap modul odoo dapat berisi beberapa bagian berikut :
Selain itu dalam penulisannya odoo juga biasanya membagi ke empat bagian
tersebut menjadi beberapa folder secara lebih spesifik sesuai dengan fungsinya
masing-masing. Ini sama dengan konsep MVC (model, view, controller) pada
aplikasi/sistem lainnya. Sebenarnya pembagian menjadi beberapa folder ini tidak
wajib (kecuali static file), kita tetap bisa menambahkan file-file tersebut tanpa
membagi jadi beberapa folder. Tapi dengan menerapkan konsep MVC ini dapat
memudahkan kita ketika development karena lebih rapi.
Kalau anda ingin melihat struktur folder pada modul default odoo bisa lihat di odoo-
10.0/addons. Odoo juga sudah menyediakan syntax untuk membuat modul odoo
secara otomatis yang akan menghasilkan struktur addons default. Yaitu dengan
masuk ke folder odoo di terminal dan ketikkan python odoo-bin scaffold <nama modul>
<folder penyimpanan>. Contoh :
$ cd /home/miftah/odoo-10.0
$ python odoo-bin scaffold coba custom_addons
Note : seperti biasa, ganti miftah dengan user ubuntu anda
Maka akan terbuat addons baru di folder custom_addons dengan struktur sebagai
berikut
Fungsi dari masing-masing folder tersebut adalah :
controllers : berisi file untuk menangani permintaan dari web browser (py)
demo : berisi data demo yang akan terbaca jika kita mencentang Load
Demonstration Data saat instal database (XML, CSV, YML)
models : berisi file untuk mendeklarasikan object, field, method, dll (py)
security : berisi file-file yang berhubungan dengan hak akses (XML, CSV)
views : berisi file-file untuk membuat view atau mengatur tampilan (XML)
Selain beberapa folder tersebut, ada juga folder-folder lain yang sering dipakai,
seperti :
Komponen kunci dari odoo adalah ORM (Object Relational Mapping). Seperti yang
kita tahu ORM secara umum berfungsi untuk menghubungkan OOP dengan
database, jadi kita tidak perlu menuliskan syntax SQL secara langsung untuk
mengolah data di database (meskipun itu bisa dilakukan). Selain itu ORM juga
berfungsi untuk keamanan, karena melalui ORM akan dilakukan filter security
sesuai privilege user yang bersangkutan. Berbeda dengan kita menuliskan syntax
SQL secara langsung, maka tidak akan dilakukan pengecekan security. Tapi
meskipun demikian, ada beberapa kondisi dimana kita perlu untuk menuliskan
syntax SQL secara langsung tanpa menggunakan ORM, dengan resiko yang sudah
disebutkan sebelumnya.
pemeriksaan_ids = self.env['ms.pemeriksaan'].search([
('pendaftaran_id','=',me_id.id),
('state','!=','cancel')
])
Maka akan select ke database seperti berikut :
Berikut ini penjelasan lebih lanjut mengenai attribute yang dimiliki oleh models :
o _name : nama model yang harus ada untuk setiap model. Attribute
name ini akan menjadi table di database. Misalnya ketika kita
menulis _name = "ms.pendaftaran", maka akan membuat
table ms_pendaftarandi database. Nama model sering juga disebut object.
contoh : _name = “ms.pendaftaran”
o _rec_name : filed alternatif yang akan digunakan sebagai nama ketika
relasi ke object lain. Secara default, jika _rec_name tidak ditulis maka
akan menampilkan field name.
contoh : _rec_name = ‘partner_id’
o _inherit : untuk melakukan fungsi inheritance terhadap model yang
sudah dideklarasikan sebelumnya di addons lain. Dapat
menambahkan/mengubah field, method, attribute, dll.
contoh : _inherit = ‘ms.pendaftaran’
o _order : urutan data yang ditampilkan berdasarkan field tertentu, bisa
ascending atau descending. Secara default data diurutkan
berdasarkan id asc.
contoh : _order = ‘name desc’
o _auto : menunjukkan apakah akan dibuat table di database. Secara
default bernilai True, Jika diset False maka harus override init() untuk
membuat table. Jika tidak ingin membuat table maka set False dan
menggunakan models.AbstactModel.
contoh : _auto = False
o _table : nama table yang akan dibuat. Secara default sama dengan
_name.
contoh : _table = ‘tbl_pendaftaran’
o _inherits : ditulis dengan dictionary {‘nama_object_yg_diinherit’ :
‘field_relasi’}, bisa lebih dari satu. Fungsinya yaitu ketika membuat
record di object tersebut, maka akan membuat record juga di object yg
diinherit dengan menyimpan id record object yg di inherit pada field
relasi (many2one) di current object.
contoh : _inherits = {‘ms.pendaftaran’:’pendaftaran_id’}
o _sql_constraints : akan membuat unique constraint di database
contoh : _sql_constraints = [(‘unique_kode’,
‘unique(kode,name)’, ‘Kombinasi kode dan nama sudah ada,
mohon cek kembali !’)]
Artinya akan muncul warning saat menginput kombinasi kode dan
name yang sudah pernah diinput sebelumnya.
o _log_access : akan menambahkan beberapa field secara otomatis
ketika mendefinisikan object baru, secara default bernilai True. Field-
field yang ditambahkan tersebut adalah create_date, create_uid,
write_date dan write_uid.
contoh : _log_access = False
Praktek
Sekarang coba kita praktekkan beberapa attribute di atas ke dalam addons
puskesmas
Kita akan mengubah _rec_name poli sehingga nama poli yang tampil di form
pendaftaran adalah kodenya saja. Ikuti langkah-langkah berikut ini :
https://youtu.be/uhks46QbhEk
Penggunaan _sql_constraint sudah ada pada object “ms.poli” yaitu tidak boleh ada
kode yang sama, silahkan anda test dengan menginput kode yang pernah diinput
untuk record sebelumnya.
Di “ms.poli” pengurutan data pada tree view masih default, yaitu ‘id asc’. Sekarang
coba anda ubah menjadi ‘name asc’ atau ‘name’ saja (jika tidak menuliskan asc/desc
maka secara default adalah asc). Maka data yang diinput akan dirutkan berdasarkan
nama poli.
Belajar Odoo Untuk Pemula [Part 6/8]
Posted on22 February 2018
by Miftahussalam
2 Commentson Belajar Odoo Untuk Pemula [Part 6/8]
Meskipun sudah membuat class, object dan field, itu belum cukup untuk
menampilkan field-field yang kita buat pada form aplikasi. Maka langkah
selanjutnya kita harus membuat view, action dan menu di xml, dan juga membuat
report untuk mengekspor data ke dalam pdf.
Ada beberapa view yang bisa kita buat pada file xml, namun ada 3 view yang paling
sering digunakan, yaitu :
Search view
<record id="view_ms_pendaftaran_search" model="ir.ui.view">
<field name="name">ms.pendaftaran.search</field>
<field name="model">ms.pendaftaran</field>
<field name="arch" type="xml">
<search string="Search Pendaftaran">
<field name="name"/>
<field name="pasien_id"/>
<field name="poli_id"/>
<field name="state"/>
<filter string="Draft" name="draft" domain="[('state','=
','draft')]"/>
<filter string="Confirm" name="confirm" domain="[('state
','=','confirm')]"/>
<group expand="0">
<filter name="group_pasien" string="Pasien" domain="
[]" context="{'group_by':'pasien_id'}"/>
<filter name="group_poli" string="Poli" domain="[]"
context="{'group_by':'poli_id'}"/>
</group>
</search>
</field>
</record>
Tree view
<record model="ir.ui.view" id="ms_pendaftaran_tree_view">
<field name="name">ms.pendaftaran.tree</field>
<field name="model">ms.pendaftaran</field>
<field name="arch" type="xml">
<tree string="Pendaftaran">
<field name="name"/>
<field name="tanggal"/>
<field name="pasien_id"/>
<field name="poli_id"/>
<field name="state"/>
</tree>
</field>
</record>
Form view
<record model="ir.ui.view" id="ms_pendaftaran_form_view">
<field name="name">ms.pendaftaran.form</field>
<field name="model">ms.pendaftaran</field>
<field name="arch" type="xml">
<form string="Pendaftaran">
<header>
<button name="action_confirm" string="Confirm" type=
"object" class="oe_highlight" attrs="{'invisible': [('state','!=','d
raft')]}"/>
<button name="action_cancel" string="Cancel" type="o
bject" attrs="{'invisible': [('state','=','cancel')]}"/>
<field name="state" widget="statusbar" statusbar_vis
ible="draft,confirm"/>
</header>
<sheet>
<div class="oe_title">
<h1>
<field name="name" class="oe_inline" readonl
y="1"/>
</h1>
</div>
<group col="4">
<field name="pasien_id" attrs="{'readonly': [('s
tate','!=','draft')]}" required="1" options="{'no_open': True, 'no_c
reate': True}"/>
<field name="poli_id" attrs="{'readonly': [('sta
te','!=','draft')]}" required="1" options="{'no_open': True, 'no_cre
ate': True}"/>
<field name="tanggal" attrs="{'readonly': [('sta
te','!=','draft')]}" required="1"/>
</group>
<notebook>
<page string="Note">
<group>
<field name="note" nolabel="1" class="oe
_inline" placeholder="Note"/>
</group>
</page>
<page string="Audit Trail">
<group>
<group>
<field name="create_uid" readonly="1
"/>
<field name="create_date" readonly="
1"/>
</group>
<group>
<field name="write_uid" readonly="1"
/>
<field name="write_date" readonly="1
"/>
</group>
</group>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
Satu object bisa memiliki beberapa view, meskipun jenis view nya sama. Misalnya
object res.partner memiliki view di form dokter dan form pasien. Jadi data pasien
dan dokter akan masuk ke table yang sama yaitu res_partner, meskipun tampilan di
aplikasinya terpisah.
Sebagian besar attribute field bisa ditulis di py maupun xml. Perbedaannya, ketika
diterapkan di py maka akan berlaku untuk semua view. Tapi ketika ditulis di xml
maka hanya berlaku untuk view-view tertentu. Misalnya di object res.partner ada
field kode, kemudian saya ingin menambahkan attribute required di py nya, maka
baik form dokter maupun pasien wajib mengisi field kode tersebut. Berbeda halnya
jika attrbute required tersebut ditambahkan di form view dokter, maka required itu
hanya berlaku di form dokter sementara di form pasien tidak.
<odoo>
<data>
<template id="report_resepobat_document">
<t t-call="report.external_layout">
<t t-set="o" t-value="o.with_context({})"/>
<div class="page">
<div class="oe_structure"/>
<h1 class="text-center">Resep Obat</h1>
<div class="row mt32 mb32">
<div t-if="o.name" class="col-xs-3">
<strong>Nomor :</strong>
<p t-field="o.name"/>
</div>
<div t-if="o.pasien_id" class="col-xs-3">
<strong>Pasien :</strong>
<p t-field="o.pasien_id.name"/>
</div>
<div t-if="o.tanggal" class="col-xs-3">
<strong>Tanggal :</strong>
<p t-field="o.tanggal"/>
</div>
</div>
<table class="table table-condensed">
<thead>
<tr>
<th><strong>Obat</strong></th>
<th><strong>Aturan Minum</strong></t
h>
<th><strong>Sebelum/Sesudah Makan</s
trong></th>
<th><strong>Quantity</strong></th>
<th><strong>Satuan</strong></th>
</tr>
</thead>
<tbody>
<tr t-foreach="o.resep_line" t-as="l">
<td>
<span t-field="l.product_id.name
"/>
</td>
<td>
<span t-field="l.aturan_minum"/>
</td>
<td>
<span t-field="l.waktu_minum"/>
</td>
<td>
<span t-field="l.qty"/>
</td>
<td>
<span t-field="l.satuan_id.name"
/>
</td>
</tr>
</tbody>
</table>
<div class="oe_structure"/>
<div class="row" name="ttd" style="padding-top:2
0px;">
<div class="col-xs-4" style="text-align:cent
er">
<div style="padding-bottom:60px;">Tertan
da,</div>
<div> ( <span t-field="user.name"/> )</d
iv>
</div>
</div>
</div>
</t>
</template>
<template id="report_resepobat">
<t t-call="report.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="ms_puskesmas.report_resepobat_documen
t"/>
</t>
</t>
</template>
<report
string="Resep Obat"
id="cpl_action_report_resepobat"
model="ms.pemeriksaan"
report_type="qweb-pdf"
name="ms_puskesmas.report_resepobat"
file="ms_puskesmas.report_resepobat"
/>
</data>
</odoo>
Praktek
Jika kita mendeklarasikan menuitem tanpa mempunyai attribute parent maka menu
tersebut akan menjadi top menu. Kemudian jika ada menuitem yang parent nya ke
top menu maka akan jadi group menu (yang terletak sebah kiri). Kemudian jika ada
menuitem yang parent nya ke group menu (level ke tiga) maka akan menjadi menu
yang terletak di bawah group menu. Selanjutnya jika ada menuitem baru yang
parentnya ke menu level ke tiga tersebut maka akan menjadi dropdown, dan begitu
selanjutnya.
Setiap menuitem bisa ditambakan action untuk menampilkan form ataupun tidak.
Pada umumnya action akan ditambahkan pada menuitem level ke tiga, tapi
meskipun begitu action tetap bisa ditambahkan pada menuitem pertama atau kedua.
Selama rangkaian menu belum mempunyai action maka menu-menu tersebut tidak
akan ditampilkan. Misalnya menu-menu di atas yang terletak pada modul ms_base
tidak akan ditampilkan selama kita belum menginstal modul ms_puskesmas, karena
action baru ditambahkan pada menuitem di modul ms_puskesmas yang parent nya
ke menuitem di ms_base.
Penginputan pada umumnya dilakukan pada form view. Namun pada beberapa
object yang hanya memiliki sedikit field seperti object ms.poli, penginputan
dilakukan pada tree view. Untuk melakukan itu maka harus menambahkan attribute
editable (top/bottom) pada blok tree seperti tree view poli di atas.
Ada 3 hal yang bisa kita tambahkan pada search view :
maka klik advance search (icon kaca pembesar di sebelah kanan kolom search)
Di sebelah kanan Group by ada Favorites, fungsinya untuk menyimpan current filter
atau group bahkan kombinasi dari keduanya. Jadi jika suatu saat kita ingin
melakukan filter dan/atau group yang sama maka tinggal klik Favorites yang sudah
disimpan tersebut.
pada blok action kita bisa melakukan filter data yang akan ditampilkan, misal pada
action dokter di atas data difilter hanya yang field dokternya True
Saat klik refund invoice maka akan muncul tampilan seperti di atas, tampilan
tersebut dinamakan wizard.
Ada perbedaan antara model wizard dengan model lainnya, perbedaan tersebut
adalah pada model wizard biasanya class nya menggunakan models.TransientModel.
Dan perbedaan antara models.TransientModel dengan models.Model adalah
pada models.TransientModel data yang disimpan di database bersifat sementara.
Jadi apapun yang diinput di sana hanya akan disimpan sementara, dan akan
dihapus otomatis setelah beberapa lama.
Print-an resep obat menggunakan qweb report yang cara pembuatannya bisa anda
lihat pada file ms_puskesmas/report/report_resepobat.xml
Belajar Odoo Untuk Pemula [Part 7/8]
Posted on22 February 2018
by Miftahussalam
Leave a commenton Belajar Odoo Untuk Pemula [Part 7/8]
Workflow
Hampir semua form transaksi di odoo mempunyai field state (seperti yang terlihat
pada gambar di bawah), field state tersebut berfungsi untuk melakukan tracking
perkembangan proses seiring dengan berjalannya waktu. Perkembangan proses
itulah yang dinamakan workflow.
Perubahan workflow akan di trigger oleh proses atau action-action tertentu, dan
biasanya action tersebut dijalankan oleh button.
Button
Cara penulisan button bisa lihat di addons puskesmas. Button ada dua type :
Ada beberapa method default yang dimiliki oleh sebuah model. Method-method
tersebut otomatis ditambahkan ketika menambahkan model, meskipun kita tidak
menuliskannya. Method-method tersebut adalah :
Untuk cara pemanggilan pertama maka value dari type adalah ‘consu’. Sementara
pada pemanggilan kedua value type adalah ‘product’
Domains
Domain adalah list kriteria pencarian record yang ditulis dengan format
[(nama_field, operator, value)], dengan penjelasan masing-masing sebagai berikut :
nama_field (type str) : nama field pada model bersangkutan atau nama field
pada model lain yang mempunyai relasi Many2one dengan model tersebut.
Misal ‘alamat’ atau ‘partner_id.name’ (partner_id adalah field Many2one
yang ada pada current model dan name adalah field yang ada pada model
relasi)
operator (type str) : digunakan untuk mencocokkan antara nama_field dan
value. Operator yang bisa digunakan adalah :
=sama dengan (case sensitive)
Misal : [(‘name’, ‘=’, ‘dog’)], maka akan mencari name ‘dog’ (case sensitive)
>lebih dari
Misal : [(‘qty’, ‘>’, 2)], maka akan mencari qty 3,4,5,dst
<kurang dari
Misal : [(‘qty’, ‘<‘, 2)], maka akan mencari qty 1,0,-1,-2,dst
=?tidak diisi (None atau False) atau sama dengan (case sensitive)
Misal : [(‘name’, ‘=?’, ‘dog’)], maka akan mencari name ‘dog’ atau name ‘ ‘ / False /
None
=like hampir sama dengan fungsi samadengan, tapi bisa menambahkan % pada
inputan sehingga fungsinya jadi sama dengan like (case sensitive)
Misal : [(‘name’, ‘=like’, ‘dog’)], maka akan mencari name ‘dog’. Jika pada inputan
ditulis %dog% maka akan mencari name ‘dog’, ‘doggy’, ‘bulldog’
not like kebalikan dari like, tidak mengandung karakter (case sensitive)
ilike mengandung karakter (tidak case sensitive)
Misal : [(‘name’, ‘ilike’, ‘dog’)], maka akan mencari name ‘dog’, ‘doggy’, ‘bulldog’,
‘Dog’, ‘dOg’
not ilike kebalikan dari ilike, tidak mengandung karakter (tidak case sensitive)
=ilike hampir sama dengan fungsi samadengan, tapi bisa menambahkan % pada
inputan sehingga fungsinya jadi sama dengan ilike (tidak case sensitive)
Misal : [(‘name’, ‘=ilike’, ‘dog’)], maka akan mencari name ‘dog’, ‘Dog’, ‘DoG’, dll.
Jika pada inputan ditulis %dog% maka akan mencari name ‘dog’, ‘doggy’, ‘doGgy’,
‘bulldog’, ‘BulldoG’
in sama dengan salah satu dari list value (value harus list dan case sensitive)
not in tidak sama dengan semua list value (value harus list dan case sensitive)
value (type variable, yang bisa berisi str, int, dll) : yang akan dicocokkan
dengan nama field
Method Decorators
@api.multi : method berisi recordset. Artinya self bisa berisi lebih dari satu
record
@api.one : method hanya berisi satu record
@api.model : self tidak mempunyai ids karena record belum disimpan ke
database
@api.depends(‘nama_field1′,’nama_field2’) : merupakan daftar field yang
dapat men trigger method. Artinya jika field-field yang ditulis di depends ini
valuenya berubah maka method akan dijalankan/compute. Biasanya dipakai
pada field compute
@api.constrains(‘nama_field1′,’nama_field2’) : hampir sama dengan
api.depends, fungsinya untuk melakukan pengecekan validasi data
@api.onchange(‘nama_field1′,’nama_field2’) : triggernya hampir sama
seperti api.depends, fungsinya untuk memberikan value field, domain atau
memberikan warning
dll
Praktek
Method def get_sequence pada addons ms_base diperlukan untuk penomoran
otomatis sesuai format tertentu. Method ini akan dipanggil di model lain, khususnya
di method create (karena penomoran akan muncul otomatis saat record transaksi di
save)
def _get_usia pada file ms_pemeriksaan merupakan method yang dipakai pada field
compute/function usia, menghitung usia dari tanggal kelahiran pasien. Method ini
menggunakan api.one karena untuk menghitung usia pasti hanya dari satu record.
Sebenarnya bisa juga menggunakan api.multi asal self nya di looping dulu
override def create untuk mengisi value field name dengan penomoran otomatis.
Saat override existing method kita harus menjalankan super(nama_class,
self).nama_method(parameter_jika_ada) agar action yang ada pada method asalnya
juga dijalankan. Jika kita override atau menulis ulang method tanpa menjalankan
super maka method aslinya atau method di parent modelnya tidak akan dijalankan
pada method def action_confirm dilakukan looping pada self karena seperti yang
dijelaskan di atas action_confirm menggunakan api.multi sehingga self bisa berisi
multi record. Method ini ditrigger oleh button Confirm yang nama button nya sama
dengan nama method. Saat button Confirm di klik maka dalam method
menjalankan action untuk mengubah state dari Draft menjadi Confirmed dan
membuat satu record pemeriksaan
Belajar Odoo Untuk Pemula [Part 8/8]
Posted on22 February 2018
by Miftahussalam
2 Commentson Belajar Odoo Untuk Pemula [Part 8/8]
Inheritance
Model Inheritance
Odoo menyediakan dua mekanisme inheritance untuk memperluas model yang ada
dengan cara yang modular.
Menambahkan field
Menambahkan constraint
Menambahkan method
Override field yang ada di model lain (mengubah attribute)
Override method di model lain
dll
Kedua, pendelegasian yang memungkinkan untuk menghubungkan semua record
model terhadap parent model. Jenis kedua ini ditulis dengan syntax _inherits seperti
yang sudah dibahas di part sebelumnya.
View Inheritance
View inheritance me refer ke parent menggunakan inherit_id. Setelah itu kita bisa
memodifikasi isi dari view parent dengan menggunakan position.
</field>
</record>
position bisa berisi beberapa value :
Praktek
Contoh inherit untuk menambahkan method salah satunya ada pada file
ms_base/models/ir_sequence.py
Selain menambahkan field kita juga bisa mengubah attribute fields dengan cara
menulis ulang field beserta type nya yang sudah ada di model parent, dan kita hanya
perlu menuliskan attribute yang mau diubah atau ditambahkan. Misal kita akan
menggunakan field city di res.partner akan tetapi string nya mau diubah menjadi
‘Kota’, seperti ini :
city = fields.Char(string='Kota')
Silahkan restart service dan upgrade, maka string filed city akan berubah menjadi
‘Kota’
Pada ms_base/views/ir_module_module.xml merupakan contoh inherit
view view_module_filter (tempat install addons pada menu Apps) untuk
menambahkan field author, website dan filter, serta membuat default filter agar
ketika klik menu Apps maka sudah otomatis ter filter hanya addons custom yang
muncul.
Selanjutnya kita akan coba praktekkan mekanisme inheritance yang kedua, yaitu
pendelegasian dengan menggunakan syntax _inherits.
Silahkan buat file baru di ms_puskesmas/models dengan nama ms_room.py dan isi
dengan syntax berikut
class ms_room(models.Model):
_name = "ms.room"
_description = "Poli"
_sql_constraints = [
('unique_kode', 'unique(kode)', 'Kode Poli duplicate, mohon
cek kembali !'),
]
@api.multi
def name_get(self):
result = []
for me in self :
if me.posisi :
result.append((me.id, "%s - %s" % (me.posisi, me.nam
e)))
else :
result.append((me.id, me.name))
return result
@api.model
def name_search(self, name, args=None, operator='ilike', limit=1
00):
args = args or []
if name :
recs = self.search([
'|',
('posisi', operator, name),
('name', operator, name),
] + args, limit=limit)
else :
recs = self.search([] + args, limit=limit)
return recs.name_get()
dan di ms_puskesmas/views dengan nama ms_room.xml
<odoo>
<data>
</data>
</odoo>
Jangan lupa tambah import ms_room di ms_puskesmas/models/__init__.py dan
update __manifest__.py untuk membaca file ms_puskesmas.xml
ms_poli.py
class ms_poli(models.Model):
_name = "ms.poli"
_description = "Poli"
_inherits = {'ms.room': 'room_id'}
@api.multi
def name_get(self):
result = []
for me in self :
result.append((me.id, "%s - %s" % (me.kode, me.name)))
return result
@api.model
def name_search(self, name, args=None, operator='ilike', limit=1
00):
args = args or []
if name :
recs = self.search([
'|',
('kode', operator, name),
('name', operator, name),
] + args, limit=limit)
else :
recs = self.search([] + args, limit=limit)
return recs.name_get()
ms_poli.xml
<odoo>
<data>
<form string="Poli">
<sheet>
<group col="4">
<field name="kode"/>
<field name="name"/>
<field name="room_id" readonly="1" attrs
="{'invisible': [('id','=',False)]}" required="0"/>
<field name="id" invisible="1"/>
</group>
</sheet>
</form>
</field>
</record>
</data>
</odoo>
Silahkan upgrade modul sehingga muncul menu baru di Data Master yaitu menu
Ruangan
Jika belum berhasil/error silahkan ambil source code berikut puskesmas branch
lanjut
ms.poli menginherits ms.room sehingga setiap create Poli baru maka akan otomatis
membuat Ruangan baru dengan nama dan kode yang sama. Tapi tidak berlaku
sebaliknya, ketika membuat ruangan baru tidak akan otomatis membuat poli.
Karena setiap poli pasti membutuhkan ruangan, tapi tidak setiap ruangan ditujukan
untuk poli.
Note : Jika sebelumnya master poli sudah terdapat record maka akan ada error
akses. Cara mengatasinya silahkan hapus semua record poli lewat pgAdmin.
https://youtu.be/q2kZksnU2po
Alhamdulillah, kita sudah menyelesaikan materi dasar odoo teknikal. Saya rasa jika
anda sudah memahami materi-materi yang disampaikan dari part 1-8 ini maka
Saran saya setelah ini anda harus mempelajari satu materi lagi yang belum dibahas
di serial ini dan cukup penting ketika implementasi, yaitu mengenai hak akses. Dan
insya Allah di lain waktu saya juga akan membahasnya di blog ini.
Saya menyadari tutorial ini masih banyak kekurangan, dan insya Allah saya akan
terus mengupdate dan melengkapinya agar lebih mudah difahami. Kemudian jika
yang saya sampaikan terdapat kekeliruan mohon beri tahu saya karena saya juga
masih belajar.