27 Januari 2012

Mengatur Hak Akses Modul OpenERP (module security in OpenERP)

Bismillahirrahmaanirrahiim

Ini tentang hak akses dari suatu modul yang kita buat. Intinya saya ingin modul yang saya buat hanya bisa diakses dengan group tertentu.
Kuncinya ada di folder security dari suatu modul.
Agak susah untuk menemukan tutorial tentang hal ini, sampai akhirnya saya coba pahami dan dapat pencerahan deh :)

Oke, kalau kita lihat contoh-contoh modul yang sudah ada, di folder security ada setidaknya 2 file, yaitu:
  • ir.model.access.csv
  • nama_modul_security.xml
Saat pertama lihat isi ir.model.access.csv saya bingung itu kolom maksudnya apa aja ya...
Contoh:


Penjelasan:
  • id dan name itu adalah id dan name access control (menu Administrator > Security > Access Control List)
    Kita bisa lihat name nya sesuai dengan field name di list access control (tabel ir_model_access)
    Kalau id saya belum tahu akan tersimpan di mana ya...
  • model_id:id
    sintaksnya: model_ + nama tabel
  • group_id:id
    id dari group user.
    sintaksnya: nama_modul + id_group_user
    Nah hal ini yang buat saya bingung, karena yang saya pahami group user itu disetting di menu Administrator > Users > Groups
    tapi saya tidak bisa menemukan group contoh: account.group_account_user

    Setelah saya uprek2.. akhirnya saya menemukan pencerahan kembali, yaitu dengan melihat file nama_modul_security.xml. Contoh kita bisa lihat id group_account_user di file account_security.xml
    <record id="group_account_invoice" model="res.groups">
        <field name="name">Accounting / Invoice</field>
    </record>

    <record id="group_account_user" model="res.groups" context="{'noadmin':True}">
        <field name="name">Accounting / Accountant</field>
    </record>
    <record id="group_account_manager" model="res.groups" context="{'noadmin':True}">
        <field name="name">Accounting / Manager</field>
    </record>
Lihat contoh tersebut, yang menunjukkan bahwa id group_id:id account.group_account_user adalah group name Accounting / Accountant yang didefinisikan di modul account (addons/account).


Sedangkan untuk contoh yang saya buat, saya buat 2 group yaitu:
cash_out_voucher.group_co_voucher_user
dan
cash_out_voucher.group_co_voucher_approval


Yang sebelumnya telah saya definisikan di file cash_out_voucher_security.xml

       <record id="group_co_voucher_approval" model="res.groups">
            <field name="name">Cash Out Voucher Approver</field>
        </record>
        <record id="group_co_voucher_user" model="res.groups">
            <field name="name">Cash Out Voucher User</field>
        </record>
  • perm_read, perm_write, perm_create, perm_unlink
    Set 1 jika group tersebut mendapatkan akses di tabel yang didefinisikan di model_id:id
    Set 0 jika tidak dapat akses
    * perm_read: membaca
    * perm_write: edit
    * perm_create: buat baru
    * perm_unlink: hapus data
Yap... selanjutnya jangan lupa definisikan di file _openerp_.py

    "update_xml" : [
        "security/cash_out_voucher_security.xml",
        "security/ir.model.access.csv",
    ],
Restart server dan upgrade modul ... selanjutnya tentukan user mana yang berhak masuk di group yang sudah didefinisikan

Demikan dari saya,
semoga bermanfaat

Tolong koreksi ya kalo ada yang salah...

24 Januari 2012

Balance dari account yang tidak sesuai untuk kebutuhan migrasi sistem (incorrect account balance in OpenERP)

Bismillahirrahmaanirrahiim

Jadi, ini masih berhubungan dengan migrasi sistem akutansi dari Accurate ke OpenERP.
Setelah dipusingkan dengan report balance sheet dan P/L yang agak kacau balau, kembali saya dipusingkan dengan balance dari journal items...

Hmm bagaimana cara melihat balance dari journal items ... mudah saja.
Masuk ke menu Accounting > Journal Entries > Journal Items.
Contoh kasus.

Kita ingin melihat daftar transaksi yang melibatkan suatu account (COA) tertentu. contohnya COA bank_idr.

Balance terlihat dari kolom Balance,
jadi seperti buku rekening bank , kita bisa mendapatkan saldo untuk setiap transaksi.
Ohya kalau ada yang bingung, di mana bisa mengeluarkan kolom balance pada tabel tersebut, mudah saja. Kita bisa klik menu Manage Views di sebelah kanan (hanya bisa dilakukan Administrator)
Nah keanehan bisa dilihat pada contoh 2 journal items berikut:

coba jumlahkan balance -285,220, 520 dengan 252,000,000. Tidak mungkin kan bernilai -2 Miliar seperti itu... karena hasilnya hanya -33,220,520

lalu selisih sebanyak itu didapat dari manakah?
mari kita lihat method untuk menghitung balance tersebut di file account\account_move_line.py
method _balance

def _balance(self, cr, uid, ids, name, arg, context=None):
        if context is None:
            context = {}
        c = context.copy()
        c['initital_bal'] = True
        sql = """SELECT l2.id, SUM(l1.debit-l1.credit)
                    FROM account_move_line l1, account_move_line l2
                    WHERE l2.account_id = l1.account_id
                      AND l1.id <= l2.id
                      AND l2.id IN %s AND """ + \
                self._query_get(cr, uid, obj='l1', context=c) + \
                " GROUP BY l2.id"

        cr.execute(sql, [tuple(ids)])
        return dict(cr.fetchall())

Nah di situ ada query dengan where clause l1.id <= l2.id

Bagaimana menurut teman2?
Query tersebut sangat tidak cocok dengan kondisi data hasil migrasi, di mana bisa terjadi data tahun lalu dimasukkan setelah data baru (yang berarti id data lama akan lebih besar dari id data baru)
Dalam hal ini, ada sejumlah data dari Accurate yang tertinggal  saya migrasi ke OpenERP karena datanya tersembunyi di accurate, sedangkan data tersebut merupakan data2 awal perusahaan.

Belum lagi, kebiasaan user yang memungkinkan memasukkan jurnal untuk transaksi udah berlalu, dikarenakan kondisi2 tertentu...

Nah kalau sudah begini query tersebut pasti menjadi tidak cocok...
Setelah muter2 cari ide... akhirnya saya merubah querynya menjadi sepert ini:
sql = """SELECT l2.id, SUM(l1.debit)-SUM(l1.credit)
                    FROM (select l.*, row_number() over (order by l.date,l.id) as number from account_move_line l inner join account_move m on l.move_id=m.id where m.state='posted') l1, (select l.*, row_number() over (order by l.date,l.id) as number from account_move_line l inner join account_move m on l.move_id=m.id where m.state='posted') l2 WHERE l2.account_id = l1.account_id AND l1.number <= l2.number AND l2.id IN %s AND """ + \
                self._query_get(cr, uid, obj='l1', context=c) + \
                " GROUP BY l2.id"

Lihat perubahan query agak drastis yang saya lakukan... kuncinya di urutan jurnal berdasarkan date dan id... lalu jurnal item tersebut diberi nomor baris... kemudian where clause nya di ganti menjadi l1.number <= l2.number

Begitu sharing dari saya, kalau bingung boleh ditanya kok...
Semoga bermanfaat


13 Januari 2012

Bank account Employee tidak bisa tersimpan (Impossible to add a bank account on an employee)

Bismillahirrahmaanirrahiim

Ini termasuk masalah yang saya temukan di awal2 menggunakan OpenERP, yaitu di modul Human Resource.
tapi karena pak bos meminta saya untuk pending modul ini untuk megerjakan modul lain, jadinya baru akhir2 ini deh ketemu penyebabnya,

Eh bugsnya apa tho? hehe

Jadi Di data Employee tab Miscellaneous (menu Human Resource > Human Resource > Employees)

Nah di tab tersebut kan ada field Bank Account Number

Kalau sudah memasukkan account number dengan salah satu partner (harus buat baru di situ) lalu kita save. Kemudian mau kita edit karena salah misalnya.Pas kita klik kaca pembesar di field tersebut, kita dapatkan data kosong, account number yang kita masukkan tadi hilang.

Mau cari ke mana? bingung kaannn

Sejumlah postingan forum saya temukan, tapi belum menemukan jawaban yang pas.
Akhirnya saya baca deh source codenya. di file addons\hr\hr.py

saya telusuri class hr_employee 

lalu didefinis columns terlihat bahawa untuk bank_account definisinya adalah sebagai berikut:
'bank_account_id':fields.many2one('res.partner.bank', 'Bank Account Number', domain="[('partner_id','=',partner_id)]", help="Employee bank salary account"),
Nah domain dari field tersebu adalah domain="[('partner_id','=',partner_id)]" di mana definisi field partner_id adalah:
'partner_id': fields.related('address_home_id', 'partner_id', type='many2one', relation='res.partner', readonly=True, help="Partner that is related to the current employee. Accounting transaction will be written on this partner belongs to employee."),
dimana dari definisi field tersebut, partner_id merupakan mapping dari field address_home_id
'address_home_id': fields.many2one('res.partner.address', 'Home Address'),
Jadi, intinya field Home Address di tab Personal harus diisi.


maka isi dulu ya home address yang juga harus mapping dengan partner_id 
Karena repot membuat partner untuk setiap employee,
maka saya buat saja partner global untuk setiap kelompok employee.

Setelah memasukkan home address, save (atau save & Edit) dulu baru masukkan bank Account. 
karena kalau tidak disave dulu, partner_id nya belum akan tersimpan. 
Repot yaaa.... 

Harus dibenerin sebenarnya biar gak kayak begini lagii... 
Ohya,,, Kalau buat partner sudah tau kan caranya.
bisa di menu customer/supplier. Uncek saja checkbox supplier dan customer nya..

Demikan dari saya,
semoga bermanfaat
terima kasih