Lewati ke isi

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.md Jika 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 saldo GENERATED di transaksi — 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 di pusat_pajak_master.sql + 01_schema_pusat.sql
  • [x] transaksi.kredit (rename dari sisa_kredit) — selesai, ada di V034
  • [x] V003: subtotal fix (t.nilai bukan t.nilaitotal)
  • [x] Formula total terdokumentasi: (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 kas table 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