From 5c28fbdea5490af3fa682572557563a3d8af7fb2 Mon Sep 17 00:00:00 2001 From: DanielS Date: Fri, 3 Jul 2026 14:21:15 +0200 Subject: [PATCH] feat(wizard): support OR logic for requirements (at least one dependency satisfies requirements) --- shop/components/order-wizard.tsx | 18 +++++++++--------- shop/lib/actions/orders.ts | 32 ++++++++++++++++---------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/shop/components/order-wizard.tsx b/shop/components/order-wizard.tsx index 1f5eb9c..0cdf86c 100644 --- a/shop/components/order-wizard.tsx +++ b/shop/components/order-wizard.tsx @@ -55,7 +55,7 @@ function toggleModuleInList( const beforeLength = next.length next = next.filter(mId => { const m = modules.find(mod => mod.id === mId) - return !m?.requirements || m.requirements.every(reqId => next.includes(reqId)) + return !m?.requirements || m.requirements.length === 0 || m.requirements.some(reqId => next.includes(reqId)) }) changed = next.length !== beforeLength } @@ -69,7 +69,7 @@ function toggleModuleInList( function isModuleDisabled(module: ProductModule, selectedModules: string[]): boolean { const requirementsMet = !module.requirements?.length || - module.requirements.every(reqId => selectedModules.includes(reqId)) + module.requirements.some(reqId => selectedModules.includes(reqId)) const isExcluded = module.exclusions?.some(exId => selectedModules.includes(exId)) return !requirementsMet || !!isExcluded } @@ -237,12 +237,12 @@ export function OrderWizard({ // Requirements check if (prod.requirements && prod.requirements.length > 0) { - const missing = prod.requirements.filter(reqId => !selectedProductIds.includes(reqId)) - if (missing.length > 0) { - const names = missing + const hasMetRequirement = prod.requirements.some(reqId => selectedProductIds.includes(reqId)) + if (!hasMetRequirement) { + const names = prod.requirements .map(reqId => products.find(p => p.id === reqId)?.name || reqId) - .join(', ') - errors.push(`"${prod.name}" benötigt das Produkt: ${names}`) + .join(' oder ') + errors.push(`"${prod.name}" benötigt mindestens eines dieser Produkte: ${names}`) } } @@ -898,8 +898,8 @@ export function OrderWizard({ )} {disabled && (

- {module.requirements?.some( - reqId => !sel?.moduleIds.includes(reqId) + {module.requirements?.length && !module.requirements.some( + reqId => sel?.moduleIds.includes(reqId) ) ? 'Benötigt weitere Module' : 'Nicht kombinierbar mit aktueller Auswahl'} diff --git a/shop/lib/actions/orders.ts b/shop/lib/actions/orders.ts index 741be7b..7778ce1 100644 --- a/shop/lib/actions/orders.ts +++ b/shop/lib/actions/orders.ts @@ -90,9 +90,9 @@ export async function submitOrder(params: { } // Requirements check if (mod.requirements && mod.requirements.length > 0) { - const missing = mod.requirements.filter(reqId => !sel.moduleIds.includes(reqId)) - if (missing.length > 0) { - throw new Error(`Das Modul "${mod.name}" setzt die Aktivierung anderer Module voraus.`) + const hasMetRequirement = mod.requirements.some(reqId => sel.moduleIds.includes(reqId)) + if (!hasMetRequirement) { + throw new Error(`Das Modul "${mod.name}" setzt die Aktivierung mindestens eines der folgenden Module voraus: ${mod.requirements.join(', ')}.`) } } // Exclusions check @@ -117,12 +117,12 @@ export async function submitOrder(params: { // Product requirements check if (prod.requirements && prod.requirements.length > 0) { - const missing = prod.requirements.filter(reqId => !selectedProductIds.includes(reqId)) - if (missing.length > 0) { - const missingNames = missing + const hasMetRequirement = prod.requirements.some(reqId => selectedProductIds.includes(reqId)) + if (!hasMetRequirement) { + const reqNames = prod.requirements .map(reqId => dbProducts.find(p => p.id === reqId)?.name || reqId) - .join(', ') - throw new Error(`Das Produkt "${prod.name}" erfordert die Auswahl von: ${missingNames}.`) + .join(' oder ') + throw new Error(`Das Produkt "${prod.name}" erfordert die Auswahl von mindestens einem dieser Produkte: ${reqNames}.`) } } @@ -530,9 +530,9 @@ export async function updateOrder( } // Requirements check if (mod.requirements && mod.requirements.length > 0) { - const missing = mod.requirements.filter(reqId => !sel.moduleIds.includes(reqId)) - if (missing.length > 0) { - throw new Error(`Das Modul "${mod.name}" setzt die Aktivierung anderer Module voraus.`) + const hasMetRequirement = mod.requirements.some(reqId => sel.moduleIds.includes(reqId)) + if (!hasMetRequirement) { + throw new Error(`Das Modul "${mod.name}" setzt die Aktivierung mindestens eines der folgenden Module voraus: ${mod.requirements.join(', ')}.`) } } // Exclusions check @@ -557,12 +557,12 @@ export async function updateOrder( // Product requirements check if (prod.requirements && prod.requirements.length > 0) { - const missing = prod.requirements.filter(reqId => !selectedProductIds.includes(reqId)) - if (missing.length > 0) { - const missingNames = missing + const hasMetRequirement = prod.requirements.some(reqId => selectedProductIds.includes(reqId)) + if (!hasMetRequirement) { + const reqNames = prod.requirements .map(reqId => dbProducts.find(p => p.id === reqId)?.name || reqId) - .join(', ') - throw new Error(`Das Produkt "${prod.name}" erfordert die Auswahl von: ${missingNames}.`) + .join(' oder ') + throw new Error(`Das Produkt "${prod.name}" erfordert die Auswahl von mindestens einem dieser Produkte: ${reqNames}.`) } }