feat(catalog): add sales_end_at field to catalog items and implement sale logic
feat(event): include catalog items in event resource and update event service test(seeder): add FiestaTradicionArrufoSeeder for event and catalog item setup config: set event timezone for local event dates
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('catalog_items', function (Blueprint $table): void {
|
||||
$table->timestamp('sales_end_at')->nullable()->after('precio');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('catalog_items', function (Blueprint $table): void {
|
||||
$table->dropColumn('sales_end_at');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -33,6 +33,7 @@ class DatabaseSeeder extends Seeder
|
||||
BrandSeeder::class,
|
||||
ProductCatalogFromImagesSeeder::class,
|
||||
FiestaFutbolInfantilProductSeeder::class,
|
||||
FiestaTradicionArrufoSeeder::class,
|
||||
TelepagosIntegrationSeeder::class,
|
||||
EmailIntegrationSeeder::class,
|
||||
MenuSeeder::class,
|
||||
|
||||
109
database/seeders/FiestaTradicionArrufoSeeder.php
Normal file
109
database/seeders/FiestaTradicionArrufoSeeder.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Domains\Commerce\Catalog\Enums\InventoryPolicy;
|
||||
use App\Domains\Commerce\Catalog\Models\CatalogItem;
|
||||
use App\Domains\Commerce\Catalog\Models\Attribute;
|
||||
use App\Domains\Commerce\Catalog\Services\CatalogService;
|
||||
use App\Domains\Core\Tenant\Models\Tenant;
|
||||
use App\Domains\Ticketing\Event\Models\Event;
|
||||
use App\Shared\Attachable\Services\AttachmentService;
|
||||
use App\Shared\Enums\FieldType;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Carbon;
|
||||
use RuntimeException;
|
||||
|
||||
class FiestaTradicionArrufoSeeder extends Seeder
|
||||
{
|
||||
private const TITLE = '26.º Fiesta de la Tradición y 4.º Encuentro de Agrupaciones Gauchas';
|
||||
|
||||
private const IMAGE = __DIR__.'/assets/fiesta-tradicion-arrufo-2026.png';
|
||||
|
||||
public function __construct(
|
||||
private readonly CatalogService $catalog,
|
||||
private readonly AttachmentService $attachments,
|
||||
) {}
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$tenant = Tenant::query()->where('codigo', 'onticket')->first();
|
||||
|
||||
if ($tenant === null) {
|
||||
throw new RuntimeException("Tenant 'onticket' no encontrado.");
|
||||
}
|
||||
|
||||
Attribute::query()->firstOrCreate(
|
||||
['tenant_codigo' => $tenant->codigo, 'codigo' => 'event_date'],
|
||||
['nombre' => 'Fecha', 'type' => FieldType::EventDate, 'is_required' => true],
|
||||
);
|
||||
|
||||
$event = Event::query()->firstOrCreate(
|
||||
['tenant_code' => $tenant->codigo, 'title' => self::TITLE],
|
||||
['published_at' => now()],
|
||||
);
|
||||
$event->update([
|
||||
'subtitle' => 'Una noche para celebrar nuestras raíces y mantener viva la tradición gaucha.',
|
||||
'description' => 'La 26.º Fiesta de la Tradición y 4.º Encuentro de Agrupaciones Gauchas reunirá a agrupaciones, artesanos, pilcheros y público en general para compartir una jornada dedicada a nuestras costumbres y cultura.'
|
||||
."\n\n".'Un encuentro para disfrutar de la tradición, la identidad gaucha y el espíritu de camaradería, en el Predio de Doma del Club Unión Deportiva Arrufó.'
|
||||
."\n\n".'Organiza: Biblioteca Popular Miguel Ángel Sosa.',
|
||||
'location' => 'Predio de Doma del Club Unión Deportiva Arrufó',
|
||||
]);
|
||||
|
||||
if ($event->attachment_id === null) {
|
||||
$event->update(['attachment_id' => $this->attachments->store($this->image(), 'events')->id]);
|
||||
}
|
||||
|
||||
// La hora de cierre es provisoria hasta que la organización la confirme.
|
||||
$date = $event->dates()->firstOrCreate(
|
||||
['date' => '2026-11-14'],
|
||||
['tenant_code' => $tenant->codigo, 'time_start' => '19:00', 'time_end' => '23:59'],
|
||||
);
|
||||
|
||||
$this->createItem($tenant, $event, $date->id, [
|
||||
'slug' => 'fiesta-tradicion-arrufo-2026-entrada-anticipada',
|
||||
'nombre' => 'Entrada anticipada',
|
||||
'descripcion' => 'Entrada para personas de 12 años en adelante. Venta anticipada hasta el 13/11/2026 a las 22:00 h.',
|
||||
'precio' => 12000,
|
||||
'sales_end_at' => Carbon::parse('2026-11-13 22:00:00', 'America/Argentina/Buenos_Aires')->utc(),
|
||||
'group_order' => 1,
|
||||
]);
|
||||
|
||||
$this->createItem($tenant, $event, $date->id, [
|
||||
'slug' => 'fiesta-tradicion-arrufo-2026-puesto-feria',
|
||||
'nombre' => 'Espacio para puesto en la feria',
|
||||
'descripcion' => 'Para artesanos, pilcheros y otros puestos de venta. Incluye una entrada para la persona que atiende el puesto. No se permiten puestos de venta de comidas ni bebidas.',
|
||||
'precio' => 50000,
|
||||
'group_order' => 2,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $data */
|
||||
private function createItem(Tenant $tenant, Event $event, int $dateId, array $data): void
|
||||
{
|
||||
$existing = CatalogItem::query()->where('tenant_code', $tenant->codigo)->where('slug', $data['slug'])->first();
|
||||
if ($existing !== null) {
|
||||
$existing->update(['sales_end_at' => $data['sales_end_at'] ?? null]);
|
||||
return;
|
||||
}
|
||||
|
||||
$item = $this->catalog->create([
|
||||
'tenant_code' => $tenant->codigo,
|
||||
'inventory_policy' => InventoryPolicy::Unlimited->value,
|
||||
'has_tickets' => true,
|
||||
'attribute_codes' => ['event_date'],
|
||||
'hidden_attribute_codes' => ['event_date'],
|
||||
'variants' => [['event_date_id' => $dateId]],
|
||||
'images' => [$this->image()],
|
||||
...$data,
|
||||
]);
|
||||
|
||||
$item->forceFill(['event_id' => $event->id])->save();
|
||||
}
|
||||
|
||||
private function image(): UploadedFile
|
||||
{
|
||||
return new UploadedFile(self::IMAGE, basename(self::IMAGE), 'image/png', null, true);
|
||||
}
|
||||
}
|
||||
BIN
database/seeders/assets/fiesta-tradicion-arrufo-2026.png
Normal file
BIN
database/seeders/assets/fiesta-tradicion-arrufo-2026.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 786 KiB |
Reference in New Issue
Block a user