$periodIds * @return array> */ public function summariesForPeriodIds(array $periodIds, ?AdminUser $admin = null): array { if ($periodIds === []) { return []; } $query = DB::table('settlement_bills') ->whereIn('settlement_period_id', $periodIds); if ($admin !== null) { AdminAgentSettlementScope::applySubtreeToBillsQuery($query, $admin); } $rows = $query ->groupBy('settlement_period_id') ->selectRaw('settlement_period_id') ->selectRaw("SUM(CASE WHEN bill_type = 'player' THEN 1 ELSE 0 END) as player_bills") ->selectRaw("SUM(CASE WHEN bill_type = 'agent' THEN 1 ELSE 0 END) as agent_bills") ->selectRaw("SUM(CASE WHEN bill_type IN ('adjustment', 'reversal') THEN 1 ELSE 0 END) as adjustment_bills") ->selectRaw("SUM(CASE WHEN status = 'pending_confirm' THEN 1 ELSE 0 END) as pending_confirm") ->selectRaw("SUM(CASE WHEN status IN ('confirmed', 'partial_paid', 'overdue') AND unpaid_amount > 0 THEN 1 ELSE 0 END) as awaiting_payment") ->selectRaw("SUM(CASE WHEN status = 'settled' THEN 1 ELSE 0 END) as settled") ->selectRaw('COALESCE(SUM(unpaid_amount), 0) as total_unpaid') ->selectRaw('COALESCE(SUM(net_amount), 0) as total_net') ->get(); $out = []; foreach ($rows as $row) { $periodId = (int) $row->settlement_period_id; $out[$periodId] = [ 'player_bills' => (int) $row->player_bills, 'agent_bills' => (int) $row->agent_bills, 'adjustment_bills' => (int) $row->adjustment_bills, 'pending_confirm' => (int) $row->pending_confirm, 'awaiting_payment' => (int) $row->awaiting_payment, 'settled' => (int) $row->settled, 'total_unpaid' => (int) $row->total_unpaid, 'total_net' => (int) $row->total_net, ]; } return $out; } /** * @param Collection $periods * @return list> */ public function attachToPeriodRows(Collection $periods, ?AdminUser $admin = null): array { $ids = $periods->pluck('id')->map(static fn ($id): int => (int) $id)->all(); $summaries = $this->summariesForPeriodIds($ids, $admin); $pipelines = $this->pipelineService->countsForPeriods($periods, $admin); $empty = [ 'player_bills' => 0, 'agent_bills' => 0, 'adjustment_bills' => 0, 'pending_confirm' => 0, 'awaiting_payment' => 0, 'settled' => 0, 'total_unpaid' => 0, 'total_net' => 0, ]; $viewerScope = $this->scopedProfitAggregator->resolveViewer($admin)['scope']; $emptyPipeline = [ 'credit_ledger_count' => 0, 'share_ledger_count' => 0, 'game_win_loss_total' => 0, 'win_loss_scope' => $viewerScope, 'basic_rebate_total' => 0, 'unsettled_ticket_count' => 0, ]; $items = []; foreach ($periods as $period) { $row = (array) $period; $row['summary'] = $summaries[(int) $period->id] ?? $empty; $row['pipeline'] = $pipelines[(int) $period->id] ?? $emptyPipeline; $items[] = $row; } return $items; } }