# Admin Dashboard — Service Order Guide

## Overview

Admin sees the **full financial breakdown** of every order — all pricing fields, app fee, broker commission, discounts, and net provider earnings.

---

## Service Order Show — Full Pricing Breakdown

All pricing fields in `pricing` block:

| Field | Description |
|---|---|
| `service_price` | Base price agreed at order creation (= `base_price` on the order) |
| `broker_discount_amount` | Discount given to client via broker code |
| `package_discount_amount` | Discount given to client via package subscription |
| `total_discount_amount` | `broker_discount_amount + package_discount_amount` |
| `vat_percentage` | VAT % captured at order creation |
| `vat_amount` | VAT amount in SAR |
| `app_fee_percentage` | Platform service fee % captured at order creation |
| `app_fee_amount` | Platform service fee SAR amount captured at order creation |
| `net_provider_earnings` | `service_price − app_fee_amount` — what the provider actually receives |
| `total_price` | Total paid by client = `service_price − discounts + vat_amount + app_fee_amount` |
| `broker_commission_amount` | Commission earned by the broker (separate from client discount) |
| `broker_code_used` | The broker code string used on this order |

### Example Pricing Response

```json
"pricing": {
    "service_price": 500.00,
    "broker_discount_amount": 0.00,
    "package_discount_amount": 0.00,
    "total_discount_amount": 0.00,
    "vat_percentage": 15.00,
    "vat_amount": 75.00,
    "app_fee_percentage": 10.00,
    "app_fee_amount": 50.00,
    "net_provider_earnings": 450.00,
    "total_price": 575.00,
    "broker_commission_amount": 0.00,
    "broker_code_used": null
}
```

> `app_fee_percentage` and `app_fee_amount` are **captured at order creation time** — they reflect the rate at the time of the order, not the current platform setting.

> For **negotiated orders**: pricing fields are `null` until the client accepts and pays. They are stored at payment time with the final agreed price.

---

## Integrated Contract Order — Additional Keys

These keys are only present when `service_type = integrated_contract`.

### `show_client_contact` (bool)
Whether the provider can see sensitive client and party data.
- Default: `false` — sensitive data hidden from provider
- Toggle: `PATCH /admin/service-orders/{id}/toggle-client-contact`

### `contract_attachment`
Media file object (PDF/document) uploaded as the contract. Present if client uploaded a file instead of typing terms.

### `contract_terms`
Free-text contract body. Present if client typed terms instead of uploading a file.

### `parties_data`
Contract signatories added at order creation.

```json
"parties_data": [
    {
        "id": 12,
        "full_name": "Ahmed Ali",
        "national_id": "1234567890",
        "national_id_type": "national_id",
        "phone_code": "+966",
        "phone": "501234567",
        "has_confirmed": true,
        "confirmed_at": 1728123456,
        "user_data": { "id": 12, "full_name": "Ahmed Ali", "avatar": "..." }
    }
]
```

### `edit_requests`
Full approval history grouped by iteration (edit request round).

```json
"edit_requests": [
    {
        "edit_request": 1,
        "approved_count": 1,
        "pending_count": 0,
        "rejected_count": 1,
        "approvals": [
            {
                "user_id": 5,
                "full_name": "Client Name",
                "is_client": true,
                "status": "approved",
                "revision_note": null,
                "responded_at": 1728123456
            },
            {
                "user_id": 12,
                "full_name": "Party Name",
                "is_client": false,
                "status": "rejected",
                "revision_note": "Please revise clause 3",
                "responded_at": 1728123500
            }
        ]
    },
    {
        "edit_request": 2,
        "approved_count": 2,
        "pending_count": 0,
        "rejected_count": 0,
        "approvals": [...]
    }
]
```

---

## Toggle Client Data Visibility

```
PATCH /admin/service-orders/{id}/toggle-client-contact
PATCH /admin/urgent-orders/{id}/toggle-client-contact
```

**Response:**
```json
{
    "status": "success",
    "message": "Client data is now visible to the provider.",
    "data": { "show_client_contact": true }
}
```

| Field | `show_client_contact = false` | `show_client_contact = true` |
|---|---|---|
| `client_data.phone_code` | `null` | real value |
| `client_data.phone` | `null` | real value |
| `parties_data[*].national_id` | `null` | real value |
| `parties_data[*].national_id_type` | `null` | real value |
| `parties_data[*].phone_code` | `null` | real value |
| `parties_data[*].phone` | `null` | real value |
| `client_data.full_name` | always visible | always visible |
| `parties_data[*].full_name` | always visible | always visible |

---

## Integrated Contract Approval Flow

```
1. Client creates order with parties[]
   → ServiceOrderParty records created

2. Provider uploads work + marks as finished
   → status: provider_finished
   → contract_party_approvals created (client + all parties), iteration: 1

3. Each person calls confirm independently
   → When ALL approved → status: completed → provider paid

4. Any person requests revision
   → status: active (back to provider)
   → revision_requests_count + 1, revision_iteration + 1

5. Provider re-submits → new iteration approval records created
```

---

## Category Exam Settings (Main Category Only)

| Field | Required | Notes |
|---|---|---|
| `exam_passing_score` | optional | Set freely even before questions exist (0–100) |
| `exam_max_attempts` | required | Max attempts per provider |
| `exam_cooldown_days` | required | Days between retries |
| `exam_duration_minutes` | required | Exam time limit |

> Questions have a **separate CRUD** at `/admin/categories/{id}/questions` — they are not part of category creation.

---

## Client Broker Code Toggle

```
PATCH /admin/clients/{client}/broker-code-status
```
Toggles `is_broker_code_active`. Returns `{ "is_broker_code_active": true/false }`.

> Broker-client blocks are managed separately via `/admin/broker-blocks` (not via the clients endpoints).
