# GET /v2/core/hub/reservation

# Hub: Get Master Reservation List

این اندپوینت یک لیست جامع و **صفحه‌بندی شده** از تمام رزروهای ثبت شده در سیستم مرکزی (Hub) را برمی‌گرداند. برای هر رزرو، اطلاعات از جداول مختلفی مانند `offices`، `factor_items`، `colleagues`، و `wallet` استخراج و با داده‌های اصلی ادغام می‌شود تا یک خروجی کامل و غنی‌شده ارائه دهد.

<div class="api-docs" id="bkmrk-"></div>## Request Overview

<div class="api-docs" id="bkmrk-url%3A-%2Fv2%2Fcore%2Fhub%2Fre"><div class="endpoint-info"><div>**URL:** `/v2/core/hub/reservation`</div><div>**Method:** <span class="method-get">GET</span></div><div>**Controller:** HubController@hubReservation</div><div>**Middleware:** authWithJwt</div></div></div>## Access Control

<div class="api-docs" id="bkmrk-%D9%86%DB%8C%D8%A7%D8%B2-%D8%A8%D9%87-%D8%AA%D9%88%DA%A9%D9%86-%D8%A7%D8%AD%D8%B1%D8%A7%D8%B2-%D9%87">- نیاز به توکن احراز هویت (JWT) دارد.

</div>## Query Parameters (Custom Pagination)

این اندپوینت از یک ساختار صفحه‌بندی سفارشی استفاده می‌کند که معمولاً توسط کتابخانه‌های جدولی مانند (jQuery DataTables) ارسال می‌شود. پارامترها باید در یک آبجکت به نام `paginate` ارسال شوند.

<div class="api-docs" id="bkmrk-field-type-descripti"><table class="schema-table" dir="rtl"><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>paginate\[length\]</td><td>integer</td><td>**(الزامی)** تعداد آیتم‌های مورد نظر در هر صفحه.</td></tr><tr><td>paginate\[start\]</td><td>integer</td><td>**(الزامی)** آفست (offset) شروع رکوردها. برای صفحه اول `0`، برای صفحه دوم (با length=10)، `10` و به همین ترتیب.</td></tr></tbody></table>

</div>**Example URL:** `/v2/core/hub/reservation?paginate[length]=15&paginate[start]=0`

<div class="api-docs" id="bkmrk--1"></div>## Logic Details

فرآیند دریافت و پردازش رزروها بسیار گسترده است و شامل مراحل زیر می‌شود:

<div class="api-docs" id="bkmrk-%DA%A9%D9%88%D8%A6%D8%B1%DB%8C-%D8%A7%D9%88%D9%84%DB%8C%D9%87-%D9%88-%D8%B5%D9%81%D8%AD%D9%87%E2%80%8C%D8%A8">1. **کوئری اولیه و صفحه‌بندی:**
    - یک کوئری اصلی به جدول `hub_reservation` زده می‌شود.
    - این کوئری با جدول `offices` بر اساس `hub_reservation.branch` جوین می‌شود تا نام فارسی شعبه (`brand_fa`) استخراج شود.
    - نتایج بر اساس `id` به صورت نزولی مرتب می‌شوند.
    - با استفاده از پارامترهای `length` و `start`، صفحه‌بندی سفارشی روی نتایج اعمال می‌شود.
2. **حلقه غنی‌سازی داده‌ها (Data Enrichment Loop):**
    - سیستم روی هر یک از رزروهای برگشتی از کوئری اصلی، یک حلقه اجرا کرده و برای هرکدام، مجموعه‌ای از عملیات و کوئری‌های اضافی را انجام می‌دهد:
    - **نکته عملکردی (Performance Consideration):** این رویکرد (کوئری در حلقه) به مشکل **N+1 Query** منجر می‌شود و ممکن است با افزایش تعداد آیتم‌ها در هر صفحه، عملکرد را تحت تأثیر قرار دهد.
3. **مراحل داخل حلقه برای هر رزرو:**
    1. **واکشی آیتم فاکتور:** از جدول `factor_items`، آیتم مربوط به رزرو (`item_id`) واکشی می‌شود. اگر آیتم یافت نشود، کل آن رزرو از خروجی نهایی **حذف می‌شود**.
    2. **واکشی نام سرویس‌ها:** شناسه‌های عددی `service` و `sub_service` با اجرای کوئری روی جدول `colleagues` به نام متنی (فیلد `office`) تبدیل می‌شوند.
    3. **تولید عنوان آیتم (`title_item`):** با فراخوانی متد پیچیده `TradeController::getReferenceItemTitle`، یک عنوان توصیفی و قابل فهم برای آیتم (مانند "هواپیما تهران به مشهد | ۱۴۰۴/۰۹/۱۸ ۱۲:۳۰") تولید می‌شود. این متد به شدت از **کش Redis** برای بهینه‌سازی عملکرد استفاده می‌کند.
    4. **واکشی اطلاعات اپراتور:** با فراخوانی متد `StaticController::getOperators`، شناسه اپراتور به یک آبجکت کامل شامل نام، نام خانوادگی و سایر مشخصات تبدیل می‌شود. در صورت عدم وجود اپراتور، مقدار `false` بازگردانده می‌شود.
    5. **پردازش فیلدهای JSON:** رشته‌های JSON موجود در فیلدهای `supplier_details` و `details` به آبجکت/آرایه تبدیل می‌شوند.
    6. **ضمیمه کردن داده‌های جدید:** اطلاعات پردازش شده (نام سرویس، عنوان، اطلاعات اپراتور و...) به آبجکت اصلی رزرو اضافه می‌شوند.
    7. **بررسی استرداد (Refund):** سیستم در جدول `wallet` جستجو می‌کند تا ببیند آیا تراکنش استردادی (`target_type='refund'`) برای این رزرو ثبت شده است یا خیر. در صورت وجود، جزئیات آن به فیلد `refund` اضافه می‌شود؛ در غیر این صورت، این فیلد مقدار `false` می‌گیرد.

</div>## Response Structure

### پاسخ موفق

<div class="api-docs" id="bkmrk-status-code%3A-200-ok-">- **Status Code:** `200 OK`
- فیلد `items` حاوی آرایه‌ای از آبجکت‌های رزرو غنی‌شده است.
- فیلد `meta.table` حاوی جزئیات کامل صفحه‌بندی است.

</div>```json
{
    "items": [
        {
            "id": 12345,
            "branch": "آژانس تابان", // از جدول offices
            "item_id": 54321,
            "operator": { // از متد getOperators
                "id": 101,
                "text": "1100 - علی اکبری",
                "query": { /* ... details ... */ }
            },
            "service": "Ghasreshirin", // نام تبدیل شده
            "sub_service": "Parsian System", // نام تبدیل شده
            "supplier_details": { /* آبجکت JSON */ },
            "details": { /* آبجکت JSON */ },
            "status": "issued",
            "created_at": "2025-12-09T12:00:00.000000Z",
            
            // --- Fields added in the loop ---
            "title_item": "هواپیما تهران به مشهد | ۱۴۰۴/۰۹/۱۸ ۱۲:۳۰ | W5065 | ماهان", // از getReferenceItemTitle
            "item": { // آبجکت کامل از factor_items
                "id": 54321,
                "product": "online",
                "byproduct": "aircraft",
                "details": { /* ... */ },
                "buy": 5400000,
                "sell": 5500000
                /* ... */
            },
            "refund": { // یا false اگر وجود نداشته باشد
                "id": 789,
                "credit": 5000000,
                "description": "استرداد بابت کنسلی پرواز"
            }
        }
    ],
    "meta": {
        "timestamp": 1733737200,
        "table": {
            "total": 500,
            "per_page": 15,
            "current_page": 1,
            "last_page": 34,
            "from": 1,
            "to": 15
        }
    }
}
```

<div class="api-docs" id="bkmrk--2"></div>## Flowchart

<div class="api-docs" id="bkmrk-start-request-%28get-%2F"><div class="flowchart"><div class="flow-item">Start Request (GET /v2/core/hub/reservation)</div><div class="flow-arrow">↓</div><div class="flow-item-process" style="background-color: #e3f2fd;">Execute Paginated Query on `hub_reservation` with JOIN on `offices`.  
(Using custom `start`/`length` params)</div><div class="flow-arrow">↓</div><div class="flow-item-loop">**For each reservation in results:**<div class="flow-sub-item"><div class="flow-item-process">Query `factor_items` using `item_id`</div><div class="flow-arrow">↓</div><div class="flow-item-decision">Item Found?</div><div style="position: relative;"><div class="flow-arrow-label-left" style="top: -20px; left: -30px;">No</div><div class="flow-item-process" style="float: left; margin-left: -130px; background-color: #ffcdd2;">Skip to next reservation</div></div><div class="flow-arrow">↓ (Yes)</div><div class="flow-item-process">Query `colleagues` for Service &amp; Sub-Service names</div><div class="flow-arrow">↓</div><div class="flow-item-process">Call `getReferenceItemTitle` (Cached Title Generation)</div><div class="flow-arrow">↓</div><div class="flow-item-process">Call `getOperators` to format operator data</div><div class="flow-arrow">↓</div><div class="flow-item-process">Query `wallet` to find refund details</div><div class="flow-arrow">↓</div><div class="flow-item-process" style="background-color: #e8f5e9;">Assemble all new data into the final reservation object</div></div></div><div class="flow-arrow">↓</div><div class="flow-item-success">Return 200 OK with `items` array &amp; `meta.table`</div></div></div>