# KONTEKS ARSITEKTUR & ALUR LOGIKA: STATUS PEMBAYARAN VIEW RESUME PENJUALAN

Dokumen ini mendokumentasikan secara komprehensif alur kerja, hierarki badge, dan mekanisme penentuan status pembayaran pada modal **View Resume Transaksi Penjualan** (`viewResumeDetails`) agar dapat dilanjutkan, diaudit, atau dikembangkan di kemudian hari.

---

## 1. Lokasi Berkas & Fungsi Kunci

| Komponen | Berkas | Fungsi / Baris Kunci | Deskripsi |
| :--- | :--- | :--- | :--- |
| **Modal Resume Controller** | `application/modules/penjualan/controllers/Transaksi.php` | `viewResumeDetails()` (~baris 8540–9300) | Menarik riwayat entry points, menghitung status pembayaran, dan me-render modal resume. |
| **Listing History Controller** | `application/modules/penjualan/controllers/History.php` | `viewHistory__()` (~baris 2850–3250) | Menampilkan kolom `status_bayar` pada tabel daftar penjualan. |
| **SOT Finansial Helper** | `application/helpers/he_finansial_helper.php` | `fin_get_payment_status()` & `fin_evaluate_payment_status()` | *Single Source of Truth* (SSOT) evaluasi piutang dari `transaksi_payment_source`. |
| **Dokumen Konteks Terkait** | `KONTEKS_STATUS_PEMBAYARAN_REVERT_SO.md` | Root directory | Analisis kasus bug anomali LUNAS pada transaksi revert SO (Customer THEDY). |

---

## 2. Alur Pengumpulan Data di `viewResumeDetails()`

```
                    viewResumeDetails($masterID)
                                 │
         ┌───────────────────────┼───────────────────────┐
         ▼                       ▼                       ▼
lookupEntryPoints()      lookupSignatures()     Query Kasir (4464)
  (Tabel transaksi         (Tabel signatures)     (Penerimaan Penjualan
   melalui masterID)                               Tunai Kasir)
         │                       │                       │
         └───────────────────────┼───────────────────────┘
                                 │
                     Filter Status Dokumen:
                     - Cek trash_4 == 1 (Reject)
                     - Deteksi $hasInvoice (spd/INV)
                     - Deteksi $hasPackingList (pkd/spd)
                     - Deteksi $hasCashPayment (kasir)
                     - Deteksi $hasArPayment (A/R Receipt)
                                 │
                                 ▼
                     Kompilasi ID Transaksi ($searchIDs)
                                 │
                                 ▼
             fin_get_payment_status($searchIDs, 1000.0, true)
                                 │
                                 ▼
               Evaluasi Status & Pemilihan Badge ($paymentBadge)
                                 │
                                 ▼
           Render Header Resume + Tabel History Entry Points
```

### Penjelasan Langkah:
1. **Pengambilan Entry Points:**
   Memanggil `lookupEntryPoints($masterID)` untuk mengumpulkan seluruh rantai transaksi yang terhubung ke dokumen master tersebut (`$trOrigIDs`).
2. **Pendeteksian Dokumen Batal / Reject (`trash_4 = 1`):**
   Dokumen yang memiliki `trash_4 == 1` atau tercatat dalam `$epDetail` diabaikan dari flag dokumen aktif (`$hasInvoice`, `$hasPackingList`).
3. **Pelacakan Penerimaan Kas / Tunai Kasir (`t.jenis = 4464`):**
   Mencari record di tabel `transaksi` dan `transaksi_data` yang terkait dengan `$searchIDs` untuk mendeteksi apakah ada pembayaran tunai di kasir (`$totalCashBayar`).
4. **Pemanggilan SOT Helper Finansial:**
   Memanggil `fin_get_payment_status($searchIDs, 1000.0, true)`.

---

## 3. Mekanisme SOT Helper Finansial (`he_finansial_helper.php`)

### A. Sanitasi Rantai Transaksi (`fin_get_payment_status`)
* **Pencegahan Kontaminasi Faktur Mati:**
  Saat `$autoResolveChain = true`, helper menelusuri rantai transaksi melalui `id_top` dan `id_master`.
  Jika rantai terbukti memiliki dokumen aktif (`trash = 0 AND trash_4 = 0`), seluruh transaksi yang berstatus reject/batal (`trash_4 = 1` atau `trash = 1`) **dieliminasi dari `$cleanIDs`**.
* **Keamanan Dokumen Batal Murni:**
  Jika user sengaja memeriksa sebuah dokumen yang memang berstatus batal murni (tidak memiliki dokumen aktif dalam rantainya), ID tersebut tidak dibuang sehingga helper tetap dapat mengevaluasi dan menetapkan status `BATAL`.

### B. Rumus Piutang & Status (`fin_evaluate_payment_status`)
* **Rumus Dasar:**
  $$\text{Sisa} = \text{Tagihan} - \text{Terbayar} - \text{Returned}$$
* **Logika Evaluasi Status:**
  1. **LUNAS (`is_lunas = true`):**
     Syarat: `totTerbayar > 0` DAN `totTagihan > 0` DAN `(totSisa <= 0 || totSisa <= toleransi)`.
     *(Wajib ada uang masuk riil; `sisa = 0` karena retur tidak dianggap lunas).*
  2. **CICILAN (`is_cicilan = true`):**
     Syarat: `totTerbayar > 0` DAN `totTagihan > 0` DAN `totSisa > toleransi`.
  3. **DOWN PAYMENT / UANG MUKA (`is_dp = true`):**
     Syarat: `totTerbayar > 0` DAN `totTagihan == 0`.
     *(Kondisi ketika customer menyetor uang muka saat transaksi masih di tahap pesanan SO sebelum faktur diterbitkan).*
  4. **BATAL / RETUR (`is_batal = true`):**
     Syarat: `totReturned >= totTagihan` ATAU `(totReturned > 0 && totSisa <= 0)`.
  5. **BELUM LUNAS (`status = BELUM_LUNAS`):**
     Kondisi default lainnya.

---

## 4. Matriks Hierarki Badge Modal Resume

Pada `Transaksi.php::viewResumeDetails()`, badge status pembayaran (`$paymentBadge`) dievaluasi dengan urutan prioritas ketat:

| Prioritas | Kondisi Evaluasi | Tampilan Badge | Keterangan |
| :---: | :--- | :--- | :--- |
| **1** | `$payStatus['is_lunas'] == true` & `$hasCashPayment` | `🟢 LUNAS (Tunai Kasir)` | Lunas via kasir POS / penerimaan kas |
| **2** | `$payStatus['is_lunas'] == true` & `$hasArPayment` | `🟢 LUNAS (Melalui A/R Receipt)` | Lunas via modul pelunasan piutang (A/R) |
| **3** | `$payStatus['is_lunas'] == true` | `🟢 LUNAS` | Lunas umum |
| **4** | `$payStatus['is_cicilan'] == true` | `🟠 PELUNASAN SEBAGIAN (Terbayar: Rp ... / Sisa: Rp ...)` | Pembayaran parsial dengan faktur aktif |
| **5** | `$payStatus['is_batal'] == true` & `!$hasInvoice && !$hasPackingList` | `🟡 BELUM MENERIMA PELUNASAN (Tahap Pesanan SO)` | **Kasus Revert SO:** Faktur lama batal, alur kembali ke SO aktif |
| **6** | `$payStatus['is_batal'] == true` (lainnya) | `⚪ BELUM MENERIMA PELUNASAN (Faktur Batal/Retur)` | Dokumen target memang dibatalkan |
| **7** | Dokumen POS (`jenisMasterTrans == '5823'`) | `🟡 BELUM MENERIMA PELUNASAN (Menunggu pembayaran Cash)` | Kasir POS belum dibayar |
| **8** | Dokumen memiliki faktur aktif (`$hasInvoice == true`) | `🟡 BELUM MENERIMA PELUNASAN (Invoice Belum Lunas)` | Faktur terbit, belum ada pelunasan |
| **9** | Dokumen memiliki packing list aktif (`$hasPackingList == true`) | `🟡 BELUM MENERIMA PELUNASAN (Barang Sudah Dikirim)` | Barang keluar gudang, invoice belum terbit/lunas |
| **10** | Belum ada tagihan, tapi ada uang masuk (`$totalCashBayar > 0` / `is_dp`) | `🟠 UANG MUKA / DP DITERIMA (Rp ...)` | Customer sudah menyetor DP di tahap SO |
| **11** | Kondisi Default Operasional | `🟡 BELUM MENERIMA PELUNASAN (Tahap Pesanan SO)` | Dokumen berada pada tahap Sales Order awal |

---

## 5. Sinkronisasi dengan Halaman Listing History (`History.php`)

Agar status di modal resume selalu selaras dengan kolom **Status Bayar** pada tabel daftar transaksi:
1. Di `History.php`, kueri `$chainTrans` memfilter `trash = 0 AND trash_4 = 0`.
2. Array `$activeChainIDs` dibentuk dari hasil kueri tersebut.
3. Saat membaca array jejak audit masa lalu (`ids_his`), nilai `trID` **hanya dimasukkan** jika ID tersebut ada di dalam `$activeChainIDs`:
   ```php
   if (in_array($trHistID, $activeChainIDs)) {
       $allPayTransIDs[] = $trHistID;
       $arrAllRowStepIDs[$hRow->id][] = $trHistID;
   }
   ```
4. Hal ini menjamin baris history transaksi revert SO menampilkan badge **`🟡 BELUM LUNAS`** (bukan Lunas dan bukan Batal).

---

## 6. Checklist & Panduan untuk Pengembang Mendatang

Jika di masa depan Anda perlu memodifikasi alur resume atau status pembayaran, perhatikan poin-poin krusial berikut:

- [ ] **Jangan pernah menghapus filter `trash_4 = 0`:**
  Di sistem Everest, `trash = 1` adalah soft delete standar, sedangkan `trash_4 = 1` adalah penanda dokumen dibatalkan/reject oleh alur revisi operasional. Keduanya harus selalu diperiksa.
- [ ] **Jangan mengubah mekanisme pengisian kolom `returned`:**
  Ketika packing list / faktur dibatalkan, pengisian `returned = tagihan` pada `transaksi_payment_source` adalah mekanisme baku akuntansi agar kartu piutang customer tidak menagih piutang fiktif. Jangan menihilkan dengan menghapus record (*hard delete*).
- [ ] **Perhatikan Kasus Multi-Invoice:**
  Jika satu Sales Order dipecah menjadi beberapa pengiriman (*partial delivery* / multiple packing list), `transaksi_payment_source` akan memiliki beberapa baris untuk masing-masing faktur. Helper `fin_evaluate_payment_status()` sudah mendukung penjumlahan multi-baris (`foreach ($paymentData as $item)`).
- [ ] **Penanganan Pengembalian DP (Refund):**
  Jika transaksi di tahap SO yang sudah menerima DP akhirnya dibatalkan total secara permanen oleh manajemen, pastikan modul kas/bank pengembalian dana (refund) mencatat pengurangan pada saldo kas terkait agar tidak ada saldo mengambang.
- [ ] **Kompatibilitas PHP 5.6:**
  Seluruh kode baru di modul ini wajib 100% kompatibel dengan PHP 5.6 (gunakan `array()`, `isset() ? :`, tanpa null coalescing `??` atau short array syntax).
