lotteryAdmin(); abort_if($admin === null, 401); $periodId = (int) $request->query('settlement_period_id', 0); $adminSiteId = (int) $request->query('admin_site_id', 0); $query = DB::table('settlement_bills as sb') ->leftJoin('settlement_periods as sp', 'sp.id', '=', 'sb.settlement_period_id') ->select([ 'sb.*', 'sp.period_start', 'sp.period_end', 'sp.admin_site_id', ]) ->orderByDesc('sb.id'); if ($periodId > 0) { $query->where('sb.settlement_period_id', $periodId); } if ($adminSiteId > 0) { $query->where('sp.admin_site_id', $adminSiteId); } $billId = (int) $request->query('bill_id', 0); if ($billId > 0) { $query->where('sb.id', $billId); } $billType = (string) $request->query('bill_type', ''); if ($billType !== '') { $query->where('sb.bill_type', $billType); } $scope = (string) $request->query('scope', ''); match ($scope) { 'pending_confirm' => $query->where('sb.status', 'pending_confirm'), 'awaiting_payment' => $query ->whereIn('sb.status', ['confirmed', 'partial_paid', 'overdue']) ->where('sb.unpaid_amount', '>', 0), 'settled' => $query->where('sb.status', 'settled'), 'adjustment' => $query->whereIn('sb.bill_type', ['adjustment', 'reversal']), default => null, }; $keyword = trim((string) $request->query('keyword', '')); if ($keyword !== '') { $this->applyKeywordFilter($query, $keyword); } AdminAgentSettlementScope::applyToBillsQuery($query, $admin, 'sb'); $meta = $this->paginationMeta($request, defaultPerPage: 20, maxPerPage: 100); $paginator = $query->paginate($meta['per_page'], ['sb.*', 'sp.period_start', 'sp.period_end', 'sp.admin_site_id'], 'page', $meta['page']); /** @var Collection $items */ $items = collect($paginator->items()); return ApiResponse::success([ 'items' => $this->enrichBillRows($items), 'total' => $paginator->total(), 'page' => $paginator->currentPage(), 'per_page' => $paginator->perPage(), ]); } private function applyKeywordFilter(\Illuminate\Database\Query\Builder $query, string $keyword): void { $like = '%'.addcslashes($keyword, '%_\\').'%'; $query->where(function (\Illuminate\Database\Query\Builder $outer) use ($keyword, $like): void { if (ctype_digit($keyword)) { $outer->orWhere('sb.id', (int) $keyword) ->orWhere('sb.owner_id', (int) $keyword); } $outer->orWhere(function (\Illuminate\Database\Query\Builder $player) use ($like): void { $player->where('sb.owner_type', 'player') ->whereExists(function (\Illuminate\Database\Query\Builder $exists) use ($like): void { $exists->selectRaw('1') ->from('players as p') ->whereColumn('p.id', 'sb.owner_id') ->where(function (\Illuminate\Database\Query\Builder $match) use ($like): void { $match->where('p.username', 'like', $like) ->orWhere('p.site_player_id', 'like', $like); }); }); }); $outer->orWhere(function (\Illuminate\Database\Query\Builder $agent) use ($like): void { $agent->where('sb.owner_type', 'agent') ->whereExists(function (\Illuminate\Database\Query\Builder $exists) use ($like): void { $exists->selectRaw('1') ->from('agent_nodes as a') ->whereColumn('a.id', 'sb.owner_id') ->where(function (\Illuminate\Database\Query\Builder $match) use ($like): void { $match->where('a.name', 'like', $like) ->orWhere('a.code', 'like', $like); }); }); }); $outer->orWhere(function (\Illuminate\Database\Query\Builder $counter) use ($like): void { $counter->where('sb.counterparty_type', 'agent') ->whereExists(function (\Illuminate\Database\Query\Builder $exists) use ($like): void { $exists->selectRaw('1') ->from('agent_nodes as a') ->whereColumn('a.id', 'sb.counterparty_id') ->where(function (\Illuminate\Database\Query\Builder $match) use ($like): void { $match->where('a.name', 'like', $like) ->orWhere('a.code', 'like', $like); }); }); }); }); } /** * @param Collection $items * @return list> */ private function enrichBillRows(Collection $items): array { if ($items->isEmpty()) { return []; } $playerIds = []; $agentIds = []; foreach ($items as $row) { if ((string) $row->owner_type === 'player') { $playerIds[] = (int) $row->owner_id; } elseif ((string) $row->owner_type === 'agent') { $agentIds[] = (int) $row->owner_id; } if ((string) $row->counterparty_type === 'agent' && (int) $row->counterparty_id > 0) { $agentIds[] = (int) $row->counterparty_id; } } $players = $playerIds !== [] ? DB::table('players') ->whereIn('id', array_unique($playerIds)) ->select(['id', 'username', 'site_player_id', 'agent_node_id', 'funding_mode', 'auth_source']) ->get() ->keyBy('id') : collect(); foreach ($players as $player) { $aid = (int) ($player->agent_node_id ?? 0); if ($aid > 0) { $agentIds[] = $aid; } } $agents = $this->partyEnrichment->loadAgents($agentIds); $out = []; foreach ($items as $row) { $item = (array) $row; $ownerType = (string) $row->owner_type; $counterType = (string) $row->counterparty_type; $counterId = (int) $row->counterparty_id; $item['owner_label'] = $this->legacyOwnerLabel($ownerType, (int) $row->owner_id, $players, $agents); $item['counterparty_label'] = $this->partyEnrichment->formatCounterpartyLabel($counterType, $counterId, $agents); $item['player_username'] = null; $item['player_site_player_id'] = null; $item['player_id_display'] = null; $item['direct_agent_label'] = null; $item['superior_agent_label'] = null; $item['owner_party_label'] = null; if ($ownerType === 'player') { $player = $players->get((int) $row->owner_id); $item['player_username'] = $this->partyEnrichment->formatPlayerUsername($player); $item['player_site_player_id'] = $this->partyEnrichment->formatPlayerSiteId($player); $item['player_id_display'] = (int) $row->owner_id; $item['owner_funding_mode'] = $player !== null ? (string) ($player->funding_mode ?? '') : null; $item['owner_auth_source'] = $player !== null ? $player->auth_source : null; $directId = $counterType === 'agent' ? $counterId : (int) ($player->agent_node_id ?? 0); $line = $this->partyEnrichment->agentLineLabels($directId > 0 ? $directId : null, $agents); $item['direct_agent_label'] = $line['direct_agent_label']; $item['superior_agent_label'] = $line['parent_agent_label']; } elseif ($ownerType === 'agent') { $ownerAgentId = (int) $row->owner_id; $item['owner_party_label'] = $this->partyEnrichment->formatAgent($agents->get($ownerAgentId), $ownerAgentId); $item['superior_agent_label'] = $counterType === 'platform' ? 'platform' : $this->partyEnrichment->formatCounterpartyLabel($counterType, $counterId, $agents); } $out[] = $item; } return $out; } /** * @param Collection $players * @param Collection $agents */ private function legacyOwnerLabel( string $type, int $id, Collection $players, Collection $agents, ): string { if ($type === 'player') { $player = $players->get($id); return $player !== null ? (string) ($player->username ?: $player->site_player_id ?: "player#{$id}") : "player#{$id}"; } if ($type === 'agent') { return $this->partyEnrichment->formatAgent($agents->get($id), $id); } return "{$type}#{$id}"; } }