refactor: hapus menu approvals, pindahkan tombol setujui/tolak langsung ke halaman transaksi kas
This commit is contained in:
@@ -2,11 +2,15 @@
|
||||
|
||||
namespace App\Filament\Resources\CashRecords\Tables;
|
||||
|
||||
use App\Models\Approval;
|
||||
use App\Models\ApprovalItem;
|
||||
use App\Models\CashCategory;
|
||||
use App\Models\CashRecord;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Table;
|
||||
@@ -22,27 +26,121 @@ class CashRecordsTable
|
||||
TextColumn::make('amount')->label('Jumlah')->money('IDR')->sortable(),
|
||||
TextColumn::make('description')->label('Keterangan')->limit(40),
|
||||
TextColumn::make('creator.name')->label('Dibuat Oleh'),
|
||||
|
||||
// Status approval untuk transaksi 500rb–2jt
|
||||
TextColumn::make('approval_status')
|
||||
->label('Persetujuan Ketua')
|
||||
->state(function (CashRecord $record): string {
|
||||
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) {
|
||||
'approved' => 'Disetujui',
|
||||
'rejected' => 'Ditolak',
|
||||
'pending' => 'Menunggu',
|
||||
default => '-',
|
||||
};
|
||||
})
|
||||
->badge()
|
||||
->color(fn ($state) => match ($state) {
|
||||
'Disetujui' => 'success',
|
||||
'Ditolak' => 'danger',
|
||||
'Menunggu' => 'warning',
|
||||
default => 'gray',
|
||||
}),
|
||||
|
||||
TextColumn::make('verifier.name')->label('Diverifikasi')->default('-'),
|
||||
TextColumn::make('verified_at')->label('Tgl Verifikasi')->dateTime('d M Y')->default('-'),
|
||||
])
|
||||
->filters([
|
||||
SelectFilter::make('category_id')->label('Kategori')
|
||||
->options(\App\Models\CashCategory::pluck('name', 'id')),
|
||||
->options(CashCategory::pluck('name', 'id')),
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make()->hidden(fn ($record) => $record->verified_at !== null),
|
||||
Action::make('verify')
|
||||
->label('Verifikasi')
|
||||
// Ketua: approve transaksi 500rb–2jt
|
||||
Action::make('approve_ketua')
|
||||
->label('Setujui')
|
||||
->icon('heroicon-o-check-circle')
|
||||
->color('success')
|
||||
->requiresConfirmation()
|
||||
->hidden(fn ($record) => $record->verified_at !== null)
|
||||
->action(function ($record) {
|
||||
$record->update([
|
||||
'verified_by' => auth()->id(),
|
||||
'verified_at' => now(),
|
||||
->visible(function (CashRecord $record): bool {
|
||||
if (! auth()->user()->hasAnyRole(['ketua', 'super_admin'])) 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';
|
||||
})
|
||||
->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();
|
||||
ApprovalItem::create([
|
||||
'approval_id' => $approval->id,
|
||||
'user_id' => auth()->id(),
|
||||
'decision' => 'approve',
|
||||
'notes' => $data['notes'] ?? null,
|
||||
]);
|
||||
$approval->update(['status' => 'approved']);
|
||||
}),
|
||||
|
||||
// Ketua: tolak transaksi 500rb–2jt
|
||||
Action::make('reject_ketua')
|
||||
->label('Tolak')
|
||||
->icon('heroicon-o-x-circle')
|
||||
->color('danger')
|
||||
->visible(function (CashRecord $record): bool {
|
||||
if (! auth()->user()->hasAnyRole(['ketua', 'super_admin'])) 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';
|
||||
})
|
||||
->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();
|
||||
ApprovalItem::create([
|
||||
'approval_id' => $approval->id,
|
||||
'user_id' => auth()->id(),
|
||||
'decision' => 'reject',
|
||||
'notes' => $data['notes'],
|
||||
]);
|
||||
$approval->update(['status' => 'rejected']);
|
||||
}),
|
||||
|
||||
// Bendahara/ketua: verifikasi (hanya jika approval sudah selesai atau tidak diperlukan)
|
||||
Action::make('verify')
|
||||
->label('Verifikasi')
|
||||
->icon('heroicon-o-shield-check')
|
||||
->color('info')
|
||||
->requiresConfirmation()
|
||||
->hidden(fn (CashRecord $record) => $record->verified_at !== null)
|
||||
->visible(function (CashRecord $record): bool {
|
||||
if (! auth()->user()->hasAnyRole(['ketua', 'super_admin', 'bendahara'])) 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';
|
||||
}
|
||||
if ($record->amount > 2_000_000) {
|
||||
$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
|
||||
})
|
||||
->action(fn (CashRecord $record) => $record->update([
|
||||
'verified_by' => auth()->id(),
|
||||
'verified_at' => now(),
|
||||
])),
|
||||
|
||||
EditAction::make()->hidden(fn ($record) => $record->verified_at !== null),
|
||||
])
|
||||
->toolbarActions([BulkActionGroup::make([DeleteBulkAction::make()])]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user