feat(purchase): refactor stock reservation expiration handling and update related tests
This commit is contained in:
@@ -343,9 +343,9 @@ class StockReservationService
|
||||
});
|
||||
}
|
||||
|
||||
public function refreshForPurchase(Purchase $purchase, ?Carbon $expiresAt): void
|
||||
public function clearExpirationForReview(Purchase $purchase): void
|
||||
{
|
||||
DB::transaction(function () use ($purchase, $expiresAt): void {
|
||||
DB::transaction(function () use ($purchase): void {
|
||||
/** @var Purchase $purchase */
|
||||
$purchase = Purchase::query()->lockForUpdate()->findOrFail($purchase->getKey());
|
||||
if ($purchase->stock_reservation_id === null) {
|
||||
@@ -363,7 +363,7 @@ class StockReservationService
|
||||
throw new StockReservationExpiredException;
|
||||
}
|
||||
|
||||
$reservation->update(['expires_at' => $expiresAt]);
|
||||
$reservation->update(['expires_at' => null]);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,6 @@ class PurchaseController extends Controller
|
||||
PaymentIntentRequest $request,
|
||||
Tenant $tenant,
|
||||
Purchase $compra,
|
||||
CheckoutService $checkoutService,
|
||||
PurchaseStateGuard $purchaseState,
|
||||
): JsonResponse {
|
||||
$compra = $this->resolveScopedPurchase($tenant, $request->user()->id, $compra);
|
||||
@@ -103,7 +102,6 @@ class PurchaseController extends Controller
|
||||
: null;
|
||||
|
||||
$updated = DB::transaction(function () use (
|
||||
$checkoutService,
|
||||
$compra,
|
||||
$method,
|
||||
$purchaseState,
|
||||
@@ -142,12 +140,6 @@ class PurchaseController extends Controller
|
||||
$purchaseUpdate['transfer_payer_dni'] = $transferPayerDni;
|
||||
}
|
||||
$purchase->update($purchaseUpdate);
|
||||
$checkoutService->refreshReservationExpiration(
|
||||
$purchase,
|
||||
now()->addMinutes(
|
||||
max(1, (int) config("purchase.payment_expiration_minutes.{$method}", 30)),
|
||||
),
|
||||
);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -70,7 +70,7 @@ class CompleteCheckoutService
|
||||
$purchase->update([
|
||||
'status' => Purchase::STATUS_IN_REVIEW,
|
||||
]);
|
||||
$this->reservations->refreshForPurchase($purchase, null);
|
||||
$this->reservations->clearExpirationForReview($purchase);
|
||||
|
||||
return $this->loadPurchase($purchase);
|
||||
});
|
||||
|
||||
@@ -2,14 +2,12 @@
|
||||
|
||||
namespace App\Domains\Purchase\Services;
|
||||
|
||||
use App\Domains\Catalog\Services\StockReservationService;
|
||||
use App\Domains\Purchase\Models\Purchase;
|
||||
use App\Domains\Purchase\Services\Checkout\CompleteCheckoutService;
|
||||
use App\Domains\Purchase\Services\Checkout\EditCheckoutService;
|
||||
use App\Domains\Purchase\Services\Checkout\ReleaseCheckoutService;
|
||||
use App\Domains\Purchase\Services\Checkout\StartCheckoutService;
|
||||
use App\Domains\Tenant\Models\Tenant;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
@@ -24,7 +22,6 @@ class CheckoutService
|
||||
private readonly EditCheckoutService $editor,
|
||||
private readonly CompleteCheckoutService $completer,
|
||||
private readonly ReleaseCheckoutService $releaser,
|
||||
private readonly StockReservationService $reservations,
|
||||
) {}
|
||||
|
||||
/** @param array<string, mixed> $purchaseData */
|
||||
@@ -78,9 +75,4 @@ class CheckoutService
|
||||
{
|
||||
return $this->releaser->expire($purchase);
|
||||
}
|
||||
|
||||
public function refreshReservationExpiration(Purchase $purchase, ?Carbon $expiresAt): void
|
||||
{
|
||||
$this->reservations->refreshForPurchase($purchase, $expiresAt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,4 @@
|
||||
|
||||
return [
|
||||
'checkout_expiration_minutes' => (int) env('PURCHASE_CHECKOUT_EXPIRATION_MINUTES', 30),
|
||||
|
||||
'payment_expiration_minutes' => [
|
||||
'qr' => (int) env('PURCHASE_QR_EXPIRATION_MINUTES', 15),
|
||||
'telepagos' => (int) env('PURCHASE_TELEPAGOS_EXPIRATION_MINUTES', 30),
|
||||
'transfer' => (int) env('PURCHASE_TRANSFER_EXPIRATION_MINUTES', 1440),
|
||||
],
|
||||
];
|
||||
|
||||
@@ -60,9 +60,9 @@ class TelepagosWebhookTest extends TestCase
|
||||
->assertJsonValidationErrors(['transfer_payer_dni']);
|
||||
}
|
||||
|
||||
public function test_transfer_payment_intent_persists_transfer_payer_dni_without_replacing_customer_dni(): void
|
||||
public function test_transfer_payment_intent_persists_data_without_extending_checkout_expiration(): void
|
||||
{
|
||||
config()->set('purchase.payment_expiration_minutes.transfer', 60);
|
||||
config()->set('purchase.checkout_expiration_minutes', 30);
|
||||
$now = now()->startOfSecond();
|
||||
$this->travelTo($now);
|
||||
|
||||
@@ -106,7 +106,7 @@ class TelepagosWebhookTest extends TestCase
|
||||
$this->assertDatabaseHas('stock_reservations', [
|
||||
'id' => $purchase->stock_reservation_id,
|
||||
'status' => 'active',
|
||||
'expires_at' => $now->copy()->addMinutes(60)->toDateTimeString(),
|
||||
'expires_at' => $now->copy()->addMinutes(30)->toDateTimeString(),
|
||||
]);
|
||||
|
||||
$this->travelBack();
|
||||
|
||||
@@ -796,12 +796,18 @@ class StorePurchaseTest extends TestCase
|
||||
|
||||
public function test_it_updates_customer_data_for_a_pending_payment_purchase(): void
|
||||
{
|
||||
config()->set('purchase.checkout_expiration_minutes', 30);
|
||||
$now = now()->startOfSecond();
|
||||
$this->travelTo($now);
|
||||
|
||||
$this->createTenant('sonder', 'Sonder', 'sonder.com.ar');
|
||||
$user = User::factory()->create();
|
||||
$variant = $this->createVariantForTenant('sonder', 10, '50.00');
|
||||
$purchase = $this->createCheckoutPurchase($user, 'sonder', $variant, 1);
|
||||
$purchase->update(['status' => Purchase::STATUS_PENDING_PAYMENT]);
|
||||
|
||||
$this->travel(10)->minutes();
|
||||
|
||||
$this->actingAs($user, 'sanctum')
|
||||
->patchJson("/api/tenants/sonder/compras/{$purchase->id}/customer-data", [
|
||||
'dni' => '987654321',
|
||||
@@ -818,6 +824,12 @@ class StorePurchaseTest extends TestCase
|
||||
'status' => Purchase::STATUS_PENDING_PAYMENT,
|
||||
'dni' => '987654321',
|
||||
]);
|
||||
$this->assertDatabaseHas('stock_reservations', [
|
||||
'id' => $purchase->stock_reservation_id,
|
||||
'expires_at' => $now->copy()->addMinutes(30)->toDateTimeString(),
|
||||
]);
|
||||
|
||||
$this->travelBack();
|
||||
}
|
||||
|
||||
public function test_checkout_items_are_immutable_and_editing_routes_are_unavailable(): void
|
||||
|
||||
Reference in New Issue
Block a user