feat(inventory): add InventorySubject enum and integrate into catalog item management

This commit is contained in:
2026-08-12 14:42:30 -03:00
parent 5b089e71b2
commit 8e94cf7856
13 changed files with 280 additions and 6 deletions

View File

@@ -0,0 +1,43 @@
<?php
namespace App\Domains\Purchase\Services\Checkout;
use App\Domains\Catalog\Enums\InventorySubject;
use App\Domains\Catalog\Models\CatalogItem;
use App\Domains\Catalog\Models\Variant;
class InsufficientStockMessageBuilder
{
public function build(
CatalogItem $catalogItem,
CatalogItem|Variant $selection,
int $availableQuantity,
): string {
return match ($catalogItem->inventory_subject) {
InventorySubject::Seat => __('api.purchase.stock.seat_unavailable', [
'selection' => $selection->getSelectionLabel(),
]),
InventorySubject::Ticket => __('api.purchase.stock.ticket_unavailable', [
'selection' => $selection->getSelectionLabel(),
]),
InventorySubject::Product => __('api.purchase.stock.product_unavailable', [
'selection' => $this->productSelectionLabel($catalogItem, $selection),
'max' => $availableQuantity,
]),
};
}
private function productSelectionLabel(
CatalogItem $catalogItem,
CatalogItem|Variant $selection,
): string {
if ($selection instanceof CatalogItem) {
return $selection->getSelectionLabel();
}
return __('api.purchase.stock.product_selection', [
'product' => $catalogItem->getName(),
'selection' => $selection->getSelectionLabel(),
]);
}
}

View File

@@ -22,6 +22,7 @@ class StartCheckoutService
private readonly UserPurchaseLimitService $purchaseLimits,
private readonly CatalogSelectionResolver $selections,
private readonly PurchaseItemSnapshotFactory $snapshots,
private readonly InsufficientStockMessageBuilder $stockMessages,
) {}
/** @param array<string, mixed> $purchaseData */
@@ -128,17 +129,25 @@ class StartCheckoutService
if ($availableQuantity !== null && $availableQuantity < $line['quantity']) {
throw ValidationException::withMessages([
"{$line['field']}.cantidad" => __('api.purchase.direct_items_max_stock', [
'max' => $availableQuantity,
]),
"{$line['field']}.cantidad" => $this->stockMessages->build(
$line['catalog_item'],
$line['selection'],
$availableQuantity,
),
]);
}
try {
$this->inventory->reserve($line['selection'], $line['quantity']);
} catch (\InvalidArgumentException) {
$availableQuantity = $this->inventory->availableQuantity($line['selection']) ?? 0;
throw ValidationException::withMessages([
"{$line['field']}.cantidad" => __('api.purchase.insufficient_stock'),
"{$line['field']}.cantidad" => $this->stockMessages->build(
$line['catalog_item'],
$line['selection'],
$availableQuantity,
),
]);
}
}