# REFACTORING DOKUMENTASI - ERP Controller Architecture

## 📋 Overview

Refactoring untuk memisahkan tanggung jawab OrderController, PaymentController, dan ProductionController berdasarkan prinsip Single Responsibility Principle.

---

## 🔄 NEW WORKFLOW

### 1️⃣ READY STOCK FLOW

```
Admin
  ↓
OrderController::create()   [Form order, tanpa input pembayaran pertama]
  ↓
OrderController::store()    [Insert order (status=unpaid), insert order_items]
  ↓
Order Created (ID: #ORD001, status: unpaid, payment_status: unpaid)
  ↓
PaymentController::create() [Form pembayaran]
  ↓
PaymentController::store()  [Insert payment, update order (paid_amount, payment_status=paid)]
  ↓
Order Updated (payment_status: paid)
  ↓
Invoice Generated & Sent (Email + WhatsApp)
  ↓
✅ COMPLETED (Tidak masuk produksi)
```

### 2️⃣ PO DENGAN DP (MINIMUM 50%)

```
Admin
  ↓
OrderController::create()   [Form order, tanpa input pembayaran pertama]
  ↓
OrderController::store()    [Insert order (status=unpaid), insert order_items]
  ↓
Order Created (ID: #ORD002, status: unpaid, production_status: waiting)
  ↓
PaymentController::create() [Form pembayaran (DP)]
  ↓
PaymentController::store()  [Insert payment, update order (paid_amount, payment_status=partial)]
  ↓
Check: payment >= 50%?     [YES]
  ↓
ProductionController::createQueueFromPayment()
  ↓
Production Queue Created (antrian produksi dimulai)
  ↓
Invoice Generated & Sent (Email + WhatsApp) - Invoice #1 (DP)
  ↓
Production Progress
  ↓
PaymentController::store()  [Insert payment (pelunasan)]
  ↓
Order Updated (paid_amount, payment_status=paid)
  ↓
Invoice Generated & Sent (Email + WhatsApp) - Invoice #2 (Lunas)
  ↓
✅ COMPLETED
```

### 3️⃣ PO LANGSUNG LUNAS (100%)

```
Admin
  ↓
OrderController::create()   [Form order, tanpa input pembayaran pertama]
  ↓
OrderController::store()    [Insert order (status=unpaid), insert order_items]
  ↓
Order Created (ID: #ORD003, status: unpaid, production_status: waiting)
  ↓
PaymentController::create() [Form pembayaran (100%)]
  ↓
PaymentController::store()  [Insert payment, update order (paid_amount, payment_status=paid)]
  ↓
Check: order PO & payment >= 50%?     [YES]
  ↓
ProductionController::createQueueFromPayment()
  ↓
Production Queue Created (antrian produksi langsung dimulai)
  ↓
Invoice Generated & Sent (Email + WhatsApp) - Invoice #1 (Lunas)
  ↓
Production Progress
  ↓
✅ COMPLETED
```

---

## 🔧 CHANGES BREAKDOWN

### OrderController

**REMOVED:**
- ❌ PaymentModel import
- ❌ NotificationService import
- ❌ Payment validation ($paid > 0)
- ❌ Payment status calculation
- ❌ Payment insertion (insert payment)
- ❌ Production queue creation ($this->dbQueue())
- ❌ Notification sending

**KEPT:**
- ✅ Order validation
- ✅ Order number generation
- ✅ PO limit calculation
- ✅ Target date calculation
- ✅ Order item insertion
- ✅ Order creation with initial status = 'unpaid'

**KEY CHANGE:**
```php
// BEFORE:
$paid = (float)$this->request->getPost('jumlah_bayar');
$paymentStatus = calculatePaymentStatus($paid, $total);
$this->paymentModel->insert([...]);
$this->dbQueue($orderId, ...);

// AFTER:
// Tidak ada input pembayaran di form
$orderId = $this->orderModel->insert([
    'paid_amount' => 0,
    'remaining_amount' => $total,
    'payment_status' => 'unpaid',
    'payment_method' => 'pending'
]);
```

---

### PaymentController

**ADDED:**
- ✅ Production queue trigger
  ```php
  $productionController = new ProductionController();
  if ($order['order_type'] === 'po' && $productionController->canStartProduction($orderId)) {
      $productionController->createQueueFromPayment($orderId);
  }
  ```

**UPDATED:**
- ✅ Update payment_method saat payment dimasukkan
- ✅ Better structured code dengan sections

**FLOW:**
1. Insert payment
2. Update order (paid_amount, remaining_amount, payment_status, payment_method)
3. Check if PO and payment >= 50% → Create production queue
4. Send invoice notification

---

### ProductionController

**ADDED:**
- ✅ `createQueueFromPayment($orderId)` - Buat queue dari payment
- ✅ `canStartProduction($orderId)` - Validasi syarat pembayaran (>= 50%)
- ✅ `createQueueItem()` - Helper untuk insert single queue

**LOGIC:**
- Dipanggil HANYA dari PaymentController
- Hanya bekerja jika:
  - order.order_type = 'po'
  - order.paid_amount >= 50% dari total
- Membuat production_queue item untuk setiap product (exclude custom)

---

## 📊 DATABASE CHANGES

### Orders Table

```
BEFORE:
- order_id, paid_amount, remaining_amount, payment_status, payment_method
- Filled saat OrderController::store()

AFTER:
- order_id, paid_amount (0), remaining_amount (= total), payment_status (unpaid), payment_method (pending)
- Filled saat OrderController::store()
- UPDATED saat PaymentController::store()
```

### Payments Table

```
BEFORE:
- payment_id, id_order, id_payment_method, amount, status
- Inserted dari OrderController::store() + PaymentController::store()

AFTER:
- payment_id, id_order, id_payment_method, amount, status
- ONLY inserted dari PaymentController::store()
- No more initial payment dari OrderController
```

### Production_Queue Table

```
BEFORE:
- Created dari OrderController::store() saat order_type='po'

AFTER:
- Created dari ProductionController::createQueueFromPayment()
- Triggered otomatis dari PaymentController::store()
- Hanya dibuat saat payment >= 50% (DP)
```

---

## ✅ VALIDATION CHECKLIST

- [x] OrderController hanya handle Order & OrderItem
- [x] PaymentController handle semua pembayaran
- [x] ProductionController handle production queue creation
- [x] Production queue dibuat otomatis saat payment memenuhi syarat
- [x] NotificationService tetap berjalan dari PaymentController
- [x] PO limit calculation tetap di OrderController
- [x] Single Responsibility Principle diterapkan

---

## 🚨 NEXT STEPS (Optional)

1. **Update Views:**
   - admin/orders/create - Remove payment input field
   - admin/orders/show - Add button "Tambah Pembayaran"
   - admin/payments/create - Show as separate flow

2. **Testing:**
   - Test Ready Stock flow
   - Test PO with DP (50%)
   - Test PO with 100% payment
   - Test partial payment progression

3. **Edge Cases:**
   - Pembayaran overpay (jika ada)
   - Production queue sudah ada sebelumnya
   - Custom products (tidak masuk queue)

---

## 📝 NOTES

- Semua business rules tetap sama
- Hanya perubahan pada struktur dan flow
- Database tidak perlu migration (gunakan column yang sudah ada)
- NotificationService tetap sama, dipanggil dari PaymentController
