From 060d669d5c71c334463d8197951798aff636fcc0 Mon Sep 17 00:00:00 2001 From: tuxarmy Date: Fri, 3 Apr 2026 07:41:07 +0700 Subject: [PATCH] feat: tambah AuditSeeder dan perbaiki tampilan audit agar human-readable --- .../Resources/Audits/Schemas/AuditForm.php | 29 ++++++-- .../Resources/Audits/Tables/AuditsTable.php | 34 ++++++++-- database/seeders/AuditSeeder.php | 66 +++++++++++++++++++ database/seeders/DatabaseSeeder.php | 1 + 4 files changed, 119 insertions(+), 11 deletions(-) create mode 100644 database/seeders/AuditSeeder.php diff --git a/app/Filament/Resources/Audits/Schemas/AuditForm.php b/app/Filament/Resources/Audits/Schemas/AuditForm.php index 74785fb..8044264 100644 --- a/app/Filament/Resources/Audits/Schemas/AuditForm.php +++ b/app/Filament/Resources/Audits/Schemas/AuditForm.php @@ -2,10 +2,11 @@ namespace App\Filament\Resources\Audits\Schemas; +use App\Models\Activity; +use App\Models\CashRecord; use App\Models\User; use Filament\Forms\Components\Select; use Filament\Forms\Components\Textarea; -use Filament\Forms\Components\TextInput; use Filament\Schemas\Schema; class AuditForm @@ -17,12 +18,28 @@ class AuditForm ->options(User::pluck('name', 'id')) ->searchable() ->required(), - TextInput::make('model_type')->label('Tipe Model')->required(), - TextInput::make('model_id')->label('ID Model')->numeric()->required(), - Select::make('issue_type')->label('Jenis Temuan') - ->options(['warning' => 'Peringatan', 'critical' => 'Kritis']) + Select::make('model_type')->label('Tipe Objek') + ->options([ + 'App\\Models\\CashRecord' => 'Transaksi Kas', + 'App\\Models\\Activity' => 'Kegiatan', + 'App\\Models\\User' => 'Anggota', + ]) + ->required() + ->live(), + Select::make('model_id')->label('Objek') + ->options(fn ($get) => match ($get('model_type')) { + 'App\\Models\\CashRecord' => CashRecord::get() + ->mapWithKeys(fn ($r) => [$r->id => "{$r->description} — Rp " . number_format($r->amount, 0, ',', '.')]), + 'App\\Models\\Activity' => Activity::pluck('title', 'id'), + 'App\\Models\\User' => User::pluck('name', 'id'), + default => [], + }) + ->searchable() ->required(), - Textarea::make('description')->label('Deskripsi')->rows(3)->required()->columnSpanFull(), + Select::make('issue_type')->label('Jenis Temuan') + ->options(['warning' => '⚠️ Peringatan', 'critical' => '🚨 Kritis']) + ->required(), + Textarea::make('description')->label('Deskripsi Temuan')->rows(3)->required()->columnSpanFull(), Select::make('status') ->options(['open' => 'Terbuka', 'resolved' => 'Selesai']) ->default('open') diff --git a/app/Filament/Resources/Audits/Tables/AuditsTable.php b/app/Filament/Resources/Audits/Tables/AuditsTable.php index 47a4520..8b7dd31 100644 --- a/app/Filament/Resources/Audits/Tables/AuditsTable.php +++ b/app/Filament/Resources/Audits/Tables/AuditsTable.php @@ -2,9 +2,11 @@ namespace App\Filament\Resources\Audits\Tables; +use App\Models\Audit; use Filament\Actions\BulkActionGroup; use Filament\Actions\DeleteBulkAction; use Filament\Actions\EditAction; +use Filament\Actions\ViewAction; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Filters\SelectFilter; use Filament\Tables\Table; @@ -16,17 +18,39 @@ class AuditsTable return $table ->columns([ TextColumn::make('auditor.name')->label('Auditor'), - TextColumn::make('model_type')->label('Tipe'), + TextColumn::make('model_type')->label('Tipe Objek') + ->formatStateUsing(fn ($state) => match ($state) { + 'App\\Models\\CashRecord' => '💰 Transaksi Kas', + 'App\\Models\\Activity' => '📅 Kegiatan', + 'App\\Models\\User' => '👤 Anggota', + default => class_basename($state), + }), + TextColumn::make('subject')->label('Objek') + ->state(function (Audit $record): string { + $subject = $record->auditable; + return match (true) { + $subject instanceof \App\Models\CashRecord => + $subject->description . ' — Rp ' . number_format($subject->amount, 0, ',', '.'), + $subject instanceof \App\Models\Activity => $subject->title, + $subject instanceof \App\Models\User => $subject->name, + default => "#{$record->model_id}", + }; + })->limit(45), TextColumn::make('issue_type')->label('Jenis')->badge() + ->formatStateUsing(fn ($state) => $state === 'critical' ? '🚨 Kritis' : '⚠️ Peringatan') ->color(fn ($state) => $state === 'critical' ? 'danger' : 'warning'), - TextColumn::make('description')->label('Deskripsi')->limit(50), + TextColumn::make('description')->label('Temuan')->limit(50), TextColumn::make('status')->badge() + ->formatStateUsing(fn ($state) => $state === 'resolved' ? 'Selesai' : 'Terbuka') ->color(fn ($state) => $state === 'resolved' ? 'success' : 'danger'), - TextColumn::make('created_at')->label('Tanggal')->date('d M Y'), + TextColumn::make('created_at')->label('Tanggal')->date('d M Y')->sortable(), ]) + ->defaultSort('created_at', 'desc') ->filters([ - SelectFilter::make('issue_type')->options(['warning' => 'Peringatan', 'critical' => 'Kritis']), - SelectFilter::make('status')->options(['open' => 'Terbuka', 'resolved' => 'Selesai']), + SelectFilter::make('issue_type')->label('Jenis') + ->options(['warning' => 'Peringatan', 'critical' => 'Kritis']), + SelectFilter::make('status') + ->options(['open' => 'Terbuka', 'resolved' => 'Selesai']), ]) ->recordActions([EditAction::make()]) ->toolbarActions([BulkActionGroup::make([DeleteBulkAction::make()])]); diff --git a/database/seeders/AuditSeeder.php b/database/seeders/AuditSeeder.php new file mode 100644 index 0000000..1545719 --- /dev/null +++ b/database/seeders/AuditSeeder.php @@ -0,0 +1,66 @@ +first(); + $ketua = User::role('ketua')->first(); + $kas = CashRecord::first(); + $kegiatan = Activity::where('status', 'approved')->first(); + + $audits = [ + [ + 'model' => $kas, + 'issue_type' => 'warning', + 'description' => 'Transaksi tidak disertai bukti kwitansi yang memadai. Mohon dilampirkan dokumen pendukung.', + 'status' => 'resolved', + 'response' => 'Kwitansi sudah dilampirkan dan disimpan di sekretariat.', + ], + [ + 'model' => $kegiatan, + 'issue_type' => 'warning', + 'description' => 'Laporan pelaksanaan kegiatan belum mencantumkan daftar hadir peserta secara lengkap.', + 'status' => 'open', + 'response' => null, + ], + [ + 'model' => $kas ? CashRecord::skip(1)->first() ?? $kas : null, + 'issue_type' => 'critical', + 'description' => 'Ditemukan selisih antara catatan kas dengan laporan keuangan bulan lalu sebesar Rp 50.000. Perlu klarifikasi segera.', + 'status' => 'open', + 'response' => null, + ], + ]; + + foreach ($audits as $data) { + if (! $data['model']) continue; + + $audit = Audit::create([ + 'auditor_id' => $auditor->id, + 'model_type' => get_class($data['model']), + 'model_id' => $data['model']->id, + 'issue_type' => $data['issue_type'], + 'description' => $data['description'], + 'status' => $data['status'], + ]); + + if ($data['response']) { + AuditResponse::create([ + 'audit_id' => $audit->id, + 'responded_by' => $ketua->id, + 'response_text' => $data['response'], + ]); + } + } + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 42ecb62..84e21a0 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -17,6 +17,7 @@ class DatabaseSeeder extends Seeder CashSeeder::class, VoteSeeder::class, PostSeeder::class, + AuditSeeder::class, ]); } }