#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)
- ورود درخواست با JSON شامل بازه و نوع تحلیل.
- خواندن فاکتورها از DB (با branch و زمان) → select(id,operator,created_at).
- واکشی مالی از Redis → اگر خالی بود:
ApiTradeController::financial() اجرا و ذخیره میشود.
- واکشی تعهدها (pledgers) از DB یا Redis.
- محاسبات تفکیکی مالی برای بخشهای فعال.
- تجمیع اعداد کل در آرایههای Total*.
- تولید گزارش نهایی شامل دستهبندیها و دادههای نموداری.
عملکرد و کش
- 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) است، نه اجرای زنده برای کاربران چندگانه.