diff --git a/app/Domains/Commerce/Purchase/Resources/PurchaseItemResource.php b/app/Domains/Commerce/Purchase/Resources/PurchaseItemResource.php index 75162a6..29547f6 100644 --- a/app/Domains/Commerce/Purchase/Resources/PurchaseItemResource.php +++ b/app/Domains/Commerce/Purchase/Resources/PurchaseItemResource.php @@ -3,6 +3,7 @@ namespace App\Domains\Commerce\Purchase\Resources; use App\Domains\Commerce\Purchase\Models\PurchaseItem; +use App\Domains\Core\Tenant\Models\StorefrontWebsiteType; use App\Domains\Core\Tenant\Models\Tenant; use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\JsonResource; @@ -14,7 +15,11 @@ class PurchaseItemResource extends JsonResource public function toArray(Request $request): array { $tenant = $request->route('tenant'); - $displayImage = ! $tenant instanceof Tenant || $tenant->display_cart_item_images; + $usesEventSummary = $tenant instanceof Tenant + && $tenant->storefrontWebsiteType?->checkout_summary_type + === StorefrontWebsiteType::CHECKOUT_SUMMARY_EVENT; + $displayImage = ! $tenant instanceof Tenant + || (! $usesEventSummary && $tenant->display_cart_item_images); $imageUrl = $displayImage ? $this->imageAttachment?->getTemporaryUrl(1440) @@ -31,7 +36,7 @@ class PurchaseItemResource extends JsonResource 'nombre' => $this->item_nombre, 'descripcion' => $this->descripcion, 'slug' => $this->slug, - 'imagen' => $imageUrl, + 'imagen' => $this->when(! $usesEventSummary, $imageUrl), 'attributes' => $this->variant_attributes ?? [], ], ]; diff --git a/app/Domains/Commerce/Purchase/Resources/PurchaseResource.php b/app/Domains/Commerce/Purchase/Resources/PurchaseResource.php index 029495f..2e98a2e 100644 --- a/app/Domains/Commerce/Purchase/Resources/PurchaseResource.php +++ b/app/Domains/Commerce/Purchase/Resources/PurchaseResource.php @@ -5,6 +5,9 @@ namespace App\Domains\Commerce\Purchase\Resources; use App\Domains\Commerce\Purchase\Models\Purchase; use App\Domains\Commerce\Purchase\Models\PurchaseItem; use App\Domains\Commerce\Purchase\Models\TelepagosPaymentCandidate; +use App\Domains\Core\Tenant\Models\StorefrontWebsiteType; +use App\Domains\Core\Tenant\Models\Tenant; +use App\Domains\Ticketing\Event\Models\Event; use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\JsonResource; @@ -27,6 +30,18 @@ class PurchaseResource extends JsonResource ? (int) $this->resource->getAttribute('tickets_count') : null; $paymentVerification = $this->resolvePaymentVerification(); + $tenant = $request->route('tenant'); + $usesEventSummary = $tenant instanceof Tenant + && $tenant->storefrontWebsiteType?->checkout_summary_type + === StorefrontWebsiteType::CHECKOUT_SUMMARY_EVENT; + /** @var Event|null $checkoutEvent */ + $checkoutEvent = $usesEventSummary + ? $items + ->map(fn (PurchaseItem $item) => $item->sourceCatalogItem?->event) + ->filter() + ->unique('id') + ->first() + : null; $subtotal = $items->isNotEmpty() ? $items->reduce( @@ -64,6 +79,13 @@ class PurchaseResource extends JsonResource 'email' => $this->email, 'items_source' => $items->isNotEmpty() ? 'purchase' : null, 'items' => PurchaseItemResource::collection($items), + 'event' => $this->when($usesEventSummary, fn () => $checkoutEvent === null + ? null + : [ + 'id' => $checkoutEvent->id, + 'title' => $checkoutEvent->title, + 'image' => $checkoutEvent->attachment?->getTemporaryUrl(1440), + ]), 'tickets_count' => $this->when($ticketsCount !== null, $ticketsCount), 'has_generated_tickets' => $this->when($ticketsCount !== null, $ticketsCount > 0), 'payment_verification' => $this->when($paymentVerification !== null, $paymentVerification), diff --git a/app/Domains/Commerce/Purchase/Services/Checkout/PurchaseResponseLoader.php b/app/Domains/Commerce/Purchase/Services/Checkout/PurchaseResponseLoader.php index 1da4684..ed82d2d 100644 --- a/app/Domains/Commerce/Purchase/Services/Checkout/PurchaseResponseLoader.php +++ b/app/Domains/Commerce/Purchase/Services/Checkout/PurchaseResponseLoader.php @@ -3,12 +3,24 @@ namespace App\Domains\Commerce\Purchase\Services\Checkout; use App\Domains\Commerce\Purchase\Models\Purchase; +use App\Domains\Core\Tenant\Models\StorefrontWebsiteType; class PurchaseResponseLoader { public function load(Purchase $purchase): Purchase { - $relations = ['tenant', 'items.imageAttachment', 'stockReservation']; + $purchase->loadMissing('tenant.storefrontWebsiteType'); + $usesEventSummary = $purchase->tenant?->storefrontWebsiteType?->checkout_summary_type + === StorefrontWebsiteType::CHECKOUT_SUMMARY_EVENT; + $relations = [ + 'tenant', + 'items.sourceCatalogItem.event.attachment', + 'stockReservation', + ]; + + if (! $usesEventSummary) { + $relations[] = 'items.imageAttachment'; + } if ( $purchase->status === Purchase::STATUS_IN_REVIEW diff --git a/tests/Feature/Purchase/PurchaseCatalogItemTest.php b/tests/Feature/Purchase/PurchaseCatalogItemTest.php index bb44660..6890c13 100644 --- a/tests/Feature/Purchase/PurchaseCatalogItemTest.php +++ b/tests/Feature/Purchase/PurchaseCatalogItemTest.php @@ -2,14 +2,16 @@ namespace Tests\Feature\Purchase; -use App\Shared\Attachable\Enums\AttachmentType; -use App\Shared\Attachable\Models\Attachment; -use App\Domains\Core\Auth\Models\User; use App\Domains\Commerce\Cart\Models\Cart; use App\Domains\Commerce\Catalog\Models\CatalogItem; use App\Domains\Commerce\Catalog\Models\Inventory; use App\Domains\Commerce\Purchase\Services\CheckoutService; +use App\Domains\Core\Auth\Models\User; +use App\Domains\Core\Tenant\Models\StorefrontWebsiteType; use App\Domains\Core\Tenant\Models\Tenant; +use App\Domains\Ticketing\Event\Models\Event; +use App\Shared\Attachable\Enums\AttachmentType; +use App\Shared\Attachable\Models\Attachment; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Storage; @@ -117,6 +119,70 @@ class PurchaseCatalogItemTest extends TestCase ]); } + public function test_multi_event_checkout_returns_only_the_event_image(): void + { + Storage::fake('s3'); + Storage::disk('s3')->buildTemporaryUrlsUsing( + fn (string $path): string => "https://snapshots.test/{$path}", + ); + + StorefrontWebsiteType::query()->create([ + 'codigo' => 'onticket_multi_event', + 'nombre' => 'OnTicket - mĂșltiples eventos', + 'header_type' => 'immersive', + 'checkout_summary_type' => StorefrontWebsiteType::CHECKOUT_SUMMARY_EVENT, + ]); + $tenant = $this->createTenant(); + $tenant->update(['storefront_website_type_code' => 'onticket_multi_event']); + $user = User::factory()->create(); + + $eventImage = $this->createAttachment('checkout-event'); + $productImage = $this->createAttachment('checkout-product'); + Storage::disk('s3')->put($eventImage->path, 'event-image'); + Storage::disk('s3')->put($productImage->path, 'product-image'); + + $event = Event::query()->create([ + 'tenant_code' => $tenant->codigo, + 'title' => 'Festival de prueba', + 'published_at' => now(), + 'attachment_id' => $eventImage->id, + ]); + $inventory = Inventory::query()->create(['real_stock' => 10]); + $catalogItem = CatalogItem::query()->create([ + 'tenant_code' => $tenant->codigo, + 'inventory_id' => $inventory->id, + 'slug' => 'entrada-general', + 'nombre' => 'Entrada general', + 'precio' => 10000, + ]); + $catalogItem->event_id = $event->id; + $catalogItem->save(); + $catalogItem->attachments()->attach($productImage->id, ['orden' => 0]); + + $cart = Cart::query()->create([ + 'tenant_codigo' => $tenant->codigo, + 'user_id' => $user->id, + 'status' => 'active', + ]); + $cart->addItem($catalogItem->id, null, 1); + + $purchase = app(CheckoutService::class)->startCheckout($tenant, $user->id, [ + 'cart_id' => $cart->id, + 'dni' => '12345678', + 'telefono' => '123456789', + 'nombre_apellido' => 'Test User', + 'email' => 'test@example.com', + ]); + + $this->actingAs($user, 'sanctum') + ->getJson("/api/tenants/{$tenant->codigo}/compras/{$purchase->id}") + ->assertOk() + ->assertJsonMissingPath('data.items.0.item_details.imagen') + ->assertJsonPath('data.event.id', $event->id) + ->assertJsonPath('data.event.title', 'Festival de prueba') + ->assertJsonPath('data.event.image', "https://snapshots.test/{$eventImage->path}"); + } + private function createTenant(): Tenant { $headerLogo = $this->createAttachment('purchase-header');