# Rencana Implementasi: Fitur Switch Pelaksana & Auto-Void Biaya Aktif (Modul Master Project)

Rencana ini merinci implementasi fitur interaktif untuk mengubah tipe pelaksana (**INTERNAL** $\leftrightarrow$ **EXTERNAL**) secara langsung melalui klik pada badge tipe pelaksana, lengkap dengan modal pop-up, auto-check biaya aktif (transaksi `3674`), opsi pembatalan/void otomatis, dan dual audit trail logging.

---

## Ringkasan Fitur & Alur Kerja

```mermaid
graph TD
    A["Klik Badge Tipe Pelaksana<br/>(Hijau INTERNAL / Orange EXTERNAL)"] --> B["Buka Modal Switch Pelaksana"]
    B --> C["AJAX Check: Ambil Data SPK, Karyawan, Vendor & Cek Biaya Aktif (3674)"]
    C --> D{"Pilihan Perpindahan Tipe"}
    
    D -->|INTERNAL -> EXTERNAL| E["Pilih Vendor dari Dropdown"]
    E --> F["Klik Simpan"]
    F --> G["Update tasklist_project ke Type 22 & Vendor"]
    G --> H{"Apakah SPK Sudah QC?"}
    H -->|Ya| I["Auto-Trigger AutoPostingBiaya (Terbitkan 3674 Vendor Baru)"]
    H -->|Belum| J["Selesai (Biaya terbit saat QC nanti)"]
    
    D -->|EXTERNAL -> INTERNAL| K["Pilih Karyawan dari Dropdown"]
    K --> L{"Apakah Ada Biaya 3674 Aktif?"}
    L -->|Tidak Ada| M["Klik Simpan Langsung"]
    L -->|Ada Biaya Aktif| N["Tampilkan Panel Biaya:<br/>No. Nota, Nominal, Status Pembayaran"]
    N --> O["Checkbox Konfirmasi:<br/>[x] Batalkan/Void Biaya Vendor ini otomatis"]
    O --> P["Klik Simpan"]
    P --> Q["Void Transaksi 3674 (trash_4 = 1, status_4 = 3)"]
    Q --> R["Reset post_biaya_id di tasklist_project"]
    R --> S["Update tasklist_project ke Type 11 & Karyawan"]
    
    G --> T["Catat Dual Audit Trail:<br/>1. project_tasklist_log (Timeline SPK)<br/>2. log (Activity Log Keuangan jika ada Void)"]
    S --> T
    T --> U["Tutup Modal & Refresh Datatable / Tampilan"]
```

---

## User Review Required

> [!IMPORTANT]
> **Kebijakan Pembatalan Biaya yang Sudah Terbayar (Disbursed):**
> Jika biaya vendor (`3674`) terdeteksi sudah memiliki pembayaran riil dari kasir/bank (`nilai_bayar > 0`), sistem **TIDAK AKAN** membatalkan transaksi secara otomatis untuk menghindari ketidaksesuaian saldo kas fisik. Modal akan menampilkan peringatan bahwa biaya sudah dicairkan dan meminta pengguna berkoordinasi dengan kasir/keuangan. Jika `nilai_bayar == 0` (masih pending/hutang belum dibayar), pembatalan (void) dapat dilakukan secara otomatis 100%.

---

## Proposed Changes

### 1. Backend: Controller `MasterData.php`

#### [MODIFY] [`MasterData.php`](file:///z:/everest_11sept/application/modules/master_project/controllers/MasterData.php)

Tambahkan dua method AJAX baru dan perbarui metadata datatable:

1. **`checkPelaksanaBiayaAjax()`:**
   - Menerima `no_spk` via GET/POST.
   - Mengambil data SPK saat ini (`type_pelaksana`, `employee_id`, `employee_nama`, `progress_id`, `produk_id`).
   - Query transaksi biaya aktif di tabel `transaksi`:
     - `referensi_nomer = $no_spk`, `jenis IN ('3674r', '3674')`, `trash_4 = 0`.
   - Mengambil daftar Karyawan aktif (`MdlEmployee_all` dengan filter `allow_project = 1`) dan Vendor aktif (`MdlSupplier`).
   - Mengembalikan response JSON terstruktur berisi status biaya, rincian pembayaran, dan daftar opsi pelaksana.

2. **`saveSwitchPelaksanaAjax()`:**
   - Menerima `no_spk`, `new_type`, `pelaksana_id`, `pelaksana_nama`, dan `void_biaya` (0/1).
   - Membungkus seluruh proses dalam `$this->db->trans_start()` dan `$this->db->trans_complete()`.
   - **Jika External $\rightarrow$ Internal:**
     - Jika `void_biaya == 1`:
       - Mengupdate transaksi `3674r`/`3674` terkait: `trash_4 = 1`, `status_4 = 3` (dibatalkan).
       - Menulis log keuangan ke `MdlActivityLog` (tabel `log`).
       - Mereset `post_biaya_id = 0` dan `post_biaya_no = NULL` pada `tasklist_project`.
     - Mengupdate `type_pelaksana = 11`, `employee_id`, dan `employee_nama` pada `tasklist_project`.
   - **Jika Internal $\rightarrow$ External:**
     - Mengupdate `type_pelaksana = 22`, `employee_id`, dan `employee_nama` pada `tasklist_project`.
     - Mereset `post_biaya_id = 0` pada `tasklist_project`.
     - Jika status SPK sudah QC (`progress_id == 3`), otomatis memanggil `AutoPostingBiaya` untuk menerbitkan tagihan vendor `3674` yang baru.
   - **Dual Audit Logging:**
     - Menulis riwayat perubahan ke tabel `project_tasklist_log` via `MdlTasklistProjectLog` dengan tipe `'SWITCH_PELAKSANA'`.
     - Menulis riwayat ke tabel `log` via `MdlActivityLog` jika ada transaksi biaya yang di-void.

3. **Perkaya Metadata Datatable (`action` array di `showHalamanPelaksana` / list data):**
   - Pastikan objek data di setiap baris membawa atribut `_no_spk`, `_tasklist_id`, `_type_pelaksana`, `_employee_id`, `_employee_nama`, dan `_progress_id` sehingga fungsi klik modal memiliki data lengkap.

---

### 2. Frontend: View & Template

#### [MODIFY] [`views/data.php`](file:///z:/everest_11sept/application/modules/master_project/views/data.php)

1. **Jadikan Badge Tipe Pelaksana Clickable:**
   - Ubah badge di kolom pelaksana (target 8) agar memiliki efek kursor klik (`cursor: pointer`), tooltip (*"Klik untuk ubah pelaksana/tipe"*), dan trigger `onclick="openModalSwitchPelaksana(this)"`.
2. **Tambahkan Markup Modal `#modalSwitchPelaksana`:**
   - Modal Bootstrap dengan desain AdminLTE yang rapi.
   - Form Tipe Pelaksana (Radio: Internal vs External).
   - Dropdown Pelaksana dinamis (Karyawan vs Vendor).
   - Container Status Biaya (alert box interaktif yang menampilkan info transaksi 3674 jika ada dan checkbox pembatalan/void otomatis).
   - Tombol Batal & Simpan.
3. **Tambahkan Javascript Handler:**
   - Fungsi `openModalSwitchPelaksana(el)`: membaca data SPK, menampilkan spinner, dan memanggil AJAX `checkPelaksanaBiayaAjax`.
   - Dynamic form switcher: saat radio diganti dari Internal ke External atau sebaliknya, dropdown dan panel biaya menyesuaikan secara instan.
   - Fungsi `submitSwitchPelaksana()`: mengirim perubahan via AJAX `saveSwitchPelaksanaAjax`, menampilkan notifikasi SweetAlert berhasil/gagal, dan me-reload DataTables.

#### [MODIFY] [`template/tasklist_update.html`](file:///z:/everest_11sept/application/modules/master_project/template/tasklist_update.html)

1. **Jadikan Badge di Header QC Modal Clickable:**
   - Di baris tabel `#tipe_pelaksana_badge`, tambahkan styling pointer dan trigger klik agar pengguna juga dapat langsung mengubah tipe pelaksana saat sedang berada di dalam modal QC.

---

## Verification Plan

### Automated / Syntax Verification
- Validasi sintaks PHP 5.6 pada berkas yang dimodifikasi menggunakan PHP CLI:
  ```powershell
  C:\xampp\php\php.exe -l application/modules/master_project/controllers/MasterData.php
  C:\xampp\php\php.exe -l application/modules/master_project/views/data.php
  ```

### Manual Verification Flow
1. **Skenario 1 (INTERNAL $\rightarrow$ EXTERNAL):**
   - Buka halaman Daftar Pelaksana & Pekerjaan.
   - Klik badge hijau `INTERNAL` pada salah satu SPK.
   - Pastikan modal muncul dengan radio terpilih *Internal* dan Karyawan aktif.
   - Ganti radio ke *External*, pastikan dropdown beralih menampilkan daftar Vendor.
   - Pilih Vendor, klik Simpan.
   - Pastikan badge berubah menjadi orange `PIHAK KE-3 / VENDOR / SUBKON`.
   - Periksa database `project_tasklist_log` untuk memastikan riwayat audit tercatat.

2. **Skenario 2 (EXTERNAL $\rightarrow$ INTERNAL tanpa Biaya):**
   - Klik badge orange pada SPK External yang belum memiliki biaya.
   - Pilih *Internal*, pilih Karyawan, klik Simpan.
   - Pastikan badge beralih ke hijau *INTERNAL* tanpa error.

3. **Skenario 3 (EXTERNAL $\rightarrow$ INTERNAL dengan Biaya Aktif):**
   - Klik badge orange pada SPK External yang sudah memiliki biaya `3674` (status pending/belum terbayar).
   - Pastikan modal menampilkan peringatan kuning berisi No. Nota `3674` dan nominalnya.
   - Pastikan checkbox pembatalan/void otomatis muncul dan dapat dicentang.
   - Klik Simpan $\rightarrow$ periksa bahwa transaksi `3674` berstatus `trash_4 = 1` (void) dan riwayat audit di tabel `log` serta `project_tasklist_log` tercatat lengkap.
