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

169 lines
4.8 KiB
JavaScript

(function(global) {
'use strict';
var fileInput = null;
function getFileInput() {
if (!fileInput) {
fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = '.json,application/json';
fileInput.style.display = 'none';
document.body.appendChild(fileInput);
fileInput.addEventListener('change', handleFileSelect);
}
return fileInput;
}
function importQuoteJSON() {
getFileInput().click();
}
function handleFileSelect(e) {
var file = e.target.files && e.target.files[0];
if (!file) return;
var reader = new FileReader();
reader.onload = function(ev) {
try {
var payload = JSON.parse(ev.target.result);
applyImport(payload);
} catch (err) {
alert('Import failed: invalid JSON file.');
console.warn('importQuoteJSON: parse error', err);
}
};
reader.readAsText(file);
// reset so same file can be re-imported
e.target.value = '';
}
function applyImport(p) {
var set = function(id, val) {
var el = document.getElementById(id);
if (el) el.value = val;
};
var check = function(id, val) {
var el = document.getElementById(id);
if (el) el.checked = !!val;
};
// client name + rep name + notes
set('clientName', p.clientName || '');
set('repName', p.repName || '');
var notesEl = document.getElementById('quoteNotes');
if (notesEl) notesEl.value = p.quoteNotes || '';
// counts
set('userCount', p.users || 0);
set('endpointCount', p.endpoints || 0);
set('serverCount', p.servers || 0);
// licensing
var isBYOL = p.licensing === 'BYOL';
check('rateBYOL', isBYOL);
check('rateM365', !isBYOL);
// user/endpoint add-ons
var addons = p.addons || {};
check('addExtHours', addons.extendedHours);
check('addPWM', addons.passwordManager);
check('addINKY', addons.inkyPro);
check('addZT', addons.zeroTrustUsers);
check('addUSB', addons.usbBlocking);
check('addBMB', addons.baremetalBackup);
// Zero Trust networking
var zt = p.zeroTrustNetwork || {};
set('ztNetSeats', zt.seats || 0);
set('ztNetRouters', zt.routers || 0);
// VoIP
var voip = p.voip || {};
var tierEl = document.querySelector('input[name="voipTier"][value="' + (voip.tier || 'basic') + '"]');
if (tierEl) tierEl.checked = true;
set('voipSeats', voip.seats || 0);
check('addVoipPhone', voip.phoneHardware);
check('addVoipFax', voip.faxLine);
set('currentPhoneBill', voip.currentPhoneBill || 0);
// contract term — reverse map from display to value
var termReverseMap = {
'Month-to-Month': 'm2m',
'12-Month': '12mo',
'24-Month': '24mo'
};
var termVal = termReverseMap[p.contractTerm] || 'm2m';
var termEl = document.querySelector('input[name="contractTerm"][value="' + termVal + '"]');
if (termEl) termEl.checked = true;
// admin waived
check('adminWaived', p.adminWaived);
// onboarding
check('onboardingWaived', p.onboardingWaived);
if (p.onboardingManual && !p.onboardingWaived) {
var fee = (p.pricing && p.pricing.oneTimeFee) || 0;
set('oneTimeFee', fee);
var feeEl = document.getElementById('oneTimeFee');
if (feeEl) feeEl.dataset.manual = '1';
}
// HST
check('hstToggle', p.pricing && p.pricing.hstIncluded);
// sync addon row highlights
var rowMap = {
addExtHours: 'row-ext',
addPWM: 'row-pwm',
addINKY: 'row-inky',
addZT: 'row-zt',
addBMB: 'row-bmb',
addUSB: 'row-usb',
addVoipPhone: 'row-vphone',
addVoipFax: 'row-vfax'
};
var addonIds = ['addExtHours', 'addPWM', 'addINKY', 'addZT', 'addBMB', 'addUSB', 'addVoipPhone', 'addVoipFax'];
addonIds.forEach(function(id) {
var cb = document.getElementById(id);
var row = document.getElementById(rowMap[id]);
if (row) {
if (cb && cb.checked) {
row.classList.add('selected');
} else {
row.classList.remove('selected');
}
}
});
// update quote reference display
if (p.quoteRef) {
var refEl = document.getElementById('quoteRef');
if (refEl) refEl.textContent = p.quoteRef;
}
// trigger recalculation
if (typeof global.update === 'function') {
global.update();
}
// flash confirmation on the import button
var btn = document.getElementById('btnImportQuote');
if (btn) {
var orig = btn.innerHTML;
btn.innerHTML = '✓ Quote Imported';
setTimeout(function() { btn.innerHTML = orig; }, 2000);
}
// persist the imported state
if (typeof global.debouncedSave === 'function') {
global.debouncedSave();
}
}
global.importQuoteJSON = importQuoteJSON;
global.SVSQuoteImport = { importQuoteJSON: importQuoteJSON };
})(window);