Skip to main content
#P1679

POST /v2/charter/reservation/temporary

Charter: Create Temporary Reservation (Lock)

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

Request Overview

URL: /v2/charter/reservation/temporary
Method: POST
Controller: CharterController@storeTemporaryCharterReservation
Middleware Stack: authWithJwt

Access Control

  • دسترسی معتبر JWT

Request Body (JSON)

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

Field Type Description
main_id integer (الزامی) شناسه چارتر اصلی (از جدول charters). برای تشخیص نوع چارتر استفاده می‌شود.
item_id integer (الزامی) شناسه آیتم خاص چارتر (مثلاً شناسه یک پرواز یا یک نوع اتاق).
branch integer (الزامی) شناسه شعبه رزرو کننده. این مقدار از درخواست دریافت می‌شود.
operator object (تزریق شده) این شیء توسط میدلور authWithJwt به درخواست اضافه می‌شود. شناسه اپراتور (operator.id) برای ثبت رزرو کننده استفاده می‌شود.
requester object (الزامی) شیء حاوی اطلاعات درخواست کننده نهایی.
ساختار: { "type": string, "id": integer }
duration integer (الزامی) مدت زمان اعتبار قفل به دقیقه. پس از این زمان، قفل به صورت خودکار منقضی می‌شود.
description string (اختیاری) توضیحات مربوط به این رزرو موقت.
checkin_date string (شرطی) تاریخ ورود با فرمت YYYY-MM-DD. فقط برای چارترهای اقامتگاهی الزامی است.
checkout_date string (شرطی) تاریخ خروج با فرمت YYYY-MM-DD. فقط برای چارترهای اقامتگاهی الزامی است.
capacity object (الزامی) شیء حاوی تعداد ظرفیت درخواستی. ساختار آن بسته به نوع چارتر تغییر می‌کند.

ساختار شیء `capacity`

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

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

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

{
  "capacity": {
    "room": 3
  }
}

Logic Details

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

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

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

  • فراخوانی تابع کمکی: متد 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->capacity['room']`) مقایسه می‌کند.
  • در صورت وجود ظرفیت کافی:
    • به تعداد اتاق‌های درخواستی، یک حلقه تکرار می‌شود.
    • در هر تکرار، یک رکورد رزرو موقت مجزا برای یکی از اتاق‌های آزاد ایجاد می‌شود. یعنی اگر ۳ اتاق درخواست شود، ۳ رکورد مجزا در جدول charter_temporary_reservation درج خواهد شد که هر کدام به یک `room_id` متفاوت اشاره دارند.
    • این رکوردها به صورت دسته‌ای (Bulk Insert) در پایگاه داده ذخیره می‌شوند.
  • در صورت عدم وجود ظرفیت کافی: عملیات متوقف شده و یک پاسخ خطا با پیام "اتاق خالی به تعداد درخواست شده در بازه زمانی مورد نظر وجود ندارد." بازگردانده می‌شود.

۲. منطق برای چارتر غیر اقامتگاهی (Route)

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

  • عدم بررسی ظرفیت: در این حالت، API هیچ‌گونه بررسی ظرفیتی انجام نمی‌دهد و فرض می‌کند که ظرفیت لازم قبلاً در سمت کلاینت (UI) بررسی شده است.
  • مقادیر adult، child و infant از شیء capacity به داده‌های آماده برای درج اضافه می‌شوند.
  • یک رکورد واحد در جدول charter_temporary_reservation با استفاده از `insertGetId` درج می‌شود.
  • شناسه رکورد درج شده ($id) با عدد 20,000 جمع شده و در پاسخ بازگردانده می‌شود. این یک قانون تجاری برای متمایز کردن شناسه‌های رزرو موقت است.

Response Structure

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

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

  • Status Code: 200 OK
  • Body:
    {
      "status": true,
      "time": 1733285100
    }

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

  • Status Code: 200 OK
  • Body:
    {
      "status": true,
      "time": 1733285105,
      "data": 20123
    }

    توجه: مقدار data همان شناسه رکورد درج شده در پایگاه داده به علاوه 20,000 است.

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

  • Status Code: 200 OK
  • Body:
    {
      "status": false,
      "time": 1733285110,
      "message": "اتاق خالی به تعداد درخواست شده در بازه زمانی مورد نظر وجود ندارد."
    }

پاسخ خطا (استثنای عمومی)

  • Status Code: 200 OK
  • Body:
    {
      "status": false,
      "time": 1733285115,
      "message": "An error occurred ...",
      "trace": [ ... ]
    }

Flowchart

Start (POST /reservation/temporary)
Receive Request Body
Fetch charter `type` from DB using `main_id`
Is `type` == 'accommodation'?
↓ Yes
Call `getAccommodationRooms` to find fully available rooms
Available rooms >= Requested rooms?
↓ Yes
Create & Bulk Insert one record per requested room
Return Success (no data)
↓ No
Return Error (Capacity Message)
↓ No
1. Add seat counts to data
2. Insert single record & Get ID
Return Success (with `data = ID + 20000`)