diff --git a/app/Domains/Event/Models/Event.php b/app/Domains/Event/Models/Event.php index 52ac62e..15582f7 100644 --- a/app/Domains/Event/Models/Event.php +++ b/app/Domains/Event/Models/Event.php @@ -3,6 +3,7 @@ namespace App\Domains\Event\Models; use App\Domains\Catalog\Models\CatalogItem; +use App\Domains\Purchase\Models\Purchase; use App\Domains\Tenant\Models\Tenant; use Illuminate\Database\Eloquent\Attributes\Fillable; use Illuminate\Database\Eloquent\Factories\HasFactory; @@ -38,4 +39,10 @@ class Event extends Model { return $this->hasMany(CatalogItem::class); } + + /** @return HasMany */ + public function purchases(): HasMany + { + return $this->hasMany(Purchase::class); + } } diff --git a/app/Domains/Purchase/Models/Purchase.php b/app/Domains/Purchase/Models/Purchase.php index a5dcb11..698f4df 100644 --- a/app/Domains/Purchase/Models/Purchase.php +++ b/app/Domains/Purchase/Models/Purchase.php @@ -4,6 +4,7 @@ namespace App\Domains\Purchase\Models; use App\Domains\Auth\Models\User; use App\Domains\Cart\Models\Cart; +use App\Domains\Event\Models\Event; use App\Domains\Logging\Models\Concerns\LogsValueChanges; use App\Domains\Purchase\Events\PurchasePaid; use App\Domains\Tenant\Models\Tenant; @@ -19,6 +20,7 @@ use Illuminate\Support\Facades\DB; #[Fillable([ 'cart_id', 'tenant_codigo', + 'event_id', 'user_id', 'status', 'payment_method', @@ -70,6 +72,7 @@ class Purchase extends Model { return [ 'cart_id' => 'integer', + 'event_id' => 'integer', 'user_id' => 'integer', 'expires_at' => 'datetime', 'total' => 'decimal:2', @@ -84,6 +87,12 @@ class Purchase extends Model return $this->belongsTo(Tenant::class, 'tenant_codigo', 'codigo'); } + /** @return BelongsTo */ + public function event(): BelongsTo + { + return $this->belongsTo(Event::class); + } + /** * @return BelongsTo */ diff --git a/app/Domains/Purchase/Resources/PurchaseResource.php b/app/Domains/Purchase/Resources/PurchaseResource.php index b383adc..161c7cf 100644 --- a/app/Domains/Purchase/Resources/PurchaseResource.php +++ b/app/Domains/Purchase/Resources/PurchaseResource.php @@ -42,6 +42,7 @@ class PurchaseResource extends JsonResource 'id' => $this->id, 'cart_id' => $this->cart_id, 'tenant_codigo' => $this->tenant_codigo, + 'event_id' => $this->event_id, 'user_id' => $this->user_id, 'created_at' => $this->created_at, 'status' => $this->status, diff --git a/app/Domains/Purchase/Services/CheckoutService.php b/app/Domains/Purchase/Services/CheckoutService.php index 90431c8..3da31e6 100644 --- a/app/Domains/Purchase/Services/CheckoutService.php +++ b/app/Domains/Purchase/Services/CheckoutService.php @@ -26,6 +26,11 @@ class CheckoutService public function startCheckout(Tenant $tenant, int $userId, array $purchaseData): Purchase { return DB::transaction(function () use ($tenant, $userId, $purchaseData): Purchase { + /** @var Tenant $tenant */ + $tenant = Tenant::query() + ->lockForUpdate() + ->findOrFail($tenant->getKey()); + $directItem = $purchaseData['direct_item'] ?? null; $cartId = isset($purchaseData['cart_id']) ? (int) $purchaseData['cart_id'] : null; unset($purchaseData['direct_item'], $purchaseData['cart_id']); @@ -615,6 +620,7 @@ class CheckoutService ...$purchaseData, 'cart_id' => $cartId, 'tenant_codigo' => $tenant->codigo, + 'event_id' => $tenant->active_event_id, 'user_id' => $userId, 'status' => Purchase::STATUS_CREATED, 'payment_method' => null, diff --git a/database/migrations/2026_08_04_000100_add_event_id_to_compras_table.php b/database/migrations/2026_08_04_000100_add_event_id_to_compras_table.php new file mode 100644 index 0000000..30b87fa --- /dev/null +++ b/database/migrations/2026_08_04_000100_add_event_id_to_compras_table.php @@ -0,0 +1,26 @@ +foreignId('event_id') + ->nullable() + ->after('tenant_codigo') + ->constrained('events') + ->nullOnDelete(); + }); + } + + public function down(): void + { + Schema::table('compras', function (Blueprint $table): void { + $table->dropConstrainedForeignId('event_id'); + }); + } +}; diff --git a/tests/Feature/Purchase/StorePurchaseTest.php b/tests/Feature/Purchase/StorePurchaseTest.php index bd9be50..ab003c7 100644 --- a/tests/Feature/Purchase/StorePurchaseTest.php +++ b/tests/Feature/Purchase/StorePurchaseTest.php @@ -11,6 +11,7 @@ use App\Domains\Catalog\Models\CatalogItem; use App\Domains\Catalog\Models\Category; use App\Domains\Catalog\Models\Inventory; use App\Domains\Catalog\Models\Variant; +use App\Domains\Event\Models\Event; use App\Domains\Purchase\Models\Purchase; use App\Domains\Purchase\Services\CheckoutService; use App\Domains\Tenant\Models\Tenant; @@ -33,6 +34,12 @@ class StorePurchaseTest extends TestCase public function test_it_creates_an_independent_purchase_snapshot_from_cart(): void { $tenant = $this->createTenant('sonder', 'Sonder', 'sonder.com.ar'); + $event = Event::query()->create([ + 'tenant_code' => $tenant->codigo, + 'name' => 'Sonder Fest', + 'address' => 'Test address', + ]); + $tenant->update(['active_event_id' => $event->id]); $user = User::factory()->create([ 'email' => 'buyer@example.com', ]); @@ -85,6 +92,7 @@ class StorePurchaseTest extends TestCase $response->assertJsonPath('data.nombre_apellido', null); $response->assertJsonPath('data.email', null); $response->assertJsonPath('data.tenant_codigo', 'sonder'); + $response->assertJsonPath('data.event_id', $event->id); $response->assertJsonPath('data.status', Purchase::STATUS_CREATED); $response->assertJsonPath('data.items_source', 'purchase'); $response->assertJsonCount(1, 'data.items'); @@ -97,6 +105,7 @@ class StorePurchaseTest extends TestCase 'id' => $purchaseId, 'cart_id' => $cartId, 'tenant_codigo' => 'sonder', + 'event_id' => $event->id, 'user_id' => $user->id, 'dni' => null, 'telefono' => null, diff --git a/tests/Unit/Forms/SaleFormServiceTest.php b/tests/Unit/Forms/SaleFormServiceTest.php new file mode 100644 index 0000000..41bdab2 --- /dev/null +++ b/tests/Unit/Forms/SaleFormServiceTest.php @@ -0,0 +1,25 @@ +get(); + + $this->assertSame(Purchase::statuses(), array_column($form['statuses'], 'code')); + $this->assertSame([ + 'Creada', + 'Esperando pago', + 'Confirmada', + 'Cancelada', + 'Rechazada', + 'Vencida', + ], array_column($form['statuses'], 'name')); + } +}