Untuk memastikan keakuratan data maka kita perlu membuat batasan-batasan sesuai nilai wajar dalam suatu field. Pada artikel kali ini kita akan memberikan pembatasan pada database dengan SQL Constraint.

SQL Constraint dalam kustomisasi Odoo ERP adalah seperti pada penjelasan-penjelasan berikut ini

  1. Menambahkan contraint pada model

    Kita menambahkan  SQL contraint pada model utama dengam masuk ke Webmin dari Virtualmin dan masuk ke File Manager seperti pada gambar di atas.


    Kita juga menambahkan sql constraint untuk model kedua.


    Kita menambahkan sql contraint untuk model ketiga.
  2. Restart Odoo

    Kita perlu melakukan restart Odoo karena kita mengubah model.
  3. Upgrade modul

    Kita melanjutkan dengan melakukan upgrade modul.
  4. Mengisi form

    Kita kemudian mengisi form dengan isian yang tidak diperbolehkan seperti pada gambar di atas.


    Tampak ada warning berupa validation error sesuai sql contraint yang kita buat.
  5. Melihat log jika ada masalah

    Ada kemungkinan kita gagal memasukkan sql contraint karena data-data yang sudah ada ada yang tidak sesuai dengan sql contraint yang kita buat.
    Kita dapat melihat lognya dengan mengetikkan perintah

    cat  /var/log/odoo/odoo-server.log | grep unable |  tail -1
    
  6. Perbaiki data di database jika diperlukan

    Jika ada data yang tidak sesuai dengan sql contraint kita maka kita dapat masuk ke Wenmail kemudian menuju menu Servers | PostgreSQL Database Server seperti pada gambar di atas. Kita kemudian memilih databasenya.


    Kita melanjutkan dengan memilih tabelnya.


    Kita melanjutkan dengan View Data


    Kita kemudian melakukan update data sesuai kebutuhan kita.
  7. Source code model estate_property.py
    from odoo import api, fields, models
    
    class EstateProperty(models.Model):
    	_name = "estate.property"
    	_description = "Real Estate Property"
    
    	_sql_constraints = [
    		("check_expected_price", "CHECK(expected_price > 0)", "The expected price must be strictly positive"),
    		("check_selling_price", "CHECK(selling_price >= 0)", "The offer price must be positive"),
    	]
    
    	active = fields.Boolean(default=True)
    	state = fields.Selection(
        	[ 
            	('n', 'New'),
            	('o', 'Offer Received'),
            	('a', 'Offer Accepted'),
            	('s', 'Sold'),('c', 'Cancelled'),
            ],
        	'State', default='n'
        )
    
    	name = fields.Char(required=True,default='Rumah Baru')
    	description = fields.Text()
    
    	property_type_id = fields.Many2one("estate.property.type", string="Property Type")
    	tags_id = fields.Many2many("estate.property.tag", string="Property Tags")
    
    	postcode = fields.Char()
    	date_availability = fields.Date(copy=False)
    	expected_price = fields.Float()
    	selling_price = fields.Float(readonly=True,copy=False)
    	bedrooms = fields.Integer(default=2)
    	living_area = fields.Integer()
    	facades = fields.Integer()
    	garage = fields.Boolean()
    	garden = fields.Boolean()
    	garden_area = fields.Integer()
    	garden_orientation = fields.Selection(
        	[ 
            	('n', 'North'),
            	('s', 'South'),
            	('e', 'East'),
            	('w', 'West'),
            ],
        	'Garden Orientation', default='e'
    	)
    
    	user_id = fields.Many2one("res.users", string="Salesman",default=lambda self: self.env.user)
    	buyer_id = fields.Many2one("res.partner", string="Buyer",copy=False)
    
    	offer_ids = fields.One2many("estate.property.offer", "property_id", string="Offer")
    
    	best_price = fields.Float("Best Offer", compute="_compute_best_price", help="Best offer received")
    
    	@api.depends("offer_ids.price")
    	def _compute_best_price(self):
    		for prop in self:
    			prop.best_price = max(prop.offer_ids.mapped("price")) if prop.offer_ids else 0.0
    
    	@api.onchange("garden")
    	def _onchange_garden(self):
    		if self.garden:
    			self.garden_area = 10
    			self.garden_orientation = "n"
    		else:
    			self.garden_area = 0
    			self.garden_orientation = False
    
    	def action_sold(self):
    		if "c" in self.mapped("state"):
    			raise UserError("Canceled properties cannot be sold.")
    		return self.write({"state": "s"})
    
    	def action_cancel(self):
    		if "s" in self.mapped("state"):
    			raise UserError("Sold properties cannot be canceled.")
    		return self.write({"state": "c"})
    
  8. Source code model estate_property_type.py
    from odoo import fields, models
     
    class EstatePropertyType(models.Model):
    	_name = "estate.property.type"
    	_description = "Property Type"
    
    	name = fields.Char(required=True)
    
    	_sql_constraints = [
    		("check_name", "UNIQUE(name)", "The name must be unique"),
    	]
    
  9. Source code model estate_property_tag.py
    from odoo import fields, models
      
    class EstatePropertyTag(models.Model):
    	_name = "estate.property.tag"
    	_description = "Property Tag"
      
    	name = fields.Char(required=True)
    
    	_sql_constraints = [
    		("check_name", "UNIQUE(name)", "The name must be unique"),
    	]
    

Informasi lebih lanjut silahkan menghubungi
1. https://www.odoo.com/documentation/16.0/developer/howtos/rdtraining/11_constraints.html .
2. https://github.com/odoo/technical-training-solutions/tree/16.0-core/estate .

Kunjungi www.proweb.co.id untuk menambah wawasan anda.

Jika anda tertarik mengenai aplikasi Odoo ERP silahkan mengisi form di bawah ini

SQL Constraint dalam Kustomisasi Odoo ERP