[Odoo 10] Technical Documentation -Part 7-

Bismillah ..

InsyaAllah kita lanjutkan kembali serial tutorial technical ini. Pada pertemuan kali ini, insyaAllah hal yang pertama kita bahas adalah fitur onchange. Mekanisme onchange berbentuk sebuah method yang berfungsi memberikan cara ‘komunikasi’ kepada user setiap kali mengupdate nilai field suatu form TANPA menyimpan apapun ke database. Pada umumnya onchange digunakan untuk 3 hal berikut :

1. value = mengisi nilai suatu field berdasarkan inputan user
2. domain = memberikan domain suatu field berdasarkan inputan user
3. warning = memberikan pesan informasi kepada user ketika proses penginputan data

Kali ini kita akan gunakan point 1 dan 3 pada object training_sesi kita. Silahkan update file model sesi seperti berikut :



class Sesi(models.Model):
    ...

    
    @api.onchange('seats', 'attendee_ids')
    def _verify_valid_seats(self):
        if self.seats <= 0: # cek nilai field seats, jika dibawah 0 (negatif), maka masuk kondisi if
            return {
                    'value': {
                              'seats': len(self.attendee_ids) or 1 # mengisi field seats dengan nilai jumlah peserta atau 1
                              },
                    'warning': {
                                'title': "Nilai Jumlah Kursi Salah", # judul pop up
                                'message': "Jumlah Kursi Tidak Boleh Negatif" # pesan pop up
                                }
                    }
            
        if self.seats < len(self.attendee_ids): # cek nilai field seats (jumlah kursi) apakah lebih kecil dari field attendee_ids (jumlah peserta), jika iya maka masuk kondisi if
            return {
                    'value': {
                              'seats': len(self.attendee_ids) # mengisi field seats dengan nilai jumlah peserta
                              },
                    'warning': {
                                'title': "Peserta Terlalu Banyak", # judul pop up
                                'message': "Tambahkan Kursi atau Kurangi Peserta" # pesan pop up
                                }
                    }

Ada perubahan signifikan antara api lama dan baru pada fitur onchange ini, jika api lama maka kita harus mendefiniskan nama method onchange pada setiap field yang dinginkan di view file xml. Dengan api baru ini, kita tidak perlu repot untuk melakukan hal itu, cukup gunakan decorator @api.onchange dan masukan field mana saja yang kita inginkan untuk mengalami onchange terkait. Contoh diatas kita memberikan fitur onchange pada field ‘seats’ dan ‘attendee_ids’. Jadi saat 2 field tersebut mengalami perubahan nilai oleh user, maka method _verify_valid_seats() akan dijalankan.

Sebenarnya field compute secara otomatis mengalami fitur onchange tetapi dengan keterbatasan yaitu mengupdate field saja. Sedangkan untuk pengecekan nilai inputan user, dll kita harus menggunakan onchange. Pada contoh diatas kita akan mengecek inputan user, diantaranya :

1. Pengecekan jumlah kursi, apakah dibawah 0 atau tidak. Jika 0 dan dibawah 0, maka jumlah kursi akan terisi 1 atau sebanyak jumlah peserta beserta pesan errornya

2. Pengecekan apakah jumlah kursi lebih sedikit dari jumlah peserta. Jika iya maka akan ada pesan error dan nilai jumlah kursi di isi sesuai jumlah peserta

Jika kita hanya mereturn value saja tanpa warning atau domain, maka di v10 ini kita bisa menggunakan perintah self.update() seperti contoh berikut :


self.update({'nama_field': 'nilai'})

self.update({'partner_id': self.partner_id.id, 'fiscalyear_id': self.partner_id.fiscalyear_id.id})

Silahkan dicoba dan cek hasilnya.

Selanjutnya kita akan bahas constraints. Ada 2 jenis untuk model constraints ini, yaitu :

1. Python Constraints

Sebuah constraints yang dibuat oleh method python. Biasanya digunakan untuk pengecekan nilai antar field pada record yang sama. Cara menggunakannya dengan decorator @api.constrains() dengan parameter nama field. Contohnya :


    
@api.constrains('umur')
def _cek_umur(self):
    for r in self:
        if r.umur < 17:
            raise ValidationError("Umur anda masih terlalu muda")

#  ATAU

@api.constrains('name', 'code')
def _cek_name_code(self):
    for r in self:
        if r.name == r.code:
            raise ValidationError("Name dan Code tidak boleh sama")


2. SQL Constraints

Sebuah constraints yang dibuat seperti syntax SQL. Biasanya digunakan untuk pengecekan nilai antar field pada record yang sama atau record yang berbeda. Cara menggunakannya dengan attribute model _sql_constraints dengan parameter tuple berisi nama_constraints, definis_sql, dan pesan_error. Contohnya :



_sql_constraints = [
                    ('nama_constraints_bebas', 'CHECK(name != description)', 'Pesan error pengecekan field name dan description pada record yang sama')
]

# ATAU

_sql_constraints = [
                    ('nama_constraints_bebas', 'UNIQUE(name)', 'Pesan error pengecekan field name pada semua record (harus unik)')
]

# ATAU


_sql_constraints = [
                    ('name_description_check', 'CHECK(name != description)', 'The title of the course should not be the description'),
                    ('name_unique', 'UNIQUE(name)', 'The course title must be unique')
]

Pada contoh diatas kita bisa menggunakan constraints dengan perintah CHECK(), UNIQUE(), dll sebagaimana syntax SQL. Kita juga bisa mendefiniskan beberapa constraints sekaligus.

Sekarang kita buat constraints pada object training kita, yaitu Kursus() dan Sesi() seperti berikut :



class Kursus(models.Model):
    ...
    
    _sql_constraints = [
                    ('name_description_cek', 'CHECK(name != description)', 'Judul kursus dan keterangan tidak boleh sama '),
                    ('name_unik', 'UNIQUE(name)', 'Judul kursus harus unik')
    ]



    
class Sesi(models.Model):
    ...
    
         
    @api.constrains('instructor_id', 'attendee_ids')
    def _check_instructor_not_in_attendees(self):
        for r in self:
            if r.instructor_id and r.instructor_id in r.attendee_ids: # Jika field instructor_id (Instruktur) diisi DAN instructor_id ada di tabel attendee_ids (Peserta), maka munculkan pesan error 
                raise exceptions.ValidationError("Seorang instruktur tidak boleh menjadi peserta")
    


Pada contoh diatas kita membuat 2 constraints, pertama pada class Kursus(), yaitu constraints dengan tipe SQL Constraints, fungsinya untuk mengecek nilai field name (Judul) dan description (Keterangan) tidak boleh sama dalam 1 record. Lalu pengecekan ke semua record bahwa field name (Judul Kursus) harus unik. Kedua adalah Python Constraints pada class Sesi(), fungsinya untuk pengecekan bahwa seorang Instruktur tidak boleh menjadi Peserta.

Setelah kita menambahkan contraints unik untuk judul kursus, maka hal ini bisa membuat masalah ketika kita menggunakan fitur duplicate pada object kursus. Untuk itu kita harus mengoverride method duplicate yaitu copy() dan ‘merevisi’ dengan beberapa tambahan, seperti berikut :



class Kursus(models.Model):
    ...    
    

    @api.multi
    def copy(self, default=None):
        default = dict(default or {})
        copied_count = self.search_count([('name', '=like', "Copy of {}%".format(self.name))]) # Searching judul kursus yang sama dan menyimpannya pada variable copied_count 
        
        if not copied_count: # Cek isi variable copied_count (hasil searching) 
            new_name = "Copy of {}".format(self.name) # Jika proses searching judul yang sama tidak ditemukan, maka judul baru akan dikasih imbuhan 'Copy of'
        else:
            new_name = "Copy of {} ({})".format(self.name, copied_count) # Jika proses searching judul yang sama ditemukan, maka judul baru akan dikasih imbuhan 'Copy of' dan angka terakhir duplicate
        
        default['name'] = new_name # Mereplace value field name dengan yang sudah di sesuaikan
        return super(Kursus, self).copy(default)



Fungsi dari overriding diatas adalah untuk menambahkan imbuhan setiap record kursus di duplicate, sehingga judul kursus selalu unik.

Mungkin ini saja yang bisa saya sampikan, bagi yang ingin mengecek hasil tutorial ini bisa di download disini

Semoga bermanfaat, CMIIW …

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