Lewati ke konten

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

#KeunggulanTier 2 Terkait
1Jurnal granular 23 debet + 11 kredit otomatis dari 1 form input#02, #11
2Auto-fill potongan turunan BPJS dari komponen perhitungan#02
3PPh Pesangon — toggle cerdas dengan threshold otomatis#02, #10
4PPh 21 dual-mode (Dipotong vs Ditanggung) — alur jurnal beda otomatis#11
53 mode tampilan REKAP / DETAIL / ALL — fleksibel per sudut pandang user#08, #10
6UI dinamis per-COA (kolom & label menyesuaikan tbl_coa)#10
7Pembayaran 1-klik via drawer + outstanding tagihan otomatis#08, #13
8Konteks 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.BuildJurnalLinesAsync loop semua komponen, generate Transaksi line per komponen non-zero (baris dengan jumlah=0 di-skip)
  • Setiap line dapat COA & NamaAkun dari tbl_coa via ICoaService.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_pengawasangaji dalam 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:

  • useEffect di InputGajiModal.tsx dengan 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.confirm Antd
  • 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:

ModeJurnal yang Dibentuk
DipotongKredit: Hutang PPh Pasal 21 (mengurangi gaji bersih yang diterima karyawan)
DitanggungDebet: 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 (_100 Rutin “21610” vs _401 Pesangon “21611”) agar memudahkan equalisasi dengan SPT Masa Bulanan

Bagaimana Booku Melakukannya:

  • Validasi simpan cek konsistensi: kalau pilih “Dipotong” → PotonganHutangPPhPasal21Rutin harus > 0; kalau “Ditanggung” → PPhDitanggungRutin harus > 0 (analog untuk Pesangon)
  • BuildJurnalLinesAsync deterministik 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:

ModePemilihTampilanAksi Tersedia
REKAP (default)filter Bulan = REKAP12 baris bulan fixed (Januari–Desember, termasuk yang kosong) + grand totalDetail Perbulan, Detail Pembayaran, Bayar
DETAILfilter Bulan = nama bulan (Januari, …)Rincian gaji 1 bulan tertentu (bisa multi-record) + grand totalEdit, Hapus, Lihat Jurnal
ALLfilter Bulan = ALLRincian seluruh records dikelompokkan per bulan + subtotal per bulan + grand totalEdit, 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:

  • displayItems useMemo dengan branch per mode (REKAP loop 12 bulan + empty placeholder, ALL detail+subtotal+separator, DETAIL flat)
  • Synthetic marker rows via nomorID negatif: -1 grand total, -50..-61 empty bulan REKAP, -100..-111 subtotal ALL, ≤-200 separator ALL
  • noMap precomputed → nomor urut tetap 1-12 di REKAP (termasuk empty bulan), 1-N di DETAIL/ALL (tanpa gap di antara marker)
  • getAksiMenuItems skip 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_Akun dari tbl_coa kalau 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: columnDefs filter kolom by isVisible(meta) + override header by info?.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 GetOutstandingHutangGajiAsync di BuktiPengeluaranService parse NomorBP (BPHG-{Tahun}-{NomorBulan}), agregat SUM(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:

KonteksYang Berubah
Tahun Buku NORMAL, tahun aktifSemua aksi visible (Input, Edit, Hapus, Bayar); judul “Buku Pengawasan Gaji”; mode REKAP/DETAIL/ALL semua available
Tahun Buku NORMAL, telusur tahun closedMode 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 header X-Tahun-Buku per request → backend pilih DB transaksi yang sesuai
  • State filterTahun !== TahunBukuAktif → kondisi “tahun closed”, aktifkan visibility rules read-only via view-mode-action-scope-pattern.md Lapis 2 (SHOW + DISABLED + tooltip)
  • Mode LAMPAU vs NORMAL via prop pageMode (PageMode_BukuPengawasan vs PageMode_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)