# 🏛️ Arsitektur & Rekonsiliasi Menyeluruh Modul Penerimaan (A/R)
**ERP Everest Enterprise Financial Control — Berbasis Kaidah PSAK 72 / IFRS 15 & ISA 500**

Dokumen ini memetakan seluruh rumusan masalah, aliran data database, siklus dokumen, serta logika verifikasi transaksi pada modul **Penerimaan (A/R)**, **Kas (Kwitansi Uang Muka)**, **PenerimaanProjek (Faktur Penagihan)**, dan **Buku Besar Akuntansi (GL)** dalam bentuk diagram visual Mermaid lengkap.

---

## 1. Alur Siklus Hidup Uang Muka (DP Lifecycle Flowchart)

Diagram ini menggambarkan bagaimana sistem membuktikan apakah DP pernah diterima, mendeteksi pembatalan (void), menentukan apakah DP sudah dipakai atau belum, serta merekonsiliasi sisa saldo liabilitas di Buku Pembantu Rekening 2010050.

```mermaid
flowchart TD
    classDef kasir fill:#e0f2fe,stroke:#0284c7,stroke-width:2px,color:#0369a1;
    classDef proyek fill:#fef3c7,stroke:#d97706,stroke-width:2px,color:#92400e;
    classDef finance fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#166534;
    classDef void fill:#fee2e2,stroke:#dc2626,stroke-width:2px,color:#991b1b;
    classDef gl fill:#ede9fe,stroke:#7c3aed,stroke-width:2px,color:#5b21b6;
    classDef decision fill:#f1f5f9,stroke:#475569,stroke-width:2px,color:#1e293b;

    subgraph SUB_KASIR["1. TRANSAKSI KASIR (Penerimaan Kas Masuk)"]
        A["Konsumen Bayar Uang Muka Proyek"]:::kasir
        B["Input Transaksi 4467 di Modul Kas<br/>Kwitansi Kas Masuk"]:::kasir
        A --> B
        B --> C{"Cek Status Keabsahan<br/>trash = 0 AND cancel_dtime IS NULL?"}:::decision
    end

    subgraph SUB_VOID["JALUR PEMBATALAN (VOID / REFUND)"]
        C -- "TIDAK (trash=1 / Void)" --> V1["Deteksi Pembatalan Kasir<br/>transaksi.cancel_dtime terisi<br/>transaksi.cancel_name terisi"]:::void
        V1 --> V2["Reversal Jurnal Otomatis<br/>Debet: 2010050 (Uang Muka)<br/>Kredit: 1010010010 (Kas/Bank)"]:::void
        V2 --> V3["Status di Laporan:<br/>KWITANSI BATAL (STRIKETHROUGH)<br/>Nilai Tidak Masuk Saldo Proyek"]:::void
    end

    subgraph SUB_GL["JURNAL BUKU BESAR PEMBANTU (GL)"]
        C -- "YA (Sah & Aktif)" --> J1["Posting Jurnal Masuk (4467)<br/>Debet: 1010010010 (Kas/Bank)<br/>Kredit: 2010050 (Uang Muka Proyek)<br/>Kredit: PPN Uang Muka"]:::gl
        J1 --> J2["Saldo Mengendap di Rekening 2010050<br/>Liabilitas Kontrak / Uang Muka Konsumen"]:::gl
    end

    subgraph SUB_PROYEK["2. TRANSAKSI PROYEK (Invoicing Penagihan)"]
        J2 --> D{"Apakah Tim Proyek Sudah Menerbitkan<br/>Faktur Tagihan DP Resmi (7499)?"}:::decision
        
        D -- "BELUM TERBIT" --> S1["Status Uang Muka Proyek:<br/>DP DITERIMA KASIR - FAKTUR BELUM TERBIT<br/>Badge: Label Warning (Kuning)"]:::kasir
        S1 --> S1_NOTE["Faktur Diterbitkan = Rp 0<br/>Realisasi A/R = Rp 0<br/>Sisa Saldo DP = 100% TERSEDIA"]:::kasir

        D -- "SUDAH TERBIT" --> E["Faktur DP Terdaftar di TPS<br/>jenis = '7499', target_jenis = '749'<br/>_key = 'dp', tagihan = X"]:::proyek
    end

    subgraph SUB_SETTLEMENT["3. TRANSAKSI FINANCE / AR (Settlement Pelunasan)"]
        E --> F{"Apakah Finance Sudah Memproses<br/>Pelunasan di Modul A/R (749)?"}:::decision

        F -- "BELUM PROSES" --> S2["Status Uang Muka Proyek:<br/>MENUNGGU SETTLEMENT A/R<br/>Badge: Label Info (Biru Muda)"]:::proyek
        S2 --> S2_NOTE["Faktur Terbit = Ada<br/>Dana 4467 = Tersedia<br/>Action: Silakan Potong DP di A/R 749"]:::proyek

        F -- "SUDAH PROSES" --> G["Eksekusi Transaksi 749 di A/R<br/>Metode: Potong Uang Muka Proyek<br/>transaksi_data_registry.items"]:::finance
        G --> H["Update Tabel TPS Faktur 7499:<br/>terbayar = terbayar + nilai_bayar<br/>sisa = tagihan - terbayar"]:::finance
        G --> I["Posting Jurnal Pelunasan A/R (749):<br/>Debet: 2010050 (Uang Muka Berkurang)<br/>Kredit: 1010020010 (Piutang Dagang Lunas)"]:::gl
        H --> K{"Evaluasi Sisa Tagihan Faktur DP<br/>sisa <= 1000?"}:::decision
        K -- "YA" --> S3["Status Uang Muka Proyek:<br/>DP LUNAS / TERPAKAI PENUH<br/>Badge: Label Success (Hijau)"]:::finance
        K -- "TIDAK" --> S4["Status Uang Muka Proyek:<br/>DP DIBAYAR SEBAGIAN<br/>Badge: Label Warning (Kuning)"]:::finance
    end
```

---

## 2. Alur Penagihan Termin (Progress Billing) & Retensi (Warranty)

Diagram ini menggambarkan bagaimana sistem mengalokasikan nilai kontrak, mendeteksi siklus fisik lapangan (SPK vs BAST), memisahkan **Kontrak Belum Aktif** dari **Proyek Berjalan**, serta memvalidasi keabsahan status **Seluruh Termin Lunas**.

```mermaid
flowchart TD
    classDef contract fill:#f8fafc,stroke:#334155,stroke-width:2px,color:#0f172a;
    classDef physical fill:#fef3c7,stroke:#d97706,stroke-width:2px,color:#92400e;
    classDef unbilled fill:#ffedd5,stroke:#ea580c,stroke-width:2px,color:#9a3412;
    classDef active fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#1e40af;
    classDef lunas fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#166534;
    classDef piutang fill:#fee2e2,stroke:#dc2626,stroke-width:2px,color:#991b1b;
    classDef decision fill:#f1f5f9,stroke:#475569,stroke-width:2px,color:#1e293b;

    subgraph SUB_KONTRAK["1. STRUKTUR NILAI KONTRAK (master_project)"]
        CTR["TOTAL NILAI KONTRAK (Contract Incl PPN)"]:::contract
        CTR --> A_DP["Alokasi DP: Contract x %DP"]:::contract
        CTR --> A_TRM["Alokasi Termin: Contract - DP - Retensi"]:::contract
        CTR --> A_RET["Alokasi Retensi: Contract x %Retensi"]:::contract
    end

    subgraph SUB_LIFECYCLE["2. SIKLUS FISIK LAPANGAN (Audit Dokumen Transaksi)"]
        DOCS{"Periksa Dokumen Siklus Lapangan Terdaftar"}:::decision
        DOCS -- "Dokumen 588" --> P_FHO["SERAH TERIMA AKHIR (BAST 2 / FHO)<br/>Fisik Selesai 100%"]:::lunas
        DOCS -- "Dokumen 588sta" --> P_PHO["SERAH TERIMA 1 (BAST 1 / PHO)<br/>Masa Garansi / Retensi Dimulai"]:::active
        DOCS -- "Dokumen 588st" --> P_SPK["PEKERJAAN LAPANGAN (SPK AKTIF)<br/>Konstruksi Sedang Berjalan"]:::physical
        DOCS -- "Dokumen 588so / Tidak Ada SPK" --> P_SO["KONTRAK AKTIF - BELUM START<br/>Tahap Administrasi / Negosiasi"]:::contract
    end

    subgraph SUB_KLASIFIKASI["3. KLASIFIKASI SISA KONTRAK BELUM TERBIT FAKTUR"]
        A_TRM --> CHK_START{"Apakah Fisik Sudah Start?<br/>(Ada SPK 588st / BAST?)"}:::decision
        P_SO -.-> CHK_START
        P_SPK -.-> CHK_START

        CHK_START -- "BELUM START (issued=0, sisa=0)" --> KBA["KONTRAK BELUM AKTIF<br/>Card KPI 5 (Abu-abu Slate)<br/>Rp 716 Juta (13 Proyek)"]:::contract
        KBA --> KBA_DESC["Belum Ada Hak Tagih Tanpa Syarat<br/>Tidak Dihitung Sebagai Beban Unbilled Lapangan<br/>Status Termin: KONTRAK BELUM AKTIF"]:::contract

        CHK_START -- "SUDAH START LAPANGAN" --> UNB["BELUM DITAGIHKAN (PROYEK BERJALAN)<br/>Card KPI 4 (Kuning/Oranye)<br/>Rp 9,67 Miliar (24 Proyek)"]:::unbilled
        UNB --> UNB_DESC["Hak Tagih Berjalan Sesuai Progres Prestasi<br/>UnbilledTermin = max(0, AllocTermin - IssuedTermin)"]:::unbilled
    end

    subgraph SUB_INVOICE_TERMIN["4. PENERBITAN FAKTUR TERMIN & PELUNASAN A/R"]
        UNB --> INV_TRM["Penerbitan Faktur Termin (7499)<br/>di Modul PenerimaanProjek (_key='termin')"]:::active
        INV_TRM --> TPS_TRM["Tercatat di transaksi_payment_source<br/>NetTagihan = Tagihan - Returned - Diskon"]:::active
        TPS_TRM --> PAY_TRM["Pelunasan di Modul A/R (749)<br/>Kasir Terima Kas / Bank / Potong Titipan"]:::active
        PAY_TRM --> EVAL_TRM{"Evaluasi Status Termin (issued > 0?)"}:::decision

        EVAL_TRM -- "sisa <= 0 AND unbilled <= 0 AND issued > 0" --> TRM_LUNAS["SELURUH TERMIN LUNAS<br/>Badge: Label Success (Hijau)"]:::lunas
        EVAL_TRM -- "sisa <= 0 AND unbilled > 0" --> TRM_PARTIAL["TERMIN AKTIF LUNAS - BELUM LENGKAP<br/>Badge: Label Warning (Kuning)"]:::unbilled
        EVAL_TRM -- "sisa > 0" --> TRM_PIUTANG["PIUTANG TERMIN (MENUNGGU BAYAR)<br/>Badge: Label Danger (Merah)"]:::piutang
    end

    subgraph SUB_RETENSI["5. SIKLUS PENAGIHAN RETENSI (GARANSI PEMELIHARAAN)"]
        A_RET --> CHK_RET{"Evaluasi Masa Pemeliharaan<br/>Dokumen BAST 2 (588) Terbit?"}:::decision
        P_PHO -.-> CHK_RET
        P_FHO -.-> CHK_RET

        CHK_RET -- "BELUM (Masih Masa Garansi)" --> RET_WAIT["MENUNGGU MASA PEMELIHARAAN<br/>Faktur Retensi Belum Boleh Diterbitkan<br/>Badge: Label Default (Abu-abu)"]:::contract
        CHK_RET -- "SUDAH SELESAI (FHO / Waktu Tuntas)" --> RET_INV["Penerbitan Faktur Retensi (7499 / 7488)<br/>di Modul PenerimaanProjek"]:::active
        RET_INV --> RET_PAY["Pelunasan Retensi di Modul A/R (749)"]:::active
        RET_PAY --> EVAL_RET{"Evaluasi Sisa Retensi"}:::decision
        EVAL_RET -- "sisa <= 0" --> RET_LUNAS["RETENSI LUNAS<br/>Badge: Label Success (Hijau)"]:::lunas
        EVAL_RET -- "sisa > 0" --> RET_PIUTANG["PIUTANG RETENSI<br/>Badge: Label Danger (Merah)"]:::piutang
    end
```

---

## 3. Arsitektur Hubungan Database Antar-Tabel (Entity-Relationship & Data Flow)

Diagram ini memetakan bagaimana relasi antar-tabel MySQL bekerja secara riil saat transaksi berpindah dari kasir ke penagihan proyek hingga pelunasan A/R.

```mermaid
erDiagram
    master_project ||--o{ transaksi : "memiliki riwayat dokumen"
    master_project ||--o{ transaksi_payment_source : "memiliki baris tagihan & piutang"
    customer ||--o{ master_project : "memiliki kontrak proyek"
    customer ||--o{ transaksi : "melakukan pembayaran kasir"

    master_project {
        int id PK "ID Proyek Unik"
        string nama "Nama Proyek"
        decimal contract_nilai "Nilai Kontrak Proyek"
        decimal contract_dpp "Nilai Kontrak Sebelum PPN"
        string quot_nomer "No. SO / Quotation Penjualan (588so)"
        string project_start_nomer "No. SPK Pelaksanaan Lapangan (588st)"
        date start_dtime "Tanggal Mulai Proyek"
    }

    transaksi {
        int id PK "ID Transaksi Transaksional"
        string nomer "Nomor Dokumen (4467.1.x / 7499.1.x / 749.1.x)"
        string transaksi_jenis "Jenis: 4467 (Kasir DP), 7499 (Faktur), 749 (AR), 588 (BAST)"
        int project_id FK "Tautan ke master_project.id"
        int reference_id "Tautan Dokumen Referensi / SO"
        string reference_nomer "Nomor Referensi SO (588so...)"
        decimal transaksi_nilai "Total Nilai Termasuk PPN"
        decimal transaksi_net "DPP Nilai Bersih"
        decimal ppn_nilai "Pajak Pertambahan Nilai"
        int trash "0 = Aktif, 1 = Void / Batal"
        datetime cancel_dtime "Waktu Pembatalan Transaksi"
        string cancel_name "Nama User Pembatal"
        string cancel_transaksi_nomer "Nomor Dokumen Pembatalan"
    }

    transaksi_payment_source {
        int id PK "ID Sumber Piutang (TPS ID)"
        int project_id FK "Tautan ke master_project.id"
        string nomer "Nomor Faktur Tagihan / Kwitansi"
        string jenis "Jenis Transaksi Asal (7499, 4467)"
        string target_jenis "Modul Pelunasan: 749 (AR), 04467 (Kasir)"
        string _key "Komponen Tagihan: dp, termin, retensi"
        decimal tagihan "Nominal Tagihan Awal"
        decimal returned "Nominal Retur / Pengurangan Tagihan"
        decimal diskon "Diskon Potongan Faktur"
        decimal terbayar "Total Realisasi Pembayaran Masuk"
        decimal sisa "Sisa Saldo Piutang Aktif"
        datetime cancel_dtime "Waktu Void TPS"
    }

    transaksi_data_registry {
        int id PK "ID Registry"
        int transaksi_id FK "Tautan ke transaksi.id (Transaksi 749)"
        blob items "JSON/Serialize Payload Rincian Pelunasan"
    }

    jurnal {
        int id PK "ID Jurnal Akuntansi"
        int transaksi_id FK "Tautan ke transaksi.id"
        string rekening "Kode Akun COA (1010010010, 1010020010, 2010050)"
        decimal debet "Mutasi Debet"
        decimal kredit "Mutasi Kredit"
        int project_id FK "Tautan Buku Pembantu Proyek"
    }

    transaksi ||--o{ transaksi_data_registry : "menyimpan payload items"
    transaksi ||--o{ jurnal : "membukukan mutasi double-entry"
    transaksi_payment_source ||--o{ transaksi_data_registry : "dirujuk via items.tabel_id"
```

---

## 4. Rekonsiliasi 3 Pilar Buku Pembantu (Triple-Entry Subledger Verification)

Diagram ini mengilustrasikan protokol audit rekonsiliasi matematis antara modul operasional dengan Buku Besar (General Ledger).

```mermaid
graph LR
    classDef operasional fill:#e0f2fe,stroke:#0284c7,stroke-width:2px,color:#0369a1;
    classDef gl fill:#ede9fe,stroke:#7c3aed,stroke-width:2px,color:#5b21b6;
    classDef audit fill:#fef3c7,stroke:#d97706,stroke-width:2px,color:#92400e;
    classDef pass fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#166534;

    subgraph PILAR1["PILAR 1: PIUTANG DAGANG KONSUMEN"]
        OP1["Modul Penerimaan (A/R)<br/>Total Sisa Piutang Aktif<br/>transaksi_payment_source.sisa"]:::operasional
        GL1["Buku Besar Akuntansi (GL)<br/>Saldo Debet Netto Rekening 1010020010<br/>(Saldo Debet - Saldo Kredit)"]:::gl
        OP1 <== "Audit Balance 1:1" ==> GL1
    end

    subgraph PILAR2["PILAR 2: UANG MUKA KONSUMEN PROYEK"]
        OP2["Modul Kas (Kwitansi 4467)<br/>Total Sisa Saldo Kwitansi DP Sah<br/>(Diterima - Dipotong di AR 749)"]:::operasional
        GL2["Buku Besar Pembantu Proyek (GL)<br/>Saldo Kredit Rekening 2010050<br/>(Liabilitas Uang Muka Proyek)"]:::gl
        OP2 <== "Audit Balance 1:1" ==> GL2
    end

    subgraph PILAR3["PILAR 3: TITIPAN KONSUMEN BEBAS"]
        OP3["Modul Kasir Bebas (Project_id = 0)<br/>Deposit Titipan Bebas Pelanggan<br/>Belum Diikat ke Proyek Manapun"]:::operasional
        GL3["Buku Besar Konsumen (GL)<br/>Saldo Kredit Rekening 2030060<br/>(Titipan Konsumen Bebas)"]:::gl
        OP3 <== "Audit Balance 1:1" ==> GL3
    end

    PILAR1 -.-> VERIFY["ENGINE AUDIT OTOMATIS<br/>Penerimaan/Transaksi.php"]:::audit
    PILAR2 -.-> VERIFY
    PILAR3 -.-> VERIFY
    VERIFY ==> RESULT["INTEGRITAS FINANSIAL TERVERIFIKASI<br/>Badge: Rekonsiliasi 3 Pilar Aktif<br/>Zero Unreconciled Balance"]:::pass
```

---

## 5. Ringkasan Kamus Kode Transaksi ERP Everest Terkait

| Kode Transaksi | Modul Utama | Peran Akuntansi / Operasional | Akun Terkait (COA) |
|---|---|---|---|
| **`4467`** | Kas | Penerimaan Kasir Uang Muka Proyek / Titipan Bebas | D: `1010010010` (Kas/Bank) \| K: `2010050` (Uang Muka) |
| **`4467re`** / **Void** | Kas / Pembatalan | Pembatalan / Pengembalian (Refund) Uang Muka | D: `2010050` (Uang Muka) \| K: `1010010010` (Kas/Bank) |
| **`7499`** | PenerimaanProjek | Penerbitan Faktur Penagihan Proyek (DP, Termin, Retensi) | D: `1010020010` (Piutang) \| K: Pendapatan Proyek |
| **`749`** | Penerimaan | Pelunasan Piutang Konsumen (Kas/Bank atau Potong DP) | D: Kas/Bank atau `2010050` \| K: `1010020010` (Piutang) |
| **`7488`** | PenerimaanProjek | Penerbitan Faktur Penagihan Khusus Retensi Pemeliharaan | D: `1010020010` (Piutang) \| K: Retensi Ditagihkan |
| **`588so`** | Penjualan / Proyek | Sales Order Kontrak Proyek (Tahap Persiapan / Negosiasi) | Dokumen Non-Akuntansi (Komitmen Legal) |
| **`588st`** | Produksi / Proyek | Surat Perintah Kerja (SPK) Lapangan (Fisik Sedang Start) | Dokumen Fisik (Dasar Pengakuan Hak Tagih Termin) |
| **`588sta`** | Produksi / Proyek | Berita Acara Serah Terima 1 (BAST 1 / PHO Masa Garansi) | Trigger Masa Pemeliharaan Retensi Dimulai |
| **`588`** | Produksi / Proyek | Berita Acara Serah Terima 2 (BAST 2 / FHO Serah Terima Akhir)| Trigger Hak Tagih Retensi Resmi Dibuka |
