fix(ticket): temporarily disable maximum use date validation in ticket generation

This commit is contained in:
2026-07-27 17:01:08 -03:00
parent aa4f3303fc
commit 5107d858cc
3 changed files with 73 additions and 27 deletions

View File

@@ -7,7 +7,6 @@ use App\Domains\Catalog\Models\CatalogItem;
use App\Domains\Catalog\Models\Variant;
use App\Domains\Ticket\Exceptions\TicketGenerationException;
use App\Domains\Ticket\Models\Ticket;
use Carbon\CarbonInterface;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
@@ -27,14 +26,11 @@ class TicketGeneratorService
throw TicketGenerationException::invalidQuantity();
}
$now = now();
return DB::transaction(function () use ($catalogItem, $user, $quantity, $sourceVariantId, $now): Collection {
return DB::transaction(function () use ($catalogItem, $user, $quantity, $sourceVariantId): Collection {
$targets = $this->resolveTargets(
$catalogItem,
$quantity,
$sourceVariantId,
$now,
);
return $targets->map(function (array $target) use (
@@ -68,11 +64,10 @@ class TicketGeneratorService
CatalogItem $catalogItem,
int $quantity,
?int $sourceVariantId,
CarbonInterface $now,
): Collection {
if (! $catalogItem->isBundle()) {
$variant = $this->resolveVariant($catalogItem, $sourceVariantId);
$this->validateTarget($catalogItem, $variant, $now);
$this->validateTarget($catalogItem, $variant);
return Collection::times($quantity, fn (): array => [
'catalog_item' => $catalogItem,
@@ -90,10 +85,10 @@ class TicketGeneratorService
}
return $catalogItem->bundleComponents
->flatMap(function ($component) use ($quantity, $now): Collection {
->flatMap(function ($component) use ($quantity): Collection {
$componentItem = $component->catalogItem;
$variant = $component->variant;
$this->validateTarget($componentItem, $variant, $now);
$this->validateTarget($componentItem, $variant);
return Collection::times(
$quantity * $component->quantity,
@@ -133,16 +128,17 @@ class TicketGeneratorService
private function validateTarget(
CatalogItem $catalogItem,
?Variant $variant,
CarbonInterface $now,
): void {
if (! $catalogItem->has_tickets) {
throw TicketGenerationException::ticketsDisabled($catalogItem);
}
$selectedItem = $variant ?? $catalogItem;
if ($selectedItem->getMaximumUseDate()?->lessThanOrEqualTo($now)) {
throw TicketGenerationException::maximumUseDateReached($catalogItem);
}
// TODO: Reactivar esta validación cuando los pagos con productos vencidos
// deban rechazarse nuevamente. Se deja deshabilitada temporalmente.
// $selectedItem = $variant ?? $catalogItem;
//
// if ($selectedItem->getMaximumUseDate()?->lessThanOrEqualTo(now())) {
// throw TicketGenerationException::maximumUseDateReached($catalogItem);
// }
}
}

View File

@@ -259,6 +259,56 @@ class TelepagosWebhookTest extends TestCase
]);
}
public function test_webhook_confirms_a_purchase_when_its_ticket_use_date_has_ended(): void
{
$tenant = $this->createTenant('expired-ticket', 'Expired Ticket', 'expired-ticket.com.ar');
$this->configureTelepagosIntegration($tenant);
$user = User::factory()->create();
$variant = $this->createVariantForTenant('expired-ticket', 1, '50.00');
$variant->catalogItem->update([
'has_tickets' => true,
'maximum_use_date' => now()->subMinute(),
]);
$purchase = $this->createPendingTransferPurchase(
$tenant,
$user->id,
$variant->id,
1,
'87654321',
);
Http::fake([
'https://api.telepagos.com.ar/v2/auth/token' => Http::response([
'status' => 'ok',
'token' => 'test-token',
'expires_at' => now()->addHour()->toIso8601String(),
]),
'https://api.telepagos.com.ar/v2/payment/cashin/7001' => Http::response([
'status' => 'ok',
'data' => [
'amount' => 50,
'operation_id' => 1,
'transaction_id' => 'tx-expired-ticket',
'buyer' => ['cuit' => '20876543219'],
],
]),
]);
$this->postJson('/api/webhooks/telepagos/expired-ticket', ['id' => '7001'])
->assertOk()
->assertJsonPath('status', 'success');
$this->assertDatabaseHas('compras', [
'id' => $purchase->id,
'status' => Purchase::STATUS_PAID,
]);
$this->assertDatabaseHas('tickets', [
'source_catalog_item_id' => $variant->catalog_item_id,
'source_variant_id' => $variant->id,
'user_id' => $user->id,
]);
}
private function createPendingTransferPurchase(
Tenant $tenant,
int $userId,

View File

@@ -84,14 +84,14 @@ class TicketGeneratorServiceTest extends TestCase
$this->service->generate($item->fresh(), $this->user);
}
public function test_it_rejects_an_item_when_its_maximum_use_date_was_reached(): void
public function test_it_generates_a_ticket_when_its_maximum_use_date_was_reached(): void
{
$item = $this->createTicketableItem('expired', maximumUseDate: now());
$this->expectException(TicketGenerationException::class);
$this->expectExceptionMessage('alcanzó su fecha máxima de uso');
$tickets = $this->service->generate($item, $this->user);
$this->service->generate($item, $this->user);
$this->assertCount(1, $tickets);
$this->assertTrue($tickets->first()->expires_at->equalTo($item->maximum_use_date));
}
public function test_variant_dates_override_and_inherit_catalog_item_dates(): void
@@ -228,18 +228,18 @@ class TicketGeneratorServiceTest extends TestCase
Event::assertNotDispatched(TicketsAvailable::class);
}
public function test_paid_status_is_rolled_back_when_ticket_generation_fails(): void
public function test_paid_status_is_confirmed_when_ticket_maximum_use_date_was_reached(): void
{
$item = $this->createTicketableItem('expired-paid-ticket', maximumUseDate: now());
$purchase = $this->createPurchase($item, 1);
try {
$purchase->markAsPaid();
$this->fail('La generación debería haber fallado.');
} catch (TicketGenerationException) {
$this->assertSame(Purchase::STATUS_PENDING_PAYMENT, $purchase->fresh()->status);
$this->assertDatabaseCount('tickets', 0);
}
$purchase->markAsPaid();
$this->assertSame(Purchase::STATUS_PAID, $purchase->fresh()->status);
$this->assertDatabaseHas('tickets', [
'source_catalog_item_id' => $item->id,
'user_id' => $purchase->user_id,
]);
}
private function createTicketableItem(