user(); if (!$user) { return response()->json(['message' => 'Unauthorized'], 401); } $wallet = $user->wallet; if (!$wallet) { $wallet = Wallet::create([ 'user_id' => $user->id, 'balance' => 0, 'total_deposited' => 0, 'total_withdrawn' => 0, ]); } WalletActivityLog::log( $wallet, 'balance_viewed', 'مشاهده موجودی کیف پول', null, ['balance' => $wallet->balance], $user ); return response()->json([ 'balance' => $wallet->balance, 'total_deposited' => $wallet->total_deposited, 'total_withdrawn' => $wallet->total_withdrawn, 'is_frozen' => $wallet->isFrozen(), 'currency' => 'IRR', ]); } /** * لیست تراکنش‌های کاربر (paginated) */ public function transactions(Request $request): JsonResponse { $user = $request->user(); if (!$user) { return response()->json(['message' => 'Unauthorized'], 401); } $wallet = $user->wallet; if (!$wallet) { return response()->json([ 'transactions' => [], 'total' => 0, 'current_page' => 1, ]); } $perPage = $request->query('per_page', 15); $status = $request->query('status'); // pending, completed, failed $type = $request->query('type'); // deposit, withdrawal $query = $wallet->transactions()->orderByDesc('created_at'); if ($status) { $query->where('status', $status); } if ($type) { $query->where('type', $type); } $transactions = $query->paginate($perPage); return response()->json([ 'transactions' => $transactions->map(fn ($t) => [ 'id' => $t->id, 'amount' => $t->amount, 'formatted_amount' => $t->formatted_amount, 'type' => $t->type->label(), 'status' => $t->status->label(), 'status_code' => $t->status->value, 'gateway' => $t->gateway?->label(), 'reference_id' => $t->gateway_reference_id, 'description' => $t->description, 'created_at' => $t->created_at->toIso8601String(), 'created_at_jalali' => \Morilog\Jalali\Jalalian::fromCarbon($t->created_at)->format('Y/m/d H:i'), ]), 'total' => $transactions->total(), 'current_page' => $transactions->currentPage(), 'last_page' => $transactions->lastPage(), ]); } /** * شارژ/کسر دستی توسط ادمین */ public function adminAdjust(Request $request): JsonResponse { $user = $request->user(); if (!$user || !$user->isSuperAdmin()) { return response()->json(['message' => 'Forbidden — Only Super Admin can perform this action'], 403); } try { $validated = $request->validate([ 'user_id' => ['required', 'exists:users,id'], 'amount' => ['required', 'numeric', 'not_in:0'], // مثبت = شارژ، منفی = کسر 'description' => ['required', 'string', 'max:1000'], 'admin_notes' => ['nullable', 'string', 'max:2000'], ]); } catch (ValidationException $e) { return response()->json([ 'message' => 'Validation failed', 'errors' => $e->errors(), ], 422); } $targetUser = User::findOrFail($validated['user_id']); $wallet = $targetUser->wallet ?? Wallet::create([ 'user_id' => $targetUser->id, 'balance' => 0, ]); try { $amount = abs($validated['amount']); if ($validated['amount'] > 0) { // شارژ $transaction = $this->walletService->manualDeposit( wallet: $wallet, amount: $amount, description: $validated['description'], admin: $user, adminNotes: $validated['admin_notes'] ?? null ); $message = 'شارژ دستی با موفقیت انجام شد'; } else { // کسر $transaction = $this->walletService->manualWithdrawal( wallet: $wallet, amount: $amount, description: $validated['description'], admin: $user, adminNotes: $validated['admin_notes'] ?? null ); $message = 'کسر دستی با موفقیت انجام شد'; } return response()->json([ 'message' => $message, 'transaction_id' => $transaction->id, 'target_user_id' => $targetUser->id, 'target_user_name' => $targetUser->name, 'balance_before' => $transaction->balance_before, 'balance_after' => $transaction->balance_after, 'amount' => $transaction->amount, 'description' => $transaction->description, 'admin_notes' => $transaction->admin_notes, 'performed_by' => $user->name, 'created_at' => $transaction->created_at->toIso8601String(), ]); } catch (\Exception $e) { return response()->json([ 'message' => 'خطا در انجام عملیات: ' . $e->getMessage(), ], 422); } } /** * مسدود کردن کیف پول (توسط ادمین) */ public function freeze(Request $request, $walletId): JsonResponse { $user = $request->user(); if (!$user || !$user->isSuperAdmin()) { return response()->json(['message' => 'Forbidden'], 403); } $validated = $request->validate([ 'reason' => ['required', 'string', 'max:1000'], ]); $wallet = Wallet::findOrFail($walletId); $oldFrozen = $wallet->isFrozen(); $wallet->freeze($validated['reason'], $user); WalletActivityLog::log( $wallet, 'wallet_frozen', 'کیف پول مسدود شد توسط ' . $user->name, ['is_frozen' => $oldFrozen], ['is_frozen' => true, 'reason' => $validated['reason']], $user ); return response()->json([ 'message' => 'کیف پول با موفقیت مسدود شد', 'wallet_id' => $wallet->id, 'reason' => $validated['reason'], ]); } /** * رفع مسدودی کیف پول (توسط ادمین) */ public function unfreeze(Request $request, $walletId): JsonResponse { $user = $request->user(); if (!$user || !$user->isSuperAdmin()) { return response()->json(['message' => 'Forbidden'], 403); } $wallet = Wallet::findOrFail($walletId); $oldReason = $wallet->freeze_reason; $wallet->unfreeze($user); WalletActivityLog::log( $wallet, 'wallet_unfrozen', 'کیف پول از مسدودی خارج شد توسط ' . $user->name, ['reason' => $oldReason], ['is_frozen' => false], $user ); return response()->json([ 'message' => 'کیف پول با موفقیت از مسدودی خارج شد', 'wallet_id' => $wallet->id, ]); } /** * مشاهده لاگ فعالیت‌های کیف پول (توسط ادمین) */ public function activityLog(Request $request, $walletId): JsonResponse { $user = $request->user(); if (!$user || !$user->isSuperAdmin()) { return response()->json(['message' => 'Forbidden'], 403); } $wallet = Wallet::findOrFail($walletId); $perPage = $request->query('per_page', 20); $logs = $wallet->activityLogs()->with('user')->paginate($perPage); return response()->json([ 'wallet_id' => $wallet->id, 'user_name' => $wallet->user->name, 'balance' => $wallet->balance, 'is_frozen' => $wallet->isFrozen(), 'freeze_reason' => $wallet->freeze_reason, 'logs' => $logs->map(fn ($log) => [ 'id' => $log->id, 'action' => $log->action, 'description' => $log->description, 'old_values' => $log->old_values, 'new_values' => $log->new_values, 'performed_by' => $log->user?->name ?? 'سیستم', 'ip_address' => $log->ip_address, 'created_at' => $log->created_at->toIso8601String(), 'created_at_jalali' => \Morilog\Jalali\Jalalian::fromCarbon($log->created_at)->format('Y/m/d H:i'), ]), 'total' => $logs->total(), 'current_page' => $logs->currentPage(), 'last_page' => $logs->lastPage(), ]); } }