Keunggulan Booku: Buku Pengawasan Gaji
Tier 3 — keunggulan-keunggulan Booku yang muncul saat user memakai menu Buku Pengawasan Gaji dan form Input Gaji.
📘 Deskripsi user-friendly:
deskripsi/buku-pengawasan-gaji.md
Deskripsi Singkat Menu
Buku Pengawasan Gaji adalah halaman untuk mencatat hutang gaji perusahaan ke karyawan (agregat per bulan) dan melacak pelunasannya. Berbeda dengan aplikasi payroll yang fokus per-karyawan, Booku memandang gaji sebagai tagihan korporat per bulan — input sekali, lalu Booku pecah ke 23 baris debet granular + 11 baris kredit (potongan, hutang gaji, PPh) secara otomatis lewat jurnal yang dibentuk dari satu form input.
Form Input Gaji memungkinkan user memecah komponen gaji menjadi rincian halus (Produksi vs Administrasi × 11 komponen masing-masing + 8 potongan), dengan auto-kalkulasi subtotal di setiap level dan auto-fill turunan BPJS.
Daftar Keunggulan di Menu Ini
| # | Keunggulan | Tier 2 Terkait |
|---|---|---|
| 1 | Jurnal granular 23 debet + 11 kredit otomatis dari 1 form input | #02, #11 |
| 2 | Auto-fill potongan turunan BPJS dari komponen perhitungan | #02 |
| 3 | PPh Pesangon — toggle cerdas dengan threshold otomatis | #02, #10 |
| 4 | PPh 21 dual-mode (Dipotong vs Ditanggung) — alur jurnal beda otomatis | #11 |
| 5 | 3 mode tampilan REKAP / DETAIL / ALL — fleksibel per sudut pandang user | #08, #10 |
| 6 | UI dinamis per-COA (kolom & label menyesuaikan tbl_coa) | #10 |
| 7 | Pembayaran 1-klik via drawer + outstanding tagihan otomatis | #08, #13 |
| 8 | Konteks tahun buku adaptif (NORMAL vs LAMPAU / aktif vs closed) | #08, #10 |
Detail per Keunggulan
1. Jurnal Granular 23 Debet + 11 Kredit Otomatis dari 1 Form Input
Apa yang dirasakan user: User cukup mengisi satu form Input Gaji (Produksi + Administrasi + Potongan + PPh). Saat Simpan, Booku otomatis membentuk jurnal multi-line yang detail dan terpisah per komponen — sampai 23 baris Debet granular + 11 baris Kredit dalam 1 voucher. User tidak perlu hafal mana akun untuk Biaya Gaji Produksi vs Biaya BPJS TK JKK/JKM Produksi vs Biaya Tunjangan PPh 21 — semua sudah ditentukan via konstanta KodeTautanCOA.
Mengapa penting:
- Laporan Laba Rugi & Buku Besar otomatis dapat rincian per komponen biaya — bukan agregat. Manajemen bisa lihat “Biaya BPJS Kesehatan Produksi” sebagai line item terpisah dari “Biaya Gaji Produksi” → analisis biaya per komponen jadi mudah.
- Equalisasi dengan SPT Masa PPh 21 & SPT Tahunan PPh Badan lebih akurat karena PPh 21 Rutin & PPh 21 Pesangon di-jurnal ke 2 akun terpisah (
HutangPPhPasal21_100“21610” untuk Rutin,HutangPPhPasal21_401“21611” untuk Pesangon) - Aplikasi payroll lain umumnya hanya generate jurnal agregat (“Beban Gaji” 1 baris debet) — user harus turun manual untuk rincian
Bagaimana Booku Melakukannya:
- Backend
GajiService.BuildJurnalLinesAsyncloop semua komponen, generateTransaksiline per komponen non-zero (baris dengan jumlah=0 di-skip) - Setiap line dapat
COA&NamaAkundaritbl_coaviaICoaService.GetCoaNameAsync(bukan hardcode) — saat user ganti kode COA di Data Master, jurnal otomatis ikut - Lawan Transaksi pakai konstanta Internal (
INT/Internal) — sama dengan transaksi reklasifikasi internal lain di Booku - Save jurnal + simpan ke
tbl_pengawasangajidalam 1 SaveChangesAsync (atomic) → kalau gagal, rollback otomatis - Saat Edit Gaji: NomorJV tetap, hapus jurnal lama + buat baru dalam transaksi yang sama
- Multi-user safe: pakai retry exponential backoff (200ms/500ms/1000ms + jitter) untuk handle race condition
MAX(Nomor_ID)+1
→ Cross-link: #02 Automatic Everything, #11 Jurnal Multi-line
2. Auto-Fill Potongan Turunan BPJS dari Komponen Perhitungan
Apa yang dirasakan user: Saat user mengisi komponen-komponen BPJS Kesehatan (Produksi/Administrasi/Dibayar Karyawan), field Potongan_Hutang_BPJS_Kesehatan di kolom Potongan otomatis ter-update dengan total semua komponennya. Sama untuk BPJS Ketenagakerjaan (JKK/JKM + JHT/IP + porsi karyawan). User tidak perlu menjumlahkan manual.
Mengapa penting:
- Iuran BPJS terdiri dari banyak sub-komponen (Produksi vs Administrasi, JKK/JKM vs JHT/IP, porsi perusahaan vs karyawan) — kalau dihitung manual rawan typo
- Hasil potongan ini harus = tagihan ke pihak ketiga (BPJS Kesehatan / BPJS TK) yang dicatat di menu Buku Pengawasan Turunan Gaji → kalau salah jumlah, akan muncul “Selisih ≠ 0” di menu turunan
- Auto-fill menjamin sinkronisasi otomatis antara Buku Pengawasan Gaji dan turunannya
Bagaimana Booku Melakukannya:
useEffectdiInputGajiModal.tsxdengan dependency komponen BPJS — saat berubah, recompute total & set ke field potongan- Hanya aktif di
JalurMasuk_Default— di JalurMasuk turunan (turunan-bpjs-kesehatan/turunan-bpjs-ketenagakerjaan) field potongan dapat di-edit manual untuk koreksi cepat - Logic dipindah persis dari Booku Lama
wpfWin_InputGaji.xaml.vb(event TextChanged pada komponen BPJS)
→ Cross-link: #02 Automatic Everything
3. PPh Pesangon — Toggle Cerdas dengan Threshold Otomatis
Apa yang dirasakan user: Group radio “PPh Pesangon Dipotong/Ditanggung” awalnya disabled. Saat user mengisi field Pesangon Karyawan dan total Pesangon > Rp 50 juta (threshold PPh 21 final tarif progresif), Booku otomatis menampilkan konfirmasi: “Apakah ada PPh untuk Pesangon?”. Jika “Ya” → group radio enabled, user pilih mode (Dipotong vs Ditanggung). Jika ≤ 50 juta atau “Tidak ada PPh”, group otomatis disabled & value PPh-Pesangon di-clear.
Mengapa penting:
- Pesangon adalah penghasilan tidak teratur dengan aturan PPh 21 berbeda (tarif final progresif: 0% sampai 50jt, 5% sampai 100jt, 15% sampai 500jt, 25% di atas 500jt)
- Tanpa toggle threshold, user kebingungan kapan harus menerapkan tarif Pesangon vs Rutin — bisa salah hitung PPh
- Threshold 50jt otomatis trigger UI → user dapat reminder edukatif tanpa harus baca dokumentasi pajak
Bagaimana Booku Melakukannya:
- Event LostFocus pada 2 field Pesangon (Produksi + Administrasi) → cek total > 50jt →
Modal.confirmAntd - Helper
hitungPPhPesangonProgresif(jumlah)disiapkan (5%/15%/25% tier 50jt/100jt/500jt) tapi tidak auto-assign ke field — sesuai keputusan Booku Lama (“Sementara ini belum dibutuhkan perhitungan”). User tetap input manual nominal PPh sesuai perhitungan kebijakan perusahaan - Mode EDIT: toggle disabled (PPh mode tidak boleh berubah saat edit) — sehingga konsistensi jurnal terjaga
→ Cross-link: #02 Automatic Everything, #10 UI Dinamis
4. PPh 21 Dual-Mode (Dipotong vs Ditanggung) — Alur Jurnal Beda Otomatis
Apa yang dirasakan user: Saat input gaji, user pilih radio PPh 21 Rutin: Dipotong / Ditanggung (dan opsional Pesangon kalau ada). Setelah Simpan, Booku otomatis bentuk jurnal yang berbeda struktur tergantung mode:
| Mode | Jurnal yang Dibentuk |
|---|---|
| Dipotong | Kredit: Hutang PPh Pasal 21 (mengurangi gaji bersih yang diterima karyawan) |
| Ditanggung | Debet: Biaya PPh Pasal 21 (sebagai biaya perusahaan) + Kredit: Hutang PPh Pasal 21 (tagihan ke negara tetap muncul) |
Mengapa penting:
- Kebijakan PPh 21 perusahaan berbeda-beda — ada yang potong dari gaji, ada yang ditanggung perusahaan sebagai benefit. Dua mode ini punya dampak laporan keuangan yang sangat berbeda (mode Ditanggung = biaya naik, gaji bersih karyawan tetap utuh)
- Aplikasi payroll standar biasanya hanya mendukung 1 mode; di Booku, sekali pilih radio, jurnal otomatis ikut — user tidak perlu hafal logikanya
- Plus: PPh 21 Rutin & Pesangon di-jurnal ke akun terpisah (
_100Rutin “21610” vs_401Pesangon “21611”) agar memudahkan equalisasi dengan SPT Masa Bulanan
Bagaimana Booku Melakukannya:
- Validasi simpan cek konsistensi: kalau pilih “Dipotong” →
PotonganHutangPPhPasal21Rutinharus > 0; kalau “Ditanggung” →PPhDitanggungRutinharus > 0 (analog untuk Pesangon) BuildJurnalLinesAsyncdeterministik per mode — Rutin & Pesangon di-treat independent (boleh kombinasi: Rutin Dipotong + Pesangon Ditanggung)- Saat Edit: mode PPh terkunci (group radio disabled) untuk hindari inkonsistensi jurnal vs tabel pengawasan
→ Cross-link: #11 Jurnal Multi-line
5. 3 Mode Tampilan REKAP / DETAIL / ALL — Fleksibel per Sudut Pandang User
Apa yang dirasakan user: Dropdown filter Bulan di header bukan sekadar filter, tapi sekaligus pemilih 3 sudut pandang terhadap data gaji:
| Mode | Pemilih | Tampilan | Aksi Tersedia |
|---|---|---|---|
| REKAP (default) | filter Bulan = REKAP | 12 baris bulan fixed (Januari–Desember, termasuk yang kosong) + grand total | Detail Perbulan, Detail Pembayaran, Bayar |
| DETAIL | filter Bulan = nama bulan (Januari, …) | Rincian gaji 1 bulan tertentu (bisa multi-record) + grand total | Edit, Hapus, Lihat Jurnal |
| ALL | filter Bulan = ALL | Rincian seluruh records dikelompokkan per bulan + subtotal per bulan + grand total | Edit, Hapus, Lihat Jurnal |
Mengapa penting:
- Konsisten dengan Booku Lama yang menampilkan 12 baris fixed di mode REKAP — user existing tidak perlu adaptasi
- Mode REKAP dengan 12 baris fixed memungkinkan user langsung lihat slot kosong — bulan mana yang belum di-input
- Mode ALL berguna untuk audit cross-bulan (validasi subtotal REKAP = jumlah records di DETAIL) atau cetak laporan komprehensif
- Konsep “scope aksi = scope row” (REKAP = bulan-level, DETAIL/ALL = record-level) menjaga predictability menu — user tidak menebak aksi mana yang muncul
Bagaimana Booku Melakukannya:
displayItemsuseMemo dengan branch per mode (REKAP loop 12 bulan + empty placeholder, ALL detail+subtotal+separator, DETAIL flat)- Synthetic marker rows via
nomorIDnegatif:-1grand total,-50..-61empty bulan REKAP,-100..-111subtotal ALL,≤-200separator ALL noMapprecomputed → nomor urut tetap 1-12 di REKAP (termasuk empty bulan), 1-N di DETAIL/ALL (tanpa gap di antara marker)getAksiMenuItemsskip semua marker rows (nomorID < 0) → tidak ada aksi misleading pada row sintetis
→ Cross-link: #08 Simple for User, #10 UI Dinamis
6. UI Dinamis Per-COA (Kolom & Label Menyesuaikan tbl_coa)
Apa yang dirasakan user: Tabel utama & form Input Gaji menyesuaikan diri dengan setting COA perusahaan:
- Kolom yang COA-nya di-set “Visibilitas: Tidak” di Data COA → otomatis hidden baik di tabel utama maupun form input
- Header kolom / label field pakai
Nama_Akundaritbl_coakalau ada — bukan label default. Mis. perusahaan rename COA “Biaya Gaji Produksi” jadi “Beban Gaji Pegawai Pabrik” → label di Booku ikut otomatis
Mengapa penting:
- Setiap perusahaan punya struktur COA berbeda — ada yang tidak pakai komponen tertentu (mis. tidak ada Asuransi Karyawan terpisah), atau pakai nomenklatur berbeda
- Tanpa visibility per-COA, kolom-kolom yang tidak relevan jadi clutter → user kebingungan
- Konsisten dengan filosofi Booku: COA adalah single source of truth untuk struktur akun perusahaan
Bagaimana Booku Melakukannya:
- Saat halaman/modal mount, paralel fetch
coaService.getByCode(kodeTautan)untuk semua KodeTautanCOA yang dipakai (~25 kode tautan COA untuk Gaji) - Hasil di-simpan di
visibilityMap: Record<string, { visible, namaAkun }>(state useMemo) - Tabel utama:
columnDefsfilter kolom byisVisible(meta)+ override header byinfo?.namaAkun - Form Input: pasangan label+input di-conditional render by
visibilityMap - Pengecualian: PPh 21 Rutin & Pesangon mempertahankan label custom (sesuai keputusan Booku Lama) — overlay label tidak diambil dari Nama_Akun
→ Cross-link: #10 UI Dinamis
7. Pembayaran 1-Klik via Drawer + Outstanding Tagihan Otomatis
Apa yang dirasakan user: Di mode REKAP, klik kanan baris bulan → Bayar. Booku otomatis: (1) buka Detail Pembayaran Drawer di sisi kanan (riwayat pembayaran bulan tsb + info Sisa Pembayaran + status Lunas/Belum Lunas), (2) langsung membuka modal Input Pengeluaran Bank/Cash dengan preset lengkap (Kategori “Pembayaran Hutang” terkunci, Peruntukan “Pembayaran Hutang Gaji” terkunci, Lawan Transaksi KRY/Karyawan Internal terisi otomatis, NomorBP = NomorBPHG bulan tsb), (3) tabel kanan modal menampilkan 1 baris tagihan dengan Jumlah Tagihan, Sudah Dibayar, Sisa Tagihan, dan Jumlah Bayar default = sisa. User tinggal pilih Sarana Pembayaran (bank/cash) lalu Simpan.
Mengapa penting:
- Mencatat pembayaran gaji manual = pindah menu, isi 10+ field, hafal Lawan Transaksi → boros waktu & rawan salah
- Pattern 1-klik ini share dengan modul Hutang/Piutang Karyawan, Pemegang Saham, Pihak Ketiga, Afiliasi, Pajak → user belajar sekali, pakai di banyak menu
- Drawer punya status visual (Lunas hijau / Belum Lunas oranye) → user langsung tahu apa yang perlu dibayar
Bagaimana Booku Melakukannya:
- Frontend
useBuktiPengeluaranStore.openAddModal()dengan preset dari menu → modal share dengan menu Bukti Pengeluaran utama tapi field-field locked sesuai konteks - Backend
GetOutstandingHutangGajiAsyncdiBuktiPengeluaranServiceparseNomorBP(BPHG-{Tahun}-{NomorBulan}), agregatSUM(JumlahGajiDibayarkan)semua record bulan tsb, hitung sisa = total −SUM(JumlahBayar), return 1 item ke modal - Multi-record per bulan handled: SUM agregat di backend menjamin Sisa Tagihan benar meski user input gaji multi-record di Januari (kasus gelombang pembayaran / per-divisi / dst.)
- Saat hutang sudah lunas → tombol Bayar otomatis disabled + tooltip “Sudah Lunas” (Lapis 2 dari
view-mode-action-scope-pattern.md)
→ Cross-link: #08 Simple for User, #13 Buku Pengawasan Penerimaan/Pengeluaran
8. Konteks Tahun Buku Adaptif (NORMAL vs LAMPAU / Aktif vs Closed)
Apa yang dirasakan user: Tampilan menu otomatis menyesuaikan dengan konteks tahun buku:
| Konteks | Yang Berubah |
|---|---|
| Tahun Buku NORMAL, tahun aktif | Semua aksi visible (Input, Edit, Hapus, Bayar); judul “Buku Pengawasan Gaji”; mode REKAP/DETAIL/ALL semua available |
| Tahun Buku NORMAL, telusur tahun closed | Mode read-only — Input/Edit/Hapus/Bayar hidden; pewarnaan row tahun lalu (abu-abu); Lihat Jurnal tetap available |
| Tahun Buku LAMPAU (Data Awal) | Judul ganti jadi “Saldo Akhir Hutang Gaji”; alur input data historis (saldo akhir manual); drawer Detail Pembayaran sembunyikan tombol Tambah Pembayaran + tampilkan Alert info |
Mengapa penting:
- Booku V2 punya multi-tenant per tahun — 1 database transaksi per tahun (mis.
bookuid_booku_dummycli_2022). User bisa telusur tahun lampau tanpa mengganggu tahun aktif - Mode LAMPAU butuh alur input berbeda karena saldo awal diinput manual (bukan hasil transaksi); jurnal balancing-nya juga beda
- Tanpa adaptasi konteks, user bisa tanpa sadar mengubah data tahun closed → audit trail rusak
Bagaimana Booku Melakukannya:
- Frontend ganti tahun via filter →
gajiService.getAllForYear(tahun)override headerX-Tahun-Bukuper request → backend pilih DB transaksi yang sesuai - State
filterTahun !== TahunBukuAktif→ kondisi “tahun closed”, aktifkan visibility rules read-only viaview-mode-action-scope-pattern.mdLapis 2 (SHOW + DISABLED + tooltip) - Mode LAMPAU vs NORMAL via prop
pageMode(PageMode_BukuPengawasanvsPageMode_DataAwal) +useAppStore().JenisTahunBuku - Dual-entry route:
/buku-pengawasan/gaji(NORMAL) +/data-awal/hutang/gaji/gaji(LAMPAU) → komponen yang sama dengan prop berbeda
→ Cross-link: #08 Simple for User, #10 UI Dinamis
Catatan Implementasi
Detail teknis lengkap (algoritma jurnal, struktur DTO, validasi, marker nomorID, mode tampilan, dst) ada di:
Terakhir diperbarui: 23-05-2026 (file baru — 8 keunggulan menu Buku Pengawasan Gaji + Input Gaji)