163 lines
6.8 KiB
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));
|
|
}
|
|
}
|