Mendesain Sistem Pembukuan Berpasangan (Double-Entry Bookkeeping) pada Aplikasi Keuangan Sekolah
Bagaimana cara merancang arsitektur database akuntansi berpasangan (debit & kredit) untuk menjamin seimbangnya laporan keuangan dan mencegah fraud transaksi pada aplikasi sekolah.
Table of Contents
Dalam pengelolaan keuangan lembaga pendidikan atau sekolah, salah satu kesalahan paling fatal pada aplikasi kasir konvensional adalah hanya mencatat transaksi secara satu sisi (single-entry) seperti kas masuk dan kas keluar. Pendekatan ini sangat rentan terhadap ketidakseimbangan laporan, kehilangan jejak piutang SPP siswa, serta kesulitan saat dilakukan audit akuntansi harian.
Di dalam pengembangan sistem ForgeSPP, kami mengimplementasikan sistem Pembukuan Berpasangan (Double-Entry Bookkeeping) tingkat akuntansi enterprise. Setiap rupiah transaksi—baik penerimaan SPP, cicilan, maupun pengeluaran operasional—secara otomatis mendokumentasikan entri Debit dan Kredit seimbang ke dalam jurnal umum dan buku besar (General Ledger).
1. Prinsip Dasar Akuntansi Berpasangan
Persamaan dasar akuntansi yang melandasi arsitektur sistem ini adalah:
$$\text{Aset} = \text{Liabilitas} + \text{Ekuitas}$$
Dalam pencatatan transaksi:
- Debit: Menambah akun Aset (seperti Kas Tangan atau Kas Bank) dan Beban Operasional, atau mengurangi Akun Liabilitas.
- Kredit: Menambah akun Pendapatan atau Liabilitas, serta mengurangi Akun Aset (seperti pencatatan pengeluaran kas).
2. Perancangan Skema Database (Prisma ORM)
Untuk mendukung pembukuan berpasangan yang aman, kami memisahkan struktur header jurnal (jurnal) dan detail baris pencatatan entri (jurnal_detail):
model Akun {
id_akun String @id @db.VarChar(20)
nama_akun String @db.VarChar(100)
kategori String @db.VarChar(50)
saldo_normal String @db.VarChar(10)
details JurnalDetail[]
}
model Jurnal {
id_jurnal String @id @default(uuid())
no_referensi String @db.VarChar(50)
tgl_transaksi DateTime @default(now())
keterangan String @db.Text
details JurnalDetail[]
}
model JurnalDetail {
id_jurnal_detail Int @id @default(autoincrement())
id_jurnal String
id_akun String @db.VarChar(20)
debit Int @default(0)
kredit Int @default(0)
jurnal Jurnal @relation(fields: [id_jurnal], references: [id_jurnal])
akun Akun @relation(fields: [id_akun], references: [id_akun])
}3. Logika Transaksi Otomatis (Node.js Service)
Setiap kali petugas mencatat pembayaran SPP siswa, backend Express secara atomik memicu pembuatan entri jurnal berpasangan di dalam sebuah Prisma Transaction untuk menjamin konsistensi ACID:
async function catatJurnalPembayaran(tx, idPembayaran, nominal, tglBayar) {
// Debit: Kas Tangan (1-1000), Kredit: Piutang SPP (1-2000)
const jurnal = await tx.jurnal.create({
data: {
id_jurnal: uuidv4(),
no_referensi: `PAY-${idPembayaran}`,
keterangan: `Penerimaan Pembayaran SPP #${idPembayaran}`,
tgl_transaksi: tglBayar,
details: {
create: [
{ id_akun: '1-1000', debit: nominal, kredit: 0 },
{ id_akun: '1-2000', debit: 0, kredit: nominal }
]
}
}
});
return jurnal;
}4. Rekonsiliasi & Laporan Neraca Saldo Seimbang
Dengan penerapan struktur di atas, laporan Buku Besar Mutasi dan Neraca Saldo (Trial Balance) dapat ditarik secara real-time. Query pencocokan menjamin total saldo Debit selalu sama persis dengan total saldo Kredit:
SELECT
a.id_akun,
a.nama_akun,
SUM(jd.debit) AS total_debit,
SUM(jd.kredit) AS total_kredit,
(SUM(jd.debit) - SUM(jd.kredit)) AS saldo_akhir
FROM akun a
JOIN jurnal_detail jd ON a.id_akun = jd.id_akun
GROUP BY a.id_akun, a.nama_akun;Kesimpulan
Implementasi Double-Entry Bookkeeping pada ForgeSPP membuktikan bahwa aplikasi tata usaha sekolah tidak hanya sekadar mencatat kwitansi pembayaran, melainkan sebuah sistem keuangan transparan yang meminimalisasi potensi kecurangan kas.