Files
shopit-back/app/Domains/Ticketing/Ticket/Services/ConvertValidityTimesToUtcService.php

66 lines
2.6 KiB
PHP

<?php
namespace App\Domains\Ticketing\Ticket\Services;
use Carbon\CarbonImmutable;
use DateTimeZone;
use Illuminate\Support\Facades\DB;
use InvalidArgumentException;
class ConvertValidityTimesToUtcService
{
/**
* @param array<int, int> $ids
* @return array<int, array<string, mixed>>
*/
public function run(array $ids, string $timezone, bool $apply = false, bool $all = false, bool $reverse = false): array
{
if (! in_array($timezone, DateTimeZone::listIdentifiers(DateTimeZone::ALL_WITH_BC), true)) {
throw new InvalidArgumentException('Zona horaria inválida.');
}
if ($all === ($ids !== [])) {
throw new InvalidArgumentException('Indicar --all o --ids, exclusivamente una opción.');
}
return DB::transaction(function () use ($ids, $timezone, $apply, $all, $reverse): array {
$query = DB::table('validity_times')->orderBy('id');
$all ? $query->where('type', 'fixed_window') : $query->whereIn('id', $ids);
if ($apply) {
$query->lockForUpdate();
}
$rows = $query->get();
if (! $all && $rows->count() !== count(array_unique($ids))) {
throw new InvalidArgumentException('Uno o más IDs no existen.');
}
if ($rows->contains(fn ($row): bool => $row->type !== 'fixed_window')) {
throw new InvalidArgumentException('Sólo se admiten IDs de fixed_window.');
}
$source = $reverse ? 'UTC' : $timezone;
$target = $reverse ? $timezone : 'UTC';
$result = [];
foreach ($rows as $row) {
$convert = fn (?string $value): ?string => $value === null
? null
: CarbonImmutable::parse($value, $source)->setTimezone($target)->format('Y-m-d H:i:s');
$start = $convert($row->fixed_starts_at);
$end = $convert($row->fixed_expires_at);
$result[] = [
'id' => $row->id,
'original_start' => $row->fixed_starts_at,
'original_end' => $row->fixed_expires_at,
'result_start' => $start,
'result_end' => $end,
];
if ($apply) {
DB::table('validity_times')->where('id', $row->id)->update([
'fixed_starts_at' => $start,
'fixed_expires_at' => $end,
]);
}
}
return $result;
});
}
}