Add tests for ticket validity and event date formatting
- Create TicketValiditySchemaTest to verify database schema for ticket validity. - Update CatalogModelsTest to include tests for event date attributes and selection options. - Introduce EventDateTextFormatterTest for formatting event dates in Spanish. - Refactor EventModelsTest to include validity time relationships. - Add SaleDetailResourceTest to ensure correct serialization of purchase items. - Enhance TicketTest with validity time checks and status management. - Implement ValidityTimeResourceTest to validate resource output for different validity types. - Add ValidityTimeTest to verify casting and validity checks for validity time types.
This commit is contained in:
@@ -5,20 +5,20 @@ namespace App\Domains\Catalog\Models;
|
||||
use App\Domains\Attachable\Models\Attachment;
|
||||
use App\Domains\Event\Models\EventDate;
|
||||
use App\Domains\Ticket\Models\Ticket;
|
||||
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\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
#[Fillable([
|
||||
'catalog_item_id',
|
||||
'event_date_id',
|
||||
'inventory_id',
|
||||
'minimum_use_date',
|
||||
'maximum_use_date',
|
||||
'descripcion',
|
||||
'precio',
|
||||
])]
|
||||
class Variant extends Model
|
||||
{
|
||||
@@ -34,8 +34,7 @@ class Variant extends Model
|
||||
'catalog_item_id' => 'integer',
|
||||
'event_date_id' => 'integer',
|
||||
'inventory_id' => 'integer',
|
||||
'minimum_use_date' => 'datetime',
|
||||
'maximum_use_date' => 'datetime',
|
||||
'precio' => 'decimal:2',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -51,6 +50,17 @@ class Variant extends Model
|
||||
return $this->belongsTo(EventDate::class);
|
||||
}
|
||||
|
||||
/** @return BelongsToMany<EventDate, $this> */
|
||||
public function eventDates(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(
|
||||
EventDate::class,
|
||||
'variant_event_dates',
|
||||
'variant_id',
|
||||
'event_date_id',
|
||||
)->orderBy('date')->orderBy('time_start');
|
||||
}
|
||||
|
||||
/** @return HasMany<Ticket, $this> */
|
||||
public function sourceTickets(): HasMany
|
||||
{
|
||||
@@ -90,7 +100,12 @@ class Variant extends Model
|
||||
|
||||
public function getPrice(): float
|
||||
{
|
||||
return $this->catalogItem->getPrice();
|
||||
return (float) ($this->precio ?? $this->catalogItem->precio);
|
||||
}
|
||||
|
||||
public function getDescription(): ?string
|
||||
{
|
||||
return $this->descripcion ?? $this->catalogItem->descripcion;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
@@ -98,17 +113,132 @@ class Variant extends Model
|
||||
return $this->catalogItem->nombre;
|
||||
}
|
||||
|
||||
public function getMinimumUseDate(): ?CarbonInterface
|
||||
/** @return Collection<string, string|array<int, string>> */
|
||||
public function selectionValues(): Collection
|
||||
{
|
||||
return $this->eventDate?->startsAt()
|
||||
?? $this->minimum_use_date
|
||||
?? $this->catalogItem->getMinimumUseDate();
|
||||
$values = $this->definitions
|
||||
->groupBy('item_attribute_id')
|
||||
->mapWithKeys(function (Collection $definitions): array {
|
||||
$itemAttribute = $definitions->first()?->itemAttribute;
|
||||
$attributeCode = $itemAttribute?->attribute?->codigo;
|
||||
|
||||
if ($attributeCode === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$definitionValues = $definitions->pluck('value')->values();
|
||||
|
||||
return [
|
||||
$attributeCode => $itemAttribute->allow_multi_select
|
||||
? $definitionValues->all()
|
||||
: $definitionValues->first(),
|
||||
];
|
||||
});
|
||||
|
||||
$eventDateIds = $this->selectedEventDates()
|
||||
->pluck('id')
|
||||
->map(fn ($id): string => (string) $id)
|
||||
->values();
|
||||
|
||||
if ($eventDateIds->count() === 1) {
|
||||
$values->put('event_date', $eventDateIds->first());
|
||||
} elseif ($eventDateIds->isNotEmpty()) {
|
||||
$values->put('event_date', $eventDateIds->all());
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
public function getMaximumUseDate(): ?CarbonInterface
|
||||
/**
|
||||
* @return Collection<string, array{value: string, label: string}|array<int, array{value: string, label: string}>>
|
||||
*/
|
||||
public function selectionOptions(?Collection $itemAttributes = null): Collection
|
||||
{
|
||||
return $this->eventDate?->endsAt()
|
||||
?? $this->maximum_use_date
|
||||
?? $this->catalogItem->getMaximumUseDate();
|
||||
$options = $this->definitions
|
||||
->groupBy('item_attribute_id')
|
||||
->mapWithKeys(function (Collection $definitions): array {
|
||||
$itemAttribute = $definitions->first()?->itemAttribute;
|
||||
$attribute = $itemAttribute?->attribute;
|
||||
$attributeCode = $attribute?->codigo;
|
||||
|
||||
if ($attributeCode === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$values = $definitions
|
||||
->pluck('value')
|
||||
->values()
|
||||
->map(function (string $value) use ($attribute): array {
|
||||
$attributeOption = $attribute->options->firstWhere('value', $value);
|
||||
|
||||
return [
|
||||
'value' => $value,
|
||||
'label' => $attributeOption?->label ?? $value,
|
||||
];
|
||||
});
|
||||
|
||||
return [
|
||||
$attributeCode => $itemAttribute->allow_multi_select
|
||||
? $values->all()
|
||||
: $values->first(),
|
||||
];
|
||||
});
|
||||
|
||||
$eventDateOptions = $this->selectedEventDates()
|
||||
->map(fn (EventDate $eventDate): array => [
|
||||
'value' => (string) $eventDate->id,
|
||||
'label' => $eventDate->date->format('d/m/Y'),
|
||||
])
|
||||
->values();
|
||||
|
||||
if ($eventDateOptions->count() === 1) {
|
||||
$options->put('event_date', $eventDateOptions->first());
|
||||
} elseif ($eventDateOptions->isNotEmpty()) {
|
||||
$options->put('event_date', $eventDateOptions->all());
|
||||
}
|
||||
|
||||
if ($itemAttributes === null) {
|
||||
$itemAttributes = $this->definitions
|
||||
->map(fn (VariantDefinition $definition) => $definition->itemAttribute)
|
||||
->filter()
|
||||
->unique('id')
|
||||
->values();
|
||||
|
||||
if ($this->catalogItem !== null) {
|
||||
$itemAttributes = $itemAttributes
|
||||
->merge($this->catalogItem->itemAttributes)
|
||||
->unique('id')
|
||||
->values();
|
||||
}
|
||||
}
|
||||
|
||||
$ordering = $itemAttributes->mapWithKeys(function (ItemAttribute $itemAttribute): array {
|
||||
$attribute = $itemAttribute->attribute;
|
||||
|
||||
return $attribute === null
|
||||
? []
|
||||
: [$attribute->codigo => [$itemAttribute->sort_order, mb_strtolower($attribute->nombre)]];
|
||||
});
|
||||
|
||||
return $options->sortKeysUsing(function (string $left, string $right) use ($ordering): int {
|
||||
[$leftOrder, $leftLabel] = $ordering->get($left, [0, mb_strtolower($left)]);
|
||||
[$rightOrder, $rightLabel] = $ordering->get($right, [0, mb_strtolower($right)]);
|
||||
|
||||
return $leftOrder <=> $rightOrder
|
||||
?: $leftLabel <=> $rightLabel
|
||||
?: $left <=> $right;
|
||||
});
|
||||
}
|
||||
|
||||
/** @return Collection<int, EventDate> */
|
||||
public function selectedEventDates(): Collection
|
||||
{
|
||||
$eventDates = $this->eventDates;
|
||||
|
||||
if ($eventDates->isEmpty() && $this->event_date_id !== null && $this->eventDate !== null) {
|
||||
return collect([$this->eventDate]);
|
||||
}
|
||||
|
||||
return $eventDates;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user