refactor(event): move event configuration onto tenant

This commit is contained in:
2026-08-07 09:08:14 -03:00
parent 60b8415c59
commit 7b7efeb4cc
27 changed files with 433 additions and 271 deletions

View File

@@ -12,7 +12,6 @@ use App\Domains\Catalog\Models\Category;
use App\Domains\Catalog\Models\Inventory;
use App\Domains\Catalog\Models\ItemAttribute;
use App\Domains\Catalog\Models\Variant;
use App\Domains\Event\Models\Event;
use App\Domains\Event\Models\EventDate;
use App\Domains\Tenant\Models\Tenant;
use Illuminate\Database\Eloquent\Builder;
@@ -47,7 +46,14 @@ class CatalogService
);
$hasVariants = $attributeCodes !== [] || $hasEventDateVariants;
$this->validateEventData($data);
if ($hasEventDateVariants && in_array('event_date', $attributeCodes, true)) {
throw ValidationException::withMessages([
'attribute_codes' => ['The event_date code is reserved for event dates.'],
]);
}
$this->validateEventProductType($data);
$this->validateUniqueVariantCombinations($variants, $attributeCodes);
if ($type === CatalogItemType::Bundle) {
$this->validateBundleData($data, $components);
@@ -127,7 +133,6 @@ class CatalogService
'inventory',
'category',
'brand',
'event',
'validityTime',
'itemAttributes.attribute',
'variants.inventory',
@@ -147,7 +152,6 @@ class CatalogService
'inventory',
'category',
'brand',
'event',
'validityTime',
'itemAttributes.attribute.options.validityTime',
'variants' => fn ($query) => $query->orderBy('id'),
@@ -492,16 +496,15 @@ class CatalogService
if (
$eventDateId !== null
&& (
$catalogItem->event_id === null
|| ! EventDate::query()
! EventDate::query()
->whereKey($eventDateId)
->where('event_id', $catalogItem->event_id)
->where('tenant_code', $catalogItem->tenant_code)
->exists()
)
) {
throw ValidationException::withMessages([
"variants.{$index}.event_date_id" => [
'The event date must belong to the catalog item event.',
'The event date must belong to the catalog item tenant.',
],
]);
}
@@ -533,30 +536,14 @@ class CatalogService
}
/** @param array<string, mixed> $data */
private function validateEventData(array $data): void
private function validateEventProductType(array $data): void
{
$eventId = $data['event_id'] ?? null;
$eventProductType = $data['event_product_type'] ?? null;
if (($eventId === null) !== ($eventProductType === null)) {
throw ValidationException::withMessages([
'event_id' => ['Event and event product type must be provided together.'],
]);
}
if ($eventId === null) {
if ($eventProductType === null) {
return;
}
if (! Event::query()
->whereKey($eventId)
->where('tenant_code', $data['tenant_code'] ?? null)
->exists()) {
throw ValidationException::withMessages([
'event_id' => ['The event must belong to the catalog item tenant.'],
]);
}
if (! in_array($eventProductType, EventProductType::values(), true)) {
throw ValidationException::withMessages([
'event_product_type' => ['The event product type is invalid.'],
@@ -564,6 +551,35 @@ class CatalogService
}
}
/**
* @param array<int, array<string, mixed>> $variants
* @param array<int, string> $attributeCodes
*/
private function validateUniqueVariantCombinations(array $variants, array $attributeCodes): void
{
$seen = [];
$attributeCodes = array_values(array_unique($attributeCodes));
sort($attributeCodes);
foreach (array_values($variants) as $index => $variant) {
$combination = [(string) ($variant['event_date_id'] ?? '')];
foreach ($attributeCodes as $attributeCode) {
$value = trim((string) ($variant['values'][$attributeCode] ?? ''));
$combination[] = Str::ascii(mb_strtolower($value));
}
$key = implode('|', $combination);
if (isset($seen[$key])) {
throw ValidationException::withMessages([
"variants.{$index}" => ['The variant combination must be unique.'],
]);
}
$seen[$key] = true;
}
}
/**
* @param array<string, mixed> $data
* @param array<int, array<string, mixed>> $variants