﻿# Mapping Tabel SO: Legacy -> Format Baru GLIMS

Dokumen ini adalah revisi dari mapping sebelumnya dengan validasi langsung terhadap:
- SQL dump: `persadal_db_smartlab2_live (2).sql` (generated Apr 12, 2026)
- Migrasi target: `apps/glims/database/migrations/2026_04_12_000001_create_sales_order_tables.php`

## 1. Koreksi Penting dari Versi Sebelumnya

1. `t_po_det_param` memang ada di database legacy.
2. `nomor` pada `t_po` adalah `varchar(150)`, bukan `varchar(25)`.
3. `tanggal_sampling` dan `tanggal_sampling_akhir` di legacy bertipe `timestamp`, bukan `date`.
4. `nomor_bukti_bayar` pada `t_po_pembayaran` adalah `varchar(100)`.
5. `idempotency_key` pada `t_po_pembayaran` adalah `varchar(255)` nullable.
6. Banyak kolom `t_po` (operasional/logistik/cetak dokumen) ada di legacy namun tidak ikut dibawa ke skema GLIMS baru.

## 2. Ringkasan Mapping Tabel

| Legacy | Baru |
|---|---|
| `t_po` | `glims_t_sales_orders` |
| `t_po_det` | `glims_t_sales_order_items` |
| `t_po_det_param` | `glims_t_sales_order_item_params` |
| `t_po_pembayaran` | `glims_t_sales_order_payments` |

## 3. Mapping `t_po` -> `glims_t_sales_orders`

### 3.1 Kolom yang Dipetakan

| Kolom Legacy | Tipe Legacy | Kolom Baru | Tipe Baru | Catatan |
|---|---|---|---|---|
| `id` | `int(11) AI` | `id` | `bigint AI` | PK |
| - | - | `uuid` | `uuid unique` | Kolom baru |
| `nomor` | `varchar(150)` | `so_number` | `varchar(50) unique` | Dipendekkan |
| - | - | `quotation_number` | `varchar(50) nullable` | Kolom baru |
| `tanggal` | `date nullable` | `transaction_date` | `date` | Di baru dibuat required |
| `m_customer` | `int(11)` | `customer_id` | `unsignedBigInteger` | FK bisnis |
| `m_status_penawaran` | `int(11)` | `quotation_status` | `string nullable` | Integer status -> string |
| `m_status_pembayaran` | `int(11)` | `payment_status` | `string default unpaid` | Integer status -> string |
| - | - | `status` | `string default draft` | Status operasional SO |
| `tanggal_sampling` | `timestamp nullable` | `sampling_start_date` | `date nullable` | Presisi waktu turun ke tanggal |
| `tanggal_sampling_akhir` | `timestamp nullable` | `sampling_end_date` | `date nullable` | Presisi waktu turun ke tanggal |
| `is_sampling_gmp` | `int(3)` | `is_gmp_sampling` | `boolean` | Flag |
| - | - | `deadline_date` | `date nullable` | Baru |
| `ppn_persen` | `float default 12` | `tax_percentage` | `decimal(5,2)` | Normalisasi tipe |
| - | - | `subtotal` | `decimal(15,2)` | Baru |
| `disc` | `double` | `discount_amount` | `decimal(15,2)` | Mapping diskon level SO |
| `ppn` | `double` | `tax_amount` | `decimal(15,2)` | Mapping nominal pajak |
| `grand_total` | `double` | `grand_total` | `decimal(15,2)` | Tetap |
| `nomor_invoice` | `varchar(50) nullable` | `invoice_number` | `string nullable` | Tetap konsep |
| `tanggal_cetak_invoice` | `timestamp nullable` | `invoice_printed_at` | `timestamp nullable` | Rename |
| `id_transaction_accurate` | `bigint(20) nullable` | `accurate_transaction_id` | `unsignedBigInteger nullable` | Tetap konsep |
| `created_user` | `int(11)` | `created_by` | `unsignedBigInteger nullable` | Rename |
| `created_date` | `timestamp nullable` | `created_at` | `timestamps` | Laravel timestamps |
| `updated_user` | `int(11)` | `updated_by` | `unsignedBigInteger nullable` | Rename |
| `updated_date` | `timestamp nullable` | `updated_at` | `timestamps` | Laravel timestamps |
| `deleted_user` | `int(11)` | `deleted_by` | `unsignedBigInteger nullable` | Audit delete |
| `deleted_date` / `is_delete` | `timestamp` / `int(11)` | `deleted_at` | `softDeletes` | Soft delete Laravel |
| `tanggal_approved` | `timestamp nullable` | `approved_at` | `timestamp nullable` | Approval |
| - | - | `approved_by` | `unsignedBigInteger nullable` | Approval actor |
| - | - | `notes` | `text nullable` | Baru |

### 3.2 Kolom Legacy `t_po` yang Tidak Dibawa Langsung

Kelompok kolom berikut ada di legacy tetapi tidak dimodelkan langsung di tabel baru SO:
- Struktur nomor dan revisi: `nomor_urut`, `nomor_bulan`, `nomor_tahun`, `nomor_rev`, `is_rev`, `duplicate_from`
- Grup/cabang/marketing: `m_group_po`, `m_cabang`, `m_cabang_ro`, `m_ref_marketing`, `m_cabang_akuisisi`, `m_cabang_pelaksana`
- Sampling detail lanjut: `perkiraan_tanggal_sampling*`, `propose_tanggal_sampling*`, `tanggal_validasi_sampling`, `tanggal_realisasi_sampling*`, `tanggal_terima_sampel`, dll
- Status dokumen operasional: `m_status_cetak_*`, `m_status_kirim_*`, `m_status_terima*`, `nomor_resi*`, `nomor_spp`, `nomor_faktur`, `nomor_sj`, `nomor_io`, dll
- Kolom finansial tambahan: `sub_total`, `disc_persen`, `total`, `piutang`, `cashback`, `total_cou`, `persen_gpm`, `bea_transfer`, dll
- Catatan khusus non-core: `note_teknis`, `note_administrasi`, `note_internal_marketing`, `reason_*`, dll

## 4. Mapping `t_po_det` -> `glims_t_sales_order_items`

### 4.1 Kolom yang Dipetakan

| Kolom Legacy | Tipe Legacy | Kolom Baru | Tipe Baru | Catatan |
|---|---|---|---|---|
| `id` | `int(11) AI` | `id` | `bigint AI` | PK |
| - | - | `uuid` | `uuid unique` | Baru |
| `t_po` | `int(11)` | `sales_order_id` | `foreignId` | FK ke SO baru |
| `m_jenis_pengujian` | `int(11)` | `test_type_id` | `unsignedBigInteger` | Tetap konsep |
| `titik` | `int(11)` | `sample_points` | `integer` | Rename |
| - | - | `quantity` | `integer default 1` | Baru |
| `tarif` | `double` | `unit_price` | `decimal(15,2)` | Normalisasi tipe |
| `disc_rupiah` | `double` | `discount_amount` | `decimal(15,2)` | Rename |
| `jumlah` | `double` | `subtotal` | `decimal(15,2)` | Mapping subtotal item |
| `note` | `text nullable` | `notes` | `text nullable` | Rename |
| `created_user` | `int(11)` | `created_by` | `unsignedBigInteger nullable` | Rename |
| `created_date` | `timestamp` | `created_at` | `timestamps` | Laravel timestamps |
| `updated_user` | `int(11)` | `updated_by` | `unsignedBigInteger nullable` | Rename |
| `updated_date` | `timestamp` | `updated_at` | `timestamps` | Laravel timestamps |
| `deleted_user` | `int(11)` | `deleted_by` | `unsignedBigInteger nullable` | Audit delete |
| `deleted_date` / `is_delete` | `timestamp` / `int(11)` | `deleted_at` | `softDeletes` | Soft delete Laravel |

### 4.2 Kolom Legacy `t_po_det` yang Tidak Dibawa Langsung

`provide_by_client`, `m_peraturan`, `m_parameter_uji`, `disc_persen`, `cou_param`, `sum_cou_param`, `is_subkon`, `is_hide`.

## 5. Mapping `t_po_det_param` -> `glims_t_sales_order_item_params`

### 5.1 Kolom yang Dipetakan

| Kolom Legacy | Tipe Legacy | Kolom Baru | Tipe Baru | Catatan |
|---|---|---|---|---|
| `id` | `int(11) AI` | `id` | `bigint AI` | PK |
| - | - | `uuid` | `uuid unique` | Baru |
| `t_po_det` | `int(11)` | `sales_order_item_id` | `foreignId` | FK ke item SO baru |
| - | - | `parameter_id` | `unsignedBigInteger nullable` | Referensi master jika ada |
| `m_parameter_uji` | `varchar(750)` | `parameter_name` | `string` | Snapshot nama parameter |
| - | - | `test_method` | `string nullable` | Baru |
| - | - | `unit` | `string(50) nullable` | Baru |
| - | - | `specification` | `string nullable` | Baru |
| `harga` | `double` | `unit_price` | `decimal(15,2)` | Rename |
| - | - | `notes` | `text nullable` | Baru |
| `created_user` | `int(11)` | `created_by` | `unsignedBigInteger nullable` | Rename |
| `created_date` | `timestamp` | `created_at` | `timestamps` | Laravel timestamps |
| `updated_user` | `int(11)` | `updated_by` | `unsignedBigInteger nullable` | Rename |
| `updated_date` | `timestamp` | `updated_at` | `timestamps` | Laravel timestamps |
| `deleted_user` | `int(11)` | `deleted_by` | `unsignedBigInteger nullable` | Audit delete |
| `deleted_date` / `is_delete` | `timestamp` / `int(11)` | `deleted_at` | `softDeletes` | Soft delete Laravel |

### 5.2 Kolom Legacy `t_po_det_param` yang Tidak Dibawa Langsung

`is_parameter_tambahan`, `cou`.

## 6. Mapping `t_po_pembayaran` -> `glims_t_sales_order_payments`

### 6.1 Kolom yang Dipetakan

| Kolom Legacy | Tipe Legacy | Kolom Baru | Tipe Baru | Catatan |
|---|---|---|---|---|
| `id` | `int(11) AI` | `id` | `bigint AI` | PK |
| - | - | `uuid` | `uuid unique` | Baru |
| `t_po` | `int(11)` | `sales_order_id` | `foreignId` | FK ke SO baru |
| `nomor_bukti_bayar` | `varchar(100) nullable` | `receipt_number` | `string nullable` | Rename |
| `tanggal_bayar` | `date nullable` | `payment_date` | `date` | Di baru dibuat required |
| - | - | `status` | `string default pending` | Baru |
| - | - | `payment_method` | `string nullable` | Baru |
| `jumlah` | `double` | `amount` | `decimal(15,2)` | Normalisasi tipe |
| `diskon` | `int(11)` | `discount_amount` | `decimal(15,2)` | Normalisasi tipe |
| `pph` | `int(11)` | `tax_withheld` | `decimal(15,2)` | Normalisasi tipe |
| - | - | `bank_name` | `string nullable` | Baru |
| - | - | `bank_account_number` | `string nullable` | Baru |
| `idempotency_key` | `varchar(255) nullable` | `idempotency_key` | `string unique nullable` | Tetap konsep |
| - | - | `verified_by` | `unsignedBigInteger nullable` | Baru |
| - | - | `verified_at` | `timestamp nullable` | Baru |
| `keterangan` | `varchar(500) nullable` | `notes` | `text nullable` | Dipetakan ke kolom catatan |
| `created_user` | `int(11) not null` | `created_by` | `unsignedBigInteger nullable` | Standarisasi audit |
| `created_date` | `timestamp not null` | `created_at` | `timestamps` | Laravel timestamps |
| `updated_user` | `int(11) not null` | `updated_by` | `unsignedBigInteger nullable` | Standarisasi audit |
| `updated_date` | `timestamp` | `updated_at` | `timestamps` | Laravel timestamps |
| `deleted_user` | `int(11)` | `deleted_by` | `unsignedBigInteger nullable` | Audit delete |
| `deleted_date` / `is_delete` | `timestamp` / `int(11)` | `deleted_at` | `softDeletes` | Soft delete Laravel |

### 6.2 Kolom Legacy `t_po_pembayaran` yang Tidak Dibawa Langsung

Tidak ada kolom bisnis besar yang hilang selain normalisasi audit/soft-delete dan pergeseran model status.

## 7. Catatan Implementasi

1. Skema baru mengurangi ketergantungan pada integer status master dan mengganti dengan string status yang lebih mudah dibaca.
2. Banyak kolom legacy yang sifatnya operasional historis tidak dimigrasikan 1:1 ke tabel baru, dan perlu dipetakan ke modul lain jika masih dibutuhkan.
3. Untuk migrasi data produksi, sebaiknya dibuat rule transform eksplisit per kolom untuk tiga kategori:
   - direct map
   - transform map
   - archived/not migrated

---

Dokumen direvisi: 14 April 2026
Sumber validasi: `persadal_db_smartlab2_live (2).sql` + migrasi SO GLIMS terbaru
