Penggunaan onchange dan compute pada Odoo

Pada odoo ada 2 cara untuk menghitung nilai suatu field secara otomatis. Yaitu menggunakan decorator onchange atau field parameter compute.

Gunakan decorator onchange jika kita ingin nilai suatu field berubah jika nilai field lain berubah. Misal kita memiliki 3 field seperti ini

# -*- coding: utf-8 -*-

from odoo import api, fields, models, _

class MyModel(models.Model):
    _name = 'my.model'

    field_1 = fields.Integer(string='Field 1')
    field_2 = fields.Integer(string='Field 2')
    result = fields.Integer(string='Result')

Jika kita ingin nilai dari field result berubah jika nilai dari field_1 atau field_2 berubah kita bisa menggunakan decorator onchange seperti dibawah ini

@api.onchange('field_1', 'field_2')
def calculate_result(self):
    self.result = self.field_1 + self.field_2

Masukkan field yang digunakan sebagai trigger pada decorator onchange sebagai parameter. Jumlah field yang bisa dimasukkan bebas. Selanjutnya diikuti method dengan nama bebas. Saat program berjalan, jika salah satu dari field yang digunakan sebagai trigger nilainya berubah, method tersebut, dalam contoh kasus ini adalah calculate_result akan dieksekusi.

Berikut ini adalah contoh tampilan nilai yang sudah diubah secara otomatis dengan decorator onchange

Field yang dihitung dengan decorator onchange masih bisa diubah oleh user, baik dari frontend atau dari backend (misal lewat perintah SQL) dan nilainya akan disimpan oleh odoo selama nilai dari field trigger tidak berubah. Berikut ini adalah contoh tampilan field yang dihitung dengan decorator onchange tapi diubah lagi oleh user kemudian disimpan.

Method yang ditandai dengan decorator onchange hanya dipanggil jika nilai field trigger diubah dari frontend, atau saat form tersebut diedit. Jadi jika nilai field_1 diubah dari model lain dengan python atau lewat perintah SQL nilai dari field result tidak akan berubah.

Seperti disebutkan sebelumnya bahwa field yang dihitung dengan decorator onchange masih bisa diubah oleh user, jadi kita mungkin perlu menambahkan attribute readonly. Tetapi field yang ditandai dengan attribute readonly nilainya tidak akan disimpan di database. Jika ingin nilai tersebut disimpan pastikan untuk menggunakan attribute force_save seperti dibawah ini.

<field name="result" readonly="1" force_save="1" />

Selanjutnya kita juga bisa menggunakan field parameter compute untuk menghitung nilai suatu field secara otomatis. Seperti pada kode dibawah ini

# -*- coding: utf-8 -*-

from odoo import api, fields, models, _

class MyModel(models.Model):
    _name = 'my.model'

    field_1 = fields.Integer(string='Field 1')
    field_2 = fields.Integer(string='Field 2')
    result = fields.Integer(string='Result', compute='compute_result')
    
    def compute_result(self):
        for rec in self:
            rec.result = rec.field_1 + rec.field_2

Berbeda dengan decorator onchange saat menggunakan field parameter compute pastikan loop parameter self. Karena jika tidak, akan terjadi error expected singleton jika data pada model tersebut banyak. Jadi hindari menggunakan kode seperti dibawah ini

result = fields.Integer(string='Result', compute='compute_result')
    
def compute_result(self):
    self.result = self.field_1 + self.field_2

Field yang ditandai dengan field parameter compute secara otomatis akan jadi readonly. Sehingga tidak ada kemungkinan bagi user untuk mengubah nilai field tersebut dari frontend.

Field yang ditandai dengan field parameter compute, secara default nilainya tidak akan berubah sampai form tersebut disimpan. Saat masih dalam mode create / edit, nilai field tersebut tidak akan berubah karena method compute belum dipanggil

Method compute secara default dipanggil pada proses read. Yaitu saat kita buka tree view atau form view tapi tidak sedang dalam mode create atau edit. Setelah kita klik tombol Save, dan kita keluar dari mode create / edit barulah nilainya berubah, seperti pada gambar dibawah ini

Tetapi ada juga kelebihannya, yaitu jika kita ubah salah satu field yang dijadikan dasar perhitungan dari backend, dengan kode python dari model apapun atau dari database lewat perintah SQL, nilainya akan selalu berubah jika kita buka form tersebut.

Dari kedua gambar diatas terlihat bahwa nilai dari result berubah walaupun nilai field_1 diubah dari database lewat perintah SQL. Hal ini tidak mungkin terjadi jika kita menggunakan decorator onchange.

Tetapi jika kita menginginkan nilai field result langsung berubah tanpa harus klik tombol save juga bisa, carannya gunakan decorator depends seperti dibawah ini.

# -*- coding: utf-8 -*-

from odoo import api, fields, models, _

class MyModel(models.Model):
    _name = 'my.model'

    field_1 = fields.Integer(string='Field 1')
    field_2 = fields.Integer(string='Field 2')
    result = fields.Integer(string='Result', compute='compute_result')
    
    @api.depends('field_1', 'field_2')
    def compute_result(self):
        for rec in self:
            rec.result = rec.field_1 + rec.field_2

Penulisan decorator depends sama dengan decorator onchange. Yang berbeda dengan decorator onchange, jika nilai dari field trigger di ubah dari backend dengan python dari model apapun atau dengan perintah SQL nilai dari field result akan berubah.

Field yang ditandai dengan field parameter compute secara default tidak akan dibuatkan kolom di table database. Sehingga tidak memungkinkan bagi kita untuk memasukkan field tersebut pada perintah SQL.

Pada gambar diatas terlihat bahwa tidak ada kolom dengan nama result. Jika kita ingin field tersebut dibuatkan kolom pada table database, kita harus menambahkan field parameter store dengan nilai True, seperti pada gambar dibawah ini

result = fields.Integer(string='Result', compute='compute_result', store=True)

Sekarang field result sudah dibuatkan kolom. Sayangnya jika kita melakukan perubahan pada field trigger (field_1 atau field_2) lewat perintah SQL, field result nilainya tidak berubah, method compute tidak dipanggil. Sama dengan saat kita menggunakan decorator onchange

Tetapi jika kita mengubah field trigger tersebut dengan python dari model apapun, nilai dari field result akan berubah, method compute tetap dipanggil. Berbeda dengan saat kita menggunakan decorator onchange

Demikian tutorial penggunaan decorator onchange dan field parameter compute untuk menghitung nilai suatu field secara otomatis. Gunakan sesuai kebutuhan.

Tulisan Serupa

Leave a Reply

Your email address will not be published. Required fields are marked *