Membuat Transient Model pada Odoo

Transient model adalah model pada odoo dimana datanya akan dihapus secara periodik. Karena datanya akan selalu dihapus tentu saja tidak disarankan menggunakan model ini untuk menyimpan data real. Model ini biasanya digunakan sebagai wizard, sebagai penyambung proses antara beberapa model, misal pada saat create invoice dari sale order. Bisa juga untuk memberikan pesan tertentu kepada user.

Sebagai contoh kasus pada tutorial ini kita akan menggunakan transient model untuk memberikan pesan kepada user jika status customer bernilai blacklisted saat confirm sale order. Kemudian jika user tersebut memiliki hak akses Approve sale order of blacklisted customer maka sale order bisa dilanjutkan ke proses selanjutnya dengan cara mengklik tombol Approve. Jika tidak memiliki hak akses tersebut tentu saja sale order tidak bisa di confirm dan tidak bisa diproses.

Pertama kita buat hak aksesnya terlebih dahulu. Buat file security.xml dengan isi sebagai berikut.

<?xml version="1.0" encoding="utf-8"?>
<odoo>
	<data>

	    <record id="group_edit_partner_trust_state" model="res.groups">
	        <field name="name">Edit partner trust state</field>
	    </record>

	    <record id="group_approve_sale_order_of_blacklisted_customer" model="res.groups">
	        <field name="name">Approve sale order of blacklisted customer</field>
	    </record>

	</data>
</odoo>

Jangan lupa untuk import file tersebut pada file __manifest__.py. Setelah diinstal akan terdapat tambahan 2 hak akses seperti pada gambar dibawah ini.

Kemudian buat field selection pada master partner mengenai status partner tersebut.

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

from odoo import api, fields, models, _

class Partner(models.Model):
    _inherit = 'res.partner'

    trust_state = fields.Selection([
            ('trusted', 'Trusted'),
            ('blacklisted', 'Blacklisted')
        ], string='Trust Status', default='trusted')

Kemudian tambahkan field tersebut pada form master partner.

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>
        <record model="ir.ui.view" id="view_partner_form_inherit">
            <field name="name">view_partner_form_inherit</field>
            <field name="model">res.partner</field>
            <field name="inherit_id" ref="base.view_partner_form" />
            <field name="arch" type="xml">
                <field name="category_id" position="after">
                    <field name="trust_state" groups="partner_trust.group_edit_partner_trust_state" />
                </field>
            </field>
        </record>
    </data>
</odoo>

Dari kode diatas field Trust Status hanya bisa dilihat dan diedit oleh user yang memiliki hak akses Edit partner trust state. Selanjutnya buat Transient Model sebagai wizard.

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

from odoo import api, fields, models, _

class ConfirmSaleTrust(models.TransientModel):
    _name = 'sale.trust.wizard'

    order_id = fields.Many2one('sale.order', string='Sale Order')
    partner_id = fields.Many2one('res.partner', string='Customer', related='order_id.partner_id')

    def approve_blacklisted_customer_order(self):
        # panggil method action_confirm pada sale order saat ini
        # sertakan context agar bisa mencegah infinite loop
        self.order_id.with_context({'approve_blacklisted_customer_order': 1}).action_confirm()

Sekalian dengan formnya

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>
        <record model="ir.ui.view" id="sale_trust_wizard_form">
            <field name="name">sale_trust_wizard_form</field>
            <field name="model">sale.trust.wizard</field>
            <field name="arch" type="xml">
                <form>
                    <field name="partner_id" /> is blaclisted. Are you sure want to approve this Sale Order ?
                    
                    <footer>
                        <button name="approve_blacklisted_customer_order" type="object" string="Approve" class="btn-primary" groups="partner_trust.group_approve_sale_order_of_blacklisted_customer" />
                        <button string="Cancel" special="cancel" />
                    </footer>
                </form>                
            </field>
        </record>
    </data>
</odoo>

Transient model tidak dikenai hak akses create, read, update dan delete. Jadi semua user bisa mengakses jenis model ini. Kita juga tidak perlu mengatur access rule-nya.

Selanjutnya override method action_confirm pada model sale.order agar menampilkan form transient model sale.trust.wizard yang baru saja kita buat jika customer di blacklist.

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

from odoo import api, fields, models, _

class SaleOrder(models.Model):
    _inherit = 'sale.order'

    def action_confirm(self):
        # jika partner tidak diblacklist panggil super, artinya sale order bisa di confirm
        # jika ada context approve_blacklisted_customer_order artinya method ini
        # dipanggil dari transient model sale.trust.wizard dan user memiliki
        # hak akses 'Approve sale order of blacklisted customer' sehingga sale order bisa di confirm
        if self.partner_id.trust_state == 'trusted' or 'approve_blacklisted_customer_order' in self._context:
            super(SaleOrder, self).action_confirm()

        else:
            # partner di blacklist
            # buat record transient model dengan nilai order_id adalah sale order saat ini
            # dengan memasukkan order_id nantinya di transient model sale.trust.wizard
            # kita bisa memanggil method action_confirm hanya untuk sale order saat ini
            wizard_id = self.env['sale.trust.wizard'].create({'order_id': self.id})
            return {
                'name': _('Blacklisted Customer'),
                'type': 'ir.actions.act_window',
                'view_type': 'form',
                'view_mode': 'form',
                'res_model': 'sale.trust.wizard',
                'res_id': wizard_id.id,
                'target': 'new',
            }

Sebagai contoh customer ini telah di blacklist. Pastikan memiliki hak akses Edit partner trust state untuk melihat dan mengedit field Trust Status.

Jika user tidak memiliki hak akses Approve sale order of blacklisted customer saat user klik tombol Confirm pada sale order akan muncul pesan seperti gambar dibawah ini.

Jika user memiliki hak akses Approve sale order of blacklisted customer saat user klik tombol Confirm pada sale order akan muncul pesan seperti gambar dibawah ini.

Terlihat ada tambahan tombol approve. Saat user klik tombol tersebut method approve_blacklisted_customer_order pada transient model sale.trust.wizard akan dieksekusi. Akhirnya sale order bisa di confirm.

Setiap kita klik tombol Confirm pada Sale Order dan customer sedang di blacklist record sale.trust.wizard akan bertambah.

Lalu kapan data transient model dihapus ?

Odoo memiliki scheduller / cron job untuk menghapus data transient model secara otomatis. Pada mode debug masuk menu Setting >> Technical >> Automation >> Scheduled Actions kemudian cari Base: Auto-vacuum internal data

Pada gambar diatas terlihat bahwa data transient model akan dihapus setiap sehari sekali. Jika ingin menghapus data transient model saat itu juga klik tombol Run Manually. Gambar dibawah ini adalah record transient model sale.trust.wizard setelah klik tombol Run Manually.

Terlihat tidak semua record transient model sale.trust.wizard dihapus. Ada 2 kondisi untuk menyatakan record suatu transient model dihapus atau tidak saat scheduller / cron job Base: Auto-vacuum internal data dijalankan. Silakan buka file tools/config.py pada source code odoo. Perhatikan 2 konfigurasi dibawah ini.

group.add_option("--osv-memory-count-limit", dest="osv_memory_count_limit", my_default=False,
                 help="Force a limit on the maximum number of records kept in the virtual "
                      "osv_memory tables. The default is False, which means no count-based limit.",
                 type="int")
group.add_option("--osv-memory-age-limit", dest="osv_memory_age_limit", my_default=1.0,
                 help="Force a limit on the maximum age of records kept in the virtual "
                      "osv_memory tables. This is a decimal value expressed in hours, "
                      "and the default is 1 hour.",
                 type="float")

Dari kode diatas terlihat bahwa data / record transient model akan dihapus jika usianya sudah lebih dari 1 jam saat scheduller / cron job Base: Auto-vacuum internal data dijalankan. Usia data ini dihitung dari field write_date tiap record. Kita bisa mengubah konfigurasi ini langsung pada file tools/config.py tersebut atau pada file /etc/odoo/odoo.conf.

Tutorial ini dibuat pada odoo 13 enterprise edition. Ada kemungkinan perbedaan tampilan dan proses pada versi odoo lainnya. Download source code disini.

Tulisan Serupa

Leave a Reply

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