resolveTenantVariants($tenant, $items); $purchaseItemsPayload = $this->buildPurchaseItemsPayload($items, $variants); // 2. Crear la orden de compra y vaciar carrito return DB::transaction(function () use ($tenant, $userId, $purchaseData, $purchaseItemsPayload): Purchase { /** @var Purchase $purchase */ $purchase = Purchase::query()->create([ ...$purchaseData, 'tenant_codigo' => $tenant->codigo, 'user_id' => $userId, ]); $purchase->items()->createMany($purchaseItemsPayload); // Vaciar y eliminar el carrito activo del usuario $cart = \App\Domains\Cart\Models\Cart::query() ->where('tenant_codigo', $tenant->codigo) ->where('user_id', $userId) ->first(); if ($cart) { $cart->items()->delete(); $cart->delete(); } return $purchase->load(['items.variant.product', 'items.variant.definitions.productAttribute.attribute']); }); } /** * @param array> $items * @return \Illuminate\Support\Collection */ protected function resolveTenantVariants(Tenant $tenant, array $items) { $variantIds = collect($items) ->pluck('producto_variante_id') ->filter() ->map(static fn (mixed $id): int => (int) $id) ->unique() ->values(); $variants = ProductVariant::query() ->with('product') ->whereIn('id', $variantIds) ->whereHas('product', fn ($query) => $query->where('tenant_codigo', $tenant->codigo)) ->get() ->keyBy('id'); if ($variants->count() !== $variantIds->count()) { throw ValidationException::withMessages([ 'items' => 'One or more product variants do not belong to the tenant.', ]); } return $variants; } /** * @param array> $items * @param \Illuminate\Support\Collection $variants * @return array> */ protected function buildPurchaseItemsPayload(array $items, $variants): array { return collect($items) ->map(function (array $item) use ($variants): array { /** @var ProductVariant $variant */ $variant = $variants->get((int) $item['producto_variante_id']); $quantity = (int) $item['cantidad']; $unitPrice = (float) ($variant->product?->precio ?? 0); return [ 'producto_variante_id' => $variant->getKey(), 'cantidad' => $quantity, 'precio_unitario' => $unitPrice, 'discount_total' => null, 'tax_total' => null, 'total' => $unitPrice * $quantity, ]; }) ->all(); } }