simedkom/app/Filament/Resources/Manage/DataChanges/Actions/DataChangeRequest/AcceptAction.php

163 lines
6.8 KiB
PHP

<?php
namespace App\Filament\Resources\Manage\DataChanges\Actions\DataChangeRequest;
use App\Enums\DataChangeDecision;
use App\Enums\DataChangeStatus;
use App\Enums\RoleEnum;
use App\Filament\Support\CheerfulNotification;
use App\Models\DataChangeRequest;
use App\Models\DataChangeReview;
use App\Notifications\BroadcastNotification;
use Filament\Actions\Action;
use Filament\Support\Contracts\HasLabel;
use Filament\Support\Icons\Heroicon;
use Illuminate\Support\Facades\Storage;
class AcceptAction extends Action
{
protected function setUp(): void
{
parent::setUp();
$this->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));
}
}