feat: Add quantity support for product modules, multiply prices in order snapshot and pdf
Some checks failed
Staging Build / build (push) Has been cancelled

This commit is contained in:
DanielS
2026-06-25 13:04:37 +02:00
parent fe05e13d3f
commit 9e189f331a
8 changed files with 159 additions and 66 deletions

View File

@@ -85,7 +85,8 @@ export function buildOrderSnapshot(
selections: WizardSelections,
products: Product[],
categories: Category[],
billingInterval?: 'one_time' | 'monthly'
billingInterval?: 'one_time' | 'monthly',
moduleQuantities?: Record<string, number>
): OrderSnapshot {
const items: OrderItem[] = []
let subtotal = 0
@@ -103,13 +104,18 @@ export function buildOrderSnapshot(
const selectedModules = sel.moduleIds
.map((modId) => prod.modules?.find((m) => m.id === modId))
.filter((m): m is NonNullable<typeof m> => !!m)
.map((mod) => ({
module_id: mod.id,
module_name: mod.name,
price: mod.price,
}))
.map((mod) => {
const qty = moduleQuantities?.[mod.id] || 1
return {
module_id: mod.id,
module_name: mod.name,
price: mod.price,
quantity: qty,
total_price: mod.price * qty,
}
})
const moduleTotal = selectedModules.reduce((acc, m) => acc + m.price, 0)
const moduleTotal = selectedModules.reduce((acc, m) => acc + (m.total_price || m.price), 0)
const itemTotal = prod.base_price + moduleTotal
subtotal += itemTotal
@@ -157,7 +163,8 @@ export function transformToLicenseBundle(
selections: WizardSelections,
products: Product[],
categories: Category[],
customer: Partial<Profile>
customer: Partial<Profile>,
moduleQuantities?: Record<string, number>
): LicenseBundle {
const options: LicenseOption[] = []
let monthlyTotal = 0
@@ -186,6 +193,7 @@ export function transformToLicenseBundle(
for (const modId of sel.moduleIds) {
const mod = prod.modules?.find((m) => m.id === modId)
if (!mod) continue
const qty = moduleQuantities?.[mod.id] || 1
options.push({
key: `${prodKey}__${slugify(mod.name)}`,
@@ -194,10 +202,11 @@ export function transformToLicenseBundle(
// Module erben das Billing-Intervall des übergeordneten Produkts
billing: prod.billing_interval,
price_net: mod.price,
quantity: qty,
})
if (prod.billing_interval === 'monthly') monthlyTotal += mod.price
else oneTimeTotal += mod.price
if (prod.billing_interval === 'monthly') monthlyTotal += mod.price * qty
else oneTimeTotal += mod.price * qty
}
}
@@ -238,16 +247,19 @@ export function licenseBundleFromSnapshot(
else oneTimeTotal += item.base_price
for (const mod of item.selected_modules) {
const qty = mod.quantity || 1
const modPrice = mod.total_price || (mod.price * qty)
options.push({
key: `${prodKey}__${slugify(mod.module_name)}`,
label: mod.module_name,
active: true,
billing: item.billing_interval,
price_net: mod.price,
quantity: qty,
})
if (item.billing_interval === 'monthly') monthlyTotal += mod.price
else oneTimeTotal += mod.price
if (item.billing_interval === 'monthly') monthlyTotal += modPrice
else oneTimeTotal += modPrice
}
}