Skip to main content
BlogERP

Analisis Varians Anggaran vs. Aktual di ERP Kustom: Kontrol Keuangan Real-Time

Cara membangun modul analisis varians anggaran di ERP kustom — dari entri anggaran dan posting aktual hingga laporan varians otomatis, alert pengecualian, dan analisis drill-down.

Matthews Wong

Software Engineer

Juni 202510 menit baca
ERP

Ringkasan Utama

Analisis varians anggaran membandingkan rencana belanja dan pendapatan dengan yang benar-benar terjadi, dan termasuk fitur paling bernilai di modul ERP keuangan. Menghitungnya terus-menerus, bukan di akhir bulan, mengubahnya dari laporan historis menjadi alat kendali yang masih bisa mengubah hasil.

Analisis varians anggaran adalah proses membandingkan apa yang Anda rencanakan untuk dibelanjakan atau diperoleh versus apa yang sebenarnya terjadi — dan ini adalah salah satu fitur bernilai tertinggi dalam modul keuangan ERP. Jika biaya operasional Anda diproyeksikan Rp 5 miliar untuk tahun ini dan Anda mengidentifikasi varians tidak menguntungkan Rp 250 juta di Q1, tindakan korektif segera dapat mencegah kekurangan Rp 1 miliar sepanjang tahun.

Entri Anggaran dan Versioning

Modul anggaran dimulai dengan pembuatan anggaran: tim keuangan memasukkan anggaran tahunan berdasarkan pusat biaya dan kode akun, dipecah per bulan. Sistem yang saya bangun mendukung versioning anggaran — anggaran asli (Versi 1), perkiraan revisi Q1 (Versi 2), dan seterusnya. Laporan varians dapat membandingkan aktual terhadap versi mana pun.

Model Data Anggaran

Tabel anggaran menyimpan: budget_version_id, cost_center_id, account_id, fiscal_year, month (1-12), dan budgeted_amount. Aktual berasal dari tabel journal_lines yang difilter berdasarkan cost_center_id, account_id, dan bulan yang sama. Varians dihitung sebagai: aktual dikurangi anggaran. Perhitungan ini adalah view di PostgreSQL, bukan komputasi lapisan aplikasi — mereka tetap sinkron secara otomatis saat entri jurnal baru diposting.

Budget vs. Actual vs. Commitment Dashboard

  budget_lines (versioned)          journal_lines (actuals)
       │  budget_version_id               │  cost_center_id
       │  cost_center_id                  │  account_id
       │  account_id                      │  (debit - credit)
       │  month, budgeted_amount          │
       └──────────────┬───────────────────┘
                      │  PostgreSQL View (budget_variance_view)
                      │  + budget_commitments (open POs)
                      ▼
  ┌────────────────────────────────────────────────────────────┐
  │  Budget Variance Dashboard (React + Recharts)              │
  │                                                            │
  │  Cost Center    Budget    Actual  Commit  Avail  Status   │
  │  ─────────────────────────────────────────────────────── │
  │  IT Dept        500M      420M    60M     20M    🟡 96%  │
  │  Operations     800M      620M    50M    130M    🟢 77%  │
  │  Marketing      200M      240M     0M    -40M    🔴 120% │
  │  HR             300M      190M    20M     90M    🟢 63%  │
  │  ─────────────────────────────────────────────────────── │
  │  TOTAL          1.8B      1.47B  130M    200M   🟡 89%  │
  │                                                            │
  │  Available = Budget − Actual − Commitments                 │
  │  (preventive control: stops over-budget POs)              │
  └────────────────────────────────────────────────────────────┘

  Drill-down: Cost Center → Account → Journal Line

Dari pengalaman saya sebagai konsultan ERP lepas: implementasikan entri anggaran oleh manajer departemen, bukan hanya oleh keuangan. Anggaran menjadi lebih akurat dan lebih diadopsi ketika kepala departemen memiliki baris anggaran mereka sendiri. Saya membangun layar entri anggaran swalayan di mana setiap manajer departemen memasukkan anggaran mereka sendiri dengan workflow pengiriman. Manajer departemen yang menetapkan anggaran mereka sendiri juga lebih bertanggung jawab atas varians terhadapnya.

Dashboard Varians Real-Time

Dashboard varians menampilkan semua pusat biaya berdampingan dengan indikator lampu lalu lintas: hijau (aktual dalam 5% dari anggaran), kuning (varians 5-15%), merah (varians >15%). Mengklik pusat biaya apa pun akan menelusuri ke varians tingkat akun. Mengklik akun apa pun menampilkan entri jurnal individual yang membentuk aktual. Drill-down tiga tingkat ini — pusat biaya → akun → transaksi — memberi manajer keuangan semua yang mereka butuhkan untuk menyelidiki varians.

Alert Varians Otomatis

Job cron NestJS berjalan setiap Senin pagi dan memeriksa semua akun pusat biaya untuk varians di atas threshold yang dikonfigurasi. Melampaui threshold memicu email ke pemilik pusat biaya dan manajer mereka dengan: akun yang bersangkutan, jumlah anggaran, jumlah aktual, jumlah varians dan %, dan tautan satu klik ke tampilan drill-down.

-- PostgreSQL: Budget variance view (with commitments)
CREATE MATERIALIZED VIEW budget_variance_mv AS
SELECT
  cc.id            AS cost_center_id,
  cc.name          AS cost_center_name,
  coa.id           AS account_id,
  coa.account_name,
  coa.category,
  bl.fiscal_year,
  bl.month,
  -- Budget (latest approved version)
  COALESCE(bl.budgeted_amount, 0)                   AS budget,
  -- Actuals from journal
  COALESCE(SUM(jl.debit - jl.credit), 0)            AS actual,
  -- Commitments: approved POs not yet invoiced
  COALESCE(SUM(pol.amount - pol.invoiced_amount), 0) AS commitment,
  -- Computed columns
  COALESCE(bl.budgeted_amount, 0)
    - COALESCE(SUM(jl.debit - jl.credit), 0)
    - COALESCE(SUM(pol.amount - pol.invoiced_amount), 0)
    AS available,
  ROUND(
    COALESCE(SUM(jl.debit - jl.credit), 0)
      / NULLIF(bl.budgeted_amount, 0) * 100, 1
  ) AS pct_used
FROM cost_centers cc
JOIN budget_lines bl ON bl.cost_center_id = cc.id
  AND bl.budget_version_id = (
    SELECT id FROM budget_versions
    WHERE status = 'approved'
    ORDER BY version_number DESC LIMIT 1
  )
JOIN chart_of_accounts coa ON bl.account_id = coa.id
LEFT JOIN journal_lines jl ON jl.cost_center_id = cc.id
  AND jl.account_id = coa.id
  AND EXTRACT(YEAR FROM jl.posted_date) = bl.fiscal_year
  AND EXTRACT(MONTH FROM jl.posted_date) = bl.month
LEFT JOIN purchase_order_lines pol ON pol.cost_center_id = cc.id
  AND pol.account_id = coa.id
  AND pol.status = 'approved'
GROUP BY cc.id, cc.name, coa.id, coa.account_name,
         coa.category, bl.fiscal_year, bl.month, bl.budgeted_amount;

-- Refresh every 30 minutes
CREATE UNIQUE INDEX ON budget_variance_mv
  (cost_center_id, account_id, fiscal_year, month);

Bagaimana Saya Mendekati Ini

Modul varians dibangun di atas view PostgreSQL untuk komputasi inti, NestJS service untuk API, dan Recharts di React untuk visualisasi. View PostgreSQL kunci bergabung dengan budget_lines (anggaran) dengan journal_lines (aktual) dan purchase_order_lines (komitmen) pada cost_center_id dan account_id. View dibungkus dalam materialized view yang di-refresh setiap 30 menit untuk performa dashboard.

Kesalahpahaman umum adalah hanya menampilkan aktual vs. anggaran dan melewatkan pengeluaran yang berkomitmen. Jika departemen Anda memiliki anggaran Rp 100M, telah menghabiskan Rp 60M (aktual), tetapi memiliki PO senilai Rp 50M yang disetujui tetapi belum dibayar (komitmen), anggaran tersedia yang sebenarnya adalah Rp -10M — bukan Rp 40M. Gagal melacak komitmen menyebabkan pengeluaran berlebih. Sistem yang saya bangun mempertahankan tabel budget_commitments yang diisi oleh Purchase Order yang disetujui.

Selain varians periode saat ini, manajemen membutuhkan perbandingan periode-atas-periode: Apakah varians membaik atau memburuk? Saya menyediakan tampilan tren varians 12 bulan per pusat biaya, menampilkan persentase varians untuk setiap bulan. Pusat biaya dengan varians menguntungkan yang konsisten 8-10% pada biaya material kemungkinan dianggarkan terlalu rendah — wawasan berguna untuk perencanaan anggaran tahun depan.

Integrasi dengan Workflow Approval

Integrasi paling berdampak adalah antara modul anggaran dan workflow approval purchase order. Ketika Purchase Order diajukan untuk disetujui, sistem memeriksa anggaran tersedia (anggaran dikurangi aktual dikurangi komitmen) untuk pusat biaya yang relevan. Jika PO akan menyebabkan pusat biaya melampaui anggarannya, workflow approval secara otomatis menambahkan Manajer Keuangan sebagai approver tambahan. Kontrol preventif ini menangkap pembengkakan anggaran sebelum terjadi.

FAQ

Pertanyaan Umum

Jawaban singkat untuk pertanyaan yang paling sering diajukan pembaca tentang topik ini.

Mengapa dashboard menampilkan Anggaran, Aktual, DAN Komitmen — bukan sekadar Anggaran vs. Aktual?

Menampilkan hanya aktual terhadap anggaran memberikan gambaran yang salah tentang dana yang tersedia. Jika departemen memiliki anggaran Rp 100M, telah menghabiskan Rp 60M (aktual), tetapi memegang PO senilai Rp 50M yang sudah disetujui tapi belum dibayar (komitmen), anggaran tersedia yang sebenarnya adalah Rp -10M — bukan Rp 40M. Melacak komitmen bersama aktual mencegah pengeluaran berlebih sebelum uang benar-benar keluar.

Mengapa perhitungan varians disimpan sebagai view PostgreSQL, bukan dihitung di lapisan aplikasi?

Menempatkan logika varians di view PostgreSQL berarti angka-angka tetap sinkron secara otomatis setiap kali entri jurnal baru diposting, tanpa kode aplikasi tambahan. Untuk performa dashboard, view tersebut juga dibungkus dalam materialized view yang di-refresh setiap 30 menit, dengan opsi refresh sesuai permintaan ketika CFO butuh angka terbaru sebelum rapat direksi.

Bagaimana modul ini mendukung revisi anggaran di tengah tahun, yang umum terjadi di bisnis Indonesia?

Sistem mendukung versioning anggaran — anggaran tahunan asli adalah Versi 1, perkiraan revisi Q1 adalah Versi 2, dan seterusnya. Laporan varians dapat membandingkan aktual terhadap versi mana pun, sehingga manajemen dapat melihat perbandingan 'vs. anggaran asli' atau 'vs. perkiraan terbaru'. Ini sangat relevan di Indonesia di mana anggaran sering direvisi akibat depresiasi Rupiah, perubahan harga komoditas, atau kontrak pemerintah baru.

Bagaimana workflow approval purchase order terintegrasi dengan kontrol anggaran?

Ketika Purchase Order diajukan untuk disetujui, sistem otomatis memeriksa anggaran tersedia (anggaran dikurangi aktual dikurangi komitmen) untuk pusat biaya yang relevan. Jika PO akan menyebabkan pusat biaya melampaui anggarannya, workflow secara otomatis menambahkan Manajer Keuangan sebagai approver tambahan yang wajib. Kontrol preventif ini menangkap pembengkakan anggaran di tahap komitmen, sebelum uang benar-benar dikeluarkan.

Mengapa post ini merekomendasikan agar manajer departemen memasukkan baris anggaran mereka sendiri, bukan dipusatkan di tim keuangan?

Ketika kepala departemen memiliki baris anggaran mereka sendiri melalui layar entri swalayan dengan workflow pengiriman, anggaran menjadi lebih akurat karena mencerminkan realitas operasional. Manajer yang menetapkan anggaran mereka sendiri juga lebih bertanggung jawab atas varians terhadapnya. Pendekatan penganggaran partisipatif ini umumnya menghasilkan akurasi perkiraan yang lebih baik dibandingkan penetapan anggaran secara top-down.