fix: cash record policy, observer, n+1 query

This commit is contained in:
2026-05-11 18:56:54 +00:00
parent 3bc0fa58ac
commit f89bedb0fd
6 changed files with 27 additions and 29 deletions
@@ -19,6 +19,9 @@ class CashRecordResource extends Resource
protected static string|\UnitEnum|null $navigationGroup = 'Keuangan';
protected static ?string $navigationLabel = 'Transaksi';
protected static ?string $modelLabel = 'Transaksi';
protected static ?string $pluralModelLabel = 'Transaksi';
public static function form(Schema $form): Schema
{
@@ -2,7 +2,6 @@
namespace App\Filament\Resources\CashRecords\Tables;
use App\Models\Approval;
use App\Models\ApprovalItem;
use App\Models\CashCategory;
use App\Models\CashRecord;
@@ -21,6 +20,7 @@ class CashRecordsTable
public static function configure(Table $table): Table
{
return $table
->modifyQueryUsing(fn ($query) => $query->with(['category', 'creator', 'verifier', 'approval']))
->columns([
TextColumn::make('date')->label('Tanggal')->date('d M Y')->sortable(),
TextColumn::make('category.name')->label('Kategori'),
@@ -35,9 +35,7 @@ class CashRecordsTable
if ($record->amount < 500_000 || $record->amount > 2_000_000) {
return '-';
}
$approval = Approval::where('model_type', CashRecord::class)
->where('model_id', $record->id)->first();
return match ($approval?->status) {
return match ($record->approval?->status) {
'approved' => 'Disetujui',
'rejected' => 'Ditolak',
'pending' => 'Menunggu',
@@ -74,14 +72,11 @@ class CashRecordsTable
->visible(function (CashRecord $record): bool {
if (! auth()->user()->can('Update:Approval')) return false;
if ($record->amount < 500_000 || $record->amount > 2_000_000) return false;
$approval = Approval::where('model_type', CashRecord::class)
->where('model_id', $record->id)->first();
return $approval && $approval->status === 'pending';
return $record->approval && $record->approval->status === 'pending';
})
->form([Textarea::make('notes')->label('Catatan')->rows(2)])
->action(function (CashRecord $record, array $data): void {
$approval = Approval::where('model_type', CashRecord::class)
->where('model_id', $record->id)->firstOrFail();
$approval = $record->approval;
ApprovalItem::create([
'approval_id' => $approval->id,
'user_id' => auth()->id(),
@@ -108,14 +103,11 @@ class CashRecordsTable
->visible(function (CashRecord $record): bool {
if (! auth()->user()->can('Update:Approval')) return false;
if ($record->amount < 500_000 || $record->amount > 2_000_000) return false;
$approval = Approval::where('model_type', CashRecord::class)
->where('model_id', $record->id)->first();
return $approval && $approval->status === 'pending';
return $record->approval && $record->approval->status === 'pending';
})
->form([Textarea::make('notes')->label('Alasan Penolakan')->required()->rows(2)])
->action(function (CashRecord $record, array $data): void {
$approval = Approval::where('model_type', CashRecord::class)
->where('model_id', $record->id)->firstOrFail();
$approval = $record->approval;
ApprovalItem::create([
'approval_id' => $approval->id,
'user_id' => auth()->id(),
@@ -144,20 +136,16 @@ class CashRecordsTable
->visible(function (CashRecord $record): bool {
if (! auth()->user()->can('Update:CashRecord')) return false;
if ($record->verified_at) return false;
// Cek threshold
if ($record->amount >= 500_000 && $record->amount <= 2_000_000) {
$approval = Approval::where('model_type', CashRecord::class)
->where('model_id', $record->id)->first();
return $approval && $approval->status === 'approved';
return $record->approval && $record->approval->status === 'approved';
}
if ($record->amount > 2_000_000) {
$vote = \App\Models\Vote::where('type', 'finance')
->where('related_id', $record->id)->first();
$vote = \App\Models\Vote::where('type', 'finance')->where('related_id', $record->id)->first();
$total = $vote?->items()->count() ?? 0;
$approve = $vote?->items()->where('choice', 'approve')->count() ?? 0;
return $vote && $vote->status === 'closed' && $total > 0 && ($approve / $total) > 0.5;
}
return true; // < 500rb langsung bisa
return true;
})
->action(fn (CashRecord $record) => $record->update([
'verified_by' => auth()->id(),