# TSHIRTORDER-1633 — Prepaid transaction log: API for Frontend

Mockup: `files/prepaid-log-mockup.png` (Channel → *Redigera kanal* → **Prepaid** tab).

## Goal

In the **Prepaid** tab of a channel, add a **"Log prepaid"** section below the existing prepaid history table. It lists every order that is deducted from *Tillgänglig summa inkl moms*, with the amount deducted per order and a total row.

---

## Endpoint

```
GET /api/v1/channels/{id}/prepaid-orders
Authorization: Bearer <token>
```

| Query param | Type | Default | Description |
|---|---|---|---|
| `limit` | int | `50` | Page size. Values are clamped to `1..500` |
| `offset` | int | `0` | Number of rows to skip. Negative values become `0` |

Example:

```bash
curl -H "Authorization: Bearer <token>" \
  "https://<api-host>/api/v1/channels/93/prepaid-orders?limit=50&offset=0"
```

**This endpoint is read-only.** It does not insert a prepaid history row, does not update the channel and does not send the watcher email. It is safe to call every time the tab is opened.

---

## Response `200`

```json
{
  "prepaidDate": "2026-08-17T09:30:00+02:00",
  "prepaidSum": 10000,
  "prepaidWatcherLevel": 3000,
  "prepaidCurrentSum": 8750,
  "totalDeducted": 1250,
  "total": 2,
  "items": [
    {
      "orderId": 10240,
      "orderNr": "31622",
      "orderCountNr": 74080,
      "customerName": "Stallzet AB",
      "dateOrder": "2026-08-22T14:05:00+02:00",
      "totalSum": 200,
      "totalTax": 50,
      "deductedSum": 250
    },
    {
      "orderId": 10234,
      "orderNr": "31610",
      "orderCountNr": 74071,
      "customerName": "Stallzet AB",
      "dateOrder": "2026-08-20T10:12:00+02:00",
      "totalSum": 800,
      "totalTax": 200,
      "deductedSum": 1000
    }
  ]
}
```

### Top-level fields

| Field | Type | Description |
|---|---|---|
| `prepaidDate` | datetime \| null | *Förinbetalt datum & tid* of the channel |
| `prepaidSum` | number | *Förinbetalt belopp inkl. moms* |
| `prepaidWatcherLevel` | number \| null | *Bevakningsnivå skicka email* |
| `prepaidCurrentSum` | number | **Available amount calculated at request time** = `prepaidSum − totalDeducted` |
| `totalDeducted` | number | Sum of `deductedSum` of **all** matching orders (not only the current page) |
| `total` | int | Total number of matching orders, for pagination |
| `items` | array | Orders of the current page, newest first |

### `items[]` fields

| Field | Type | Description |
|---|---|---|
| `orderId` | int | Order ID — use it to link to the order detail page |
| `orderNr` | string \| null | Order number |
| `orderCountNr` | int | Order count number |
| `customerName` | string \| null | Customer name |
| `dateOrder` | datetime | Order date |
| `totalSum` | number | Order total excl. tax |
| `totalTax` | number | Order tax |
| `deductedSum` | number | Amount deducted from the prepaid sum = `totalSum + totalTax` |

All amounts are rounded to 2 decimals. Datetimes are ISO 8601 strings with timezone offset (server timezone Europe/Berlin, same offset as Sweden).

### Errors

| Status | Body | When |
|---|---|---|
| `401` | `{ "message": "Invalid token authorization" }` | Missing / invalid token |
| `403` | `{ "message": "User not allow to view prepaid of channel ..." }` | Channel (guest) account that does not belong to this channel, or the channel has *guestLoginShowPrepaid* turned off |
| `404` | `{ "message": "Channel was not found" }` | Unknown channel ID |
| `500` | `{ "message": "..." }` | Unexpected server error |

---

## UI requirements

Section title: **Log prepaid** — placed below the existing prepaid history table (see mockup).

| Column | Source |
|---|---|
| Order | `orderNr` or `orderCountNr` — use the same rule as the other order screens (`channel.switchOrderNrOrderCountNr`); link to the order detail page by `orderId` |
| Datum | `dateOrder` (format `YYYY-MM-DD`) |
| Kund | `customerName` |
| Summa inkl moms | `deductedSum` |

- Add a **total row** at the bottom: `totalDeducted`.
- Add pagination using `total`, `limit`, `offset`.
- Empty state (no orders): show a short text such as "Inga ordrar har dragits från förinbetalt belopp".

---

## ⚠️ Important notes

1. **Show `prepaidCurrentSum` from this endpoint as *Tillgänglig summa inkl moms*.**
   The value `prepaidCurrentSum` returned by `GET /channels/{id}` is only refreshed when someone clicks **Skicka**, so it is often outdated. If the tab shows the old value next to the new log, the numbers will not match (`prepaidSum − totalDeducted ≠ Tillgänglig summa`). The value from this endpoint is always consistent with the log.

2. **Do not call `POST /channels/{id}/get-prepaid-current-sum` when the tab is opened.**
   That endpoint saves the settings, inserts a new row into the prepaid history table and may send the watcher email **every time it is called**. Keep it only on the **Skicka** button. Please check whether the current code calls it on tab load — if so, remove that call and use this new endpoint for display.

3. **After clicking Skicka**, reload this endpoint (the prepaid date or sum may have changed, so the list and totals change too).

4. If the channel has no `prepaidDate`, the endpoint returns `items: []`, `totalDeducted: 0` and `prepaidCurrentSum = prepaidSum`.

5. **Which orders are deducted** (for your information — calculated by the backend, nothing to do on FE):
   - orders of this channel, not deleted, not cancelled
   - ordered **after the end of the prepaid day** (`prepaidDate` date + 23:59:59). Orders placed on the same day as the prepaid date are not deducted.

6. Guest (channel) accounts: the API allows it only for the account's own channels **and** when the channel setting *guestLoginShowPrepaid* is on (otherwise `403`). Whether to show the log in the guest view is not decided yet — for now, show it in the admin view only.

---

## Related existing endpoints (unchanged)

| Method | Path | Usage |
|---|---|---|
| `GET` | `/api/v1/channels/{id}` | Channel detail; contains `prepaidSum`, `prepaidWatcherLevel`, `prepaidDate`, `prepaidCurrentSum` (may be outdated) and `prepaidLogs` (prepaid history table, right side of the mockup) |
| `POST` | `/api/v1/channels/{id}/get-prepaid-current-sum` | **Skicka** button. Body: `{ "prepaidSum", "prepaidWatcherLevel", "prepaidDateString": "YYYY-MM-DD HH:mm:ss" }`. Saves the settings, recalculates the available amount, inserts a history row and sends the watcher email if below the level |
