Files
shopit-back/app/Domains/Catalog/Models/Variant.php
ncoronel e1ad27ecf0 feat(food): implement FoodController, FoodService, and related resources for managing food items and variants
refactor(catalog): add description and price fields to variants and update related resources

feat(migration): add commercial overrides to variants with description and price fields

test(food): add tests for FoodController and ensure correct seeding of food items and variants
2026-08-07 14:17:51 -03:00

164 lines
4.5 KiB
PHP

<?php
namespace App\Domains\Catalog\Models;
use App\Domains\Attachable\Models\Attachment;
use App\Domains\Event\Models\EventDate;
use App\Domains\Ticket\Models\Ticket;
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',
'descripcion',
'precio',
])]
class Variant extends Model
{
use HasFactory;
public $timestamps = false;
protected $table = 'variantes';
protected function casts(): array
{
return [
'catalog_item_id' => 'integer',
'event_date_id' => 'integer',
'inventory_id' => 'integer',
'precio' => 'decimal:2',
];
}
/** @return BelongsTo<CatalogItem, $this> */
public function catalogItem(): BelongsTo
{
return $this->belongsTo(CatalogItem::class);
}
/** @return BelongsTo<EventDate, $this> */
public function eventDate(): BelongsTo
{
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
{
return $this->hasMany(Ticket::class, 'source_variant_id');
}
/** @return BelongsTo<Inventory, $this> */
public function inventory(): BelongsTo
{
return $this->belongsTo(Inventory::class);
}
/** @return HasMany<VariantDefinition, $this> */
public function definitions(): HasMany
{
return $this->hasMany(VariantDefinition::class);
}
/** @return BelongsToMany<Attachment, $this> */
public function attachments(): BelongsToMany
{
$relation = $this->belongsToMany(
Attachment::class,
'catalog_items_attachments',
'variant_id',
'attachment_id'
)
->withPivot('orden')
->orderByPivot('orden');
if ($this->catalog_item_id !== null) {
$relation->withPivotValue('catalog_item_id', $this->catalog_item_id);
}
return $relation;
}
public function getPrice(): float
{
return (float) ($this->precio ?? $this->catalogItem->precio);
}
public function getDescription(): ?string
{
return $this->descripcion ?? $this->catalogItem->descripcion;
}
public function getName(): string
{
return $this->catalogItem->nombre;
}
/** @return Collection<string, string|array<int, string>> */
public function selectionValues(): Collection
{
$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;
}
/** @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;
}
}