feat: refactor purchase status handling and add finalize endpoint for purchases

This commit is contained in:
2026-07-07 15:33:29 -03:00
parent 786b4eb6a9
commit c276ccd311
11 changed files with 220 additions and 27 deletions

View File

@@ -33,21 +33,62 @@ class CheckoutService
$cart->setRelation('items', $cartItems);
$totalAmount = $cart->getTotalAmount();
/** @var Purchase $purchase */
$purchase = Purchase::query()->updateOrCreate(
[
/** @var Purchase|null $purchase */
$purchase = Purchase::query()
->where('cart_id', $cart->getKey())
->where('tenant_codigo', $tenant->codigo)
->where('user_id', $userId)
->whereIn('status', [Purchase::STATUS_CREATED, Purchase::STATUS_PENDING_PAYMENT])
->latest('id')
->first();
if ($purchase === null) {
/** @var Purchase $purchase */
$purchase = Purchase::query()->create([
...$purchaseData,
'cart_id' => $cart->getKey(),
'status' => 'pending',
'tenant_codigo' => $tenant->codigo,
'user_id' => $userId,
],
[
...$purchaseData,
'payment_status' => 'pending',
'status' => Purchase::STATUS_CREATED,
'payment_method' => null,
'total' => $totalAmount,
]
);
]);
} else {
$purchase->fill([
...$purchaseData,
'status' => Purchase::STATUS_CREATED,
'payment_method' => null,
'total' => $totalAmount,
]);
$purchase->save();
}
return $purchase->load(['items.variant.product', 'items.variant.definitions.productAttribute.attribute']);
});
}
public function finalizePurchase(Purchase $purchase): Purchase
{
return DB::transaction(function () use ($purchase): Purchase {
/** @var Purchase $purchase */
$purchase = Purchase::query()
->lockForUpdate()
->findOrFail($purchase->getKey());
if ($purchase->payment_method === null) {
throw ValidationException::withMessages([
'payment_method' => 'The purchase payment method must be selected before finalizing.',
]);
}
if (in_array($purchase->status, [Purchase::STATUS_PAID, Purchase::STATUS_CANCELLED, Purchase::STATUS_REJECTED], true)) {
return $purchase->load(['items.variant.product', 'items.variant.definitions.productAttribute.attribute']);
}
$purchase->update([
'status' => Purchase::STATUS_PENDING_PAYMENT,
'total' => $purchase->calculateCurrentTotalAmount(),
]);
return $purchase->load(['items.variant.product', 'items.variant.definitions.productAttribute.attribute']);
});