Files
portal-api/app/Http/Controllers/Api/Admin/Transaction/AdminTransactionController.php
T

177 lines
6.3 KiB
PHP

<?php
namespace App\Http\Controllers\Api\Admin\Transaction;
use App\Enums\TransactionStatus;
use App\Http\Controllers\Controller;
use App\Models\Log;
use App\Models\Transaction;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log as FacadesLog;
use Illuminate\Support\Facades\Storage;
class AdminTransactionController extends Controller
{
public function pendingCount(): JsonResponse
{
$count = Transaction::where('type', 'manual')
->where('status', TransactionStatus::PENDING->value)
->whereNotNull('proof_image')
->count();
return response()->json(['error' => false, 'data' => ['count' => $count]]);
}
public function index(Request $request): JsonResponse
{
$query = Transaction::with('customer')
->where('type', 'manual')
->orderByDesc('created_at');
if ($request->filled('status')) {
$query->where('status', $request->integer('status'));
}
if ($request->filled('filter')) {
$search = $request->string('filter')->trim();
$query->where(function ($q) use ($search) {
$q->where('public_code', 'like', "%{$search}%")
->orWhereHas('customer', fn($c) => $c
->where('fullname', 'like', "%{$search}%")
->orWhere('email', 'like', "%{$search}%"));
});
}
$perPage = $request->integer('per_page', 15);
$paginated = $query->paginate($perPage);
$items = $paginated->map(fn(Transaction $t) => [
'id' => $t->id,
'uuid' => $t->uuid,
'public_code' => $t->public_code,
'trans' => $t->trans,
'amount' => $t->amount,
'type' => $t->type,
'status' => $t->status,
'status_label' => TransactionStatus::from((int) $t->status)->label(),
'proof_image' => $t->proof_image ? Storage::disk('public')->url($t->proof_image) : null,
'created_at' => $t->created_at?->toISOString(),
'customer' => $t->customer ? [
'uuid' => $t->customer->uuid,
'fullname' => $t->customer->fullname,
'email' => $t->customer->email,
'phone' => $t->customer->phone,
'total' => $t->customer->total,
'total_pending' => $t->customer->total_pending,
] : null,
]);
return response()->json([
'error' => false,
'data' => [
'items' => $items,
'total' => $paginated->total(),
'per_page' => $paginated->perPage(),
'current_page' => $paginated->currentPage(),
'last_page' => $paginated->lastPage(),
],
]);
}
public function approve(string $uuid): JsonResponse
{
$transaction = Transaction::with('customer')
->where('uuid', $uuid)
->where('type', 'manual')
->where('status', TransactionStatus::PENDING->value)
->first();
if (!$transaction) {
return response()->json([
'error' => true,
'message' => 'Giao dịch không tồn tại hoặc không thể duyệt',
], 404);
}
DB::beginTransaction();
try {
$transaction->update(['status' => TransactionStatus::COMPLETED->value]);
$customer = $transaction->customer;
$customer->total += $transaction->amount;
$customer->credit += (int) floor($transaction->amount / 100);
$customer->total_pending = max(0, $customer->total_pending - $transaction->amount);
$customer->save();
Log::create([
'agent' => 'admin',
'client_ip' => request()->ip(),
'description' => 'Admin duyệt nạp tiền thủ công: ' . number_format($transaction->amount) . ' VNĐ (+' . floor($transaction->amount / 100) . ' credit)',
'customer_id' => $customer->id,
]);
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
FacadesLog::error('AdminTransactionController::approve error: ' . $e->getMessage());
return response()->json([
'error' => true,
'message' => 'Có lỗi xảy ra, vui lòng thử lại',
], 500);
}
return response()->json([
'error' => false,
'message' => 'Đã duyệt giao dịch thành công',
]);
}
public function reject(string $uuid): JsonResponse
{
$transaction = Transaction::with('customer')
->where('uuid', $uuid)
->where('type', 'manual')
->where('status', TransactionStatus::PENDING->value)
->first();
if (!$transaction) {
return response()->json([
'error' => true,
'message' => 'Giao dịch không tồn tại hoặc không thể từ chối',
], 404);
}
DB::beginTransaction();
try {
$transaction->update(['status' => TransactionStatus::FAILED->value]);
$customer = $transaction->customer;
$customer->total_pending = max(0, $customer->total_pending - $transaction->amount);
$customer->save();
Log::create([
'agent' => 'admin',
'client_ip' => request()->ip(),
'description' => 'Admin từ chối nạp tiền thủ công: ' . number_format($transaction->amount) . ' VNĐ',
'customer_id' => $customer->id,
]);
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
FacadesLog::error('AdminTransactionController::reject error: ' . $e->getMessage());
return response()->json([
'error' => true,
'message' => 'Có lỗi xảy ra, vui lòng thử lại',
], 500);
}
return response()->json([
'error' => false,
'message' => 'Đã từ chối giao dịch',
]);
}
}