refactor observers, fix policy, add feature tests
This commit is contained in:
@@ -41,6 +41,8 @@ class PublicController extends Controller
|
||||
{
|
||||
abort_if($activity->status !== 'approved', 404);
|
||||
|
||||
$activity->load('creator', 'participants');
|
||||
|
||||
return view('public.kegiatan-detail', compact('activity'));
|
||||
}
|
||||
|
||||
@@ -55,6 +57,8 @@ class PublicController extends Controller
|
||||
{
|
||||
abort_if($post->status !== 'published' || ! $post->published_at, 404);
|
||||
|
||||
$post->load('author');
|
||||
|
||||
return view('public.blog-detail', compact('post'));
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,6 @@ class Approval extends Model
|
||||
{
|
||||
protected $fillable = ['model_type', 'model_id', 'required_approvals', 'status'];
|
||||
|
||||
protected $with = ['items.user'];
|
||||
|
||||
public function items(): HasMany
|
||||
{
|
||||
return $this->hasMany(ApprovalItem::class);
|
||||
|
||||
@@ -12,25 +12,36 @@ use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ActivityObserver
|
||||
{
|
||||
public function updated(Activity $activity): void
|
||||
public function updating(Activity $activity): bool
|
||||
{
|
||||
if ($activity->wasChanged('status')) {
|
||||
if ($activity->isDirty('status')) {
|
||||
$old = $activity->getOriginal('status');
|
||||
$new = $activity->status;
|
||||
|
||||
// Validasi workflow: draft→pending, pending→approved/rejected
|
||||
$allowed = [
|
||||
'draft' => ['pending'],
|
||||
'pending' => ['approved', 'rejected'],
|
||||
];
|
||||
|
||||
if (isset($allowed[$old]) && ! in_array($new, $allowed[$old])) {
|
||||
$validTransition = isset($allowed[$old]) && in_array($new, $allowed[$old]);
|
||||
|
||||
if (! $validTransition) {
|
||||
Notification::make()->title('Transisi tidak diizinkan')
|
||||
->body("Status tidak bisa diubah dari {$old} ke {$new}.")
|
||||
->danger()->send();
|
||||
$activity->status = $old;
|
||||
return;
|
||||
|
||||
return false; // batalkan save
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function updated(Activity $activity): void
|
||||
{
|
||||
if ($activity->wasChanged('status')) {
|
||||
$old = $activity->getOriginal('status');
|
||||
$new = $activity->status;
|
||||
|
||||
ActivityLog::create([
|
||||
'user_id' => Auth::id(),
|
||||
|
||||
@@ -23,12 +23,10 @@ class CashRecordObserver
|
||||
|
||||
// Threshold: 500rb–2jt → buat approval ketua + notif
|
||||
if ($record->amount >= 500_000 && $record->amount <= 2_000_000) {
|
||||
Approval::create([
|
||||
'model_type' => CashRecord::class,
|
||||
'model_id' => $record->id,
|
||||
'required_approvals' => 1,
|
||||
'status' => 'pending',
|
||||
]);
|
||||
Approval::firstOrCreate(
|
||||
['model_type' => CashRecord::class, 'model_id' => $record->id],
|
||||
['required_approvals' => 1, 'status' => 'pending']
|
||||
);
|
||||
|
||||
NotificationService::toRole('ketua',
|
||||
'Transaksi Kas Butuh Persetujuan',
|
||||
@@ -38,7 +36,7 @@ class CashRecordObserver
|
||||
);
|
||||
}
|
||||
|
||||
// Threshold: > 2jt → buat voting + notif semua anggota
|
||||
// Threshold: > 2jt → buat voting (VoteObserver akan notif semua user)
|
||||
if ($record->amount > 2_000_000) {
|
||||
Vote::create([
|
||||
'title' => "Persetujuan Transaksi: {$record->description}",
|
||||
@@ -50,13 +48,6 @@ class CashRecordObserver
|
||||
'deadline' => now()->addDays(3),
|
||||
'created_by' => Auth::id() ?? $record->created_by,
|
||||
]);
|
||||
|
||||
NotificationService::toRole('ketua',
|
||||
'Voting Transaksi Besar Dibuat',
|
||||
"Transaksi \"{$record->description}\" senilai Rp " . number_format($record->amount, 0, ',', '.') . " memerlukan voting.",
|
||||
'warning',
|
||||
route('filament.admin.resources.votes.index')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,13 +67,9 @@ class CashRecordObserver
|
||||
public function deleting(CashRecord $record): void
|
||||
{
|
||||
if ($record->verified_at !== null) {
|
||||
\Filament\Notifications\Notification::make()
|
||||
->title('Tidak dapat dihapus')
|
||||
->body('Transaksi yang sudah diverifikasi tidak dapat dihapus.')
|
||||
->danger()
|
||||
->send();
|
||||
|
||||
abort(403);
|
||||
throw new \Illuminate\Auth\Access\AuthorizationException(
|
||||
'Transaksi yang sudah diverifikasi tidak dapat dihapus.'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,6 @@ class UserObserver
|
||||
{
|
||||
public function updated(User $user): void
|
||||
{
|
||||
// Pastikan role anggota selalu ada
|
||||
if (! $user->hasRole('anggota')) {
|
||||
$user->assignRole('anggota');
|
||||
}
|
||||
|
||||
// Log perubahan status anggota
|
||||
if ($user->wasChanged('status')) {
|
||||
MemberStatusLog::create([
|
||||
|
||||
@@ -34,7 +34,7 @@ class CashRecordPolicy
|
||||
|
||||
public function delete(AuthUser $authUser, CashRecord $cashRecord): bool
|
||||
{
|
||||
return $authUser->can('Delete:CashRecord');
|
||||
return $authUser->can('Delete:CashRecord') && $cashRecord->verified_at === null;
|
||||
}
|
||||
|
||||
public function deleteAny(AuthUser $authUser): bool
|
||||
|
||||
Reference in New Issue
Block a user