feat: support product quantity and separate steps
All checks were successful
Staging Build / build (push) Successful in 6m17s
All checks were successful
Staging Build / build (push) Successful in 6m17s
This commit is contained in:
@@ -49,6 +49,7 @@ function hashOrderSnapshot(snapshot: object): string {
|
||||
export async function submitOrder(params: {
|
||||
selections: WizardSelections
|
||||
moduleQuantities?: Record<string, number>
|
||||
productQuantities?: Record<string, number>
|
||||
products?: Product[]
|
||||
categories?: Category[]
|
||||
customerProfile: Partial<Profile>
|
||||
@@ -57,7 +58,7 @@ export async function submitOrder(params: {
|
||||
billingInterval?: 'one_time' | 'monthly'
|
||||
lastLicenseDate?: string | null
|
||||
}): Promise<Order> {
|
||||
const { selections, moduleQuantities, customerProfile, endCustomerId, endCustomer, billingInterval, lastLicenseDate } = params
|
||||
const { selections, moduleQuantities, productQuantities, customerProfile, endCustomerId, endCustomer, billingInterval, lastLicenseDate } = params
|
||||
const supabase = await createClient()
|
||||
|
||||
const { data: { user } } = await supabase.auth.getUser()
|
||||
@@ -85,7 +86,7 @@ export async function submitOrder(params: {
|
||||
// 1. Snapshots aufbauen
|
||||
// Wenn Endkunde vorhanden: dessen Daten einfrieren; sonst Partner-Profil (Fallback)
|
||||
const customerSnapshot = buildCustomerSnapshot(customerProfile, endCustomer ?? null)
|
||||
const orderSnapshot = buildOrderSnapshot(selections, dbProducts, dbCategories, billingInterval, moduleQuantities, lastLicenseDate)
|
||||
const orderSnapshot = buildOrderSnapshot(selections, dbProducts, dbCategories, billingInterval, moduleQuantities, lastLicenseDate, productQuantities)
|
||||
|
||||
// 2. Idempotenz-Guard: Prüfen ob identische Bestellung in den letzten 5 Minuten existiert
|
||||
const orderHash = hashOrderSnapshot(orderSnapshot)
|
||||
@@ -366,6 +367,7 @@ export async function updateOrder(
|
||||
params: {
|
||||
selections: WizardSelections
|
||||
moduleQuantities?: Record<string, number>
|
||||
productQuantities?: Record<string, number>
|
||||
customerProfile: Partial<Profile>
|
||||
endCustomerId?: string | null
|
||||
endCustomer?: EndCustomer | null
|
||||
@@ -374,7 +376,7 @@ export async function updateOrder(
|
||||
companyId?: string | null
|
||||
}
|
||||
): Promise<Order> {
|
||||
const { selections, moduleQuantities, customerProfile, endCustomerId, endCustomer, billingInterval, lastLicenseDate, companyId } = params
|
||||
const { selections, moduleQuantities, productQuantities, customerProfile, endCustomerId, endCustomer, billingInterval, lastLicenseDate, companyId } = params
|
||||
const supabase = await createClient()
|
||||
const admin = createAdminClient()
|
||||
|
||||
@@ -434,7 +436,7 @@ export async function updateOrder(
|
||||
|
||||
// 1. Snapshots aufbauen
|
||||
const customerSnapshot = buildCustomerSnapshot(customerProfile, endCustomer ?? null)
|
||||
const orderSnapshot = buildOrderSnapshot(selections, dbProducts, dbCategories, billingInterval, moduleQuantities, lastLicenseDate)
|
||||
const orderSnapshot = buildOrderSnapshot(selections, dbProducts, dbCategories, billingInterval, moduleQuantities, lastLicenseDate, productQuantities)
|
||||
const orderHash = hashOrderSnapshot(orderSnapshot)
|
||||
|
||||
// 2. Bestellung in DB aktualisieren
|
||||
|
||||
@@ -91,7 +91,8 @@ export function buildOrderSnapshot(
|
||||
categories: Category[],
|
||||
billingInterval?: 'one_time' | 'monthly',
|
||||
moduleQuantities?: Record<string, number>,
|
||||
lastLicenseDate?: string | null
|
||||
lastLicenseDate?: string | null,
|
||||
productQuantities?: Record<string, number>
|
||||
): OrderSnapshot {
|
||||
const items: OrderItem[] = []
|
||||
let subtotal = 0
|
||||
@@ -135,11 +136,12 @@ export function buildOrderSnapshot(
|
||||
}
|
||||
})
|
||||
|
||||
const productQty = productQuantities?.[prod.id] || 1
|
||||
const moduleTotal = selectedModules.reduce((acc, m) => acc + (m.total_price || m.price), 0)
|
||||
|
||||
// If this product falls under the free limit, set its base price to 0
|
||||
const actualBasePrice = (sortedIndex < freeLimit) ? 0 : prod.base_price
|
||||
const itemTotal = actualBasePrice + moduleTotal
|
||||
const itemTotal = (actualBasePrice + moduleTotal) * productQty
|
||||
subtotal += itemTotal
|
||||
|
||||
items.push({
|
||||
@@ -149,6 +151,7 @@ export function buildOrderSnapshot(
|
||||
product_name: prod.name + (actualBasePrice === 0 ? " (Inklusive/Frei)" : ""),
|
||||
base_price: actualBasePrice,
|
||||
billing_interval: prod.billing_interval,
|
||||
quantity: productQty,
|
||||
selected_modules: selectedModules,
|
||||
item_total: itemTotal,
|
||||
})
|
||||
|
||||
@@ -17,6 +17,7 @@ export type Product = {
|
||||
show_in_abo?: boolean
|
||||
requirements?: string[]
|
||||
exclusions?: string[]
|
||||
has_quantity?: boolean
|
||||
}
|
||||
|
||||
export type Category = {
|
||||
@@ -131,6 +132,7 @@ export type OrderItem = {
|
||||
product_name: string
|
||||
base_price: number
|
||||
billing_interval: BillingInterval
|
||||
quantity?: number
|
||||
selected_modules: OrderModuleSnapshot[]
|
||||
item_total: number
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user