// CQ Calculation Engine // calculateQuoteTotals — unified totals for display, PDF, signing // Depends on: cq-pricing-data.js, cq-line-items.js // ======================================================================== // UNIFIED CALCULATION ENGINE — Single source of truth for all totals // Used by: on-screen display, PDF generation, signing flow // ======================================================================== window.calculateQuoteTotals = (lineItems, options = {}) => { const { additionalRecurringDiscounts = [], additionalOneTimeDiscounts = [], multiYearDiscount = {}, contractLength = 1, paymentFrequency = 'annual', financingFeeWaived = false, monthlyFinancingFee = 10, quarterlyFinancingFee = 5, } = options; // Start from line item totals (per-item discounts already applied) let annual = lineItems.recurringTotal || 0; let oneTime = lineItems.oneTimeTotal || 0; // Pick the right deposit based on payment frequency // Use != null check (not > 0) so explicit $0 deposits are respected instead of falling back const rawFinancingOneTimeAmt = lineItems.financingOneTimeAmount || 0; const financingOneTimeAmt = paymentFrequency === 'monthly' && lineItems.monthlyDepositAmount != null ? lineItems.monthlyDepositAmount : paymentFrequency === 'quarterly' && lineItems.quarterlyDepositAmount != null ? lineItems.quarterlyDepositAmount : rawFinancingOneTimeAmt; // --- Additional Recurring Discounts --- let recurringDiscountAmount = 0; const recurringDiscountItems = []; (additionalRecurringDiscounts || []).forEach(discount => { if (discount && discount.amount > 0) { const discountValue = discount.type === 'percent' ? annual * (discount.amount / 100) : discount.amount; recurringDiscountAmount += discountValue; recurringDiscountItems.push({ name: discount.name || 'Discount', amount: discountValue, type: discount.type, value: discount.amount }); } }); annual = annual - recurringDiscountAmount; // --- Additional One-Time Discounts --- let oneTimeDiscountAmount = 0; const oneTimeDiscountItems = []; (additionalOneTimeDiscounts || []).forEach(discount => { if (discount && discount.amount > 0) { const discountValue = discount.type === 'percent' ? oneTime * (discount.amount / 100) : discount.amount; oneTimeDiscountAmount += discountValue; oneTimeDiscountItems.push({ name: discount.name || 'Discount', amount: discountValue, type: discount.type, value: discount.amount }); } }); oneTime = oneTime - oneTimeDiscountAmount; const hasAdditionalDiscounts = recurringDiscountAmount > 0 || oneTimeDiscountAmount > 0; // --- Multi-Year Discount --- let multiYearDiscountPercent = 0; if (contractLength === 2 && multiYearDiscount.twoYearEnabled) { multiYearDiscountPercent = multiYearDiscount.twoYear || 0; } else if (contractLength === 3 && multiYearDiscount.threeYearEnabled) { multiYearDiscountPercent = multiYearDiscount.threeYear || 0; } let multiYearDiscountAmount = 0; if (multiYearDiscountPercent > 0) { multiYearDiscountAmount = annual * (multiYearDiscountPercent / 100); annual = annual - multiYearDiscountAmount; } // --- Financing --- const isFinanced = paymentFrequency !== 'annual'; const currentFinancingFee = paymentFrequency === 'monthly' ? monthlyFinancingFee : quarterlyFinancingFee; const financingFeeAmount = isFinanced && !financingFeeWaived ? annual * (currentFinancingFee / 100) : 0; const totalFinanced = annual + financingFeeAmount - (isFinanced ? financingOneTimeAmt : 0); const baseAmount = paymentFrequency === 'monthly' ? (isFinanced ? totalFinanced / 12 : annual / 12) : paymentFrequency === 'quarterly' ? (isFinanced ? totalFinanced / 4 : annual / 4) : annual; const displayAmount = baseAmount; const periodLabel = paymentFrequency === 'monthly' ? '/mo' : paymentFrequency === 'quarterly' ? '/qtr' : '/yr'; const firstPeriodLabel = paymentFrequency === 'monthly' ? 'First Month' : paymentFrequency === 'quarterly' ? 'First Quarter' : 'First Year'; const dueAtSigning = displayAmount + oneTime + (isFinanced ? financingOneTimeAmt : 0); const totalSavings = (lineItems.recurringDiscountTotal || 0) + (lineItems.oneTimeDiscountTotal || 0) + recurringDiscountAmount + oneTimeDiscountAmount + multiYearDiscountAmount; return { annual, oneTime, financingOneTimeAmt, recurringDiscountAmount, recurringDiscountItems, oneTimeDiscountAmount, oneTimeDiscountItems, hasAdditionalDiscounts, multiYearDiscountPercent, multiYearDiscountAmount, isFinanced, currentFinancingFee, financingFeeAmount, financingFeeWaived, totalFinanced, baseAmount, displayAmount, periodLabel, firstPeriodLabel, dueAtSigning, totalSavings }; };