101 lines
3.8 KiB
PHP
101 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace App\Domain\Administration\Services;
|
|
|
|
use App\Domain\Administration\Models\PortalSetting;
|
|
use App\Domain\Audit\Models\AuditLog;
|
|
use App\Models\User;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
final class ReservationPolicy
|
|
{
|
|
/** @return array<string, array{label:string,description:string,default:int,min:int,max:int,unit:string}> */
|
|
public function definitions(): array
|
|
{
|
|
return [
|
|
'reservation.min_notice_hours' => [
|
|
'label' => 'Antecedência mínima',
|
|
'description' => 'Horas mínimas entre a submissão e o início da utilização.',
|
|
'default' => 0, 'min' => 0, 'max' => 720, 'unit' => 'horas',
|
|
],
|
|
'reservation.max_duration_hours' => [
|
|
'label' => 'Duração máxima',
|
|
'description' => 'Duração máxima permitida para uma requisição.',
|
|
'default' => 168, 'min' => 1, 'max' => 2160, 'unit' => 'horas',
|
|
],
|
|
'reservation.turnaround_minutes' => [
|
|
'label' => 'Margem entre reservas',
|
|
'description' => 'Tempo bloqueado antes e depois da utilização para preparação e conferência.',
|
|
'default' => 0, 'min' => 0, 'max' => 1440, 'unit' => 'minutos',
|
|
],
|
|
'reservation.approval_deadline_hours' => [
|
|
'label' => 'Prazo de aprovação',
|
|
'description' => 'Tempo até uma pré-reserva pendente expirar.',
|
|
'default' => 48, 'min' => 1, 'max' => 336, 'unit' => 'horas',
|
|
],
|
|
'reservation.max_assets' => [
|
|
'label' => 'Equipamentos por requisição',
|
|
'description' => 'Número máximo de equipamentos no mesmo pedido.',
|
|
'default' => 10, 'min' => 1, 'max' => 50, 'unit' => 'equipamentos',
|
|
],
|
|
];
|
|
}
|
|
|
|
public function integer(string $key): int
|
|
{
|
|
$definitions = $this->definitions();
|
|
if (! isset($definitions[$key])) {
|
|
throw new \InvalidArgumentException("Política desconhecida: {$key}");
|
|
}
|
|
|
|
return $this->values()[$key] ?? $definitions[$key]['default'];
|
|
}
|
|
|
|
/** @return array<string, int> */
|
|
public function values(): array
|
|
{
|
|
return Cache::remember('portal.reservation_policy', now()->addHour(), function (): array {
|
|
/** @var array<string, int> $stored */
|
|
$stored = PortalSetting::query()
|
|
->whereIn('key', array_keys($this->definitions()))
|
|
->pluck('value', 'key')
|
|
->map(fn (mixed $value): int => (int) $value)
|
|
->all();
|
|
|
|
return collect($this->definitions())
|
|
->mapWithKeys(fn (array $definition, string $key): array => [
|
|
$key => $stored[$key] ?? $definition['default'],
|
|
])
|
|
->all();
|
|
});
|
|
}
|
|
|
|
/** @param array<string, int> $values */
|
|
public function update(array $values, User $actor): void
|
|
{
|
|
DB::transaction(function () use ($values, $actor): void {
|
|
$before = $this->values();
|
|
foreach ($this->definitions() as $key => $definition) {
|
|
PortalSetting::query()->updateOrCreate(
|
|
['key' => $key],
|
|
[
|
|
'value' => $values[$key],
|
|
'description' => $definition['description'],
|
|
'updated_by' => $actor->id,
|
|
],
|
|
);
|
|
}
|
|
|
|
AuditLog::create([
|
|
'actor_id' => $actor->id,
|
|
'event' => 'settings.reservation_policy_updated',
|
|
'before' => $before,
|
|
'after' => $values,
|
|
]);
|
|
}, 3);
|
|
|
|
Cache::forget('portal.reservation_policy');
|
|
}
|
|
}
|