Files
svsmspcalc/quote-engine.js
2026-03-15 18:24:36 -04:00

198 lines
7.1 KiB
JavaScript

(function(global) {
'use strict';
const PRICING_KEYS = [
'RATE_M365',
'RATE_BYOL',
'ADDON_EXT_HOURS',
'ADDON_1PASSWORD',
'ADDON_INKY',
'ADDON_ZERO_TRUST_USER',
'RATE_ENDPOINT',
'RATE_SERVER',
'ADDON_USB_BLOCKING',
'ADDON_BARE_METAL_BACKUP',
'ZT_SEAT_RATE',
'ZT_ROUTER_RATE',
'ADMIN_FEE_FLOOR',
'ADMIN_FEE_MINIMUM',
'ADMIN_FEE_ZT',
'ADMIN_1PWM_PCT',
'VOIP_RATE_BASIC',
'VOIP_RATE_STANDARD',
'VOIP_RATE_PREMIUM',
'VOIP_PHONE_RATE',
'VOIP_FAX_RATE',
'TOOL_COST_PER_USER',
'TOOL_COST_PER_ENDPOINT',
'TOOL_COST_MIN',
'IT_SALARY_1',
'IT_SALARY_5',
'DISCOUNT_M2M',
'DISCOUNT_12MO',
'DISCOUNT_24MO',
'HST_RATE'
];
function getPricingConfig() {
if (global.SVSQuotePricing && typeof global.SVSQuotePricing.getSnapshot === 'function') {
return global.SVSQuotePricing.getSnapshot();
}
return PRICING_KEYS.reduce((snapshot, key) => {
snapshot[key] = global[key];
return snapshot;
}, {});
}
function readFormState(doc) {
const root = doc || document;
const getById = id => root.getElementById(id);
const getChecked = id => !!getById(id)?.checked;
const getInt = id => parseInt(getById(id)?.value, 10) || 0;
const getFloat = id => parseFloat(getById(id)?.value) || 0;
return {
byol: getChecked('rateBYOL'),
users: getInt('userCount'),
endpoints: getInt('endpointCount'),
servers: getInt('serverCount'),
addExtHours: getChecked('addExtHours'),
addPWM: getChecked('addPWM'),
addINKY: getChecked('addINKY'),
addZT: getChecked('addZT'),
addUSB: getChecked('addUSB'),
addBMB: getChecked('addBMB'),
ztSeats: getInt('ztNetSeats'),
ztRouters: getInt('ztNetRouters'),
voipTier: (root.querySelector('input[name="voipTier"]:checked') || {}).value || 'basic',
voipSeats: getInt('voipSeats'),
addVoipPhone: getChecked('addVoipPhone'),
addVoipFax: getChecked('addVoipFax'),
clientName: getById('clientName')?.value || '',
contractTerm: (root.querySelector('input[name="contractTerm"]:checked') || {}).value || 'm2m',
hstEnabled: getChecked('hstToggle'),
oneTimeFee: getFloat('oneTimeFee'),
adminWaived: getChecked('adminWaived')
};
}
function calculateQuote(state, pricing) {
const s = state || {};
const p = pricing || getPricingConfig();
const byol = !!s.byol;
const users = parseInt(s.users, 10) || 0;
const endpoints = parseInt(s.endpoints, 10) || 0;
const servers = parseInt(s.servers, 10) || 0;
const addExtHours = !!s.addExtHours;
const addPWM = !!s.addPWM;
const addINKY = !!s.addINKY;
const addZT = !!s.addZT;
const addUSB = !!s.addUSB;
const addBMB = !!s.addBMB;
const ztSeats = parseInt(s.ztSeats, 10) || 0;
const ztRouters = parseInt(s.ztRouters, 10) || 0;
const voipTier = s.voipTier || 'basic';
const voipSeats = parseInt(s.voipSeats, 10) || 0;
const addVoipPhone = !!s.addVoipPhone;
const addVoipFax = !!s.addVoipFax;
const clientName = s.clientName || '';
const contractTerm = s.contractTerm || 'm2m';
const hstEnabled = !!s.hstEnabled;
const oneTimeFee = parseFloat(s.oneTimeFee) || 0;
const adminWaived = !!s.adminWaived;
const ztActive = addZT || ztSeats > 0;
const VOIP_RATES = {
basic: p.VOIP_RATE_BASIC,
standard: p.VOIP_RATE_STANDARD,
premium: p.VOIP_RATE_PREMIUM
};
const CONTRACT_DISCOUNT = {
m2m: p.DISCOUNT_M2M,
'12mo': p.DISCOUNT_12MO,
'24mo': p.DISCOUNT_24MO
};
const m365Rate = contractTerm === 'm2m' ? (p.RATE_M365_M2M || p.RATE_M365) : p.RATE_M365;
const baseUserRate = byol ? p.RATE_BYOL : m365Rate;
const addonRate =
(addExtHours ? p.ADDON_EXT_HOURS : 0) +
(addPWM ? p.ADDON_1PASSWORD : 0) +
(addINKY ? p.ADDON_INKY : 0) +
(addZT ? p.ADDON_ZERO_TRUST_USER : 0);
const totalUserRate = baseUserRate + addonRate;
const userBase = users * baseUserRate;
const userExt = addExtHours ? users * p.ADDON_EXT_HOURS : 0;
const userPWM = addPWM ? users * p.ADDON_1PASSWORD : 0;
const userINKY = addINKY ? users * p.ADDON_INKY : 0;
const userZT = addZT ? users * p.ADDON_ZERO_TRUST_USER : 0;
const userTotal = userBase + userExt + userPWM + userINKY + userZT;
const endpointBase = endpoints * p.RATE_ENDPOINT;
const serverBase = servers * p.RATE_SERVER;
const endpointUSB = addUSB ? endpoints * p.ADDON_USB_BLOCKING : 0;
const endpointBMB = addBMB ? endpoints * p.ADDON_BARE_METAL_BACKUP : 0;
const endpointTotal = endpointBase + serverBase + endpointUSB + endpointBMB;
const baseSubtotal = userBase + endpointBase + serverBase;
const siteAdminBase = Math.max(p.ADMIN_FEE_FLOOR, p.ADMIN_FEE_MINIMUM - baseSubtotal);
const admin1PWM = addPWM ? Math.round(userPWM * p.ADMIN_1PWM_PCT) : 0;
const adminFeeNet = siteAdminBase + (ztActive ? p.ADMIN_FEE_ZT : 0) + admin1PWM;
const adminFeeEffective = adminWaived ? 0 : adminFeeNet;
const ztNetSeats = ztSeats * p.ZT_SEAT_RATE;
const ztNetRouters = ztRouters * p.ZT_ROUTER_RATE;
const ztNetTotal = ztNetSeats + ztNetRouters;
const voipSeatRate = VOIP_RATES[voipTier] || p.VOIP_RATE_BASIC;
const voipSeatsAmt = voipSeats * voipSeatRate;
const voipPhoneAmt = addVoipPhone ? voipSeats * p.VOIP_PHONE_RATE : 0;
const voipFaxAmt = addVoipFax ? voipSeats * p.VOIP_FAX_RATE : 0;
const voipTotal = voipSeatsAmt + voipPhoneAmt + voipFaxAmt;
const MRR = userTotal + endpointTotal + adminFeeEffective + ztNetTotal + voipTotal;
const annual = MRR * 12;
const perUserAllin = users > 0 ? MRR / users : 0;
const discountPct = CONTRACT_DISCOUNT[contractTerm] || 0;
const discountAmt = Math.round(MRR * discountPct);
const effectiveMrr = MRR - discountAmt;
const effectiveAnnual = effectiveMrr * 12;
const hstAmt = hstEnabled ? Math.round(effectiveMrr * p.HST_RATE) : 0;
const mrrWithHst = effectiveMrr + hstAmt;
const perUserServices = users > 0 ? Math.round(userTotal / users) : 0;
const perUserSiteOvhd = users > 0 ? Math.round((effectiveMrr - userTotal) / users) : 0;
return {
users, endpoints, servers, ztSeats, ztRouters, voipSeats, voipTier, addVoipPhone, addVoipFax,
byol, addPWM, addINKY, addExtHours, addZT, addUSB, addBMB, ztActive, adminWaived, clientName,
contractTerm, hstEnabled, oneTimeFee,
baseUserRate, m365Rate, totalUserRate,
userBase, userPWM, userINKY, userExt, userZT, userTotal,
endpointBase, serverBase, endpointUSB, endpointBMB, endpointTotal,
ztNetSeats, ztNetRouters, ztNetTotal,
voipSeatRate, voipSeatsAmt, voipPhoneAmt, voipFaxAmt, voipTotal,
baseSubtotal, siteAdminBase, admin1PWM, adminFeeNet,
MRR, annual, perUserAllin,
discountPct, discountAmt, effectiveMrr, effectiveAnnual,
hstAmt, mrrWithHst,
perUserServices, perUserSiteOvhd
};
}
global.SVSQuoteEngine = {
getPricingConfig,
readFormState,
calculateQuote
};
global.getPricingConfig = getPricingConfig;
global.readFormState = readFormState;
global.calculateQuote = calculateQuote;
})(window);