feat(ticket): implement validity time management for tickets and catalog items

- Added ValidityTime model and migration to manage ticket validity periods.
- Updated TicketGeneratorService to resolve and assign validity times to tickets.
- Refactored ticket generation logic to remove legacy date fields and use validity time.
- Introduced timezone support for tenants to handle service dates correctly.
- Updated migrations to remove deprecated columns and add foreign keys for validity times.
- Modified seeders and tests to accommodate new validity time structure.
- Enhanced tests to validate ticket generation and validity time behavior.
This commit is contained in:
2026-08-06 15:52:19 -03:00
parent 7f01adab73
commit 448ffb4102
30 changed files with 556 additions and 381 deletions

View File

@@ -0,0 +1,87 @@
<?php
namespace App\Domains\Ticket\Models;
use App\Domains\Catalog\Models\AttributeOption;
use App\Domains\Catalog\Models\CatalogItem;
use App\Domains\Ticket\Enums\ValidityTimeType;
use Carbon\CarbonImmutable;
use Carbon\CarbonInterface;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
#[Fillable([
'type',
'start_time',
'end_time',
'fixed_starts_at',
'fixed_expires_at',
'active',
])]
class ValidityTime extends Model
{
use HasFactory;
protected function casts(): array
{
return [
'type' => ValidityTimeType::class,
'fixed_starts_at' => 'datetime',
'fixed_expires_at' => 'datetime',
'active' => 'boolean',
];
}
/** @return HasMany<CatalogItem, $this> */
public function catalogItems(): HasMany
{
return $this->hasMany(CatalogItem::class);
}
/** @return HasMany<AttributeOption, $this> */
public function attributeOptions(): HasMany
{
return $this->hasMany(AttributeOption::class);
}
/** @return HasMany<Ticket, $this> */
public function tickets(): HasMany
{
return $this->hasMany(Ticket::class);
}
public function startsAt(?CarbonInterface $serviceDate, string $timezone): ?CarbonInterface
{
if ($this->type === ValidityTimeType::FixedWindow) {
return $this->fixed_starts_at;
}
return $this->atServiceDate($serviceDate, $this->start_time, $timezone);
}
public function expiresAt(?CarbonInterface $serviceDate, string $timezone): ?CarbonInterface
{
if ($this->type === ValidityTimeType::FixedWindow) {
return $this->fixed_expires_at;
}
return $this->atServiceDate($serviceDate, $this->end_time, $timezone);
}
private function atServiceDate(
?CarbonInterface $serviceDate,
?string $time,
string $timezone,
): ?CarbonInterface {
if ($serviceDate === null || $time === null) {
return null;
}
return CarbonImmutable::parse(
$serviceDate->format('Y-m-d').' '.$time,
$timezone,
)->utc();
}
}