# 16. API Order — Referensi Cepat

Endpoint API untuk **Order** (JSON). Autentikasi: **session** (cookie sama seperti web). User harus punya permission **order.manage**.

Base URL: `/api` (relatif ke app URL).

**Dokumentasi interaktif:** Buka **[/api-docs](/api-docs)** di browser untuk Swagger UI. Spesifikasi OpenAPI 3: `docs/openapi.yaml`.

---

## Rate limit

- **60 request per menit** per user (atau per IP jika belum login).
- Jika melebihi: response **429 Too Many Requests** dan header `Retry-After` (detik).

---

## Autentikasi

Dua cara (pilih salah satu):

1. **Session:** Login via web (`POST /login`), lalu panggil API dengan cookie session yang sama.
2. **API key:** Header `Authorization: Bearer <key>`. Key dibuat dengan `php artisan api-key:create {user_id} "Nama Client"` (key hanya ditampilkan sekali).

Header: `Accept: application/json`. Tanpa auth: response **401 Unauthorized**.

---

## Endpoint

### GET /api/orders

Daftar order (hanya outlet yang di-assign ke user).

**Query:**

| Parameter   | Tipe   | Keterangan                          |
|------------|--------|-------------------------------------|
| outlet_id  | int    | Filter by outlet                    |
| status     | string | Filter: created, confirmed, cooking, ready, completed, cancelled |
| date       | date   | Filter by tanggal order (Y-m-d)     |
| q          | string | Cari no. order                      |
| per_page   | int    | Jumlah per halaman (default 20, max 50) |
| page       | int    | Halaman                             |

**Response 200:**

```json
{
  "data": [
    {
      "id": 1,
      "outlet_id": 1,
      "order_number": "ORD20260215-0001",
      "type": "dine_in",
      "status": "created",
      "table_no": "1",
      "subtotal": 50000,
      "tax_amount": 5000,
      "service_charge_amount": 2500,
      "total": 57500,
      "paid_amount": 0,
      "outlet": { "id": 1, "name": "Outlet Utama", "code": "OUT001" },
      "items": [...]
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 1,
    "per_page": 20,
    "total": 1
  }
}
```

---

### POST /api/orders

Buat order baru beserta item.

**Body (JSON):**

| Field | Tipe | Wajib | Keterangan |
|-------|------|-------|-------------|
| outlet_id | int | Ya | ID outlet (harus akses user) |
| type | string | Tidak | dine_in, takeaway, delivery (default: dine_in) |
| table_no | string | Tidak | No. meja |
| customer_id | int | Tidak | ID pelanggan (customers) |
| pos_session_id | int | Tidak | ID session POS |
| notes | string | Tidak | Catatan order |
| items | array | Ya | Minimal 1 item |
| items[].product_id | int | Ya | ID produk (harus dari outlet yang sama) |
| items[].qty | int | Ya | Jumlah (min 1) |
| items[].modifiers | array | Tidak | Add-on: [{ id, name, price }] |

**Contoh:**

```json
{
  "outlet_id": 1,
  "type": "takeaway",
  "items": [
    { "product_id": 1, "qty": 2 },
    { "product_id": 2, "qty": 1, "modifiers": [{ "id": 1, "name": "Large", "price": 3000 }] }
  ]
}
```

**Response 201:**

```json
{
  "data": { "id": 1, "order_number": "ORD...", "outlet": {...}, "items": [...], "payments": [] },
  "message": "Order dibuat."
}
```

**Response 422:** Validasi gagal (outlet tidak akses, produk tidak ada, dll).

---

### GET /api/orders/{id}

Detail satu order. Policy: user harus punya akses outlet order tersebut.

**Response 200:**

```json
{
  "data": {
    "id": 1,
    "order_number": "ORD20260215-0001",
    "outlet": { "id": 1, "name": "...", "code": "...", "address": "..." },
    "items": [...],
    "payments": [...]
  }
}
```

**Response 403:** Tidak punya akses outlet order.

---

### POST /api/orders/{id}/status

Ubah status order.

**Body (JSON):**

```json
{
  "status": "confirmed"
}
```

Nilai `status` yang valid: `confirmed`, `cooking`, `ready`, `completed`, `cancelled`.

Transisi yang diizinkan:

- created → confirmed | cancelled  
- confirmed → cooking | cancelled  
- cooking → ready | cancelled  
- ready → completed | cancelled  

**Response 200:**

```json
{
  "data": { "id": 1, "order_number": "...", "status": "confirmed", ... },
  "message": "Status order diubah."
}
```

**Response 422:** Status tidak valid atau transisi tidak diizinkan.

```json
{
  "message": "Status tidak bisa diubah ke completed dari created"
}
```

---

## Rute (Laravel)

| Method | URI                        | Name                     |
|--------|----------------------------|--------------------------|
| GET    | /api/orders                | api.orders.index         |
| POST   | /api/orders                | api.orders.store         |
| GET    | /api/orders/{order}        | api.orders.show          |
| POST   | /api/orders/{order}/status | api.orders.update-status |
