feat(events): add event categories and filtering

This commit is contained in:
2026-09-21 09:16:28 -03:00
parent b0702b7e15
commit 79d402e210
13 changed files with 134 additions and 8 deletions

View File

@@ -37,7 +37,8 @@ class TenantBootstrapService
'roles',
fn ($query) => $query->where('codigo', RoleCode::User->value)
),
'categories' => fn ($query) => $query->orderBy('nombre'),
$tenant->storefront_website_type_code === 'onticket_multi_event'
? 'eventCategories' : 'categories' => fn ($query) => $query->orderBy('nombre'),
]
);
}

View File

@@ -11,6 +11,7 @@ use App\Domains\Core\Client\Models\Client;
use App\Domains\Ticketing\Event\Models\EventDate;
use App\Domains\Ticketing\Event\Models\EventDateChange;
use App\Domains\Ticketing\Event\Models\Event;
use App\Domains\Ticketing\Event\Models\EventCategory;
use App\Domains\Core\Menu\Models\Menu;
use App\Domains\Core\Menu\Models\TenantMenu;
use App\Domains\Core\Tenant\Enums\CartEditingPolicy;
@@ -265,6 +266,12 @@ class Tenant extends Model
return $this->hasMany(Category::class, 'tenant_code', 'codigo');
}
/** @return HasMany<EventCategory, $this> */
public function eventCategories(): HasMany
{
return $this->hasMany(EventCategory::class, 'tenant_code', 'codigo');
}
/** @return HasMany<ScanAttempt, $this> */
public function scanAttempts(): HasMany
{

View File

@@ -99,10 +99,14 @@ class TenantResource extends JsonResource
'menues',
fn () => $this->menuTree($this->menues)
),
'categories' => $this->whenLoaded(
'categories',
fn () => $this->categoryTree($this->categories)
),
'categories' => $this->storefront_website_type_code === 'onticket_multi_event'
? $this->whenLoaded('eventCategories', fn () => $this->eventCategories
->map(fn ($category) => [
'id' => $category->id,
'nombre' => $category->nombre,
'subcategories' => [],
])->values())
: $this->whenLoaded('categories', fn () => $this->categoryTree($this->categories)),
];
}

View File

@@ -17,7 +17,12 @@ class PublicEventController extends Controller
abort_unless($tenant->storefront_website_type_code === 'onticket_multi_event', 404);
$term = trim((string) $request->validated('q', ''));
return PublicEventResource::collection($events->list($tenant, $term, (int) $request->validated('page', 1)));
return PublicEventResource::collection($events->list(
$tenant,
$term,
(int) $request->validated('page', 1),
$request->validated('category_id', null) === null ? null : (int) $request->validated('category_id'),
));
}
public function show(Tenant $tenant, Event $event, PublicEventService $events): PublicEventResource

View File

@@ -13,7 +13,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
#[Fillable(['tenant_code', 'title', 'subtitle', 'description', 'location', 'exact_location', 'date_text', 'published_at', 'attachment_id'])]
#[Fillable(['tenant_code', 'event_category_id', 'title', 'subtitle', 'description', 'location', 'exact_location', 'date_text', 'published_at', 'attachment_id'])]
class Event extends Model
{
use HasFactory;
@@ -29,6 +29,12 @@ class Event extends Model
return $this->belongsTo(Tenant::class, 'tenant_code', 'codigo');
}
/** @return BelongsTo<EventCategory, $this> */
public function eventCategory(): BelongsTo
{
return $this->belongsTo(EventCategory::class);
}
/** @return BelongsTo<Attachment, $this> */
public function attachment(): BelongsTo
{

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Domains\Ticketing\Event\Models;
use App\Domains\Core\Tenant\Models\Tenant;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
#[Fillable(['tenant_code', 'nombre'])]
class EventCategory extends Model
{
/** @return BelongsTo<Tenant, $this> */
public function tenant(): BelongsTo
{
return $this->belongsTo(Tenant::class, 'tenant_code', 'codigo');
}
/** @return HasMany<Event, $this> */
public function events(): HasMany
{
return $this->hasMany(Event::class);
}
}

View File

@@ -11,6 +11,7 @@ class ListPublicEventsRequest extends FormRequest
return [
'q' => ['sometimes', 'string', 'max:120'],
'page' => ['sometimes', 'integer', 'min:1'],
'category_id' => ['sometimes', 'integer', 'min:1'],
];
}
}

View File

@@ -15,6 +15,7 @@ class PublicEventResource extends JsonResource
{
return [
'id' => $this->id,
'event_category_id' => $this->event_category_id,
'title' => $this->title,
'subtitle' => $this->subtitle,
'description' => $this->description,

View File

@@ -8,12 +8,17 @@ use Illuminate\Contracts\Pagination\LengthAwarePaginator;
class PublicEventService
{
public function list(Tenant $tenant, string $term, int $page): LengthAwarePaginator
public function list(Tenant $tenant, string $term, int $page, ?int $categoryId = null): LengthAwarePaginator
{
$query = $tenant->events()
->whereNotNull('published_at')
->where('published_at', '<=', now());
if ($categoryId !== null) {
abort_unless($tenant->eventCategories()->whereKey($categoryId)->exists(), 404);
$query->where('event_category_id', $categoryId);
}
if ($term !== '') {
$query->where(function ($query) use ($term): void {
$query->where('title', 'like', '%'.$term.'%')