label('Setujui') ->icon(Heroicon::Check) ->color('success') ->requiresConfirmation() ->modalHeading('Setujui Perubahan Data') ->modalDescription('Apakah Anda yakin ingin menyetujui dan menerapkan perubahan data ini?') ->action(function (DataChangeRequest $record): void { $entity = $record->entity; $newData = $record->new_data; if (isset($newData['__delete_request__']) && $newData['__delete_request__'] === true) { $entity->delete(); $record->update(['status' => DataChangeStatus::APPROVED]); DataChangeReview::create([ 'data_change_request_id' => $record->id, 'reviewer_id' => auth()->id(), 'decision' => DataChangeDecision::APPROVED, ]); CheerfulNotification::success( 'Penghapusan Disetujui! ✅', 'Data telah berhasil dihapus sesuai dengan permohonan.' )->send(); // Notify User $record->user?->notify(new BroadcastNotification([ 'title' => 'Permohonan Penghapusan Disetujui ✨', 'body' => "Halo! Permohonan penghapusan data Anda untuk {$record->change_reason} telah disetujui oleh admin. 🚀", ])); return; } if (! $entity) { CheerfulNotification::danger( 'Entitas Tidak Ditemukan ❌', 'Data asli untuk permohonan ini tidak dapat ditemukan.' )->send(); return; } $fields = []; $docs = []; $reverseLabels = []; if (method_exists($record->entity_type, 'dataChangeEntryLabels')) { $reverseLabels = array_flip(($record->entity_type)::dataChangeEntryLabels()); } $casts = $entity->getCasts(); foreach ($newData as $key => $value) { $actualKey = $reverseLabels[$key] ?? $key; if (str_ends_with($actualKey, '_docs')) { $docs[$actualKey] = $value; } else { // Handle Enum labels reverse mapping if (isset($casts[$actualKey])) { $castType = $casts[$actualKey]; if (is_string($castType) && enum_exists($castType)) { if (is_subclass_of($castType, HasLabel::class)) { foreach ($castType::cases() as $case) { if ($case->getLabel() === $value) { $value = $case->value; break; } } } // If it's an int-backed enum but we have a string (e.g. from older data or failed mapping) if (is_string($value) && is_numeric($value)) { $reflection = new \ReflectionEnum($castType); if ($reflection->isBacked() && $reflection->getBackingType()?->getName() === 'int') { $value = (int) $value; } } } } $fields[$actualKey] = $value; } } // Update model fields $entity->update($fields); // Update media/documents foreach ($docs as $field => $filePaths) { if (empty($filePaths)) { continue; } $docType = str($field)->replace('_docs', '')->slug('-'); $collection = match ($record->entity_type) { 'App\Models\PartnerMedia' => 'partnerMedia', default => str($record->entity_type)->afterLast('\\')->plural()->lower()->toString(), }; foreach ((array) $filePaths as $filePath) { $fullPath = Storage::disk(config('filesystems.default'))->path($filePath); if (! file_exists($fullPath)) { continue; } $entity->addMediaFromDisk($filePath, config('filesystems.default')) ->preservingOriginal() ->withCustomProperties([ 'feature' => $collection, 'date' => now()->toDateString(), 'doc_type' => $docType, ]) ->toMediaCollection($collection); } } $record->update(['status' => DataChangeStatus::APPROVED]); DataChangeReview::create([ 'data_change_request_id' => $record->id, 'reviewer_id' => auth()->id(), 'decision' => DataChangeDecision::APPROVED, ]); CheerfulNotification::success( 'Perubahan Disetujui! ✅', 'Data telah berhasil diperbarui sesuai dengan permohonan.' )->send(); // Notify User $record->user?->notify(new BroadcastNotification([ 'title' => 'Permohonan Perubahan Disetujui ✨', 'body' => "Halo! Permohonan perubahan data Anda untuk {$record->change_reason} telah disetujui oleh admin. Cek sekarang ya! 🚀", ])); }) ->visible(fn (DataChangeRequest $record): bool => $record->status === DataChangeStatus::PENDING && ! auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)); } }