validated(); $perPage = $this->perPage($request, 'per_page', 20, 100); $page = $this->page($request); $query = TicketItem::query() ->with([ 'draw:id,draw_no,business_date', 'order:id,order_no,currency_code,created_at', 'player:id,site_code,site_player_id,username,nickname', ]) ->orderByDesc('ticket_items.id'); if (! empty($validated['player_id'])) { $query->where('ticket_items.player_id', (int) $validated['player_id']); } elseif (! empty($validated['player_account'])) { $term = '%'.addcslashes(trim((string) $validated['player_account']), '%_\\').'%'; $query->whereHas('player', function ($q) use ($term): void { $q->where('site_player_id', 'like', $term) ->orWhere('username', 'like', $term) ->orWhere('nickname', 'like', $term); }); } $drawNo = $validated['draw_no'] ?? null; if (is_string($drawNo) && trim($drawNo) !== '') { $query->whereHas('draw', fn ($q) => $q->where('draw_no', trim($drawNo))); } $statusInput = $validated['status'] ?? []; if (is_string($statusInput)) { $statusInput = [$statusInput]; } $statusValues = is_array($statusInput) ? array_values(array_filter(array_map( fn ($status) => is_string($status) ? trim($status) : '', $statusInput, ))) : []; if ($statusValues !== []) { $query->whereIn('ticket_items.status', $statusValues); } $number = trim((string) ($validated['number'] ?? '')); if ($number !== '') { $query->where(function ($q) use ($number): void { $q->where('ticket_items.original_number', 'like', '%'.$number.'%') ->orWhere('ticket_items.normalized_number', 'like', '%'.$number.'%') ->orWhere('ticket_items.ticket_no', 'like', '%'.$number.'%') ->orWhereHas('order', fn ($order) => $order->where('order_no', 'like', '%'.$number.'%')); }); } $startDate = $validated['start_date'] ?? null; if (is_string($startDate) && $startDate !== '') { $query->whereHas('order', fn ($q) => $q->whereDate('created_at', '>=', $startDate)); } $endDate = $validated['end_date'] ?? null; if (is_string($endDate) && $endDate !== '') { $query->whereHas('order', fn ($q) => $q->whereDate('created_at', '<=', $endDate)); } $paginator = $query->paginate(perPage: $perPage, page: $page, columns: ['*']); $items = collect($paginator->items())->map(function (TicketItem $row): array { $totalBet = (int) $row->total_bet_amount; $actualDeduct = (int) $row->actual_deduct_amount; $winAmount = (int) $row->win_amount; $jackpotWin = (int) $row->jackpot_win_amount; return [ 'id' => $row->id, 'ticket_no' => $row->ticket_no, 'player_id' => $row->player_id, 'site_code' => $row->player?->site_code, 'site_player_id' => $row->player?->site_player_id, 'username' => $row->player?->username, 'nickname' => $row->player?->nickname, 'order_no' => $row->order?->order_no, 'draw_no' => $row->draw?->draw_no, 'currency_code' => $row->order?->currency_code, 'play_code' => $row->play_code, 'original_number' => $row->original_number, 'total_bet_amount' => $totalBet, 'total_bet_amount_formatted' => CurrencyFormatter::fromMinor($totalBet), 'actual_deduct_amount' => $actualDeduct, 'actual_deduct_amount_formatted' => CurrencyFormatter::fromMinor($actualDeduct), 'status' => $row->status, 'fail_reason_code' => $row->fail_reason_code, 'fail_reason_text' => $row->fail_reason_text, 'win_amount' => $winAmount, 'win_amount_formatted' => CurrencyFormatter::fromMinor($winAmount), 'jackpot_win_amount' => $jackpotWin, 'jackpot_win_amount_formatted' => CurrencyFormatter::fromMinor($jackpotWin), 'placed_at' => $row->order?->created_at?->toIso8601String(), 'updated_at' => $row->updated_at?->toIso8601String(), ]; })->values()->all(); return ApiResponse::success([ 'items' => $items, 'total' => $paginator->total(), 'page' => $paginator->currentPage(), 'per_page' => $paginator->perPage(), 'last_page' => $paginator->lastPage(), ]); } }