*/ public static function listRow(Draw $draw, ?array $stats, AdminUser $admin): array { $manage = AdminDrawResponsePolicy::canManageDrawResults($admin); $finance = AdminDrawResponsePolicy::canViewDrawFinance($admin); $row = [ 'id' => (int) $draw->id, 'draw_no' => $draw->draw_no, 'business_date' => self::formatBusinessDate($draw->business_date), 'sequence_no' => (int) $draw->sequence_no, 'status' => $draw->status, 'start_time' => $draw->start_time?->toIso8601String(), 'close_time' => $draw->close_time?->toIso8601String(), 'draw_time' => $draw->draw_time?->toIso8601String(), 'cooling_end_time' => $draw->cooling_end_time?->toIso8601String(), 'updated_at' => $draw->updated_at?->toIso8601String(), ]; if ($manage) { $row['result_source'] = $draw->result_source; $row['current_result_version'] = (int) $draw->current_result_version; $row['settle_version'] = (int) $draw->settle_version; $row['is_reopened'] = (bool) $draw->is_reopened; } if ($finance && $stats !== null) { $row['total_bet_minor'] = $stats['total_bet_minor']; $row['total_payout_minor'] = $stats['total_payout_minor']; $row['profit_loss_minor'] = $stats['profit_loss_minor']; } return $row; } /** @return array */ public static function show(Draw $draw, AdminUser $admin, DrawHallSnapshotBuilder $hallPreview): array { $manage = AdminDrawResponsePolicy::canManageDrawResults($admin); $nowUtc = now()->utc(); $batchCounts = [ 'published' => $draw->resultBatches() ->where('status', DrawResultBatchStatus::Published->value) ->count(), ]; if ($manage) { $batchCounts['total'] = $draw->resultBatches()->count(); $batchCounts['pending_review'] = $draw->resultBatches() ->where('status', DrawResultBatchStatus::PendingReview->value) ->count(); } $payload = [ 'id' => (int) $draw->id, 'draw_no' => $draw->draw_no, 'business_date' => self::formatBusinessDate($draw->business_date), 'sequence_no' => (int) $draw->sequence_no, 'status' => $draw->status, 'hall_preview_status' => $hallPreview->effectiveHallDisplayStatus($draw, $nowUtc), 'start_time' => $draw->start_time?->toIso8601String(), 'close_time' => $draw->close_time?->toIso8601String(), 'draw_time' => $draw->draw_time?->toIso8601String(), 'cooling_end_time' => $draw->cooling_end_time?->toIso8601String(), 'result_batch_counts' => $batchCounts, 'capabilities' => AdminDrawResponsePolicy::capabilities($admin), ]; if ($manage) { $payload['result_source'] = $draw->result_source; $payload['current_result_version'] = (int) $draw->current_result_version; $payload['settle_version'] = (int) $draw->settle_version; $payload['is_reopened'] = (bool) $draw->is_reopened; $payload['created_at'] = $draw->created_at?->toIso8601String(); $payload['updated_at'] = $draw->updated_at?->toIso8601String(); } return $payload; } /** @return array */ public static function resultBatch(DrawResultBatch $batch, AdminUser $admin): array { $manage = AdminDrawResponsePolicy::canManageDrawResults($admin); $row = [ 'id' => (int) $batch->id, 'result_version' => (int) $batch->result_version, 'status' => $batch->status, 'confirmed_at' => $batch->confirmed_at?->toIso8601String(), 'items' => $batch->items->map(static fn (DrawResultItem $item): array => [ 'prize_type' => $item->prize_type, 'prize_index' => (int) $item->prize_index, 'number_4d' => $item->number_4d, 'suffix_3d' => $item->suffix_3d, 'suffix_2d' => $item->suffix_2d, 'head_digit' => $item->head_digit, 'tail_digit' => $item->tail_digit, ])->values()->all(), ]; if ($manage) { $row['source_type'] = $batch->source_type; $row['rng_seed_hash'] = $batch->rng_seed_hash; $row['created_by'] = $batch->created_by; $row['confirmed_by'] = $batch->confirmed_by; $row['created_at'] = $batch->created_at?->toIso8601String(); $row['updated_at'] = $batch->updated_at?->toIso8601String(); } return $row; } private static function formatBusinessDate(mixed $businessDate): string { return $businessDate instanceof Carbon ? $businessDate->format('Y-m-d') : (string) $businessDate; } }