findSourceCart($purchase); if ($sourceCart === null) { return; } $sourceCart->items() ->where('catalog_item_id', $purchaseItem->source_catalog_item_id) ->where('variant_id', $purchaseItem->source_variant_id) ->update(['cantidad' => $quantity]); } public function syncItemSelection( Purchase $purchase, int $catalogItemId, ?int $previousVariantId, int $newVariantId, int $finalQuantity, ): void { $sourceCart = $this->findSourceCart($purchase); if ($sourceCart === null) { return; } /** @var CartItem|null $previousItem */ $previousItem = $sourceCart->items() ->where('catalog_item_id', $catalogItemId) ->where('variant_id', $previousVariantId) ->lockForUpdate() ->first(); /** @var CartItem|null $targetItem */ $targetItem = $sourceCart->items() ->where('catalog_item_id', $catalogItemId) ->where('variant_id', $newVariantId) ->when($previousItem !== null, fn ($query) => $query->whereKeyNot($previousItem->getKey())) ->lockForUpdate() ->first(); if ($targetItem !== null) { $targetItem->update(['cantidad' => $finalQuantity]); $previousItem?->delete(); return; } if ($previousItem !== null) { $previousItem->update([ 'variant_id' => $newVariantId, 'cantidad' => $finalQuantity, ]); return; } $sourceCart->items()->create([ 'catalog_item_id' => $catalogItemId, 'variant_id' => $newVariantId, 'cantidad' => $finalQuantity, ]); } 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); if ($sourceCart === null || $sourceCart->trashed()) { return; } $sourceCart->update([ 'status' => 'converted', 'guest_token' => null, ]); $sourceCart->delete(); } private function findSourceCart(Purchase $purchase): ?Cart { if ($purchase->cart_id === null) { return null; } /** @var Cart|null */ return Cart::withTrashed() ->whereKey($purchase->cart_id) ->lockForUpdate() ->first(); } }