feat(purchase): implement purchase limit enforcement and custom exception handling

This commit is contained in:
2026-08-19 16:43:59 -03:00
parent 8537d2ed0a
commit 5c0b3503b7
15 changed files with 124 additions and 41 deletions

View File

@@ -4,11 +4,11 @@ namespace App\Domains\Purchase\Services;
use App\Domains\Cart\Models\CartItem;
use App\Domains\Catalog\Models\CatalogItem;
use App\Domains\Purchase\Exceptions\PurchaseLimitExceededException;
use App\Domains\Purchase\Models\Purchase;
use App\Domains\Purchase\Models\PurchaseItem;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;
class UserPurchaseLimitService
{
@@ -18,6 +18,8 @@ class UserPurchaseLimitService
int $requestedQuantity,
?int $excludedPurchaseId = null,
?int $excludedCartId = null,
int $heldQuantity = 0,
?int $maximumAddableCeiling = null,
string $field = 'quantity',
): void {
DB::transaction(function () use (
@@ -26,6 +28,8 @@ class UserPurchaseLimitService
$requestedQuantity,
$excludedPurchaseId,
$excludedCartId,
$heldQuantity,
$maximumAddableCeiling,
$field,
): void {
/** @var CatalogItem $catalogItem */
@@ -86,9 +90,20 @@ class UserPurchaseLimitService
->sum('cantidad');
if ($purchasedQuantity + $checkoutQuantity + $reservedCartQuantity + $requestedQuantity > $limit) {
throw ValidationException::withMessages([
$field => __('api.purchase_limit.exceeded', ['max' => $limit]),
]);
$remainingQuota = max(
0,
$limit - $purchasedQuantity - $checkoutQuantity - $reservedCartQuantity,
);
$maximumAddableQuantity = max(0, $remainingQuota - $heldQuantity);
throw new PurchaseLimitExceededException(
$catalogItem,
$maximumAddableCeiling === null
? $maximumAddableQuantity
: min($maximumAddableQuantity, $maximumAddableCeiling),
$field,
);
}
});
}