TODO — Implementasi Kas, Biaya & Pajak¶
Dibuat: 2026-05-20 Konteks: lanjutan sesi desain arsitektur kas/biaya/pajak. Dokumen desain lengkap:
docs/14-DESAIN-KAS-BIAYA-PAJAK.mdJika token habis, agent baru baca dokumen ini +docs/14-DESAIN-KAS-BIAYA-PAJAK.md.
Status Selesai (sesi ini)¶
- [x]
transaksi_detail.barang_id→ nullable (perlu V036, belum dikerjakan) - [x] Kolom
saldoGENERATED ditransaksi— ada di V035, belum dijalankan - [x] Tabel
transaksi_bayar— ada di V035 +10_tabel.sql - [x] Tabel
transaksi_pajak— ada di V035 +10_tabel.sql - [x] Tabel
pusat.pajak— ada dipusat_pajak_master.sql+01_schema_pusat.sql - [x]
transaksi.kredit(rename darisisa_kredit) — selesai, ada di V034 - [x] V003:
subtotalfix (t.nilaibukant.nilaitotal) - [x] Formula
totalterdokumentasi:(subtotal + biaya + pembulatan) - diskon = nilaitotal
Status Implementasi (update 2026-05-20)¶
- [x] BLOK 1 — V036 + 10_tabel.sql (transaksi_detail GL columns)
- [x] BLOK 2 — fn_transaksi_bayar_setelah_ubah() + trigger transaksi_bayar AI/AU/AD
- [x] BLOK 3 — fn_transaksi_detail_setelah_ubah() extended: PELUNASAN → total_pelunasan
- [x] BLOK 4 — fn_transaksi_detail_setelah_ubah() extended: is_potong_nota → potongnota
- [x] BLOK 5 — V005__etl_buku_kas.sql (KK/KM → transaksi_detail BIAYA)
- [x] BLOK 6 — V037__etl_pelunasan.sql (PP/PH → transaksi_detail PELUNASAN) [V006/V007 sudah terpakai oleh migrasi lama]
- [x] BLOK 7 — V038__etl_saldo_awal.sql (OP/OH verifikasi + sinkronisasi kredit)
- [x] BLOK 8 — jenis_transaksi seed sudah lengkap (tidak perlu perubahan)
TODO Urutan Pengerjaan¶
BLOK 1 — DDL transaksi_detail (kerjakan duluan)¶
File yang diubah: database/ddl/10_template_tenant/10_tabel.sql
Migration baru: database/migrations/tenant/V036__transaksi_detail_gl_columns.sql
Perubahan di transaksi_detail:
-- 1. barang_id: hapus NOT NULL
ALTER TABLE transaksi_detail ALTER COLUMN barang_id DROP NOT NULL;
-- 2. Tambah kolom GL
ALTER TABLE transaksi_detail
ADD COLUMN IF NOT EXISTS akun_kode text,
ADD COLUMN IF NOT EXISTS tipe_baris text,
ADD COLUMN IF NOT EXISTS is_potong_nota boolean NOT NULL DEFAULT false,
ADD COLUMN IF NOT EXISTS id_lama bigint; -- legacy composite key
-- tipe_baris: BARANG | BIAYA | PELUNASAN | UANG_MUKA | PAJAK | DISKON | POIN
-- akun_kode: diisi untuk baris non-barang
-- is_potong_nota: true hanya untuk detail RJ/RB yang memotong saldo nota asal
-- id_lama: legacy composite key (idtrans.idbarang.refid), nullable
Juga update 10_tabel.sql (template): ubah kolom barang_id jadi nullable, tambah 4 kolom baru.
Juga update V003__transformasi_transaksi.sql: saat insert transaksi_detail, isi id_lama = d.id dan tipe_baris = 'BARANG'.
BLOK 2 — Trigger transaksi.dibayar dari transaksi_bayar¶
File: database/ddl/10_template_tenant/40_trigger.sql
-- Trigger: AFTER INSERT/UPDATE/DELETE ON transaksi_bayar
-- → UPDATE transaksi SET dibayar = (SELECT COALESCE(SUM(jumlah),0) FROM transaksi_bayar WHERE transaksi_id = ...)
-- → UPDATE transaksi SET kredit = total - dibayar WHERE id = ...
Logika:
- dibayar = SUM(transaksi_bayar.jumlah) per transaksi
- kredit = total - dibayar (recompute setelah dibayar berubah)
- saldo otomatis karena GENERATED
BLOK 3 — Trigger transaksi.total_pelunasan dari PP/PH detail¶
File: database/ddl/10_template_tenant/40_trigger.sql
-- Trigger: AFTER INSERT/UPDATE/DELETE ON transaksi_detail
-- WHEN tipe_baris = 'PELUNASAN' AND ref_transaksi_id IS NOT NULL
-- → UPDATE transaksi SET total_pelunasan = (SELECT COALESCE(SUM(jumlah),0) FROM transaksi_detail
-- WHERE ref_transaksi_id = ... AND tipe_baris = 'PELUNASAN')
-- WHERE id = NEW.ref_transaksi_id
BLOK 4 — Trigger transaksi.potongnota dari RJ/RB detail¶
File: database/ddl/10_template_tenant/40_trigger.sql
-- Trigger: AFTER INSERT/UPDATE/DELETE ON transaksi_detail
-- WHEN is_potong_nota = true AND ref_transaksi_id IS NOT NULL
-- → UPDATE transaksi SET potongnota = (SELECT COALESCE(SUM(ABS(total)),0) FROM transaksi_detail
-- WHERE ref_transaksi_id = ... AND is_potong_nota = true)
-- WHERE id = NEW.ref_transaksi_id
BLOK 5 — ETL V005: KK/KM → transaksi + transaksi_detail¶
File baru: database/migrations/tenant/V005__etl_buku_kas.sql
Sumber: staging_sparepart.stg_kas join stg_transaksi WHERE kdtrans IN ('KK','KM')
- 1 transaksi legacy → 1 transaksi baru (jenis_kode = kdtrans)
- N kas rows → N transaksi_detail baris dengan tipe_baris='BIAYA', akun_kode=k.rek
- transaksi.akun_kas_kode = t.rek_kas (sumber kas keluar/masuk)
- transaksi.total = t.bayar (jumlah total)
Idempoten: ON CONFLICT (nomor_transaksi) DO UPDATE
BLOK 6 — ETL V006: PP/PH → transaksi + transaksi_detail¶
File baru: database/migrations/tenant/V006__etl_pelunasan.sql
Sumber: stg_kas tipe KREDIT join stg_transaksi WHERE kdtrans IN ('PP','PH')
- 1 transaksi legacy → 1 transaksi baru (jenis_kode = kdtrans)
- N kas rows → N transaksi_detail baris:
- tipe_baris = 'PELUNASAN'
- akun_kode = k.rek (piutang/hutang yang dilunasi)
- ref_transaksi_id = ID transaksi asal (via map_transaksi + k.refidtrans)
- jumlah = nilai pelunasan per faktur
- Setelah insert, trigger BLOK 3 otomatis update total_pelunasan di transaksi asal
Idempoten: hapus dulu transaksi_detail PELUNASAN sebelum re-insert (atau ON CONFLICT)
BLOK 7 — ETL V007: OP/OH → saldo awal kas (opsional)¶
File baru: database/migrations/tenant/V007__etl_saldo_awal.sql
Sumber: stg_kas tipe KREDIT join stg_transaksi WHERE kdtrans IN ('OP','OH')
- OP = Opening Piutang (saldo awal piutang per pelanggan)
- OH = Opening Hutang (saldo awal hutang per supplier)
- Masuk ke tabel kas yang sudah ada (tipe = 'SALDO_AWAL')
- Data ini sudah ada di kas dari V003 (stg_kas dimuat semua) — verifikasi dulu
BLOK 8 — Seeder jenis_transaksi untuk tipe baru¶
File: database/ddl/10_template_tenant/50_seed.sql
Pastikan jenis_transaksi punya konfigurasi yang benar untuk KK/KM (tipe BIAYA) dan PP/PH (tipe PELUNASAN). Cek apakah kolom akun_kas_kode, akun_kredit_kode dsb sudah dikonfigurasi.
Referensi Cepat¶
Formula penting¶
total = (subtotal + biaya + pembulatan) - diskon = t.nilaitotal (legacy)
subtotal = t.nilai (sum baris detail item)
kredit = total - dibayar (piutang/hutang awal, FIX)
saldo = kredit - total_pelunasan - potongnota (GENERATED ALWAYS AS STORED)
Tipe baris transaksi_detail¶
BARANG → barang_id diisi, akun_kode NULL
BIAYA → barang_id NULL, akun_kode diisi (expense/biaya)
PELUNASAN → barang_id NULL, akun_kode=akun piutang, ref_transaksi_id=faktur asal
PAJAK → barang_id NULL, akun_kode=akun pajak
POIN → barang_id NULL, ref_transaksi_id=PJ asal (untuk GP)
DISKON → barang_id NULL (opsional, diskon per baris jika detail)
Kdtrans penting¶
PJ = Penjualan (kredit, jurnal, stok)
PI = Pembelian (kredit, jurnal, stok)
KK = Kas Keluar (buku kas, jurnal)
KM = Kas Masuk (buku kas, jurnal)
PP = Pelunasan Piutang
PH = Pelunasan Hutang
RJ = Retur Jual (stok balik, potongnota)
RB = Retur Beli (stok balik, potongnota)
GP = Giro Poin (bayar poin ke sales akhir bulan)
OP = Opening Piutang (saldo awal)
OH = Opening Hutang (saldo awal)
File kunci¶
database/ddl/10_template_tenant/10_tabel.sql → template DDL tabel tenant
database/ddl/10_template_tenant/40_trigger.sql → semua trigger tenant
database/ddl/01_schema_pusat.sql → pusat.pajak sudah ada
database/migrations/tenant/V035__...sql → saldo+transaksi_bayar+transaksi_pajak
database/migrations/tenant/V036__...sql → BELUM DIBUAT (BLOK 1)
database/migrations/tenant/V005__etl_buku_kas.sql → SELESAI (BLOK 5)
database/migrations/tenant/V037__etl_pelunasan.sql → SELESAI (BLOK 6)
database/migrations/tenant/V038__etl_saldo_awal.sql→ SELESAI (BLOK 7)
database/migrations/pusat_pajak_master.sql → pusat.pajak (jalankan sekali)
docs/14-DESAIN-KAS-BIAYA-PAJAK.md → desain lengkap + keputusan
Cara jalankan migrasi¶
# pusat.pajak (sekali):
psql "$ERP_MIGRASI_URL" -f database/migrations/pusat_pajak_master.sql
# per tenant (V034, V035, V036):
bash database/scripts/jalankan_migrasi_tenant.sh
# ulang ETL lengkap:
bash database/scripts/jalankan_etl_sparepart.sh
Hal yang Belum Diputuskan¶
- Kapan
kastable benar-benar di-drop (setelah berapa bulan cutover stable)? - Trigger BLOK 2-4 apakah perlu juga jalan retroaktif untuk data migrasi yang sudah ada, atau cukup forward (data baru setelah cutover)?
Dibuat: 2026-05-20 — sesi desain kas/biaya/pajak