Model pada OpenERP
Tipe field: one2many
Merupakan tipe relasional, digunakan untuk relasi one to many (satu ke banyak). Merupakan kebalikan dari many2one.
Class dan constructor: class one2many(_column)
| __init__(self, obj, fields_id, string='unknown', limit=None, auto_join=False, **args) Salah satu contoh tipe field ini yang umum ditemukan pada OpenERP adalah model sale.order, dimana
field order_line (one) berhubungan dengan model sale.order.line (pada field order_id). Contoh (cuplikan dari openerp/addons/sale/sale.py):
'order_line' : fields.one2many( 'sale.order.line' , 'order_id' , 'Order Lines' , readonly= True , states={ 'draft' : [( 'readonly' , False )], 'sent' : [( 'readonly' , False )]}),
Tipe field: many2many
Merupakan tipe relasional, digunakan untuk relasi many to many (banyak ke banyak). Merupakan multiple relationship dua arah antara object.
Class dan constructor: class many2many(_column)
| __init__(self, obj, rel=None, id1=None, id2=None, string='unknown', limit=None, **args) Salah satu contoh tipe field ini yang umum ditemukan pada OpenERP adalah hubungan antara model
res.partner dengan model res.partner.category. Contoh (cuplikan dari openerp/addons/base/res/res_partner.py): 'category_id' :
id1= 'partner_id' , id2= 'category_id' , string= 'Tags' ),
fields.many2many( 'res.partner.category' ,
Tipe field: function
Merupakan tipe functional, yang mensimulasikan field sesungguhnya, melalui proses komputasi. Class dan constructor: class function(_column)
| __init__(self, fnct, arg=None, fnct_inv=None, fnct_inv_arg=None, type='float', fnct_search=None, obj=None, store=False, multi=False, **args)
Untuk argumen fnct, fungsi harus didefinisikan sebagai berikut: fnct(model, cr, uid, ids, field_name(s), arg, context) Kita akan membahas contoh sederhana pada program 5-4. Cuplikan kode: …
def _function_test(self, cr, uid, ids, field, arg, context= None ): def _function_test(self, cr, uid, ids, field, arg, context= None ):
_columns = { 'buku_field_12' : fields.function(_function_test, type= 'float' ) }
Untuk contoh tersebut, field buku_field_12 tidak disimpan pada tabel database.
Tipe field: related
Merupakan tipe related, diturunkan dari function, yang merujuk pada data di dalam field lain untuk record aktif.
Class dan constructor: class related(function)
| __init__(self, *arg, **args)
Salah satu contoh tipe field ini yang dapat ditemukan pada OpenERP adalah field country_id dan country pada res.partner.
Contoh (cuplikan dari openerp/addons/base/res/res_partner.py): 'country_id' : fields.many2one( 'res.country' , 'Country' ),
'country' : fields.related( 'country_id' , type= 'many2one' , relation= 'res.country' , string= 'Country' ,
deprecated= "This field will be removed as of OpenERP 7.1, use country_id instead" ),
Tipe field lain
Beberapa tipe field berikut didefinisikan di dalam modul fields: • sparse(function) • dummy(function) • serialized(_column) • property(function)
5.5 Atribut: _constraints
Sebagaimana dibahas sebelumnya, atribut _constraints dapat digunakan untuk membantu memastikan input adalah valid.
Atribut ini didefinisikan dalam bentuk sebuah list dari tuple (nama_fungsi, pesan_kesalahan, fields). Mari kita lihat cuplikan dari program 5-3 berikut. Kita memiliki sebuah field dengan nama buku_field_11: class res_partner(orm.Model):
_name = 'res.partner' _inherit = 'res.partner' _columns = {
'buku_field_11' : fields.char( 'Buku Field 11' , size= 20 ,
required= True ),
Dan, kita ingin agar isi field tersebut, yang bertipe char, harus memiliki panjang minimal tiga karakter. Kita dapat definisikan _constraints dan fungsi untuk memeriksa, sebagai berikut:
def _check_field_11(self, cr, uid, ids, context= None ): for i in self.browse(cr, uid, ids, context=context):
if len(i.buku_field_11) >= 3 : return True
return False
_constraints = ( [_check_field_11, 'Panjang harus minimal 3 karakter' , [ 'buku_field_11' ]], )
Untuk nama_fungsi, kita gunakan _check_field_11. Ketika kita memberikan input pada user interface OpenERP, pesan kesalahan akan ditampilkan apabila
input tidak sesuai kriteria.
5.6 Model, tabel database dan field
Sebagaimana dibahas sebelumnya, nama tabel database secara default adalah nama model (_name) dengan titik diganti dengan underscore. Dengan demikian, untuk model res.partner sebagai contoh, tabel pada database adalah res_partner. Atau, untuk model res.partner.category, tabel pada database adalah res_partner_category.
Ketika kita menambahkan suatu field dengan cara menurunkan dari suatu model (_name sama dengan _inherit), maka field tersebut akan ditambahkan pada tabel (untuk tipe field/pengaturan tipe field yang mendukung).
Dari user interface OpenERP, kita bisa mengamati ini dengan: • Aktifkanlah terlebih dahulu developer mode • Buka salah satu model, misal res.partner, dengan mengakses Sales → Customers. Pilihlah salah
satu partner (buka form). • Pada pilihan DebugView, pilihlah View Fields. • Sebuah dialog akan ditampilkan, berisikan field-field apa saja yang telah didefinisikan.
Apa yang kita lakukan dengan _name sama dengan _inherit adalah class inheritance, yang kita gunakan dalam bab ini. Alternatif adalah:
• _name tidak sama dengan _inherit (inheritance by prototype) dimana data disimpan pada tabel lain. • Menggunakan _inherits (inheritance by delegation).
5.7 Method
Class BaseModel memiliki sejumlah method yang dapat kita gunakan (langsung atau tidak) ataupun override.
Override umumnya kita perlukan ketika fungsi yang ditawarkan perlu disesuaikan lebih lanjut. Sebagai contoh, kita menurunkan dari res.partner dan ketika suatu partner dibuat atau diedit, kita ingin melakukan fungsi tambahan, selain fungsi default yang telah disediakan.
Method-method yang ada dapat pula diakses lewat web service. Bacalah juga bab 9 apabila diperlukan. Berikut adalah sejumlah method yang disediakan oleh Model. Dokumentasi yang disediakan secara
umum cukup lengkap. Kita akan membahas beberapa diantaranya setelah ini, dalam bagian-bagian tersendiri.
self, pool, cr
browse self, cr, uid, select, context=None, list_class=None, fields_process=None
check_access_rights
self, cr, uid, operation, raise_exception=True
check_access_rule
self, cr, uid, ids, operation, context=None
check_field_access_rights
self, cr, user, operation, fields, context=None
check_recursion
self, cr, uid, ids, context=None, parent=None
clear_caches
self
copy
self, cr, uid, id, default=None, context=None
copy_data
self, cr, uid, id, default=None, context=None
copy_translations
self, cr, uid, old_id, new_id, context=None
create
self, cr, user, vals, context=None
default_get
self, cr, uid, fields_list, context=None
distinct_field_get self, cr, uid, field, value, args=None, offset=0, limit=None exists
self, cr, uid, ids, context=None
export_data
self, cr, uid, ids, fields_to_export, context=None
fields_get self, cr, user, allfields=None, context=None, write_access=True fields_get_keys
self, cr, user, context=None
fields_view_get self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False
get_external_id
self, cr, uid, ids, *args, **kwargs
Method
Argumen
get_invalid_fields
self, cr, uid
get_xml_id, get_external_id self, cr, uid, ids, *args, **kwargs import_data
self, cr, uid, fields, datas, mode='init', current_module='', noupdate=False, context=None, filename=None
is_transient
self
load
self, cr, uid, fields, data, context=None
log self, cr, uid, id, message, secondary=False, context=None name_create
self, cr, uid, name, context=None
name_get
self, cr, user, ids, context=None
name_search self, cr, user, name='', args=None, operator='ilike', context=None, limit=100
perm_read
self, cr, user, ids, context=None, details=True
perm_write
self, cr, user, ids, fields, context=None
read self, cr, user, ids, fields=None, context=None, load='_classic_read' read_group
self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False
read_string self, cr, uid, id, langs, fields=None, context=None resolve_2many_commands self, cr, uid, field_name, commands, fields=None, context=None resolve_o2m_commands_to_ self, cr, uid, field_name, commands, fields=None, context=None
record_dicts, resolve_2many_commands
search self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False
search_count
self, cr, user, args, context=None
unlink
self, cr, uid, ids, context=None
user_has_groups
self, cr, uid, groups, context=None
view_header_get self, cr, user, view_id=None, view_type='form', context=None view_init
self, cr, uid, fields_list, context=None
write
self, cr, user, ids, vals, context=None
write_string
self, cr, uid, id, langs, vals, context=None
Kalau kita cermati argumen fungsi, kita akan menemukan beberapa yang umum seperti berikut.
Cursor koneksi database (SQL Query dapat dilakukan)
user, uid Merupakan user id yang melakukan. Dalam hal ini merupakan nilai numerik, bukan nama user (string).
ids Id yang akan diproses. Umumnya berupa list dari id. Sebagai contoh, ketika memanggil unlink, yang akan menghapus record, ids dapat berisikan id-id record yang akan dihapus.
vals Merupakan nilai penting yang berhubungan langsung dengan apa yang akan dilakukan method. Umumnya berupa dictionary. Sebagai contoh, pada fungsi create yang akan membuat record baru, vals dalam hal ini adalah dictionary berisi nama field (key) dan nilainya (value).
fields
Umumnya berisi list dari nama field.
context Informasi kontekstual, berupa dictionary. Sebagai contoh adalah language. Lewatkanlah ke dalam pemanggilan method (apabila ada dan diharapkan). Ketika menulis method baru, kita juga disarankan mengharapkan informasi ini.
Bekerja dengan model lain
Untuk bekerja dengan model lain, kita bisa menggunakan self.pool.get(nama_model).
5.8 Mengakses OpenERP tanpa server dijalankan
Sebelum membahas beberapa contoh method, kita akan membahas terlebih dahulu bagaimana kita dapat mengakses OpenERP dari prompt Python, bahkan tanpa server OpenERP dijalankan. Kita tidak lakukan lewat modul ataupun web service.
Pastikanlah bahwa server database telah dijalankan/authentikasi telah dikonfigur. Kemudian, PYTHONPATH telah diset dengan baik agar kita bisa melakukan import package/modul OpenERP. Ada baiknya pula untuk bekerja dengan database yang bersih, tanpa modul pihak ketiga terinstall. Kita bisa melakukan ini juga ketika server sedang berjalan.
Catatan penting: apa yang kita lakukan di sini hanyalah untuk keperluan mempelajari OpenERP saja dan sangat tidak disarankan untuk diterapkan pada server di lingkungan produksi.
Pertama-tama, kita harus dapat mengimport modul openerp: >>> import openerp
>>> openerp <module 'openerp' from 'openerp/__init__.pyc'> >>>
Langkah kedua, kita mengakses koneksi database dan pool model: >>> db, pool = openerp.pooler.get_db_and_pool('test_buku')
No handlers could be found for logger "openerp.modules.module" >>> db <openerp.sql_db.Connection object at 0xb5732aac> >>> pool <openerp.modules.registry.Registry object at 0xb5732a2c> >>>
Setelah itu, untuk langkah ketiga, kita melakukan inisialisasi kursor database: >>> cr = db.cursor()
>>> cr <openerp.sql_db.Cursor object at 0xb479a40c> >>>
Pada langkah keempat berikut, kita akan mengakses salah satu model. Sebagai contoh, kita akan bekerja dengan model sale_order.
>>> from openerp.addons.sale import sale Dari manakah kita mendapatkan struktur package seperti itu? Perhatikanlah bahwa modul sale terletak
pada: $ file openerp/addons/sale/sale.py
openerp/addons/sale/sale.py: Python script, ASCII text executable, with very long openerp/addons/sale/sale.py: Python script, ASCII text executable, with very long
model sale.order: >>> so = sale.sale_order.create_instance(pool, cr)
>>> so <openerp.osv.orm.sale.order object at 0xb5407bec> >>>
Perhatikanlah bahwa di dalam modul sale, kita memiliki class sale_order. Sementara, class sale_order merupakan turunan dari osv.osv (orm.Model), dan kita memiliki class method create_instance.
Selanjutnya, kita tinggal menggunakan method dari Model. Kita akan membahasnya di beberapa bagian berikut.
5.9 Method: search
Method search digunakan untuk melakukan pencarian dan akan mengembalikan nilai berupa list id record yang memenuhi kriteria.
Melanjutkan dari pembahasan mengakses OpenERP tanpa server dijalankan, kita akan menggunakan method search.
Kita akan mencari dari daftar partner yang merupakan customer. Kriteria pencarian adalah customer=True.
Catatan: dalam OpenERP, kriteria pencarian umumnya juga dikenal dengan istilah domain.
>>> from openerp.addons.base.res import res_partner >>> uid = 1 >>> search_data = [('customer', '=', True)] >>> partner = res_partner.res_partner.create_instance(pool, cr) >>> search_result = partner.search(cr, uid, search_data) >>> search_result [98, 69, 6, 50, 53, 17, 43, 70, 11, 55, 13, 36, 71, 16, 18, 32, 40, 7, 75, 91, 44,
>>> search_result.sort() >>> search_result [6, 7, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 25, 27, 28, 29, 30, 31, 32, 33,
>>> Perhatikanlah bahwa kriteria pencarian dituliskan dalam Polish Notation atau prefix notation (notasi
prefix). Sebagai contoh lain, kita akan mencari dari res.partner, untuk: • nama yang mengandung 'tes' (tidak case-sensitive) atau untuk id < 3 • dan • website = ''
Karena menggunakan Polish Notation, maka operator or '|' dan and '&' ditempatkan di depan. Pertama-tama, kita menyusun untuk kriteria pertama (or): '|', ('name', 'ilike', 'tes'), ('id', '<', 3) Setelah itu, kita gabungkan dengan kriteria kedua (and):
'&', '|', ('name', 'ilike', 'tes'), ('id', '<', 3), ('website', '=', '')
Dan, kita tempatkan pada sebuah list: ['&', '|', ('name', 'ilike', 'tes'), ('id', '<', 3), ('website', '=', '')]
5.10 Method: read
Method read digunakan untuk membaca isi record dan akan mengembalikan (list dari) dictionary dengan informasi sesuai field-field yang diminta.
Melanjutkan dari pembahasan mengakses OpenERP tanpa server dijalankan dan Method: search sebelumnya, kita akan menggunakan method read.
Kita akan membaca dari hasil pencarian yang dilakukan sebelumnya, namun untuk partner dengan id yang tertinggi (yang dibuat terakhir), untuk field name dan website.
>>> from openerp.addons.base.res import res_partner >>> uid = 1 >>> partner = res_partner.res_partner.create_instance(pool, cr) >>> search_result [6, 7, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 25, 27, 28, 29, 30, 31, 32, 33,
34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 67, 69, 70, 71, 75, 91, 92, 93, 94, 95, 96, 97, 98]
>>> read_result = partner.read(cr, uid, search_result[-1], ['name', 'website']) >>> read_result {'website': False, 'name': u'A', 'id': 98} >>>
5.11 Method: write
Method write digunakan untuk mengupdate record berdasarkan ids dan vals yang dilewatkan. Melanjutkan dari pembahasan mengakses OpenERP tanpa server dijalankan dan Method: search
sebelumnya, kita akan menggunakan method write. Kita akan mengupdate data dari hasil pencarian yang dilakukan sebelumnya, namun untuk partner
dengan id yang tertinggi (yang dibuat terakhir), dimana website akan kita update dengan nilai: http://domain.tld.
>>> from openerp.addons.base.res import res_partner >>> uid = 1 >>> partner = res_partner.res_partner.create_instance(pool, cr) >>> search_result [6, 7, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 25, 27, 28, 29, 30, 31, 32, 33,
34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 67, 69, 70, 71, 75, 91, 92, 93, 94, 95, 96, 97, 98]
>>> partner.write(cr, uid, search_result[-1], {'website': 'http://domain.tld'}) True >>> read_result = partner.read(cr, uid, search_result[-1], ['name', 'website']) >>> read_result {'website': u'http://domain.tld', 'name': u'A', 'id': 98} >>>
5.12 Method: create
Method create digunakan untuk membuat record baru, dan akan mengembalikan id dari record yang dibuat.
Melanjutkan dari pembahasan mengakses OpenERP tanpa server dijalankan dan Method: search sebelumnya, kita akan menggunakan method create untuk membuat sebuah sale_order baru.
Kita akan membuat sale_order dengan customer berupa partner dengan id yang tertinggi (yang dibuat terakhir) dari hasil pencarian.
>>> so <openerp.osv.orm.sale.order object at 0xb5407bec> >>> search_result[-1] 98 >>> uid 1 >>> create_data = { ... 'partner_id': search_result[-1], ... 'partner_invoice_id': 1, ... 'partner_shipping_id': 1, ... 'pricelist_id': 1, ... } >>> so_id = so.create(cr, uid, create_data) >>> so_id 17L >>> cr.commit() >>>
Perhatikanlah bahwa kita memanggil fungsi commit dari kursor koneksi database.
5.13 Method: unlink
Method unlink digunakan untuk menghapus record sesuai ids yang dilewatkan. Melanjutkan dari pembahasan mengakses OpenERP tanpa server dijalankan dan Method: create, kita
akan menggunakan method unlink untuk menghapus sale_order yang dibuat sebelumnya. >>> so
<openerp.osv.orm.sale.order object at 0xb5407bec> >>> uid 1 >>> so_id 17L >>> so.unlink(cr, uid, [so_id]) True >>> cr.commit() >>>
5.14 Program 5-1: menambah field
Pada contoh program 5-1, kita akan menambah beberapa field pada model res.partner. Pembahasan tentang view akan dilakukan pada bab tersendiri.
Program akan didistribusikan sebagai modul OpenERP buku_partner_nop_1. Pastikanlah modul ditempatkan pada direktori addons yang terdaftar, dan telah dilakukan update pada daftar modul.
__init__.py
from . import buku_partner_nop_1
__openerp__.py
{ 'name' : 'Partner 1' , 'version' : '1.0' , 'author' : 'noprianto' , 'description' : 'Contoh sederhana tambah field pada partner' , 'category' : 'Buku' , 'website' : 'https://github.com/id-python/buku-openerp' , 'depends' :[ 'base' ], 'data' :[ 'buku_partner_nop_1_view.xml' ], { 'name' : 'Partner 1' , 'version' : '1.0' , 'author' : 'noprianto' , 'description' : 'Contoh sederhana tambah field pada partner' , 'category' : 'Buku' , 'website' : 'https://github.com/id-python/buku-openerp' , 'depends' :[ 'base' ], 'data' :[ 'buku_partner_nop_1_view.xml' ],
from openerp.osv import orm, fields
SELECTION_1 = [ ( 'pilihan1' , 'Pilihan 1' ), ( 'pilihan2' , 'Pilihan 2' ), ( 'pilihan3' , 'Pilihan 3' ), ]
SELECTION_2 = [ ( 'pilihan4' , 'Pilihan 4' ), ( 'pilihan5' , 'Pilihan 5' ), ( 'pilihan6' , 'Pilihan 6' ), ( 'pilihan7' , 'Pilihan 7' ), ( 'pilihan8' , 'Pilihan 8' ), ( 'pilihan9' , 'Pilihan 9' ), ( 'pilihan10' , 'Pilihan 10' ), ]
class res_partner(orm.Model): _name = 'res.partner' _inherit = 'res.partner'
def _get_selection_2(self, cr, uid, context= None ): return SELECTION_2
_columns = { 'buku_field_1' : fields.char( 'Buku Field 1' , size= 20 ,
required= True , help= 'Contoh help' ),
'buku_field_2' : fields.float( 'Buku Field 2' , digits=( 4 , 2 )), 'buku_field_3' : fields.integer( 'Buku Field 3' , size= 10 ), 'buku_field_4' : fields.boolean( 'Buku Field 4' ), 'buku_field_5' : fields.date( 'Buku Field 5' ), 'buku_field_6' : fields.datetime( 'Buku Field 6' ), 'buku_field_7' : fields.selection(SELECTION_1, 'Buku Field 7' ), 'buku_field_8' : fields.selection(_get_selection_2, 'Buku Field
8' ), }
buku_partner_nop_1_view.xml
<?xml version="1.0"?> <openerp>
<data>
<record model="ir.ui.view" id="view_partner_form"> <field name="name">res.partner.form</field> <field name="model">res.partner</field> <field name="inherit_id" ref="base.view_partner_form"/> <field name="type">form</field> <field name="arch" type="xml">
<notebook position="inside">
<page string="Buku (4-1)"> <group>
<field name="buku_field_1"/> <field name="buku_field_2"/> <field name="buku_field_3"/> <field name="buku_field_4"/> <field name="buku_field_5"/> <field name="buku_field_6"/> <field name="buku_field_7"/> <field name="buku_field_8"/>
</group> </page> </notebook> </field> </record> </data>
</openerp>
5.15 Program 5-2: readonly dan nilai default
Pada contoh program 5-2, kita akan bekerja dengan readonly dan nilai default pada field yang ditambahkan pada model res.partner. Pembahasan tentang view akan dilakukan pada bab tersendiri.
Program akan didistribusikan sebagai modul OpenERP buku_partner_nop_2. Pastikanlah modul ditempatkan pada direktori addons yang terdaftar, dan telah dilakukan update pada daftar modul.
__init__.py
from . import buku_partner_nop_2
__openerp__.py
{ 'name' : 'Partner 2' , 'version' : '1.0' , 'author' : 'noprianto' , 'description' : 'Contoh sederhana readonly dan default pada field' , 'category' : 'Buku' , 'website' : 'https://github.com/id-python/buku-openerp' , 'depends' :[ 'base' ], 'data' :[ 'buku_partner_nop_2_view.xml' ], { 'name' : 'Partner 2' , 'version' : '1.0' , 'author' : 'noprianto' , 'description' : 'Contoh sederhana readonly dan default pada field' , 'category' : 'Buku' , 'website' : 'https://github.com/id-python/buku-openerp' , 'depends' :[ 'base' ], 'data' :[ 'buku_partner_nop_2_view.xml' ],
from openerp.osv import orm, fields
class res_partner(orm.Model): _name = 'res.partner' _inherit = 'res.partner' _columns = {
'buku_field_9' : fields.char( 'Buku Field 9' , size= 20 , readonly= True ), 'buku_field_10' : fields.char( 'Buku Field 10' ), }
_defaults = {
'buku_field_9' : 'Contoh default' , 'buku_field_10' : lambda self, cr, uid, context: '
' .join(context.keys()), }
buku_partner_nop_2_view.xml
<?xml version="1.0"?> <openerp>
<data> <record model="ir.ui.view" id="view_partner_form"> <field name="name">res.partner.form</field> <field name="model">res.partner</field> <field name="inherit_id" ref="base.view_partner_form"/> <field name="type">form</field> <field name="arch" type="xml">
<notebook position="inside">
<page string="Buku (4-2)"> <group>
<field name="buku_field_9"/> <field name="buku_field_10"/>
</group> </page> </notebook> </field> </record> </data>
</openerp>
5.16 Program 5-3: constraint
Pada contoh program 5-3, kita akan bekerja dengan constraint pada field yang ditambahkan pada model res.partner. Pembahasan tentang view akan dilakukan pada bab tersendiri.
Program akan didistribusikan sebagai modul OpenERP buku_partner_nop_3. Pastikanlah modul ditempatkan pada direktori addons yang terdaftar, dan telah dilakukan update pada daftar modul.
__init__.py
from . import buku_partner_nop_3
__openerp__.py
{ 'name' : 'Partner 3' , 'version' : '1.0' , 'author' : 'noprianto' , 'description' : 'Contoh sederhana constraint pada field' , 'category' : 'Buku' , 'website' : 'https://github.com/id-python/buku-openerp' , 'depends' :[ 'base' ], 'data' :[ 'buku_partner_nop_3_view.xml' ], { 'name' : 'Partner 3' , 'version' : '1.0' , 'author' : 'noprianto' , 'description' : 'Contoh sederhana constraint pada field' , 'category' : 'Buku' , 'website' : 'https://github.com/id-python/buku-openerp' , 'depends' :[ 'base' ], 'data' :[ 'buku_partner_nop_3_view.xml' ],
from openerp.osv import orm, fields
class res_partner(orm.Model): _name = 'res.partner' _inherit = 'res.partner' _columns = {
'buku_field_11' : fields.char( 'Buku Field 11' , size= 20 , required= True ), }
_defaults = {
'buku_field_11' : 'hello' ,
def _check_field_11(self, cr, uid, ids, context= None ): for i in self.browse(cr, uid, ids, context=context):
if len(i.buku_field_11) >= 3 : return True
return False
_constraints = ( [_check_field_11, 'Panjang harus minimal 3 karakter' , [ 'buku_field_11' ]], )
buku_partner_nop_3_view.xml
<?xml version="1.0"?> <openerp>
<data> <record model="ir.ui.view" id="view_partner_form"> <field name="name">res.partner.form</field> <field name="model">res.partner</field> <field name="inherit_id" ref="base.view_partner_form"/> <field name="type">form</field> <field name="arch" type="xml">
<notebook position="inside">
<page string="Buku (4-3)"> <group>
<field name="buku_field_11"/> </group> </page> </notebook> </field>
</record> </data>
</openerp>
5.17 Program 5-4: field functional
Pada contoh program 5-4, kita akan menambahkan field functional pada model res.partner. Pembahasan tentang view akan dilakukan pada bab tersendiri.
Program akan didistribusikan sebagai modul OpenERP buku_partner_nop_4. Pastikanlah modul ditempatkan pada direktori addons yang terdaftar, dan telah dilakukan update pada daftar modul.
__init__.py
from . import buku_partner_nop_4
__openerp__.py
{ 'name' : 'Partner 4' , 'version' : '1.0' , 'author' : 'noprianto' , 'description' : 'Contoh sederhana field functional' , 'category' : 'Buku' , 'website' : 'https://github.com/id-python/buku-openerp' , 'depends' :[ 'base' ], 'data' :[ 'buku_partner_nop_4_view.xml' ],
buku_partner_nop_4.py
import random from openerp.osv import orm, fields
class res_partner(orm.Model): _name = 'res.partner' _inherit = 'res.partner'
def _function_test(self, cr, uid, ids, field, arg, context= None ): res = {} for i in ids: res[i] = random.random() return res
_columns = { 'buku_field_12' : fields.function(_function_test, type= 'float' ) }
buku_partner_nop_4_view.xml
<?xml version="1.0"?> <openerp>
<data> <record model="ir.ui.view" id="view_partner_form"> <field name="name">res.partner.form</field> <field name="model">res.partner</field> <field name="inherit_id" ref="base.view_partner_form"/> <field name="type">form</field> <field name="arch" type="xml">
<notebook position="inside">
<page string="Buku (4-4)"> <group>
<field name="buku_field_12" string="Buku Field 12 (function)"/>
</group> </page> </notebook> </field> </record> </data>
</openerp>
5.18 Program 5-5: method create/write
Pada contoh program 5-5, kita akan melakukan override method create dan write milik model res.partner.
Program akan didistribusikan sebagai modul OpenERP buku_partner_nop_5. Pastikanlah modul ditempatkan pada direktori addons yang terdaftar, dan telah dilakukan update pada daftar modul.
__init__.py
from . import buku_partner_nop_5
__openerp__.py
{ 'name' : 'Partner 5' , 'version' : '1.0' , 'author' : 'noprianto' , 'description' : 'Contoh sederhana override method create/write' , 'category' : 'Buku' , 'website' : 'https://github.com/id-python/buku-openerp' , 'depends' :[ 'base' ],
buku_partner_nop_5.py
from openerp.osv import orm, fields
class res_partner(orm.Model): _name = 'res.partner' _inherit = 'res.partner'
def write(self, cr, user, ids, vals, context= None ): comment = vals.get( 'comment' , '' ) try : comment = comment.strip() vals[ 'comment' ] = comment
except AttributeError: pass
return super(res_partner, self).write(cr, user, ids, vals, context)
def create(self, cr, user, vals, context= None ): comment = vals.get( 'comment' , '' ) try : comment = comment.strip() vals[ 'comment' ] = comment
except AttributeError: pass
return super(res_partner, self).create(cr, user, vals, context)