From 3545b77803709a4f1b7ae1d6891f3e7add90ecc6 Mon Sep 17 00:00:00 2001 From: DanielS Date: Tue, 18 Aug 2026 22:55:15 +0200 Subject: [PATCH] fix(wizard): prevent duplicate devices on summary step --- shop/components/order-wizard.tsx | 60 +++++++++++++++++--------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/shop/components/order-wizard.tsx b/shop/components/order-wizard.tsx index faaa20d..c133fc5 100644 --- a/shop/components/order-wizard.tsx +++ b/shop/components/order-wizard.tsx @@ -429,11 +429,15 @@ export function OrderWizard({ }) }, [visibleCategories, selections, products, selectedBillingInterval]) - const finalItemsToShow = basketItems.length > 0 - ? basketItems - : (allCategoriesFilled && productValidationErrors.length === 0 - ? [{ deviceName: deviceName || 'Kasse 1', selections, moduleQuantities, billingInterval: selectedBillingInterval }] - : []) + const finalItemsToShow = useMemo(() => { + if (basketItems.length > 0) { + return basketItems + } + if (allCategoriesFilled && productValidationErrors.length === 0 && hasActiveSelection) { + return [{ deviceName: deviceName || 'Kasse 1', licenseNumber, selections, moduleQuantities, billingInterval: selectedBillingInterval }] + } + return [] + }, [basketItems, allCategoriesFilled, productValidationErrors, hasActiveSelection, deviceName, licenseNumber, selections, moduleQuantities, selectedBillingInterval]) // Gesamtsummen für alle Items in der Bestellung (finalItemsToShow) const { overallMonthlyTotal, overallOneTimeTotal, linkedFeeProducts } = useMemo(() => { @@ -542,7 +546,7 @@ export function OrderWizard({ const nextStep = () => { if (step === 3 && allCategoriesFilled && productValidationErrors.length === 0) { - const isDirtyNewDevice = deviceName.trim() !== '' || licenseNumber.trim() !== '' || Object.values(moduleQuantities).some(q => q > 0) + const isDirtyNewDevice = (deviceName.trim() !== '' || licenseNumber.trim() !== '' || Object.values(moduleQuantities).some(q => q > 0)) && editingIdx === null if (editingIdx !== null) { addToBasket() } else if (basketItems.length === 0 && hasActiveSelection) { @@ -743,35 +747,35 @@ export function OrderWizard({ setIsSubmitting(true) try { let finalItems = [...basketItems] - const isDirtyNewDevice = deviceName.trim() !== '' || licenseNumber.trim() !== '' || Object.values(moduleQuantities).some(q => q > 0) - if ((editingIdx !== null || basketItems.length === 0 || isDirtyNewDevice) && hasActiveSelection && allCategoriesFilled && productValidationErrors.length === 0) { + const isDirtyNewDevice = (deviceName.trim() !== '' || licenseNumber.trim() !== '' || Object.values(moduleQuantities).some(q => q > 0)) && editingIdx === null + if (editingIdx !== null) { const normLicense = licenseNumber.trim().toUpperCase() - if (normLicense) { - const isDuplicateInBasket = basketItems.some( - (item, idx) => idx !== editingIdx && item.licenseNumber?.toUpperCase().trim() === normLicense - ) - if (isDuplicateInBasket) { - throw new Error(`Lizenznummer "${licenseNumber}" ist bereits im aktuellen Warenkorb vorhanden.`) - } - - const isTaken = await isLicenseNumberTaken(normLicense, initialOrder?.id) - if (isTaken) { - throw new Error(`Lizenznummer "${licenseNumber}" wird bereits von einer anderen Bestellung verwendet.`) - } - } - const currentItem = { - deviceName: deviceName || (editingIdx !== null ? basketItems[editingIdx]?.deviceName : `Kasse ${basketItems.length + 1}`), + deviceName: deviceName || basketItems[editingIdx]?.deviceName || `Kasse ${editingIdx + 1}`, licenseNumber: normLicense, selections: JSON.parse(JSON.stringify(selections)), moduleQuantities: { ...moduleQuantities }, billingInterval: selectedBillingInterval, } - if (editingIdx !== null) { - finalItems[editingIdx] = currentItem - } else { - finalItems.push(currentItem) - } + finalItems[editingIdx] = currentItem + } else if (basketItems.length === 0 && hasActiveSelection && allCategoriesFilled && productValidationErrors.length === 0) { + const normLicense = licenseNumber.trim().toUpperCase() + finalItems.push({ + deviceName: deviceName || 'Kasse 1', + licenseNumber: normLicense, + selections: JSON.parse(JSON.stringify(selections)), + moduleQuantities: { ...moduleQuantities }, + billingInterval: selectedBillingInterval, + }) + } else if (isDirtyNewDevice && hasActiveSelection && allCategoriesFilled && productValidationErrors.length === 0) { + const normLicense = licenseNumber.trim().toUpperCase() + finalItems.push({ + deviceName: deviceName || `Kasse ${basketItems.length + 1}`, + licenseNumber: normLicense, + selections: JSON.parse(JSON.stringify(selections)), + moduleQuantities: { ...moduleQuantities }, + billingInterval: selectedBillingInterval, + }) } if (finalItems.length === 0) {