# UI Data Contract Frontend-Backend Sistem Inventory Walet

## 1. Tujuan
Dokumen ini menjelaskan kontrak data utama antara frontend dan backend agar implementasi UI tidak salah tafsir, terutama pada area lot, allocation, costing, sorting, dan traceability.

## 2. Prinsip Umum
- backend adalah source of truth untuk data transaksi
- frontend boleh menyimpan draft workflow lokal sebelum submit
- angka quantity dan cost harus selalu dikirim dalam bentuk numerik
- ID utama menggunakan integer/bigint
- status harus dikirim dalam kode string yang konsisten
- field read-only harus dibedakan jelas dari field editable

## 3. Format Response Umum
Contoh standar response list:
```json
{
  "data": [],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 100
  }
}
```

Contoh standar response detail:
```json
{
  "data": {
    "id": 1
  }
}
```

Contoh error:
```json
{
  "message": "Validation error",
  "errors": {
    "qty": ["qty harus lebih besar dari 0"]
  }
}
```

## 4. Purchase Contract
### Purchase list item
```json
{
  "id": 1,
  "purchase_no": "PO-20260428-001",
  "supplier": {
    "id": 1,
    "name": "Supplier A",
    "bank_name": "BCA",
    "bank_account_number": "1234567890"
  },
  "purchase_date": "2026-04-28",
  "status": "SUBMITTED",
  "line_count": 3,
  "grand_total": 1220000000
}
```

### Purchase detail
```json
{
  "id": 1,
  "purchase_no": "PO-20260428-001",
  "supplier": {
    "id": 1,
    "name": "Supplier A",
    "bank_name": "BCA",
    "bank_account_number": "1234567890"
  },
  "purchase_date": "2026-04-28",
  "supplier_invoice_no": "INV-SUP-A-001",
  "status": "SUBMITTED",
  "notes": "Pembelian campuran",
  "lines": [
    {
      "id": 1,
      "item_type": { "id": 1, "name": "Jenis A" },
      "item_grade": { "id": 1, "name": "Grade A" },
      "qty_ordered": 50,
      "unit": { "id": 1, "code": "KG" },
      "unit_price": 18000000,
      "subtotal": 900000000,
      "classification_status": "FINAL"
    }
  ]
}
```

## 5. Receipt Contract
### Receipt detail
```json
{
  "id": 1,
  "receipt_no": "RCV-20260428-001",
  "purchase": {
    "id": 1,
    "purchase_no": "PO-20260428-001"
  },
  "supplier": {
    "id": 1,
    "name": "Supplier A",
    "bank_name": "BCA",
    "bank_account_number": "1234567890"
  },
  "receipt_date": "2026-04-28",
  "status": "FINALIZED",
  "lines": [
    {
      "id": 1,
      "purchase_line_id": 1,
      "item_type": { "id": 1, "name": "Jenis A" },
      "item_grade": { "id": 1, "name": "Grade A" },
      "qty_received": 50,
      "qty_accepted": 50,
      "qty_rejected": 0,
      "unit_cost": 18000000,
      "warehouse": { "id": 1, "name": "Gudang Pusat" },
      "location": { "id": 1, "name": "Rak A1" }
    }
  ],
  "generated_lots": [
    {
      "id": 1,
      "lot_code": "LOT-260428-SUPA-001",
      "status": "ACTIVE"
    }
  ]
}
```

## 6. Lot Contract
### Lot list item
```json
{
  "id": 1,
  "lot_code": "LOT-260428-SUPA-001",
  "supplier": "Supplier A",
  "item_type": "Jenis A",
  "item_grade": "Grade A",
  "original_qty": 50,
  "available_qty": 30,
  "unit_cost": 18000000,
  "warehouse": "Gudang Pusat",
  "location": "Rak A1",
  "aging_days": 3,
  "status": "ACTIVE"
}
```

### Lot detail
```json
{
  "id": 1,
  "lot_code": "LOT-260428-SUPA-001",
  "supplier": {
    "id": 1,
    "name": "Supplier A",
    "bank_name": "BCA",
    "bank_account_number": "1234567890"
  },
  "item_type": {
    "id": 1,
    "name": "Jenis A"
  },
  "item_grade": {
    "id": 1,
    "name": "Grade A"
  },
  "original_qty": 50,
  "available_qty": 30,
  "reserved_qty": 0,
  "damaged_qty": 0,
  "shrinkage_qty": 0,
  "unit_cost": 18000000,
  "warehouse": {
    "id": 1,
    "name": "Gudang Pusat"
  },
  "location": {
    "id": 1,
    "name": "Rak A1"
  },
  "status": "ACTIVE",
  "parent_lot": null,
  "child_lots": [],
  "labels": [
    {
      "type": "QR",
      "value": "LOT-260428-SUPA-001"
    }
  ]
}
```

## 7. Sales Contract
### Sales list item
```json
{
  "id": 1,
  "sales_no": "SLS-20260428-001",
  "customer": {
    "id": 1,
    "name": "Customer A",
    "bank_name": "BRI",
    "bank_account_number": "111222333444"
  },
  "sales_date": "2026-04-28",
  "status": "CONFIRMED",
  "grand_total": 660000000,
  "costing_total": 550000000,
  "gross_margin": 110000000
}
```

### Sales detail
```json
{
  "id": 1,
  "sales_no": "SLS-20260428-001",
  "customer": {
    "id": 1,
    "name": "Customer A",
    "bank_name": "BRI",
    "bank_account_number": "111222333444"
  },
  "sales_date": "2026-04-28",
  "status": "CONFIRMED",
  "lines": [
    {
      "id": 1,
      "item_type": { "id": 1, "name": "Jenis A" },
      "item_grade": { "id": 1, "name": "Grade A" },
      "qty_sold": 30,
      "selling_price": 22000000,
      "subtotal": 660000000,
      "costing_total": 550000000,
      "gross_margin": 110000000,
      "allocations": [
        {
          "lot_id": 1,
          "lot_code": "LOT-260428-SUPA-001",
          "supplier": "Supplier A",
          "qty_allocated": 20,
          "unit_cost": 18000000,
          "total_cost": 360000000
        },
        {
          "lot_id": 4,
          "lot_code": "LOT-260428-SUPB-001-S1",
          "supplier": "Supplier B",
          "qty_allocated": 10,
          "unit_cost": 19000000,
          "total_cost": 190000000
        }
      ]
    }
  ]
}
```

## 8. Allocation Screen Contract
### Available lots response
```json
{
  "data": [
    {
      "lot_id": 1,
      "lot_code": "LOT-260428-SUPA-001",
      "supplier": "Supplier A",
      "available_qty": 30,
      "unit_cost": 18000000,
      "received_at": "2026-04-28T09:00:00Z",
      "is_fifo_recommended": true,
      "status": "ACTIVE"
    },
    {
      "lot_id": 4,
      "lot_code": "LOT-260428-SUPB-001-S1",
      "supplier": "Supplier B",
      "available_qty": 8,
      "unit_cost": 19000000,
      "received_at": "2026-04-28T11:00:00Z",
      "is_fifo_recommended": false,
      "status": "ACTIVE"
    }
  ]
}
```

### Allocation submit payload
```json
{
  "lines": [
    {
      "sales_line_id": 1,
      "allocations": [
        {
          "inventory_lot_id": 1,
          "qty_allocated": 20
        },
        {
          "inventory_lot_id": 4,
          "qty_allocated": 10
        }
      ]
    }
  ]
}
```

### Allocation summary response
```json
{
  "sales_line_id": 1,
  "qty_required": 30,
  "qty_allocated": 30,
  "costing_total": 550000000,
  "avg_cost": 18333333.33,
  "is_complete": true
}
```

## 9. Sorting Contract
### Sorting session detail
```json
{
  "id": 1,
  "sorting_no": "SRT-20260428-001",
  "source_lot": {
    "id": 3,
    "lot_code": "LOT-260428-SUPB-001"
  },
  "input_qty": 40,
  "output_qty": 37,
  "shrinkage_qty": 3,
  "results": [
    {
      "lot_id": 4,
      "lot_code": "LOT-260428-SUPB-001-S1",
      "item_type": "Jenis A",
      "item_grade": "Grade A",
      "qty_result": 18
    }
  ]
}
```

## 10. Barcode Lookup Contract
```json
{
  "lot_id": 1,
  "lot_code": "LOT-260428-SUPA-001",
  "supplier": "Supplier A",
  "item_type": "Jenis A",
  "grade": "Grade A",
  "available_qty": 30,
  "warehouse": "Gudang Pusat",
  "location": "Rak A1",
  "status": "ACTIVE",
  "actions": {
    "can_hold": true,
    "can_release": false,
    "can_transfer": true,
    "can_pick": true
  }
}
```

## 11. Report Contract
### Stock summary row
```json
{
  "item_type": "Jenis A",
  "item_grade": "Grade A",
  "warehouse": "Gudang Pusat",
  "qty_total": 38,
  "inventory_value": 730000000,
  "active_lot_count": 2
}
```

### Traceability row
```json
{
  "sales_no": "SLS-20260428-001",
  "customer": "Customer A",
  "item": "Jenis A / Grade A",
  "qty_sold": 30,
  "sources": [
    {
      "lot_code": "LOT-260428-SUPA-001",
      "supplier": "Supplier A",
      "qty": 20,
      "purchase_no": "PO-20260428-001"
    }
  ]
}
```

## 12. Frontend Editable vs Readonly Rules
### Editable examples
- qty_received
- qty_accepted
- selling_price
- qty_allocated draft
- qty_picked actual
- notes

### Readonly examples
- lot_code
- costing_total final hasil backend
- gross_margin final hasil backend
- parent_lot relation
- source trace fields

## 13. Status Codes yang Harus Konsisten
### Purchase
- DRAFT
- SUBMITTED
- CANCELLED

### Receipt
- DRAFT
- FINALIZED

### Lot
- ACTIVE
- HOLD
- CLOSED
- REJECTED

### Sales
- DRAFT
- ALLOCATED
- PICKED
- CONFIRMED
- CANCELLED

## 14. UI Validation Expectations
Frontend harus validasi cepat untuk:
- qty > 0
- total allocation sama dengan qty line
- qty result sorting tidak melebihi input
- required fields tidak kosong

Namun final validation tetap di backend.

## 15. Kesimpulan
Kontrak data ini dibuat agar frontend dan backend bicara bahasa yang sama, khususnya pada lot, allocation, sorting, traceability, dan costing yang merupakan inti sistem walet ini.