This commit is contained in:
Saufi
2026-06-24 18:30:00 +08:00
commit c0c3d7c09c
122 changed files with 16321 additions and 0 deletions

View File

@@ -0,0 +1,119 @@
<?php
namespace App\Http\Controllers;
use App\Models\DrawResult;
use App\Models\Member;
use App\Models\Prize;
use App\Support\Spreadsheet;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Http\Request;
use Illuminate\View\View;
use Symfony\Component\HttpFoundation\Response;
class ReportController extends Controller
{
public function index(): View
{
$winners = DrawResult::with(['member', 'prize', 'confirmedBy'])
->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(),
);
}
}