class ROICalculator { #smartboxes = { "MS5": new SmartBox('MS5', 9, null, 2199, "Base Station"), "MS5E18": new SmartBox('MS5E-18', 18, null, 1799, "Expansion Unit"), "MS5E42": new SmartBox('MS5E-42', 42, null, 2499, "Expansion Unit"), }; #planPricing = { 'Lite': { price: 828, name: 'Lite' }, 'Premium': { price: 1428, name: 'Premium' }, 'Business Pro': { price: 2028, name: 'Business Pro' } }; #weeklyKeyAccesses; constructor(numKeys, weeklyKeyUsage, breakEvenTime, year3ROI, year5ROI, hardwareCost, hardwareList, softwarePlan, softwareCost){ // inputs this.numKeys = numKeys; this.weeklyKeyUsage = weeklyKeyUsage; // outputs this.breakEvenTime = breakEvenTime; this.year3ROI = year3ROI; this.year5ROI = year5ROI; this.hardwareCost = hardwareCost; this.hardwareList = hardwareList; this.softwarePlan = softwarePlan; this.softwareCost = softwareCost; } // constructor getWeeklyKeyAccesses(){ this.#weeklyKeyAccesses = this.numKeys * this.weeklyKeyUsage; return this.#weeklyKeyAccesses; } calculateHardwareCost(){ let requiredCapacity = Math.ceil(this.numKeys); if (requiredCapacity <= 0) return { cost: 0, breakdown: [] }; let totalCost = this.#smartboxes.MS5.price; let breakdown = { [this.#smartboxes.MS5.model]: 1 }; let keysNeededFromExpansions = requiredCapacity - this.#smartboxes.MS5.bins; if (keysNeededFromExpansions > 0) { const MS5E42 = this.#smartboxes.MS5E42; const MS5E18 = this.#smartboxes.MS5E18; const MS5E42Quantity = Math.floor(keysNeededFromExpansions / MS5E42.bins); if (MS5E42Quantity > 0){ totalCost += MS5E42Quantity * MS5E42.price; breakdown[MS5E42.model] = (breakdown[MS5E42.model] || 0) + MS5E42Quantity; } // if MS5E42Quantity > 0 const remainder = keysNeededFromExpansions % MS5E42.bins; if (remainder > 0){ if (remainder <= MS5E18.bins){ totalCost += MS5E18.price; breakdown[MS5E18.model] = (breakdown[MS5E18.model] || 0) + 1; } else { totalCost += MS5E42.price; breakdown[MS5E42.model] = (breakdown[MS5E42.model] || 0) + 1; } } // if remainder } // if keysNeededFromExpansions > 0 const breakdownText = Object.entries(breakdown).map(([name, count]) => `${count} x ${name}`); return { cost: totalCost, breakdown: breakdownText, }; } // calculateHardwareCost() calculateSoftwareCost(selectedPlan="Premium") { this.softwareCost = this.#planPricing[selectedPlan]?.price || 0; return this.softwareCost; } // calculateSoftwareCost() formatCurrency(number){ if (!isNaN(number)){ return { amount: new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(number), isCurrency: true, raw: number } } else { return "N/A"; } } // formatCurrency() round(value, decimals){ const multiplier = Math.pow(10, decimals || 0); return Math.round(value * multiplier) / multiplier; } // round() fillForm(industry, outputForm){ if (!outputForm) { throw new Error("fillForm: target form not found."); } const submit = outputForm.querySelector('input[type=submit'); const existingInputs = outputForm.querySelectorAll(".roi-calculation-result"); existingInputs.forEach((e) => { e.remove(); }); Object.keys(industry).forEach((key) => { const input = document.createElement("input"); input.setAttribute("type", "hidden"); input.setAttribute("id", key); input.setAttribute("name", key); input.classList.add("roi-calculation-result"); if (Object.getPrototypeOf(industry[key]) === Object.prototype) { if (industry[key].isCurrency) input.setAttribute("value", industry[key].amount); } else { input.setAttribute("value", industry[key]); } outputForm.insertBefore(input, submit); }); } // fillForm() } // ROICalculator