Enterprise Systems

Enterprise ERP Engineering: Refactoring ERPNext to a 7-Segment Chart of Accounts & Custom Flows

Bagaimana saya merekayasa skrip Python kustom dan konfigurasi Frappe di ERPNext untuk mengubah struktur dasar akuntansi menjadi bagan akun 7-segmen finansial dinamis.

#ERPNext#Python#Frappe Framework#Chart of Accounts#Workflow Engineering

Ringkasan Eksekutif

Pada tingkat korporasi skala besar, infrastruktur Enterprise Resource Planning (ERP) standar sering kali tidak mampu mengakomodasi kompleksitas pelaporan keuangan perusahaan. Di Berijalan Techno Center, model pencatatan akuntansi bawaan platform open-source ERPNext hanya mendukung bagan akun sederhana (2-segmen: Account dan Cost Center). Struktur sederhana ini tidak mampu melacak alokasi anggaran multidimensi yang melibatkan unit bisnis, lokasi fisik, tipe pendanaan eksternal, kelas aset, dan penanggung jawab departemen secara detail.

Untuk memecahkan batasan fungsional ini, saya memimpin inisiatif refaktorisasi sistem dengan:

  1. Merestrukturisasi Chart of Accounts (COA) bawaan menjadi Sistem Akuntansi Multidimensi 7-Segmen.
  2. Mengembangkan mesin persetujuan (Custom Workflow Engine) dinamis menggunakan skrip kustom berbasis Frappe & Python untuk memotong birokrasi persetujuan dokumen secara digital.

Desain Struktur Chart of Accounts (COA) 7-Segmen

Untuk mewujudkan pelaporan keuangan yang akurat sesuai standar PSAK korporat, kode akun jurnal akuntansi dirancang ulang agar memuat 7 segmen dimensi finansial yang terintegrasi. Setiap transaksi jurnal yang dicatat dalam Buku Besar (General Ledger) wajib dipecah ke dalam segmen-segmen berikut:

graph LR
    subgraph COA_Structure [General Ledger Account Key: 7-Segments]
        S1[1. Business Unit <br> 2 digits] --> S2[2. Cost Center <br> 3 digits]
        S2 --> S3[3. Location <br> 2 digits]
        S3 --> S4[4. Funding Source <br> 3 digits]
        S4 --> S5[5. Asset Class <br> 2 digits]
        S5 --> S6[6. Core Account <br> 5 digits]
        S6 --> S7[7. Sub-Account <br> 4 digits]
    end

    style COA_Structure fill:#f5f5f5,stroke:#aaa,stroke-width:1px
    style S6 fill:#bfb,stroke:#333,stroke-width:1px

Pembagian segmen ini direkayasa secara langsung di level database MariaDB ERPNext dengan menambahkan kolom dimensi kustom pada tabel transaksi jurnal inti (tabGL Entry dan tabJournal Entry Account). Penambahan kolom ini disinkronkan dengan memodifikasi kelas internal DocType Frappe untuk memastikan validasi saldo debit dan kredit tetap terjaga (double-entry balancing) di semua dimensi segmen.


Kustomisasi Alur Approval Dinamis via Python & Frappe

Proses operasional seperti pengajuan pembelian (Purchase Requisition) dan klaim pengeluaran (Expense Claim) membutuhkan alur persetujuan bertingkat yang bergantung pada jumlah pengajuan dan jabatan struktural pengusul.

Saya menulis skrip server-side kustom Python di Frappe untuk secara dinamis mengidentifikasi rantai otorisator yang tepat berdasarkan struktur organisasi dan batasan finansial (financial thresholds):

import frappe
from frappe.model.document import Document

class CustomExpenseClaim(Document):
    def validate(self):
        # Jalankan validasi saldo anggaran sebelum pengajuan diproses
        self.check_budget_limits()

    def check_budget_limits(self):
        # Ambil total pengajuan klaim
        total_amount = self.total_amount
        
        # Aturan Otorisasi Bertingkat
        if total_amount > 50000000: # Di atas 50 Juta Rupiah
            # Wajib mendapatkan persetujuan dari Head of Finance (Level 3)
            self.custom_next_approver_role = "Head of Finance"
        elif total_amount > 10000000: # Di atas 10 Juta Rupiah
            # Cukup disetujui oleh Department Manager (Level 2)
            self.custom_next_approver_role = "Department Manager"
        else:
            # Di bawah 10 Juta Rupiah, disetujui oleh Team Lead (Level 1)
            self.custom_next_approver_role = "Team Lead"
            
        frappe.log_error(
            title="Workflow Routing",
            message=f"Claim {self.name} routed to role {self.custom_next_approver_role} based on amount {total_amount}"
        )

@frappe.whitelist()
def approve_document(docname, approver_user):
    """
    Fungsi API kustom untuk mengeksekusi transisi status dokumen 
    oleh user yang terotentikasi dan memiliki role yang sesuai.
    """
    doc = frappe.get_doc("Expense Claim", docname)
    user_roles = frappe.get_roles(approver_user)
    
    if doc.custom_next_approver_role in user_roles:
        doc.status = "Approved" if doc.custom_next_approver_role == "Head of Finance" else "Reviewed"
        doc.save()
        # Trigger email notifikasi otomatis ke user berikutnya
        send_workflow_notification(doc)
    else:
        frappe.throw("Anda tidak memiliki otorisasi untuk menyetujui dokumen ini.")

Tantangan Rekayasa & Solusi

  • Migrasi Data Historis: Mengubah COA 2-segmen ke 7-segmen pada sistem yang sudah berjalan memiliki risiko tinggi merusak pelaporan laba rugi tahun lalu. Solusinya, saya membuat skrip migrasi data Python sekali pakai (data migration runner) untuk memetakan ulang seluruh transaksi buku besar historis secara otomatis ke format segmen baru berdasarkan relasi entitas induk.
  • Konsistensi Kecepatan Query: Dengan bertambahnya field filter dimensi akuntansi (7 kolom kustom di database), query laporan neraca keuangan melambat secara signifikan. Masalah ini diselesaikan dengan membuat composite index pada database MariaDB yang menggabungkan kolom tanggal posting jurnal dengan segmen-segmen transaksi finansial utama.

Dampak Bisnis & Efisiensi Sistem

Penerapan ERPNext yang disesuaikan ini menghasilkan transformasi operasional yang signifikan bagi organisasi:

  • Visibilitas Finansial Presisi Tinggi: Manajemen kini dapat menganalisis keuntungan dan kerugian (P&L) secara instan berdasarkan unit bisnis, wilayah kantor cabang, atau sumber pendanaan proyek secara mandiri tanpa rekapitulasi manual.
  • Birokrasi Bebas Kertas (Paperless): Rantai persetujuan Purchase Requisition dan Expense Claim terotomatisasi secara digital, memangkas durasi siklus otorisasi dari rata-rata 4 hari menjadi kurang dari 30 menit.
  • Kepatuhan Anggaran Ketat: Mencegah kebocoran anggaran dengan melakukan blokir pengajuan operasional secara otomatis jika total biaya melebihi alokasi dana segmen Cost Center bersangkutan.