# GET /v2/core/hub/analyze

# Hub: Flight Reservation Analysis

این اندپوینت یک گزارش تحلیلی جامع از تمام رزروهای **پرواز آنلاین** (`product='online'`, `byproduct='aircraft'`) ارائه می‌دهد. داده‌ها بر اساس **سال شمسی**، **تأمین‌کننده (Supplier)**، و **تأمین‌کننده سیستمی (System Supplier)** دسته‌بندی و agregare می‌شوند. خروجی شامل تعداد کل رزروها و مجموع مبالغ خرید در هر دسته‌بندی است.

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

<div class="api-docs" id="bkmrk-url%3A-%2Fv2%2Fcore%2Fhub%2Fan"><div class="endpoint-info"><div>**URL:** `/v2/core/hub/analyze`</div><div>**Method:** <span class="method-get">GET</span></div><div>**Controller:** HubController@hubAnalysis</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) دارد.
- این گزارش به صورت سراسری (Global) است و به شعبه کاربر لاگین کرده محدود نمی‌شود.

</div>## Logic Details

فرآیند تحلیل داده‌ها در این اندپوینت طی چندین مرحله پیچیده انجام می‌شود:

<div class="api-docs" id="bkmrk-%D8%A7%D8%B3%D8%AA%D8%AE%D8%B1%D8%A7%D8%AC-%D8%AF%D8%A7%D8%AF%D9%87%E2%80%8C%D9%87%D8%A7%DB%8C-%D8%A7%D9%88%D9%84">1. **استخراج داده‌های اولیه:**
    - یک کوئری به جدول `factor_items` ارسال می‌شود تا تمام رکوردهایی که دارای شرایط زیر هستند، استخراج شوند: 
        - `product` برابر با `'online'`
        - `byproduct` برابر با `'aircraft'`
    - نتایج بر اساس `id` به صورت نزولی (`DESC`) مرتب می‌شوند تا ابتدا جدیدترین رزروها پردازش شوند.
2. **پردازش تک‌تک رزروها:**
    - سیستم در یک حلقه (loop) تمام رزروهای استخراج شده را پیمایش می‌کند.
    - برای هر رزرو، فیلد `details` که یک رشته JSON است، به آرایه PHP تبدیل می‌شود.
    - **اعتبارسنجی حیاتی:** سیستم بررسی می‌کند که آیا مسیر `$details['Book']['DepartureSegment']` در آبجکت JSON وجود دارد یا نه. اگر وجود نداشته باشد، آن رزرو از فرآیند تحلیل **حذف شده** و حلقه به تکرار بعدی می‌رود.
3. **گروه‌بندی و تجمیع داده‌ها (Aggregation):**
    - **استخراج تاریخ:** سال و ماه شمسی از فیلد `created_at` رزرو با استفاده از `CalendarUtils::strftime` استخراج می‌شود (مثلاً `1404-09`).
    - **استخراج تأمین‌کنندگان:** شناسه‌های `Supplier` و `SystemSupplier` از آبجکت `DepartureSegment` خوانده می‌شوند.
    - **کش کردن نام تأمین‌کننده:**
        - برای جلوگیری از کوئری‌های تکراری به دیتابیس، یک آرایه به نام `$colleagues` به عنوان کش داخلی عمل می‌کند.
        - هر بار که یک شناسه تأمین‌کننده جدید یافت می‌شود، سیستم یک بار به جدول `colleagues` کوئری می‌زند تا نام دفتر (`office`) را پیدا کند.
        - اگر نام دفتر پیدا شود، در کش ذخیره می‌شود. در غیر این صورت، خود **شناسه تأمین‌کننده** به عنوان نام پیش‌فرض استفاده می‌شود.
    - **افزایش شمارنده‌ها:** برای هر رزرو معتبر، شمارنده‌های `count` (تعداد) و `paid` (مجموع مبلغ خرید از فیلد `buy`) در سطوح مختلف ساختار داده افزایش می‌یابند: 
        1. مجموع کل (Grand Total)
        2. مجموع کل سال مربوطه
        3. مجموع کل تأمین‌کننده (Supplier) در آن سال
        4. مجموع ماهانه تأمین‌کننده (Supplier) در آن سال
        5. همین فرآیند به طور موازی برای تأمین‌کننده سیستمی (System Supplier) نیز تکرار می‌شود.
4. **ساختار نهایی خروجی:**
    - نتیجه نهایی یک آبجکت بسیار تودرتو است که داده‌ها را به تفکیک سال، تأمین‌کننده، و ماه نمایش می‌دهد.
    - این آبجکت در فیلد `payload` پاسخ نهایی قرار می‌گیرد.

</div>## Response Structure

### پاسخ موفق

<div class="api-docs" id="bkmrk-status-code%3A-200-ok-">- **Status Code:** `200 OK`
- ساختار خروجی بسیار تودرتو است. کلیدهای آبجکت‌های `years`، `suppliers`، `system_suppliers` و `months` به ترتیب شناسه‌های سال، تأمین‌کننده، و ماه هستند.

</div>```json
{
    "payload": {
        "years": {
            "1404": { // سال شمسی
                "suppliers": {
                    "55": { // شناسه Supplier
                        "id": 55,
                        "title": "Ghasreshirin", // نام استخراج شده از جدول colleagues
                        "total": {
                            "count": 10, // کل رزروها از این Supplier در سال 1404
                            "paid": 95000000 // مجموع خرید از این Supplier در سال 1404
                        },
                        "months": {
                            "08": { // ماه شمسی
                                "total": {
                                    "count": 4,
                                    "paid": 38000000
                                }
                            },
                            "09": {
                                "total": {
                                    "count": 6,
                                    "paid": 57000000
                                }
                            }
                        }
                    }
                },
                "system_suppliers": {
                    "10": { // شناسه SystemSupplier
                        "id": 10,
                        "title": "Parsian System",
                        "total": {
                            "count": 10, // کل رزروها از این SystemSupplier در سال 1404
                            "paid": 95000000
                        },
                        "months": {
                            "08": { /* ... */ },
                            "09": { /* ... */ }
                        }
                    }
                },
                "total": { // مجموع کل برای سال 1404
                    "count": 10,
                    "paid": 95000000
                }
            }
        },
        "total": { // مجموع کل در تمام سال‌ها
            "count": 10,
            "paid": 95000000
        }
    },
    "meta": {
        "timestamp": 1733736600
    }
}
```

<div class="api-docs" id="bkmrk--1"></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/analyze)</div><div class="flow-arrow">↓</div><div class="flow-item-process" style="background-color: #e3f2fd;">Query `factor_items` WHERE `product`='online' AND `byproduct`='aircraft'</div><div class="flow-arrow">↓</div><div class="flow-item-process">Initialize `analyze` &amp; `colleagues` arrays</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">Decode `details` JSON</div><div class="flow-arrow">↓</div><div class="flow-item-decision">`details['Book']['DepartureSegment']` exists?</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;">Continue to next reservation</div></div><div class="flow-arrow">↓ (Yes)</div><div class="flow-item-process">Extract Year, Month, Supplier IDs</div><div class="flow-arrow">↓</div><div class="flow-item-decision">Is Supplier ID new?</div><div class="flow-arrow">↓ (Yes)</div><div class="flow-item-process" style="background-color: #fff9c4;">Query `colleagues` table &amp; cache the title</div><div class="flow-arrow">↓</div><div class="flow-item-process" style="background-color: #e8f5e9;">**Aggregate Data:**  
Increment `count` &amp; `paid` at all levels (Grand, Year, Supplier, Month) for both Supplier &amp; SystemSupplier</div></div></div><div class="flow-arrow">↓</div><div class="flow-item-success">Return 200 OK with `payload`</div></div></div>