Skip to main content
#P1398

POST /api/v2/trade/cost-benefit

اطلاعات مسیر (Route Info)

Method Endpoint Controller Middleware Purpose
POST /api/v2/trade/cost-benefit V2TradeController@costBenefit authWithJwt گزارش‌گیری سود و زیان معاملات در بازه زمانی دلخواه با تفکیک گروهی

منطق عملکرد

تابع costBenefit گزارش تحلیلی از عملکرد مالی را با معیارهای supplier، provider، operator، income و route تولید می‌کند. روند اجرا به‌ترتیب زیر است:
  • دریافت بدنه درخواست با پارامتر json و دیکود آن به آبجکت $Data.
  • محاسبه بازه زمانی بر اساس from و to؛ اگر تعیین نشده باشد، از اول ماه جاری تا امروز.
  • واکشی معاملات (فاکتورها) از جدول factors با شرط مشتری غیر‌ تهی و وضعیت معتبر (غیر از ۲ و ۵).
  • دریافت جزئیات مالی هر فاکتور از Redis (کلیدهای reference:{id}:information و reference:{id}:pledgers). در صورت عدم وجود در کش، با متد ApiTradeController::financial تولید و ذخیره می‌شود.
  • بر اساس مقدار $Data->action، محاسبات مربوط به گروه هدف انجام می‌شود. برای هر گروه:
    • تولید ساختار مالی شامل فیلدهای خرید، فروش، سود، مزد، بدهکار، بستانکار و مسافر.
    • به‌روزرسانی شمارنده‌ها و جمع کل اعداد در آرایه‌های Total* و CountReferences*.
    • ذخیره‌سازی نتایج در آرایه دو سطحی $items.
  • در انتها، داده‌ها برای رسم نمودارها (bar و treemap) ساختاردهی می‌شود، شامل categories، ‌count_references، count_passengers، و count_profit.
  • نتایج نهایی در قالب آرایه خروجی شامل کل‌ها و داده‌های تفکیک‌شده بازمی‌گردد.

ورودی‌ها (Request Parameters)

فیلد نوع ضروری توضیح
json JSON string بله شیء شامل زیرپارامترهای تحلیل عملکرد
branch int بله شناسه شعبه مورد بررسی

ساختار نمونه محتوای json:

{
  "from": "2025-10-01",
  "to": "2025-10-31",
  "action": "all"
}

خروجی (Response Structure)

فیلد نوع توضیح
total object اطلاعات تجمیعی نهایی برای هر گروه (سو‌د، خرید، فروش، بدهکاری، بستانکاری و...)
chart object داده‌های پردازش‌شده برای نمودارهای آماری (bar و treemap)
data array|false لیست آیتم‌های تفکیک‌شده بر اساس نوع تحلیل (supplier/provider/route/...)
diff array لیست شناسه‌هایی که اطلاعات Provider آنها ناقص بوده است
search object بازه زمانی اعمال‌شده بر اساس ورودی (شیء شامل from و to)

نمونه پاسخ موفق:

{
  "total": {
    "provider": {
      "Buy": 54000000,
      "Sale": 69800000,
      "Profit": 12000000,
      "Wage": 2000000,
      "Debit": 32000000,
      "Credit": 12000000,
      "Passenger": 48,
      "References": 17
    },
    ...
  },
  "chart": {
    "provider": {
      "categories": ["آژانس الف", "آژانس ب"],
      "count_references": [17, 13],
      "count_passengers": [48, 32],
      "count_profit": [1.2, 0.9],
      "treemap": {
        "international": {"name":"international","data":[{"x":"آژانس الف","y":1.2}]}
      }
    }
  },
  "data": {...},
  "diff": [],
  "search": {"from":"2025-10-01T00:00:00Z","to":"2025-10-31T23:59:59Z"}
}

جریان داده (Data Flow)

  1. ورود درخواست با JSON شامل بازه و نوع تحلیل.
  2. خواندن فاکتورها از DB (با branch و زمان) → select(id,operator,created_at).
  3. واکشی مالی از Redis → اگر خالی بود: ApiTradeController::financial() اجرا و ذخیره می‌شود.
  4. واکشی تعهدها (pledgers) از DB یا Redis.
  5. محاسبات تفکیکی مالی برای بخش‌های فعال.
  6. تجمیع اعداد کل در آرایه‌های Total*.
  7. تولید گزارش نهایی شامل دسته‌بندی‌ها و داده‌های نموداری.

عملکرد و کش

  • Redis به‌عنوان منبع موقت کل داده‌های مالی فاکتور مورد ‌استفاده است (reference:{id}:information و pledgers).
  • TTL برای کلیدها تنظیم نشده است → داده‌ها انباشته می‌شوند و حافظه Redis سریع پر می‌شود.
  • هر بار اجرای full analysis می‌تواند چند هزار hit روی Redis داشته باشد.
  • کش عنوان درآمد (accounting:title:trade_income) به‌شکل shared global نگهداری می‌شود.

امنیت و کنترل ورودی

  • ورود JWT الزامی است (middleware: authWithJwt).
  • ورودی JSON اعتبارسنجی نمی‌شود → احتمال Null reference و خطای Logic وجود دارد.
  • پارامتر branch می‌تواند از شعب غیرمجاز بیاید؛ پیشنهاد اعتبارسنجی با access levels داخلی.
  • عدم نوع‌دهی روی فیلدهای مالی در Redis می‌تواند منجر به حملات تزریق داده از کش آلوده شود.

Dependencies

  • use Carbon\Carbon;
  • use Morilog\Jalali\Jalalian;
  • use Illuminate\Support\Facades\Redis;
  • use App\Models\{Factor, Pledger, User, Colleague};
  • use App\Http\Controllers\Api\Panel\V2\ApiTradeController;
  • use App\Http\Controllers\Api\Panel\V2\StaticController;

خطاها و حالت‌های خاص

  • در صورت نبود بازه زمانی، از ابتدای ماه جاری استفاده می‌شود.
  • اگر financially ناقص باشد، داده در diff ثبت می‌شود.
  • اگر هیچ فاکتوری یافت نشود، پاسخ data=false بازمی‌گردد.
  • خطای Redis یا ناهمخوانی داده JSON ممکن است خطای 500 در runtime تولید کند.

پیچیدگی زمانی و منابع

مرحله O-Complexity
واکنش DB (Factor Select) O(N)
Redis Access O(2N)
تحلیل مالی nested O(N × M)
ترتیب‌دهی (usort) O(N log N)

پیشنهادهای بهینه‌سازی

  • تعریف TTL برای cache reference (مثلاً ۶ ساعت).
  • رباتیک‌سازی prefetch داده مالی در background jobs.
  • جداسازی ماژول گزارش از API اصلی برای جلوگیری از ایجاد latency در runtime.
  • استفاده از chunkRead برای فاکتورهای زیاد (بیش از ۱۰۰۰ رکورد).

جمع‌بندی

POST /api/v2/trade/cost-benefit قلب تپنده آنالیز مالی سیستم است. قدرتش در دقت آمار گروهی حک شده، اما ضعفش در عدم کنترل کش و تایپ‌ورودی‌هاست. در ساختار فعلی مناسب برای پردازش‌های تحلیلی آفلاین (batch job) است، نه اجرای زنده برای کاربران چندگانه.