From c17c7e68058a69fddf0bfac056c06a63087fd2a5 Mon Sep 17 00:00:00 2001 From: Amirmahdi Nourkazemi Date: Fri, 3 Jul 2026 17:21:45 +0330 Subject: [PATCH] feat: add purchase --- .claude/settings.json | 15 +++++++++ app/Http/Controllers/AdminController.php | 40 ++++++++++++++++++++++++ routes/api.php | 2 ++ 3 files changed, 57 insertions(+) create mode 100644 .claude/settings.json diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..fbabbde --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,15 @@ +{ + "permissions": { + "allow": [ + "Bash(php -l app/Http/Controllers/AdminController.php)", + "Bash(php -l routes/api.php)" + ], + "additionalDirectories": [ + "/Users/amirmahdi/StudioProjects/approagency-admin-panel/types", + "/Users/amirmahdi/StudioProjects/approagency-admin-panel/lib/api", + "/Users/amirmahdi/StudioProjects/approagency-admin-panel/app/admin/purchases", + "/Users/amirmahdi/StudioProjects/approagency-admin-panel/app/admin/dashboard", + "/Users/amirmahdi/Documents/bruno/private/collections/api-approagency/Admin" + ] + } +} diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php index 69b5528..d6b708f 100755 --- a/app/Http/Controllers/AdminController.php +++ b/app/Http/Controllers/AdminController.php @@ -5,6 +5,7 @@ use App\Models\OldPurchase; use App\Models\PackageName; use App\Models\Product; +use App\Models\Transaction; use App\Models\User; use App\Rules\MobileNumber; use Illuminate\Http\Request; @@ -30,6 +31,45 @@ public function users(Request $request) return $users; } + /** + * List all subscription purchases (transactions) across users, with + * filters for email, mobile (phone), package name and payment source + * (gateway). Returns paginated results with the related user, product + * and package eager-loaded for display in the admin panel. + */ + public function purchases(Request $request) + { + $data = $request->validate([ + 'per_page' => 'integer', + 'email' => 'string|nullable', + 'mobile' => 'string|nullable', + 'package_name' => 'string|nullable', + // payment source: accepts a gateway name (asanpardakht, zarinpal, + // digipay, cafe, myket) or its numeric code + 'gateway' => 'string|nullable', + 'status' => 'integer|nullable', + ]); + + // Resolve the payment source to its stored integer code + $gateway = null; + if (!empty($data['gateway'])) { + $gateway = Transaction::GATEWAYS[$data['gateway']] + ?? (is_numeric($data['gateway']) ? (int) $data['gateway'] : null); + } + + $purchases = Transaction::with(['user', 'product.packageName']) + ->when(!empty($data['email']), fn ($q) => $q->whereHas('user', fn ($u) => $u->where('email', 'like', '%' . $data['email'] . '%'))) + ->when(!empty($data['mobile']), fn ($q) => $q->whereHas('user', fn ($u) => $u->where('mobile', 'like', '%' . $data['mobile'] . '%'))) + ->when(!empty($data['package_name']), fn ($q) => $q->whereHas('product.packageName', fn ($p) => $p->where('name', $data['package_name']))) + ->when(!is_null($gateway), fn ($q) => $q->where('gateway', $gateway)) + ->when(isset($data['status']), fn ($q) => $q->where('status', $data['status'])) + ->latest() + ->paginate($data['per_page'] ?? 30) + ->withQueryString(); + + return $purchases; + } + public function getUserTransactions(Request $request, $identifier) { $data = $request->validate([ diff --git a/routes/api.php b/routes/api.php index 060175a..7a77d76 100755 --- a/routes/api.php +++ b/routes/api.php @@ -88,6 +88,8 @@ Route::get('/wallet', [WalletController::class, 'getWalletAdmin']); Route::post('/wallet', [WalletController::class, 'chargeWalletAdmin']); Route::get('/users', 'users'); + // All subscription purchases (transactions) with filters + Route::get('/purchases', 'purchases'); Route::post('/users/{mobile}/profile', 'updateUserProfile'); Route::delete('/users/{mobile}', 'deleteUser'); Route::get('/users/{mobile}/transactions', 'getUserTransactions');