*/ public function paginateEntries(Draw $draw, Request $request, int $page, int $perPage): LengthAwarePaginator { $action = trim((string) $request->query('action_type', '')); $number = trim((string) $request->query('normalized_number', '')); $ticketItemId = (int) $request->integer('ticket_item_id', 0); $q = RiskPoolLockLog::query() ->where('draw_id', $draw->id) ->with(['ticketItem:id,ticket_no,play_code,player_id']) ->orderByDesc('created_at') ->orderByDesc('id'); if ($action !== '' && in_array($action, ['lock', 'release'], true)) { $q->where('action_type', $action); } if ($number !== '' && preg_match('/^[0-9]{4}$/', $number) === 1) { $q->where('normalized_number', $number); } if ($ticketItemId > 0) { $q->where('ticket_item_id', $ticketItemId); } return $q->paginate($perPage, ['*'], 'page', $page); } /** * @return LengthAwarePaginator */ public function paginateByTicket(Draw $draw, Request $request, int $page, int $perPage): LengthAwarePaginator { $action = trim((string) $request->query('action_type', '')); $number = trim((string) $request->query('normalized_number', '')); $ticketItemId = (int) $request->integer('ticket_item_id', 0); $bindings = ['draw_id' => $draw->id]; $filters = 'l.draw_id = :draw_id AND l.ticket_item_id IS NOT NULL'; if ($action !== '' && in_array($action, ['lock', 'release'], true)) { $filters .= ' AND l.action_type = :action_type'; $bindings['action_type'] = $action; } if ($number !== '' && preg_match('/^[0-9]{4}$/', $number) === 1) { $filters .= ' AND l.normalized_number = :normalized_number'; $bindings['normalized_number'] = $number; } if ($ticketItemId > 0) { $filters .= ' AND l.ticket_item_id = :ticket_item_id'; $bindings['ticket_item_id'] = $ticketItemId; } $driver = DB::connection()->getDriverName(); $lockCountExpr = $driver === 'sqlite' ? "SUM(CASE WHEN l.action_type = 'lock' THEN 1 ELSE 0 END)" : "COUNT(*) FILTER (WHERE l.action_type = 'lock')"; $releaseCountExpr = $driver === 'sqlite' ? "SUM(CASE WHEN l.action_type = 'release' THEN 1 ELSE 0 END)" : "COUNT(*) FILTER (WHERE l.action_type = 'release')"; $lockAmountExpr = $driver === 'sqlite' ? "COALESCE(SUM(CASE WHEN l.action_type = 'lock' THEN l.amount ELSE 0 END), 0)" : "COALESCE(SUM(l.amount) FILTER (WHERE l.action_type = 'lock'), 0)"; $releaseAmountExpr = $driver === 'sqlite' ? "COALESCE(SUM(CASE WHEN l.action_type = 'release' THEN l.amount ELSE 0 END), 0)" : "COALESCE(SUM(l.amount) FILTER (WHERE l.action_type = 'release'), 0)"; $aggregateSql = <<aggregate_count ?? 0); $lastPage = max(1, (int) ceil($total / $perPage)); $page = min(max($page, 1), $lastPage); $offset = ($page - 1) * $perPage; $items = DB::select( "{$aggregateSql} ORDER BY last_at DESC, ticket_item_id DESC LIMIT {$perPage} OFFSET {$offset}", $bindings, ); return new LengthAwarePaginator( $items, $total, $perPage, $page, ['path' => $request->url(), 'query' => $request->query()], ); } }