# Blueprint Refactoring: Modul Pembelian (FollowUp.php)

Dokumen ini adalah *blueprint* dan *checklist* strategis untuk mengurai (*decouple*) logika bisnis dari *Controller* raksasa `FollowUp.php` menuju lapisan *Service/Library* dan *Helper*. Mengikuti prinsip **Thin Controller - Fat Service** (AGENTS.md §4), **Single Responsibility Principle** (SOLID/SRP), dan standar pemeliharaan kode **ISO/IEC 25010** (Maintainability: Modularity, Reusability, Analysability, Modifiability).

## Profil File Saat Ini

| Metrik | Nilai |
|--------|-------|
| **Total Baris** | 23.691 |
| **Total Method** | 24 (2 private, 22 public) |
| **Method Terbesar** | `doRevert()` — 5.481 baris |
| **Lokasi** | `application/modules/pembelian/controllers/FollowUp.php` |

## Peta Seluruh Method

| # | Visibilitas | Nama Method | ± Ukuran | Domain Fungsional | Target Pemindahan |
|---|-------------|-------------|----------|--------------------|--------------------|
| 1 | public | `__construct()` | 38 | Inisialisasi | **TETAP** di Controller |
| 2 | private | `parseDashIds()` | 22 | Utilitas | Helper |
| 3 | private | `lookupGroupedQtyByJenisProduk()` | 51 | Utilitas | Helper |
| 4 | public | `index()` | 622 | UI / Form | Evaluasi (>200, bagian UI → Helper) |
| 5 | public | `followupPrePreview()` | 1.048 | Revert All (Preview) | `LibPembelianFollowUpRevertAll` |
| 6 | public | `followupPreviewMobile()` | 44 | Mobile | **TETAP** di Controller |
| 7 | public | `doScan()` | 93 | Mobile | **TETAP** di Controller |
| 8 | public | `shopingCart()` | 114 | Cart | **TETAP** di Controller |
| 9 | public | `doResetMobile()` | 27 | Mobile | **TETAP** di Controller |
| 10 | public | `followupPreview()` | 2.867 | Approval (Preview) | `LibPembelianFollowUpFollowupPreview` |
| 11 | public | `doFollowup()` | 5.018 | Approval (Eksekusi) | `LibPembelianFollowUpDoFollowup` |
| 12 | public | `doRevert()` | 5.481 | Revert (Eksekusi) | `LibPembelianFollowUpDoRevert` |
| 13 | public | `doRevertAll()` | 1.484 | Revert All (Eksekusi) | `LibPembelianFollowUpRevertAll` |
| 14 | public | `viewIncompleteStepAntarCabang()` | 175 | Laporan | **TETAP** di Controller |
| 15 | public | `clearContent()` | 23 | Utilitas | **TETAP** di Controller |
| 16 | public | `viewIncomplete()` | 5 | Utilitas | **TETAP** di Controller |
| 17 | public | `doPreEdit()` | 442 | Edit | `LibPembelianFollowUpEdit` |
| 18 | public | `editForm()` | 405 | Edit | `LibPembelianFollowUpEdit` |
| 19 | public | `preCancelPacking()` | 455 | Cancel (Inisiasi) | `LibPembelianFollowUpCancelPreview` |
| 20 | public | `followupCancelPackingPrePreview()` | 594 | Cancel (Preview) | `LibPembelianFollowUpCancelPreview` |
| 21 | public | `followupCancelPackingPreview()` | 1.979 | Cancel (Preview) | `LibPembelianFollowUpCancelPreview` |
| 22 | public | `doCancelPacking()` | 2.582 | Cancel (Eksekusi) | `LibPembelianFollowUpDoCancelPacking` |
| 23 | public | `updateItems()` | 18 | Utilitas | **TETAP** di Controller |
| 24 | public | `doUpdateApproval()` | 74 | Utilitas | **TETAP** di Controller |

## Arsitektur Target

```
application/modules/pembelian/
├── controllers/
│   └── FollowUp.php                                   (~900 baris, delegasi + method kecil)
├── helpers/
│   ├── he_pembelian_ui_helper.php                     (✅ sudah dibuat)
│   └── he_pembelian_followup_helper.php               (utilitas: parseDashIds, lookupGroupedQty)
└── libraries/
    ├── LibPembelianFollowUpDoFollowup.php              (>2000 → file sendiri)
    ├── LibPembelianFollowUpDoRevert.php                (>2000 → file sendiri)
    ├── LibPembelianFollowUpFollowupPreview.php         (>2000 → file sendiri)
    ├── LibPembelianFollowUpDoCancelPacking.php         (>2000 → file sendiri)
    ├── LibPembelianFollowUpRevertAll.php               (<2000 per method → digabung per domain)
    ├── LibPembelianFollowUpCancelPreview.php           (<2000 per method → digabung per domain)
    └── LibPembelianFollowUpEdit.php                    (<2000 per method → digabung per domain)
```

### Prinsip Pengelompokan (sesuai AGENTS.md §4.3)
- **Method > 2.000 baris** → **1 file per method** (SRP ketat).
- **Domain < 2.000 baris per method** → boleh digabung beberapa method terkait dalam 1 file.
- Pasangan eksekusi + preview yang total < 2.000 baris per method ditempatkan bersama (*change locality*).

---

## 📋 Checklist Eksekusi Bertahap

### Fase 0: Ekstraksi Private Method ke Helper 🟢
Memindahkan 2 *private method* utilitas ke Helper khusus modul.
- [ ] Buat file `application/modules/pembelian/helpers/he_pembelian_followup_helper.php`
- [ ] Pindahkan `parseDashIds()` (22 baris) — DocBlock + inline comment
- [ ] Pindahkan `lookupGroupedQtyByJenisProduk()` (51 baris) — DocBlock + inline comment
- [ ] Load helper di `__construct()`: `$this->load->helper("he_pembelian_followup");`
- [ ] Tombstone comment di FollowUp.php

### Fase 1: `doRevert()` → `LibPembelianFollowUpDoRevert.php` 🔴
Method terbesar (5.481 baris). Dikerjakan pertama untuk membuktikan mekanisme.
- [ ] Buat file `LibPembelianFollowUpDoRevert.php`
- [ ] Pindahkan isi `doRevert()` ke `processDoRevert($c)`
- [ ] Konversi `$this->` → `$c->`, DocBlock + inline comment
- [ ] Delegasi di FollowUp.php, Tombstone comment
- [ ] Buat script test sederhana
- [ ] Uji coba reversal transaksi via UI

### Fase 2: `doFollowup()` → `LibPembelianFollowUpDoFollowup.php` 🔴
Inti utama controller: proses approval transaksi (5.018 baris).
- [ ] Buat file `LibPembelianFollowUpDoFollowup.php`
- [ ] Pindahkan isi `doFollowup()` ke `processDoFollowup($c)`
- [ ] Konversi `$this->` → `$c->`, DocBlock + inline comment
- [ ] Delegasi di FollowUp.php, Tombstone comment
- [ ] Buat script test sederhana
- [ ] Uji coba approval transaksi via UI

### Fase 3: `followupPreview()` → `LibPembelianFollowUpFollowupPreview.php` 🟠
Halaman preview utama sebelum approval (2.867 baris).
- [ ] Buat file `LibPembelianFollowUpFollowupPreview.php`
- [ ] Pindahkan isi `followupPreview()` ke `processFollowupPreview($c)`
- [ ] Konversi `$this->` → `$c->`, DocBlock + inline comment
- [ ] Delegasi di FollowUp.php, Tombstone comment

### Fase 4: `doCancelPacking()` → `LibPembelianFollowUpDoCancelPacking.php` 🟠
Proses pembatalan pengepakan (2.582 baris).
- [ ] Buat file `LibPembelianFollowUpDoCancelPacking.php`
- [ ] Pindahkan isi `doCancelPacking()` ke `processDoCancel($c)`
- [ ] Konversi `$this->` → `$c->`, DocBlock + inline comment
- [ ] Delegasi di FollowUp.php, Tombstone comment

### Fase 5: Domain Revert All — `LibPembelianFollowUpRevertAll.php` 🟡
Gabungan method terkait revert (setiap method < 2000 baris → digabung).
- [ ] Buat file `LibPembelianFollowUpRevertAll.php`
- [ ] Pindahkan isi `doRevertAll()` (±1.484 baris) ke `processDoRevertAll($c)`
- [ ] Pindahkan isi `followupPrePreview()` (±1.048 baris) ke `processFollowupPrePreview($c)`
- [ ] Konversi `$this->` → `$c->`, DocBlock + inline comment
- [ ] Delegasi di FollowUp.php

### Fase 6: Domain Cancel Preview — `LibPembelianFollowUpCancelPreview.php` 🟡
Gabungan method cancel preview (setiap method < 2000 baris → digabung per domain).
- [ ] Buat file `LibPembelianFollowUpCancelPreview.php`
- [ ] Pindahkan isi `followupCancelPackingPreview()` (±1.979 baris) ke `processFollowupCancelPreview($c)`
- [ ] Pindahkan isi `followupCancelPackingPrePreview()` (±594 baris) ke `processFollowupCancelPrePreview($c)`
- [ ] Pindahkan isi `preCancelPacking()` (±455 baris) ke `processPreCancelPacking($c)`
- [ ] Konversi `$this->` → `$c->`, DocBlock + inline comment
- [ ] Delegasi di FollowUp.php

### Fase 7: Domain Edit — `LibPembelianFollowUpEdit.php` 🟢
Gabungan method edit (total ~847 baris → digabung).
- [ ] Buat file `LibPembelianFollowUpEdit.php`
- [ ] Pindahkan isi `doPreEdit()` (±442 baris) ke `processDoPreEdit($c)`
- [ ] Pindahkan isi `editForm()` (±405 baris) ke `processEditForm($c)`
- [ ] Konversi `$this->` → `$c->`, DocBlock + inline comment
- [ ] Delegasi di FollowUp.php

### Fase 8: Evaluasi & Pembersihan 🟢
Method kecil (≤ 200 baris) yang **tetap tinggal di Controller**:
- [ ] `index()` (622 baris) → evaluasi: bagian UI ke Helper, sisa logika ke Library jika >200 baris
- [ ] `viewIncompleteStepAntarCabang()` (175 baris) → **tetap**
- [ ] `shopingCart()` (114 baris) → **tetap**
- [ ] `doScan()` (93 baris) → **tetap**
- [ ] `doUpdateApproval()` (74 baris) → **tetap**
- [ ] `followupPreviewMobile()` (44 baris) → **tetap**
- [ ] `doResetMobile()` (27 baris) → **tetap**
- [ ] `clearContent()` (23 baris) → **tetap**
- [ ] `updateItems()` (18 baris) → **tetap**
- [ ] `viewIncomplete()` (5 baris) → **tetap**

---

## Proyeksi Hasil Akhir

| File | Sebelum | Sesudah |
|------|---------|---------|
| `FollowUp.php` | 23.691 baris | **~900 baris** |
| `LibPembelianFollowUpDoRevert.php` | - | ~5.481 baris |
| `LibPembelianFollowUpDoFollowup.php` | - | ~5.018 baris |
| `LibPembelianFollowUpFollowupPreview.php` | - | ~2.867 baris |
| `LibPembelianFollowUpDoCancelPacking.php` | - | ~2.582 baris |
| `LibPembelianFollowUpRevertAll.php` | - | ~2.532 baris |
| `LibPembelianFollowUpCancelPreview.php` | - | ~3.028 baris |
| `LibPembelianFollowUpEdit.php` | - | ~847 baris |
| `he_pembelian_followup_helper.php` | - | ~100 baris |

---

## 🛠 Panduan Teknis

Mengacu sepenuhnya pada **AGENTS.md §4.4 - §4.7**:
- Safe Refactoring via injeksi `$c` (§4.4)
- DocBlock lengkap + inline comment di setiap blok logika utama (§4.5)
- Script test sederhana per Library (§4.6)
- Referensi: SOLID/SRP, Clean Code, ISO/IEC 25010 (§4.7)
