feat(checkout): enforce editing policy on items

This commit is contained in:
2026-08-20 10:56:19 -03:00
parent d36a929f8c
commit c8ce3b0da3
12 changed files with 272 additions and 17 deletions

View File

@@ -61,13 +61,13 @@ class EditCheckoutService
$tenant = $purchase->tenant()->firstOrFail();
$finalQuantity = $quantity ?? (int) $purchaseItem->cantidad;
if ($quantity !== null && ! $tenant->cart_editing_policy->allowsQuantityChanges()) {
if ($quantity !== null && ! $tenant->checkout_editing_policy->allowsQuantityChanges()) {
throw ValidationException::withMessages([
'quantity' => __('api.cart.editing_disabled'),
]);
}
if ($updateVariant && ! $tenant->cart_editing_policy->allowsVariantChanges()) {
if ($updateVariant && ! $tenant->checkout_editing_policy->allowsVariantChanges()) {
throw ValidationException::withMessages([
'variant_id' => __('api.purchase.variant_change_disabled'),
]);
@@ -184,7 +184,7 @@ class EditCheckoutService
$purchase = $this->lockPurchase($purchase);
$this->assertEditable($purchase);
if (! $purchase->tenant()->firstOrFail()->cart_editing_policy->allowsModification()) {
if (! $purchase->tenant()->firstOrFail()->checkout_editing_policy->allowsModification()) {
throw ValidationException::withMessages([
'purchase' => __('api.cart.editing_disabled'),
]);
@@ -204,6 +204,31 @@ class EditCheckoutService
});
}
public function removeItem(Purchase $purchase, PurchaseItem $purchaseItem): Purchase
{
return DB::transaction(function () use ($purchase, $purchaseItem): Purchase {
$purchase = $this->lockPurchase($purchase);
$this->assertEditable($purchase);
if (! $purchase->tenant()->firstOrFail()->checkout_editing_policy->allowsRemoval()) {
throw ValidationException::withMessages([
'item' => __('api.cart.editing_disabled'),
]);
}
$purchaseItem = $this->lockPurchaseItem($purchase, $purchaseItem);
$selection = $this->selections->resolvePurchaseItem($purchase->tenant, $purchaseItem);
$this->inventory->release($selection, (int) $purchaseItem->cantidad);
$this->sourceCart->removeItem($purchase, $purchaseItem);
$purchaseItem->delete();
$purchase->update([
'total' => $purchase->calculateCurrentTotalAmount(),
]);
return $this->loadPurchase($purchase);
});
}
private function adjustReservation(
Purchase $purchase,
PurchaseItem $purchaseItem,

View File

@@ -23,7 +23,7 @@ class PurchaseResponseLoader
]);
}
if (! $purchase->tenant->cart_editing_policy->allowsVariantChanges()) {
if (! $purchase->tenant->checkout_editing_policy->allowsVariantChanges()) {
return $purchase;
}
@@ -35,6 +35,13 @@ class PurchaseResponseLoader
'items.sourceCatalogItem.variants.definitions.itemAttribute.attribute.options',
'items.sourceCatalogItem.variants.eventDates',
'items.sourceCatalogItem.variants.eventDate',
'cart.items.catalogItem.itemAttributes.attribute',
'cart.items.catalogItem.variants' => fn ($query) => $query->orderBy('id'),
'cart.items.catalogItem.variants.inventory',
'cart.items.catalogItem.variants.definitions' => fn ($query) => $query->orderBy('id'),
'cart.items.catalogItem.variants.definitions.itemAttribute.attribute.options',
'cart.items.catalogItem.variants.eventDates',
'cart.items.catalogItem.variants.eventDate',
]);
return $purchase;

View File

@@ -130,6 +130,20 @@ class SourceCartService
]);
}
public function removeItem(Purchase $purchase, PurchaseItem $purchaseItem): void
{
$sourceCart = $this->findSourceCart($purchase);
if ($sourceCart === null) {
return;
}
$sourceCart->items()
->where('catalog_item_id', $purchaseItem->source_catalog_item_id)
->where('variant_id', $purchaseItem->source_variant_id)
->delete();
}
public function finalize(Purchase $purchase): void
{
$sourceCart = $this->findSourceCart($purchase);

View File

@@ -4,6 +4,7 @@ namespace App\Domains\Purchase\Services;
use App\Domains\Catalog\Services\StockReservationService;
use App\Domains\Purchase\Models\Purchase;
use App\Domains\Purchase\Models\PurchaseItem;
use App\Domains\Purchase\Services\Checkout\CompleteCheckoutService;
use App\Domains\Purchase\Services\Checkout\EditCheckoutService;
use App\Domains\Purchase\Services\Checkout\ReleaseCheckoutService;
@@ -69,6 +70,11 @@ class CheckoutService
return $this->editor->prepareItemEditing($purchase);
}
public function removeItem(Purchase $purchase, PurchaseItem $purchaseItem): Purchase
{
return $this->editor->removeItem($purchase, $purchaseItem);
}
public function confirmPurchase(Purchase $purchase): void
{
$this->completer->confirm($purchase);