where('status', DrawResult::STATUS_CONFIRMED) ->get() ->sortBy(fn ($r) => $r->prize->draw_order) ->values(); $cancelled = DrawResult::with(['member', 'prize', 'cancelledBy']) ->where('status', DrawResult::STATUS_CANCELLED) ->latest('cancelled_at') ->get(); $undrawn = Prize::available()->ordered()->get(); return view('reports.index', compact('winners', 'cancelled', 'undrawn')); } public function export(Request $request, string $type): Response { $format = $request->query('format', 'xlsx'); // xlsx | pdf return match ($type) { 'attendance' => $this->exportAttendance($format), 'winners' => $this->exportWinners($format), 'undrawn' => $this->exportUndrawn($format), 'cancelled' => $this->exportCancelled($format), default => abort(404), }; } private function exportAttendance(string $format): Response { $members = Member::hadir()->with('attendance')->orderBy('nama')->get(); $headings = ['Bil', 'No Anggota', 'No Pekerja', 'Nama', 'Jabatan', 'Bahagian', 'Masa Hadir']; $rows = $members->values()->map(fn ($m, $i) => [ $i + 1, $m->no_anggota, $m->no_pekerja, $m->nama, $m->jabatan, $m->bahagian, $m->attendance?->attended_at?->format('d/m/Y H:i:s'), ]); return $this->respond('senarai-kehadiran', 'Senarai Kehadiran MAT KOIPB', $headings, $rows, $format); } private function exportWinners(string $format): Response { $winners = DrawResult::with(['member', 'prize']) ->where('status', DrawResult::STATUS_CONFIRMED) ->get()->sortBy(fn ($r) => $r->prize->draw_order)->values(); $headings = ['Susunan', 'Hadiah', 'Nama Pemenang', 'No Pekerja', 'Jabatan', 'Masa Disahkan']; $rows = $winners->map(fn ($r) => [ $r->prize->draw_order, $r->prize->nama_hadiah, $r->member->nama, $r->member->no_pekerja, $r->member->jabatan, $r->confirmed_at?->format('d/m/Y H:i:s'), ]); return $this->respond('senarai-pemenang', 'Senarai Pemenang Cabutan Bertuah', $headings, $rows, $format); } private function exportUndrawn(string $format): Response { $prizes = Prize::available()->ordered()->get(); $headings = ['Susunan', 'Kod', 'Hadiah', 'Kategori', 'Status']; $rows = $prizes->map(fn ($p) => [ $p->draw_order, $p->kod_hadiah, $p->nama_hadiah, $p->kategori, $p->statusLabel(), ]); return $this->respond('hadiah-belum-dicabut', 'Hadiah Belum Dicabut', $headings, $rows, $format); } private function exportCancelled(string $format): Response { $cancelled = DrawResult::with(['member', 'prize']) ->where('status', DrawResult::STATUS_CANCELLED) ->latest('cancelled_at')->get(); $headings = ['Hadiah', 'Nama', 'No Pekerja', 'Sebab Batal', 'Cubaan', 'Masa Batal']; $rows = $cancelled->map(fn ($r) => [ $r->prize->nama_hadiah, $r->member->nama, $r->member->no_pekerja, $r->sebab_batal, $r->attempt_number, $r->cancelled_at?->format('d/m/Y H:i:s'), ]); return $this->respond('cabutan-dibatalkan', 'Cabutan Dibatalkan', $headings, $rows, $format); } private function respond(string $slug, string $title, array $headings, $rows, string $format): Response { if ($format === 'pdf') { $pdf = Pdf::loadView('reports.pdf', [ 'title' => $title, 'headings' => $headings, 'rows' => $rows, ])->setPaper('a4', 'landscape'); return $pdf->download($slug . '-' . date('Ymd-His') . '.pdf'); } return Spreadsheet::download( $slug . '-' . date('Ymd-His') . '.xlsx', $headings, $rows->map(fn ($r) => array_values((array) $r))->all(), ); } }