Pre-Alpha to Alpha Ready
This commit is contained in:
168
pre-alpha/quote-import.js
Normal file
168
pre-alpha/quote-import.js
Normal file
@@ -0,0 +1,168 @@
|
||||
(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);
|
||||
Reference in New Issue
Block a user