198 lines
7.1 KiB
JavaScript
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);
|