#P1396
POST /api/v2/trade/list
Route Info
| Method |
Endpoint |
Controller |
Middleware |
Purpose |
نسخه |
| POST |
/api/v2/trade/list |
V2TradeController@getTradesList |
authWithJwt |
نمایش فهرست معاملات (فاکتورها) با فیلترهای پیشرفته |
Enterprise V1.1 |
منطق عملکرد تابع
تابع
getTradesList لیست فاکتورها (تراکنشها / معاملات) را برای شعبهٔ جاری واکشی میکند. در ابتدا دادههای ورودی از پارامتر
json تجزیه میشوند؛ شامل تنظیمات DataTable مانند
start،
length،
draw و فیلترهای
advanced. اگر کاربر هیچ جستجویی انجام نداده باشد، سیستم بهصورت پیشفرض فقط فاکتورهای همان روز را نمایش میدهد. سپس مجموعهای از شرایط فیلترینگ اعمال میشود:
- فیلتر نوع پیشرفته (advanced) بر اساس شماره رزرو (
r)، محدوده تاریخ (from, to), اپراتور، وضعیت، شماره پرواز، وسیله، تعهدکننده، مسیر و درآمد.
- محاسبه و ترکیب چندین آرایهٔ ID برای محدودسازی نتایج:
$arr_id_fn, $arr_id_d, $arr_id_fu_d, $arr_id_p.
- اعمال محدودیت دسترسی (Access Control) بر اساس سطح دسترسی اپراتور از طریق تابع
Functions::getAccessUser('trade', ...).
- اتصال به Redis جهت کش (cache) اطلاعات مالی و تعهدکنندگان هر فاکتور با کلیدهای
reference:{id}:pledgers و reference:{id}:information.
- محاسبهٔ شاخصهای مالی کل برای لیست بازگشتی: مجموع خرید، فروش، سود، بدهی، بستانکاری، تخفیف، تسهیلات، تعداد مسافر.
- بازچینی داده برای هر معامله به صورت ساختارمند در قالب
items[] (جهت نمایش جدول).
- خروجی استاندارد DataTable-compatible شامل فیلدهای
draw, recordsTotal, recordsFiltered, total, و data[].
ورودیها (Request Fields)
| نام فیلد |
نوع داده |
الزامی |
توضیح |
| branch |
int|string |
بله |
شناسه شعبهای که اپراتور به آن متصل است |
| operator |
object |
بله |
شیء اپراتور استخراجشده از JWT |
| json |
object (JSON string) |
بله |
حاوی ساختار DataTable شامل start، length، draw و فیلترهای advanced |
ساختار فیلتر پیشرفته (advanced):
"advanced": {
"r": "", "from": "2025-01-01", "to": "2025-01-31",
"op": 0, "status": 1, "flightno": "W51123", "dt_departure": "2025-01-12",
"pledger": "colleague-42", "vehicle": "aircraft", "income": "", "route": ""
}
خروجی (Response)
| فیلد |
نوع داده |
توضیح |
| draw |
int |
شماره فراخوان DataTable |
| recordsTotal |
int |
تعداد کل فاکتورها مطابق فیلتر |
| recordsFiltered |
int |
تعداد پس از فیلترینگ |
| total |
object |
مجموع کل شاخصهای مالی (Buy, Sale, Profit, …) |
| data |
array |
آرایهای از معاملات شامل جزئیات Route، Operator، Pledger و Financial |
نمونه درخواست:
POST /api/v2/trade/list
Authorization: Bearer {JWT_TOKEN}
Content-Type: application/json
{
"branch": 8,
"json": {
"draw": 1,
"start": 0,
"length": 15,
"search": {"value": ""},
"advanced": {"from":"2025-01-01","to":"2025-01-31","status":"1"}
}
}
نمونه پاسخ:
{
"draw": 1,
"recordsTotal": 52,
"recordsFiltered": 52,
"total": {
"Buy": 9200000,
"Sale": 11300000,
"Profit": 2100000,
"Debit": 150000,
"Credit": 280000,
"Discount": 30000,
"Passenger": 91
},
"data": [ { "SerialId": 2048001, "Income":"direct", "RouteTitle":"پرواز تهران-کیش", ... } ]
}
امنیت و کنترل دسترسی
- لایهٔ امنیتی JWT توسط میدلور
AuthWithJWT، بررسی توکن و اعتبار کاربر از جداول مختلف (operators, customers, colleague_auth).
- اگر کاربر غیرفعال باشد یا JWT منقضی شده باشد → Error Code 1002 یا 1006.
- هیچ Permissions Role-Based دقیق برای فیلدهای مالی در Endpoint اعمال نمیشود، فقط سطح general access کنترل میشود.
- اطلاعات مالی از Redis کش خوانده شده و فاقد رمزنگاری است. خطر افشای اطلاعات مالی وجود دارد.
- هیچ validation روی ساختار داخلی
json اعمال نشده — ممکن است دادهٔ تزریقشده منجر به crash شود.
نکات کارایی و پیادهسازی
- پنج درخواست مجزا به DB در هر ثبت معامله (Factor + FactorItem + Pledger + Redis fetch/write).
- NULL caching در Redis هرگز منقضی نمیشود، حافظه بدون مدیریت رشد میکند.
- در صورت آغاز بدون فیلتر، تمام روز جاری اسکن میشود (query سنگین بدون ایندکس مناسب).
- محاسبههای مالی مجدد زمانی انجام میشود که Cache خالی باشد → افزایش CPU.
- درخواستهای موازی بدون کنترل Lock روی Redis باعث Out-of-sync در Cache میشود.
وابستگیها
- use Carbon\Carbon;
- use Morilog\Jalali\Jalalian;
- use Illuminate\Support\Facades\Redis;
- use Illuminate\Support\Facades\DB;
- use App\Models\{Factor, FactorItem, Pledger, User, Colleague};
- use App\Http\Controllers\Api\Panel\V2\ApiTradeController;
- use App\Http\Controllers\Api\Panel\V2\TradeController;
- use App\Http\Controllers\Api\Panel\V2\StaticController;
- use App\Helpers\Functions;
کدهای خطا و خروجیهای Exception
| کد خطا |
شرح |
منبع |
| 1005 |
Token not provided |
AuthWithJWT |
| 1006 |
Your token is invalid or expired |
AuthWithJWT |
| 1002 / 1003 / 1004 |
User does not have access permission |
AuthWithJWT |
| 500 |
Database / Redis Exception → Trace exposed |
V2TradeController@getTradesList |
پیشنهادهای امنیتی
- افزودن expiration به Redis cache (TTL 10m).
- قرار دادن validation برای json input و advanced filters.
- پنهانسازی جزئیات trace در پاسخ خطا.
- محدودسازی سطح اطلاعات مالی بر اساس Role.
پیشنهادهای بهبود
- Refactor منطق فیلترینگ در QueryBuilder جداگانه (TradeQueryService).
- ایجاد ایندکس ترکیبی روی فیلدهای
created_at، status و branch.
- استانداردسازی خروجی Financial در endpoint مستقل.
- کاهش حجم response با pagination سمت سرور واقعی (بدون pull تمام ستونها).
ممیزی دسترسی و عدم قطعیت
- دسترسیها با
Functions::getAccessUser کنترل میشوند اما audit در سطح route وجود ندارد.
- هیچ log مشخصی برای view یا export ثبت نمیشود؛ باید logViewTrade اضافه شود.
جمعبندی
این Endpoint یکی از مرکزیترین بخشهای سیستم حسابداری تجاری است. امنیت پایهای به لطف JWT حفظ شده اما حجم داده بزرگ، منطق فیلتر پیچیده و عدم validation ورودی میتواند منبع اشکالات عملکردی یا امنیتی شود. برای تبدیل این منطق به ساختار enterprise-grade، نیاز به جداسازی cache layer، اضافهکردن input schema validation و تعریف audit trail قطعی است.