# Seller app: working hours (أوقات الدوام)

Added 2026-11-07. The seller sets when their shop is open; our staff see it on every order. Server rules:
`App\Services\SellerWorkingHours`. New endpoints only, nothing existing changed.

All calls: `Authorization: Bearer <seller token>`, `System-Key`, `App-Language` (`ar` / `en`, used for the texts).
The shop is always the signed-in seller's. Every successful answer is the whole state, so the screen redraws from it:

```json
{
  "result": true,
  "message": "تم حفظ أوقات الدوام",
  "data": {
    "uses_general_hours": false,
    "timezone": "Asia/Damascus",
    "schedule": [
      {"day": "sat", "day_name": "السبت", "periods": [{"from": "10:00", "to": "14:00"}, {"from": "17:00", "to": "22:00"}], "text": "10:00 ص - 2:00 م، 5:00 م - 10:00 م"},
      {"day": "sun", "day_name": "الأحد", "periods": [...], "text": "..."},
      ...
      {"day": "fri", "day_name": "الجمعة", "periods": [], "text": "مغلق طوال اليوم"}
    ],
    "closures": [{"id": 7, "starts_on": "2026-11-20", "ends_on": "2026-11-22", "reason": "عطلة"}],
    "now": {
      "state": "closed",
      "is_open": false,
      "text": "مغلق الآن · يفتح 5:00 م",
      "closes_at": null,
      "opens_at": "2026-11-07T17:00:00+03:00"
    }
  }
}
```

- `schedule` is always the 7 days, Saturday first. `periods: []` = closed that day.
- `uses_general_hours: true` = the seller has not set their own hours; `schedule` then shows the general hours (the same every
  day). Show a note and let them save their own.
- Times are `HH:MM`, Syria's time. A period whose `to` is earlier than its `from` runs past midnight (`18:00` → `02:00`) and
  belongs to the day it starts. `to` may be `24:00` (until midnight; the app may send `23:59`, it is stored as `24:00`).
- `now.state`: `open`, `closing_soon` (less than an hour left), `closed`, `holiday` (a closure today). `opens_at` is null for a
  shop closed every day. `now.text` is ready to show.
- `closures` lists today's and later ones only, soonest first.

## Endpoints

| Call | Body | Notes |
|---|---|---|
| `GET api/v2/seller/working-hours` | | the state above |
| `POST api/v2/seller/working-hours` | `{"schedule": {"sat": [{"from":"10:00","to":"14:00"}], "sun": [], ...}}` | a missing day = closed; at most 2 periods a day |
| `POST api/v2/seller/working-hours` | `{"use_general_hours": true}` | removes the own hours (closures stay) |
| `POST api/v2/seller/working-hours/closures` | `{"starts_on":"2026-11-20","ends_on":"2026-11-22","reason":"عطلة"}` | `ends_on` optional (one day), `reason` optional (191 chars) |
| `DELETE api/v2/seller/working-hours/closures/{id}` | | only the seller's own closure |

## Errors

A refused change answers **422** `{"result": false, "message": "<why, in the app's language>"}` and changes nothing:
overlapping periods, a period starting and ending at the same time, a missing start / end, more than two periods,
a closure that ended already, a last day before the first, a closure longer than a year.
