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 LineDari 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.
Perbandingan Periode dan Trending
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.
