feat: tambah AuditSeeder dan perbaiki tampilan audit agar human-readable
This commit is contained in:
@@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Filament\Resources\Audits\Schemas;
|
namespace App\Filament\Resources\Audits\Schemas;
|
||||||
|
|
||||||
|
use App\Models\Activity;
|
||||||
|
use App\Models\CashRecord;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Filament\Forms\Components\Select;
|
use Filament\Forms\Components\Select;
|
||||||
use Filament\Forms\Components\Textarea;
|
use Filament\Forms\Components\Textarea;
|
||||||
use Filament\Forms\Components\TextInput;
|
|
||||||
use Filament\Schemas\Schema;
|
use Filament\Schemas\Schema;
|
||||||
|
|
||||||
class AuditForm
|
class AuditForm
|
||||||
@@ -17,12 +18,28 @@ class AuditForm
|
|||||||
->options(User::pluck('name', 'id'))
|
->options(User::pluck('name', 'id'))
|
||||||
->searchable()
|
->searchable()
|
||||||
->required(),
|
->required(),
|
||||||
TextInput::make('model_type')->label('Tipe Model')->required(),
|
Select::make('model_type')->label('Tipe Objek')
|
||||||
TextInput::make('model_id')->label('ID Model')->numeric()->required(),
|
->options([
|
||||||
Select::make('issue_type')->label('Jenis Temuan')
|
'App\\Models\\CashRecord' => 'Transaksi Kas',
|
||||||
->options(['warning' => 'Peringatan', 'critical' => 'Kritis'])
|
'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(),
|
->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')
|
Select::make('status')
|
||||||
->options(['open' => 'Terbuka', 'resolved' => 'Selesai'])
|
->options(['open' => 'Terbuka', 'resolved' => 'Selesai'])
|
||||||
->default('open')
|
->default('open')
|
||||||
|
|||||||
@@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Filament\Resources\Audits\Tables;
|
namespace App\Filament\Resources\Audits\Tables;
|
||||||
|
|
||||||
|
use App\Models\Audit;
|
||||||
use Filament\Actions\BulkActionGroup;
|
use Filament\Actions\BulkActionGroup;
|
||||||
use Filament\Actions\DeleteBulkAction;
|
use Filament\Actions\DeleteBulkAction;
|
||||||
use Filament\Actions\EditAction;
|
use Filament\Actions\EditAction;
|
||||||
|
use Filament\Actions\ViewAction;
|
||||||
use Filament\Tables\Columns\TextColumn;
|
use Filament\Tables\Columns\TextColumn;
|
||||||
use Filament\Tables\Filters\SelectFilter;
|
use Filament\Tables\Filters\SelectFilter;
|
||||||
use Filament\Tables\Table;
|
use Filament\Tables\Table;
|
||||||
@@ -16,17 +18,39 @@ class AuditsTable
|
|||||||
return $table
|
return $table
|
||||||
->columns([
|
->columns([
|
||||||
TextColumn::make('auditor.name')->label('Auditor'),
|
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()
|
TextColumn::make('issue_type')->label('Jenis')->badge()
|
||||||
|
->formatStateUsing(fn ($state) => $state === 'critical' ? '🚨 Kritis' : '⚠️ Peringatan')
|
||||||
->color(fn ($state) => $state === 'critical' ? 'danger' : 'warning'),
|
->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()
|
TextColumn::make('status')->badge()
|
||||||
|
->formatStateUsing(fn ($state) => $state === 'resolved' ? 'Selesai' : 'Terbuka')
|
||||||
->color(fn ($state) => $state === 'resolved' ? 'success' : 'danger'),
|
->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([
|
->filters([
|
||||||
SelectFilter::make('issue_type')->options(['warning' => 'Peringatan', 'critical' => 'Kritis']),
|
SelectFilter::make('issue_type')->label('Jenis')
|
||||||
SelectFilter::make('status')->options(['open' => 'Terbuka', 'resolved' => 'Selesai']),
|
->options(['warning' => 'Peringatan', 'critical' => 'Kritis']),
|
||||||
|
SelectFilter::make('status')
|
||||||
|
->options(['open' => 'Terbuka', 'resolved' => 'Selesai']),
|
||||||
])
|
])
|
||||||
->recordActions([EditAction::make()])
|
->recordActions([EditAction::make()])
|
||||||
->toolbarActions([BulkActionGroup::make([DeleteBulkAction::make()])]);
|
->toolbarActions([BulkActionGroup::make([DeleteBulkAction::make()])]);
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use App\Models\Activity;
|
||||||
|
use App\Models\Audit;
|
||||||
|
use App\Models\AuditResponse;
|
||||||
|
use App\Models\CashRecord;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
|
class AuditSeeder extends Seeder
|
||||||
|
{
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
$auditor = User::role('auditor')->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'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ class DatabaseSeeder extends Seeder
|
|||||||
CashSeeder::class,
|
CashSeeder::class,
|
||||||
VoteSeeder::class,
|
VoteSeeder::class,
|
||||||
PostSeeder::class,
|
PostSeeder::class,
|
||||||
|
AuditSeeder::class,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user