# POST /v2/charter/reservation/temporary

# Charter: Create Temporary Reservation (Lock)

این اندپوینت برای ایجاد یک "رزرو موقت" یا "قفل" روی ظرفیت یک آیتم چارتر (مانند صندلی پرواز یا اتاق هتل) برای یک مدت زمان مشخص (به دقیقه) طراحی شده است. هدف اصلی آن جلوگیری از فروش همزمان یک ظرفیت توسط چند کاربر است. منطق این اندپوینت بر اساس نوع چارتر (`type`) به دو شاخه اصلی تقسیم می‌شود: اقامتگاهی (`accommodation`) و غیر اقامتگاهی (مانند مسیر `route`).

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

<div class="api-docs" id="bkmrk-url%3A-%2Fv2%2Fcharter%2Fres"><div class="endpoint-info"><div>**URL:** `/v2/charter/reservation/temporary`</div><div>**Method:** <span class="method-post">POST</span></div><div>**Controller:** CharterController@storeTemporaryCharterReservation</div><div>**Middleware Stack:** authWithJwt</div></div></div>## Access Control

<div class="api-docs" id="bkmrk-%D8%AF%D8%B3%D8%AA%D8%B1%D8%B3%DB%8C-%D9%85%D8%B9%D8%AA%D8%A8%D8%B1-jwt">- دسترسی معتبر JWT

</div>## Request Body (JSON)

ساختار بدنه درخواست شامل اطلاعات عمومی قفل و دو شیء کلیدی `requester` و `capacity` است که ساختار `capacity` بسته به نوع چارتر متفاوت است.

<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>main\_id</td><td>integer</td><td>**(الزامی)** شناسه چارتر اصلی (از جدول `charters`). برای تشخیص نوع چارتر استفاده می‌شود.</td></tr><tr><td>item\_id</td><td>integer</td><td>**(الزامی)** شناسه آیتم خاص چارتر (مثلاً شناسه یک پرواز یا یک نوع اتاق).</td></tr><tr><td>branch</td><td>integer</td><td>**(الزامی)** شناسه شعبه رزرو کننده. این مقدار از درخواست دریافت می‌شود.</td></tr><tr><td>operator</td><td>object</td><td>**(تزریق شده)** این شیء توسط میدلور `authWithJwt` به درخواست اضافه می‌شود. شناسه اپراتور (`operator.id`) برای ثبت رزرو کننده استفاده می‌شود.</td></tr><tr><td>requester</td><td>object</td><td>**(الزامی)** شیء حاوی اطلاعات درخواست کننده نهایی.  
ساختار: `{ "type": string, "id": integer }`</td></tr><tr><td>duration</td><td>integer</td><td>**(الزامی)** مدت زمان اعتبار قفل به **دقیقه**. پس از این زمان، قفل به صورت خودکار منقضی می‌شود.</td></tr><tr><td>description</td><td>string</td><td>(اختیاری) توضیحات مربوط به این رزرو موقت.</td></tr><tr><td>checkin\_date</td><td>string</td><td>(شرطی) تاریخ ورود با فرمت `YYYY-MM-DD`. **فقط برای چارترهای اقامتگاهی الزامی است.**</td></tr><tr><td>checkout\_date</td><td>string</td><td>(شرطی) تاریخ خروج با فرمت `YYYY-MM-DD`. **فقط برای چارترهای اقامتگاهی الزامی است.**</td></tr><tr><td>capacity</td><td>object</td><td>**(الزامی)** شیء حاوی تعداد ظرفیت درخواستی. ساختار آن بسته به نوع چارتر تغییر می‌کند.</td></tr></tbody></table>

</div>#### ساختار شیء `capacity`

\- **برای چارترهای غیر اقامتگاهی (`route`, ...):**

```json
{
  "capacity": {
    "adult": 2,
    "child": 1,
    "infant": 0
  }
}
```

\- **برای چارترهای اقامتگاهی (`accommodation`):**

```json
{
  "capacity": {
    "room": 3
  }
}
```

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

پس از دریافت درخواست، سیستم ابتدا نوع چارتر را با کوئری زدن به جدول `charters` از روی `main_id` تشخیص می‌دهد. سپس منطق بر اساس نوع چارتر اجرا می‌شود.

### ۱. منطق برای چارتر اقامتگاهی (Accommodation)

این حالت پیچیده‌تر است و نیازمند بررسی دقیق ظرفیت اتاق‌ها در بازه زمانی مشخص است.

<div class="api-docs" id="bkmrk-%D9%81%D8%B1%D8%A7%D8%AE%D9%88%D8%A7%D9%86%DB%8C-%D8%AA%D8%A7%D8%A8%D8%B9-%DA%A9%D9%85%DA%A9%DB%8C%3A-">- **فراخوانی تابع کمکی:** متد `ReservationController::getAccommodationRooms` با پارامترهای `item_id`، `checkin_date` و `checkout_date` فراخوانی می‌شود.
- **عملکرد `getAccommodationRooms`:**
    1. تمام اتاق‌های فیزیکی مرتبط با آیتم (`calc\_id`) را از جدول `charter_accommodation_rooms` استخراج می‌کند.
    2. برای هر اتاق، در تمام طول بازه زمانی درخواستی (از `checkin` تا یک روز قبل از `checkout`) بررسی می‌کند که آیا اتاق در آن تاریخ خاص آزاد است یا خیر.
    3. یک اتاق در یک تاریخ خاص "اشغال" محسوب می‌شود اگر: 
        - در یک رزرو قطعی (`charter\_reservation\_accommodation\_rooms`) ثبت شده باشد.
        - تحت یک گارانتی فعال (`charter\_warranties`) باشد.
        - در یک رزرو موقت دیگر (قفل) که هنوز منقضی نشده (`charter\_temporary\_reservation`) قرار داشته باشد.
    4. در نهایت، لیستی از اتاق‌هایی را برمی‌گرداند که در **تمام روزهای بازه درخواستی** آزاد هستند (`available\_all\_dates`).
    
    **نکته مهم:** کد کنترلر فعلی فقط از خروجی `available_all_dates` استفاده می‌کند و قابلیت‌های پیچیده‌تر تابع (مانند ترکیب اتاق‌های مختلف برای یک اقامت) را به کار نمی‌گیرد.
- **بررسی ظرفیت:** سیستم تعداد اتاق‌های کاملاً آزاد (`count($charterRooms\['available\_all\_dates'\])`) را با تعداد اتاق‌های درخواستی (`$request-&gt;capacity\['room'\]`) مقایسه می‌کند.
- **در صورت وجود ظرفیت کافی:**
    - به تعداد اتاق‌های درخواستی، یک حلقه تکرار می‌شود.
    - در هر تکرار، یک رکورد رزرو موقت مجزا برای یکی از اتاق‌های آزاد ایجاد می‌شود. یعنی اگر ۳ اتاق درخواست شود، ۳ رکورد مجزا در جدول `charter_temporary_reservation` درج خواهد شد که هر کدام به یک `room\_id` متفاوت اشاره دارند.
    - این رکوردها به صورت دسته‌ای (Bulk Insert) در پایگاه داده ذخیره می‌شوند.
- **در صورت عدم وجود ظرفیت کافی:** عملیات متوقف شده و یک پاسخ خطا با پیام "اتاق خالی به تعداد درخواست شده در بازه زمانی مورد نظر وجود ندارد." بازگردانده می‌شود.

</div>### ۲. منطق برای چارتر غیر اقامتگاهی (Route)

این حالت بسیار ساده‌تر است و مبتنی بر اعتماد به درخواست‌دهنده است.

<div class="api-docs" id="bkmrk-%D8%B9%D8%AF%D9%85-%D8%A8%D8%B1%D8%B1%D8%B3%DB%8C-%D8%B8%D8%B1%D9%81%DB%8C%D8%AA%3A-%D8%AF%D8%B1-">- **عدم بررسی ظرفیت:** در این حالت، API هیچ‌گونه بررسی ظرفیتی انجام نمی‌دهد و فرض می‌کند که ظرفیت لازم قبلاً در سمت کلاینت (UI) بررسی شده است.
- مقادیر `adult`، `child` و `infant` از شیء `capacity` به داده‌های آماده برای درج اضافه می‌شوند.
- یک رکورد **واحد** در جدول `charter_temporary_reservation` با استفاده از `insertGetId` درج می‌شود.
- شناسه رکورد درج شده (`$id`) با عدد `20,000` جمع شده و در پاسخ بازگردانده می‌شود. این یک قانون تجاری برای متمایز کردن شناسه‌های رزرو موقت است.

</div>## Response Structure

مشابه اندپوینت قبلی، این API نیز در همه موارد (موفقیت یا شکست) کد وضعیت `200 OK` را به همراه یک بدنه JSON برمی‌گرداند.

### پاسخ موفق (چارتر اقامتگاهی)

<div class="api-docs" id="bkmrk-status-code%3A-200-ok-">- **Status Code:** `200 OK`
- **Body:**```json
    {
      "status": true,
      "time": 1733285100
    }
    ```

</div>### پاسخ موفق (چارتر غیر اقامتگاهی)

<div class="api-docs" id="bkmrk-status-code%3A-200-ok--1">- **Status Code:** `200 OK`
- **Body:**```json
    {
      "status": true,
      "time": 1733285105,
      "data": 20123
    }
    ```
    
    **توجه:** مقدار `data` همان شناسه رکورد درج شده در پایگاه داده به علاوه `20,000` است.

</div>### پاسخ خطا (ظرفیت ناکافی در چارتر اقامتگاهی)

<div class="api-docs" id="bkmrk-status-code%3A-200-ok--2">- **Status Code:** `200 OK`
- **Body:**```json
    {
      "status": false,
      "time": 1733285110,
      "message": "اتاق خالی به تعداد درخواست شده در بازه زمانی مورد نظر وجود ندارد."
    }
    ```

</div>### پاسخ خطا (استثنای عمومی)

<div class="api-docs" id="bkmrk-status-code%3A-200-ok--3">- **Status Code:** `200 OK`
- **Body:**```json
    {
      "status": false,
      "time": 1733285115,
      "message": "An error occurred ...",
      "trace": [ ... ]
    }
    ```

</div>## Flowchart

<div class="api-docs" id="bkmrk-start-%28post-%2Freserva"><div class="flowchart"><div class="flow-item">Start (POST /reservation/temporary)</div><div class="flow-arrow">↓</div><div class="flow-item">Receive Request Body</div><div class="flow-arrow">↓</div><div class="flow-item-process" style="background-color: #e3f2fd;">Fetch charter `type` from DB using `main_id`</div><div class="flow-arrow">↓</div><div class="flow-decision" style="background-color: #fff9c4;">Is `type` == 'accommodation'?</div><div class="flow-split"><div class="flow-path"><div class="flow-arrow">↓ Yes</div><div class="flow-item-process" style="background-color: #e3f2fd;">Call `getAccommodationRooms` to find fully available rooms</div><div class="flow-arrow">↓</div><div class="flow-decision" style="background-color: #fff9c4;">Available rooms &gt;= Requested rooms?</div><div class="flow-split"><div class="flow-path"><div class="flow-arrow">↓ Yes</div><div class="flow-item-process" style="background-color: #e8f5e9;">Create &amp; Bulk Insert one record per requested room</div><div class="flow-arrow">↓</div><div class="flow-item-success">Return Success (no data)</div></div><div class="flow-path"><div class="flow-arrow">↓ No</div><div class="flow-item-error">Return Error (Capacity Message)</div></div></div></div><div class="flow-path"><div class="flow-arrow">↓ No</div><div class="flow-item-process" style="background-color: #e8f5e9;">1. Add seat counts to data  
2. Insert single record &amp; Get ID</div><div class="flow-arrow">↓</div><div class="flow-item-success">Return Success (with `data = ID + 20000`)</div></div></div></div></div>