# Delivery Trips: Internal vs External – Implementasi

## Ringkasan

Halaman Delivery Trips diperluas dengan dua tipe pengiriman:
- **Internal** – pengiriman yang sudah ada (driver, kendaraan, KM, jam keluar/kembali).
- **External** – pengiriman via ekspedisi eksternal (vendor ekspedisi, nomor resi, jam pick-up, karton, berat, dimensi, volume).

Pengguna **harus memilih** tipe dulu; form yang tampil berbeda sesuai pilihan. Perhitungan **waktu** dan **biaya** mendukung kedua tipe, dan tetap terintegrasi dengan **ERPNext Delivery Note**.

---

## 1. Migration SQL (phpMyAdmin)

**File:** `SAPPS-BACKEND/migrations/delivery_trips_internal_external.sql`

- Jalankan script **sekali** di phpMyAdmin (pilih database SAPPS).
- Jika kolom/tabel sudah ada, MySQL akan error untuk statement itu — skip atau komentar baris tersebut.
- Script **tidak menghapus dan tidak mengubah** data existing; hanya menambah kolom/tabel baru.

**Isi migration:**
- Tabel `deliveryexpeditionvendors` (master vendor ekspedisi).
- Tabel `deliverytrips`: kolom `delivery_type` (default `'internal'`), `expedition_vendor_id`, `resi_number`, `pick_up_time`, `cartons_pcs`, `weight_kg`, `dimensions_cm`, `volume_calculated`; `driver` dan `vehicle_id` diizinkan NULL.
- Tabel `deliverytripchilds`: kolom `send_date`, `receive_date` (untuk external: Tanggal Kirim / Tanggal Terima; Total Waktu dalam hari).

Setelah migration, pastikan backend di-restart agar model Sequelize mengenal kolom baru.

---

## 2. Backend (Sudah Dikerjakan)

- **Model**
  - `deliveryTrip.model.js`: field `delivery_type`, `expedition_vendor_id`, `resi_number`, `pick_up_time`, `cartons_pcs`, `weight_kg`, `dimensions_cm`, `volume_calculated`; `driver` dan `vehicle_id` allowNull: true; association `expedition_vendor`.
  - `deliveryTripChild.model.js`: field `send_date`, `receive_date`.
  - `deliveryExpeditionVendor.model.js` + registrasi di `db.js`.
- **Service**
  - `deliveryTrip.service.js`: include `send_date`, `receive_date` di semua response child; include `expedition_vendor`; update vehicle odometer hanya jika `vehicle_id` ada (aman untuk external).

Create/Update menerima field baru; tidak ada validasi wajib driver/vehicle untuk `delivery_type === 'external'` di backend (bisa ditambah nanti).

---

## 3. Cost Info – Biaya Kurir / Ekspedisi (Sudah Dikerjakan)

- **AddEditData.jsx:** dropdown Cost Type ditambah opsi **"Biaya Kurir"** dan **"Biaya Ekspedisi"**.
- **ExportPDF.jsx, monthExport.jsx, yearExport.jsx:** kategori/kolom dan agregasi untuk Biaya Kurir dan Biaya Ekspedisi.

Tidak ada perubahan schema DB untuk cost; `item_type` tetap string.

---

## 4. Frontend – Yang Perlu Dikerjakan (Form & Tabel)

### 4.1 Pilihan Tipe Pengiriman (Langkah Pertama)

- Di form **Add/Edit** (atau di list sebelum buka form), tambah pilihan: **Internal** / **External**.
- Simpan pilihan ke state `delivery_type` (`'internal'` | `'external'`).
- Untuk **create**: set `delivery_type` di initialValues sesuai pilihan.
- Untuk **edit**: baca `value.delivery_type` (default `'internal'` jika kosong).

### 4.2 Form “Delivery Details” – Conditional by `delivery_type`

**Internal (existing):**
- Date, **Vehicle** (dropdown), **Driver** (dropdown), Current KM, Jam Keluar, Jam Kembali, KM Keluar, KM Kembali.
- Validasi: driver & vehicle_id wajib.

**External:**
- Date.
- **Vendor Ekspedisi** (dropdown dari API master ekspedisi / options dari props).
- **Nomor Resi** (text).
- **Jam Pick-Up** (time).
- **Jumlah Karton (pcs)** (number).
- **Berat Barang (Kg)** (number).
- **Dimensi (p x l x t cm)** (text atau 3 input; simpan ke `dimensions_cm`).
- **Volume Barang** (read-only): `dimensi / 5000` (hitung dari `dimensions_cm` parse "p x l x t" atau dari 3 angka).

Validasi: untuk external, expedition_vendor_id & resi_number wajib (sesuai kebijakan). Driver & vehicle_id tidak wajib.

### 4.3 Delivery Stop (Edit) – Conditional by `delivery_type`

- **Internal:** tetap **Jam Tiba** (`start`), **Jam Selesai** (`end`), **Total Waktu** (jam + menit).
- **External:** ganti menjadi **Tanggal Kirim** (`send_date`), **Tanggal Terima** (`receive_date`), **Total Waktu** = … **hari** (dari selisih send_date dan receive_date).

Simpan `send_date` dan `receive_date` di child; backend sudah menerima.

### 4.4 Tabel List (TableDataNew / Columns)

- Tampilkan kolom **Tipe** (Internal/External) dari `delivery_type`.
- Untuk external, tampilkan **Vendor Ekspedisi** (dari `expedition_vendor.name`) dan **Nomor Resi** (`resi_number`) jika perlu; untuk internal tetap Driver/Vehicle seperti sekarang.

### 4.5 Validasi Formik (AddEditData)

- Jika `delivery_type === 'internal'`: wajib company_id, driver, vehicle_id (seperti sekarang).
- Jika `delivery_type === 'external'`: wajib company_id, expedition_vendor_id, resi_number; driver & vehicle_id optional (atau dikosongkan).

### 4.6 API Option – Vendor Ekspedisi

- Endpoint list **Vendor Ekspedisi** (tabel `deliveryexpeditionvendors`, enabled=true) untuk dropdown External sudah tersedia di `/sapps/expeditions/option`.
- Frontend memanggil endpoint ini dan mengisi options untuk field “Vendor Ekspedisi”.

---

## 5. Integrasi ERPNext (Delivery Note)

- Delivery Stops tetap memakai **Delivery Note** (ERPNext doctype); tidak berubah untuk integrasi existing.
- Data external (resi, vendor, berat, dimensi, volume) bisa dipetakan ke custom fields atau ke doctype terkait di ERPNext jika diperlukan nanti; mapping tersebut bisa didokumentasikan di sini atau di file terpisah.

---

## 6. Ringkasan File

| Area              | File | Status |
|-------------------|------|--------|
| Migration         | `SAPPS-BACKEND/migrations/delivery_trips_internal_external.sql` | Siap jalankan |
| Backend model     | `deliveryTrip.model.js`, `deliveryTripChild.model.js`, `deliveryExpeditionVendor.model.js`, `db.js` | Done |
| Backend service   | `deliveryTrip.service.js` (include child + expedition_vendor, update vehicle aman) | Done |
| Cost types        | `AddEditData.jsx`, `ExportPDF.jsx`, `monthExport.jsx`, `yearExport.jsx` | Done |
| Form conditional  | `AddEditData.jsx` (pilihan Internal/External + form berbeda + validasi) | Todo |
| Delivery Stop     | Edit form child: Jam Tiba/Selesai vs Tanggal Kirim/Terima + Total Waktu hari | Todo |
| List/Table         | Kolom Tipe, Vendor/Resi untuk external | Todo |
| API option vendor | Backend + frontend options vendor ekspedisi | Todo |

Dengan ini, sistem siap dipakai untuk data existing (semua dianggap internal) dan pengembangan form/UI external bisa dilanjutkan langkah demi langkah tanpa merusak data atau alur yang sudah jalan.
