findSourceCart($purchase); if ($sourceCart === null) { return false; } /** @var Cart|null $activeCart */ $activeCart = Cart::query() ->where('tenant_codigo', $purchase->tenant_codigo) ->where('user_id', $purchase->user_id) ->where('status', 'active') ->where('id', '!=', $sourceCart->getKey()) ->lockForUpdate() ->first(); if ($activeCart !== null) { $this->mergeIntoActiveCart($sourceCart, $activeCart); $sourceCart->update([ 'status' => 'converted', 'guest_token' => null, ]); if (! $sourceCart->trashed()) { $sourceCart->delete(); } return true; } if ($sourceCart->trashed()) { $sourceCart->restore(); } $sourceCart->update([ 'status' => 'active', 'user_id' => $purchase->user_id, 'guest_token' => null, ]); return true; } public function syncItemQuantity( Purchase $purchase, PurchaseItem $purchaseItem, int $quantity, ): 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) ->update(['cantidad' => $quantity]); } 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(); } private function mergeIntoActiveCart(Cart $sourceCart, Cart $activeCart): void { $sourceItems = $sourceCart->items()->lockForUpdate()->get(); foreach ($sourceItems as $sourceItem) { /** @var CartItem|null $activeItem */ $activeItem = $activeCart->items() ->where('catalog_item_id', $sourceItem->catalog_item_id) ->where('variant_id', $sourceItem->variant_id) ->lockForUpdate() ->first(); if ($activeItem === null) { $activeCart->items()->create([ 'catalog_item_id' => $sourceItem->catalog_item_id, 'variant_id' => $sourceItem->variant_id, 'cantidad' => $sourceItem->cantidad, ]); } else { $activeItem->increment('cantidad', (int) $sourceItem->cantidad); } } } }