(function () { 'use strict'; var APLOS_LOGO_PRINT_SM = 'https://5423554.fs1.hubspotusercontent-na1.net/hubfs/5423554/%5BDigital%20Content%5D%20Aplos%20QuickBooks%20Calculator/aplos-logo-print-sm.png'; var APLOS_LOGO_PRINT = 'https://5423554.fs1.hubspotusercontent-na1.net/hubfs/5423554/%5BDigital%20Content%5D%20Aplos%20QuickBooks%20Calculator/aplos-logo-print.png'; var APLOS_LOGO_DATAURI_TXT_URL = 'https://5423554.fs1.hubspotusercontent-na1.net/hubfs/5423554/%5BDigital%20Content%5D%20Aplos%20QuickBooks%20Calculator/aplos-logo-datauri.txt'; var NS = 'AplosCalculator'; var root = document.getElementById('aplos-qb-calculator'); if (!root) return; const APLOS_PLAN_MONTHLY = 229; const APLOS_PLAN_NAME = 'Aplos Advanced Accounting'; var APLOS_ANNUAL = APLOS_PLAN_MONTHLY * 12; var BENCHMARK = { workaround_hours_per_week: 4, hourly_rate: 30, report_prep_hours_per_month: 6, audit_prep_hours_per_year: 40 }; var QB_PLAN_PRICES = { plus: 115, advanced: 275, enterprise: 200, other: 0 }; var CAPS = { money: 9999999, hoursWeek: 168, hoursMonth: 744, hoursYear: 8760, grants: 500 }; const FIELD_MAP = { email: 'email', company: 'company', firstname: 'firstname', lastname: 'lastname', qb_plan: 'qb_plan', qb_subscription_cost: 'qb_subscription_cost', qb_addons_cost: 'qb_addons_cost', workaround_hours_per_week: 'workaround_hours_per_week', hourly_rate: 'hourly_rate', report_prep_hours_per_month: 'report_prep_hours_per_month', audit_prep_hours_per_year: 'audit_prep_hours_per_year', uses_external_accountant: 'uses_external_accountant', external_accountant_cost: 'external_accountant_cost', addon_tools: 'addon_tools', restricted_grants_count: 'restricted_grants_count', tracks_restricted_separately: 'tracks_restricted_separately', prior_audit_issue: 'prior_audit_issue', true_monthly_cost: 'true_monthly_cost', estimated_annual_savings: 'estimated_annual_savings', risk_tier: 'risk_tier' }; var currencyFmt = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 }); function parseData(el, key, fallback) { var v = el.getAttribute(key); return v === null || v === '' ? fallback : v; } function clampNum(n, min, max) { if (typeof n !== 'number' || isNaN(n)) return min; return Math.min(max, Math.max(min, n)); } function riskTier(inputs) { var tracks = inputs.tracks_restricted_separately === 'yes'; var grants = Number(inputs.restricted_grants_count) || 0; var audit = inputs.prior_audit_issue === 'yes'; var high = !tracks && (grants >= 3 || audit); if (high) return 'high'; var medium = !tracks || audit || grants >= 5; if (medium) return 'medium'; return 'low'; } function riskCopy(tier) { if (tier === 'low') { return 'Your fund tracking setup looks manageable today. As your grant portfolio grows, QuickBooks workarounds get harder to sustain.'; } if (tier === 'medium') { return 'Your organization is managing restricted funds in a system that was not built for it. This is a common audit scrutiny point.'; } return 'Based on your inputs, your organization may have meaningful compliance exposure. A failed audit can cost grant funding, donor confidence, and 501(c)(3) status.'; } function collectInputs() { var qbPlan = (document.getElementById('aplos-qb_plan') || {}).value || 'plus'; var sub = parseFloat(document.getElementById('aplos-qb_subscription_cost').value); var wh = parseFloat(document.getElementById('aplos-workaround_hours_per_week').value); var rate = parseFloat(document.getElementById('aplos-hourly_rate').value); var rpt = parseFloat(document.getElementById('aplos-report_prep_hours_per_month').value); var audY = parseFloat(document.getElementById('aplos-audit_prep_hours_per_year').value); var extYes = document.querySelector('input[name="aplos-uses_external_accountant"]:checked'); var extVal = extYes && extYes.value === 'yes' ? (parseFloat(document.getElementById('aplos-external_accountant_cost').value) || 0) : 0; var addonKeys = ['excel', 'expensify', 'billcom', 'ramp', 'other']; var addonState = {}; var addonSum = 0; addonKeys.forEach(function (k) { var cb = document.getElementById('aplos-addon-' + k); var checked = cb && cb.checked; var costEl = document.getElementById('aplos-addon-cost-' + k); var c = checked && costEl ? (parseFloat(costEl.value) || 0) : 0; addonState[k] = { checked: !!checked, monthly: c }; if (checked) addonSum += c; }); var grants = parseInt(document.getElementById('aplos-restricted_grants_count').value, 10); var trk = document.querySelector('input[name="aplos-tracks_restricted_separately"]:checked'); var pri = document.querySelector('input[name="aplos-prior_audit_issue"]:checked'); return { qb_plan: qbPlan, qb_subscription_cost: isNaN(sub) ? 0 : sub, qb_addons_cost: 0, workaround_hours_per_week: isNaN(wh) ? 0 : wh, hourly_rate: isNaN(rate) ? 0 : rate, report_prep_hours_per_month: isNaN(rpt) ? 0 : rpt, audit_prep_hours_per_year: isNaN(audY) ? 0 : audY, uses_external_accountant: extYes ? extYes.value : 'no', external_accountant_cost: extVal, addon_tools: addonState, restricted_grants_count: isNaN(grants) ? 0 : grants, tracks_restricted_separately: trk ? trk.value : 'no', prior_audit_issue: pri ? pri.value : 'no' }; } function applySkipDefaults(stepIndex) { if (stepIndex === 1) { document.getElementById('aplos-qb_plan').value = 'plus'; setPlanPrice(); } else if (stepIndex === 2) { document.getElementById('aplos-workaround_hours_per_week').value = BENCHMARK.workaround_hours_per_week; document.getElementById('aplos-hourly_rate').value = BENCHMARK.hourly_rate; } else if (stepIndex === 3) { document.getElementById('aplos-report_prep_hours_per_month').value = BENCHMARK.report_prep_hours_per_month; document.getElementById('aplos-audit_prep_hours_per_year').value = BENCHMARK.audit_prep_hours_per_year; document.getElementById('aplos-ext-no').checked = true; toggleExternal(); } else if (stepIndex === 4) { ['excel', 'expensify', 'billcom', 'ramp', 'other'].forEach(function (k) { var cb = document.getElementById('aplos-addon-' + k); if (cb) { cb.checked = false; cb.dispatchEvent(new Event('change')); } }); } else if (stepIndex === 5) { document.getElementById('aplos-restricted_grants_count').value = '0'; document.getElementById('aplos-tracks-yes').checked = true; document.getElementById('aplos-prior-no').checked = true; } } function validateStep(stepIndex, silent) { var ok = true; function err(id, msg) { var el = document.getElementById(id); var eid = id + '-error'; var errEl = document.getElementById(eid); if (el) { el.setAttribute('aria-invalid', msg ? 'true' : 'false'); } if (errEl) { errEl.textContent = msg || ''; errEl.setAttribute('role', 'alert'); } if (msg) ok = false; } if (stepIndex === 1) { var sub = parseFloat(document.getElementById('aplos-qb_subscription_cost').value); if (isNaN(sub) || sub < 0 || sub > CAPS.money) { err('aplos-qb_subscription_cost', 'Enter a monthly amount from $0 to ' + currencyFmt.format(CAPS.money) + '.'); } else err('aplos-qb_subscription_cost', ''); } else if (stepIndex === 2) { var wh = parseFloat(document.getElementById('aplos-workaround_hours_per_week').value); var rate = parseFloat(document.getElementById('aplos-hourly_rate').value); if (isNaN(wh) || wh < 0 || wh > CAPS.hoursWeek) { err('aplos-workaround_hours_per_week', 'Enter hours per week between 0 and ' + CAPS.hoursWeek + '.'); } else err('aplos-workaround_hours_per_week', ''); if (isNaN(rate) || rate < 0 || rate > CAPS.money) { err('aplos-hourly_rate', 'Enter a valid hourly rate.'); } else err('aplos-hourly_rate', ''); } else if (stepIndex === 3) { var rpt = parseFloat(document.getElementById('aplos-report_prep_hours_per_month').value); var audY = parseFloat(document.getElementById('aplos-audit_prep_hours_per_year').value); var ext = document.querySelector('input[name="aplos-uses_external_accountant"]:checked'); var extCost = parseFloat(document.getElementById('aplos-external_accountant_cost').value); if (isNaN(rpt) || rpt < 0 || rpt > CAPS.hoursMonth) { err('aplos-report_prep_hours_per_month', 'Enter hours per month between 0 and ' + CAPS.hoursMonth + '.'); } else err('aplos-report_prep_hours_per_month', ''); if (isNaN(audY) || audY < 0 || audY > CAPS.hoursYear) { err('aplos-audit_prep_hours_per_year', 'Enter annual hours between 0 and ' + CAPS.hoursYear + '.'); } else err('aplos-audit_prep_hours_per_year', ''); if (ext && ext.value === 'yes') { if (isNaN(extCost) || extCost < 0 || extCost > CAPS.money) { err('aplos-external_accountant_cost', 'Enter a monthly support cost, or choose No.'); } else err('aplos-external_accountant_cost', ''); } else err('aplos-external_accountant_cost', ''); } else if (stepIndex === 4) { var keys = ['excel', 'expensify', 'billcom', 'ramp', 'other']; keys.forEach(function (k) { var cb = document.getElementById('aplos-addon-' + k); var inp = document.getElementById('aplos-addon-cost-' + k); if (cb && cb.checked && inp) { var v = parseFloat(inp.value); if (isNaN(v) || v < 0 || v > CAPS.money) { err('aplos-addon-cost-' + k, 'Enter a monthly cost for this tool.'); } else err('aplos-addon-cost-' + k, ''); } else if (inp) err('aplos-addon-cost-' + k, ''); }); } else if (stepIndex === 5) { var g = parseInt(document.getElementById('aplos-restricted_grants_count').value, 10); if (isNaN(g) || g < 0 || g > CAPS.grants) { err('aplos-restricted_grants_count', 'Enter a count between 0 and ' + CAPS.grants + '.'); } else err('aplos-restricted_grants_count', ''); var trk = document.querySelector('input[name="aplos-tracks_restricted_separately"]:checked'); var pri = document.querySelector('input[name="aplos-prior_audit_issue"]:checked'); var te = document.getElementById('aplos-tracks_restricted-error'); var pe = document.getElementById('aplos-prior_audit-error'); if (!trk) { if (te) te.textContent = 'Choose Yes or No.'; ok = false; } else if (te) te.textContent = ''; if (!pri) { if (pe) pe.textContent = 'Choose Yes or No.'; ok = false; } else if (pe) pe.textContent = ''; } if (!silent && !ok) { var firstInvalid = root.querySelector('[aria-invalid="true"]'); if (firstInvalid) firstInvalid.focus(); } return ok; } function computeResults(inputs) { var softwareSub = inputs.qb_subscription_cost + inputs.qb_addons_cost; var workaround = inputs.workaround_hours_per_week * 4.33 * inputs.hourly_rate; var reportHoursMonthly = (inputs.report_prep_hours_per_month + inputs.audit_prep_hours_per_year / 12) * inputs.hourly_rate; var extMonthly = inputs.uses_external_accountant === 'yes' ? inputs.external_accountant_cost : 0; var patchwork = 0; Object.keys(inputs.addon_tools).forEach(function (k) { var a = inputs.addon_tools[k]; if (a.checked) patchwork += a.monthly; }); var reportingOverheadDisplay = reportHoursMonthly; var trueMonthly = softwareSub + workaround + reportHoursMonthly + patchwork + extMonthly; var annual = trueMonthly * 12; var savings = annual - APLOS_ANNUAL; var tier = riskTier(inputs); return { qb_subscription_monthly: inputs.qb_subscription_cost, qb_addons_qb_monthly: inputs.qb_addons_cost, software_subscription_monthly: softwareSub, workaround_labor_monthly: workaround, reporting_overhead_monthly: reportingOverheadDisplay, addons_monthly: patchwork, external_accountant_monthly: extMonthly, true_monthly_cost: trueMonthly, annual_cost: annual, aplos_plan_monthly: APLOS_PLAN_MONTHLY, estimated_annual_savings: savings, risk_tier: tier }; } function buildHTML() { root.innerHTML = '
' + '
' + '

See your true cost of staying on QuickBooks

' + '

Answer a few questions to estimate subscription cost, staff time, extra tools, and compliance risk. Results are directional, not a quote.

' + '
' + '
Step 1 of 5
' + '' + '
' + '
' + '
' + '
Current QuickBooks cost' + '
' + '

Pick the plan closest to yours. You can adjust the dollar amount next.

' + '
' + '' + '

This should match your QuickBooks invoice before payroll or bill-pay add-ons.

' + '

' + '
' + '
' + '
Staff time on workarounds' + '
' + '' + '

' + '
' + '' + '

Default is $30/hr. Change it to match your team.

' + '

' + '
' + '
' + '
Reporting and audit prep' + '
' + '' + '

' + '
' + '' + '

' + '
Outside accounting help' + '
' + 'Do you pay an external accountant monthly?' + '' + '' + '
' + '
' + '
' + '
' + '
Add-on tools and patchwork' + '

Select tools you pay for outside QuickBooks, then add about what you spend each month.

' + '
' + rowAddon('excel', 'Excel / Google Sheets') + rowAddon('expensify', 'Expensify') + rowAddon('billcom', 'Bill.com') + rowAddon('ramp', 'Ramp') + rowAddon('other', 'Other') + '
' + '
' + '
' + '
Compliance snapshot' + '
' + '' + '

' + '
' + 'Do you track restricted funds separately in QuickBooks today?' + '
' + '' + '' + '
' + '
' + 'Was there a prior audit finding or material weakness related to grants or net assets?' + '
' + '' + '' + '
' + '
' + '
' + '' + '' + '' + '
' + '
' + '
' + '
' + '
' + '

Your estimated true cost

' + '

Costs roll up to a monthly and annual view. Use it to plan your next step.

' + '
' + '
CategoryEstimated amount
' + '

Compliance note

' + '
' + 'Book a demo with Aplos' + '' + '' + '
' + '' + '
' + '
' + ''; function rowAddon(id, label) { return '
' + '' + '' + '' + '' + '
'; } } buildHTML(); var logoImg = document.getElementById('aplos-print-logo'); if (logoImg) { logoImg.src = parseData(root, 'data-logo-url', '') || APLOS_LOGO_PRINT_SM; } var state = { step: 1, lastInputs: null, lastResults: null, hsScriptRequested: false, hubspotFormCreated: false }; var el = { formShell: document.getElementById('aplos-form-shell'), progressWrap: document.getElementById('aplos-progress-wrap'), stepLabel: document.getElementById('aplos-step-label'), progressFill: document.getElementById('aplos-progress-fill'), btnBack: document.getElementById('aplos-btn-back'), btnSkip: document.getElementById('aplos-btn-skip'), btnNext: document.getElementById('aplos-btn-next'), qbPlan: document.getElementById('aplos-qb_plan'), qbSub: document.getElementById('aplos-qb_subscription_cost'), results: document.getElementById('aplos-results'), summaryBody: document.getElementById('aplos-summary-body'), riskBox: document.getElementById('aplos-risk-box'), riskText: document.getElementById('aplos-risk-text'), riskTitle: document.getElementById('aplos-risk-title'), ctaDemo: document.getElementById('aplos-cta-demo'), ctaEmail: document.getElementById('aplos-cta-email'), ctaPrint: document.getElementById('aplos-cta-print'), btnRestart: document.getElementById('aplos-btn-restart'), modal: document.getElementById('aplos-email-modal'), modalClose: document.getElementById('aplos-modal-close'), hubspotTarget: document.getElementById('aplos-hubspot-target'), webhookFields: document.getElementById('aplos-webhook-fields'), webhookEmail: document.getElementById('aplos-webhook-email'), webhookSubmit: document.getElementById('aplos-webhook-submit'), webhookMsg: document.getElementById('aplos-webhook-msg'), webhookFail: document.getElementById('aplos-webhook-fail'), extWrap: document.getElementById('aplos-external-wrap'), extCost: document.getElementById('aplos-external_accountant_cost') }; function setPlanPrice() { var v = el.qbPlan.value; var p = QB_PLAN_PRICES[v]; if (v !== 'other') el.qbSub.value = p; } function updateProgress() { el.stepLabel.textContent = 'Step ' + state.step + ' of 5'; el.progressFill.style.width = (state.step / 5) * 100 + '%'; var steps = root.querySelectorAll('.aplos-step'); steps.forEach(function (s) { var n = parseInt(s.getAttribute('data-step'), 10); s.classList.toggle('is-active', n === state.step); }); el.btnBack.style.visibility = state.step === 1 ? 'hidden' : 'visible'; el.btnNext.textContent = state.step === 5 ? 'See your true cost' : 'Next'; } function toggleExternal() { var yes = document.getElementById('aplos-ext-yes').checked; el.extWrap.hidden = !yes; el.extCost.disabled = !yes; if (!yes) { el.extCost.setAttribute('aria-invalid', 'false'); document.getElementById('aplos-external_accountant_cost-error').textContent = ''; } } function setupAddonToggles() { ['excel', 'expensify', 'billcom', 'ramp', 'other'].forEach(function (k) { var cb = document.getElementById('aplos-addon-' + k); var cost = document.getElementById('aplos-addon-cost-' + k); if (!cb || !cost) return; function sync() { var on = cb.checked; cost.disabled = !on; cost.hidden = !on; if (!on) { cost.value = ''; cost.setAttribute('aria-invalid', 'false'); document.getElementById('aplos-addon-cost-' + k + '-error').textContent = ''; } } cb.addEventListener('change', sync); sync(); }); } function renderTable(results, inputs) { var rows = [ ['Software subscription (QuickBooks plan total)', results.software_subscription_monthly, 'monthly'], ['Staff time on workarounds', results.workaround_labor_monthly, 'monthly'], ['Reporting & audit prep overhead', results.reporting_overhead_monthly, 'monthly'], ['Add-on tools', results.addons_monthly, 'monthly'], ['External accountant support', results.external_accountant_monthly, 'monthly'], ['True monthly cost', results.true_monthly_cost, 'monthly'], ['Annual QuickBooks cost', results.annual_cost, 'annual'], [APLOS_PLAN_NAME + ' — starting price', null, 'aplos'], ['Your estimated annual savings with Aplos', results.estimated_annual_savings, 'annual'] ]; el.summaryBody.innerHTML = ''; rows.forEach(function (r, i) { var tr = document.createElement('tr'); if (i === 5) tr.className = 'aplos-row-highlight'; if (i === 8) tr.className = 'aplos-row-savings'; var th = document.createElement('th'); th.scope = 'row'; th.textContent = r[0]; var td = document.createElement('td'); if (r[2] === 'monthly' || r[2] === 'annual') { td.textContent = currencyFmt.format(r[1]); } else if (r[2] === 'aplos') { td.textContent = currencyFmt.format(APLOS_PLAN_MONTHLY) + '/mo (' + currencyFmt.format(APLOS_ANNUAL) + '/yr)'; } tr.appendChild(th); tr.appendChild(td); el.summaryBody.appendChild(tr); }); } function showResults(inputs, results) { state.lastInputs = inputs; state.lastResults = results; el.formShell.classList.add('is-hidden'); el.results.classList.add('is-visible'); renderTable(results, inputs); var tier = results.risk_tier; el.riskBox.className = 'aplos-risk aplos-risk--' + tier; el.riskTitle.textContent = tier === 'high' ? 'Higher compliance risk' : tier === 'medium' ? 'Moderate compliance risk' : 'Lower compliance risk'; el.riskText.textContent = riskCopy(tier); el.results.focus(); window.dispatchEvent( new CustomEvent('aplos:calculator-complete', { detail: { inputs: inputs, results: results } }) ); } function goNext() { if (!validateStep(state.step, false)) return; if (state.step < 5) { state.step += 1; updateProgress(); } else { var inputs = collectInputs(); var results = computeResults(inputs); showResults(inputs, results); } } function goBack() { if (state.step > 1) { state.step -= 1; updateProgress(); } } function goSkip() { applySkipDefaults(state.step); if (state.step < 5) { state.step += 1; updateProgress(); } else { if (!validateStep(5, false)) return; var inputs = collectInputs(); var results = computeResults(inputs); showResults(inputs, results); } } function restart() { state.step = 1; el.formShell.classList.remove('is-hidden'); el.results.classList.remove('is-visible'); document.getElementById('aplos-main-form').reset(); document.getElementById('aplos-qb_plan').value = 'plus'; setPlanPrice(); document.getElementById('aplos-hourly_rate').value = '30'; document.getElementById('aplos-ext-no').checked = true; toggleExternal(); ['excel', 'expensify', 'billcom', 'ramp', 'other'].forEach(function (k) { var cb = document.getElementById('aplos-addon-' + k); var cost = document.getElementById('aplos-addon-cost-' + k); if (cb) cb.checked = false; if (cost) { cost.value = ''; cost.disabled = true; cost.hidden = true; } }); root.querySelectorAll('[aria-invalid]').forEach(function (node) { node.setAttribute('aria-invalid', 'false'); }); root.querySelectorAll('.aplos-error').forEach(function (e) { e.textContent = ''; }); var te = document.getElementById('aplos-tracks_restricted-error'); var pe = document.getElementById('aplos-prior_audit-error'); if (te) te.textContent = ''; if (pe) pe.textContent = ''; updateProgress(); el.qbSub.focus(); } function openModal() { var mode = parseData(root, 'data-submit-mode', 'hubspot-form'); el.modal.hidden = false; document.getElementById('aplos-modal-desc').textContent = mode === 'webhook' ? 'Add your email to receive this estimate.' : 'After you submit, you get a copy of this summary by email.'; if (mode === 'webhook') { el.webhookFields.hidden = false; el.hubspotTarget.innerHTML = ''; el.hubspotTarget.hidden = true; } else { el.webhookFields.hidden = true; el.hubspotTarget.hidden = false; injectHubSpotForm(); } el.modalClose.focus(); } function closeModal() { el.modal.hidden = true; } function loadScript(src, cb) { var s = document.createElement('script'); s.src = src; s.async = true; s.onload = function () { cb(null); }; s.onerror = function () { cb(new Error('load fail')); }; document.head.appendChild(s); } function buildHubspotMappedValues() { var vals = {}; if (!state.lastInputs || !state.lastResults) return vals; Object.keys(FIELD_MAP).forEach(function (k) { var hubKey = FIELD_MAP[k]; if (k === 'true_monthly_cost') vals[hubKey] = String(state.lastResults.true_monthly_cost); else if (k === 'estimated_annual_savings') vals[hubKey] = String(state.lastResults.estimated_annual_savings); else if (k === 'risk_tier') vals[hubKey] = state.lastResults.risk_tier; else if (k === 'addon_tools') vals[hubKey] = JSON.stringify(state.lastInputs.addon_tools); else if (state.lastInputs[k] !== undefined && state.lastInputs[k] !== null) { vals[hubKey] = String(state.lastInputs[k]); } }); return vals; } function applyValuesToHubspotForm(formRoot, vals) { if (!formRoot || !vals) return; var elForm = formRoot.jquery ? formRoot[0] : formRoot; if (!elForm || !elForm.querySelectorAll) return; Object.keys(vals).forEach(function (name) { var v = vals[name]; var fields = elForm.querySelectorAll('[name="' + name + '"]'); fields.forEach(function (inp) { if (inp.type === 'hidden' || inp.type === 'text' || inp.type === 'number' || inp.type === 'email' || inp.tagName === 'TEXTAREA' || inp.tagName === 'SELECT') { inp.value = v; } }); }); } function aplosHsControlIsLayoutHidden(ctrl) { if (!ctrl) return true; if (ctrl.tagName === 'INPUT' && ctrl.type === 'hidden') return true; var st = window.getComputedStyle(ctrl); if (st.display === 'none' || st.visibility === 'hidden') return true; var op = parseFloat(st.opacity); if (!isNaN(op) && op === 0) return true; try { var r = ctrl.getBoundingClientRect(); if (r.width < 1 && r.height < 1) return true; } catch (e) {} return false; } function collapseHiddenHubspotFields(formRoot) { var elForm = formRoot && formRoot.jquery ? formRoot[0] : formRoot; if (!elForm || !elForm.querySelectorAll) return; elForm.querySelectorAll('.hs-form-field').forEach(function (row) { if (window.getComputedStyle(row).display === 'none') { row.classList.remove('aplos-hs-field-collapsed'); return; } var controls = row.querySelectorAll('input, select, textarea, button'); var collapse = false; if (!controls.length) { collapse = false; } else { var hasNonHidden = false; var anyVisible = false; for (var i = 0; i < controls.length; i++) { var c = controls[i]; if (c.tagName === 'INPUT' && c.type === 'hidden') continue; hasNonHidden = true; if (!aplosHsControlIsLayoutHidden(c)) anyVisible = true; } if (!hasNonHidden) { collapse = !!row.querySelector('input[type="hidden"]'); } else { collapse = !anyVisible; } } row.classList.toggle('aplos-hs-field-collapsed', collapse); }); elForm.querySelectorAll('fieldset.form-columns-1').forEach(function (fs) { var directRows = []; for (var k = 0; k < fs.children.length; k++) { var ch = fs.children[k]; if (ch.classList && ch.classList.contains('hs-form-field')) directRows.push(ch); } if (!directRows.length) return; var allCollapsed = directRows.every(function (r) { return r.classList.contains('aplos-hs-field-collapsed'); }); fs.classList.toggle('aplos-hs-fieldset-collapsed', allCollapsed); }); elForm.querySelectorAll('fieldset.form-columns-2').forEach(function (fs) { var direct = []; for (var j = 0; j < fs.children.length; j++) { var c = fs.children[j]; if (c.classList && c.classList.contains('hs-form-field')) direct.push(c); } if (!direct.length) return; var allC = direct.every(function (d) { return d.classList.contains('aplos-hs-field-collapsed'); }); var leg = null; for (var x = 0; x < fs.children.length; x++) { if (fs.children[x].tagName === 'LEGEND') { leg = fs.children[x]; break; } } if (leg) leg.classList.toggle('aplos-hs-legend-collapsed', allC); }); elForm.querySelectorAll('.hs_submit, .hs-submit').forEach(function (wrap) { var ctrls = wrap.querySelectorAll('input, button, select, textarea'); if (!ctrls.length) return; var anyVisible = false; for (var n = 0; n < ctrls.length; n++) { if (!aplosHsControlIsLayoutHidden(ctrls[n])) { anyVisible = true; break; } } wrap.classList.toggle('aplos-hs-submit-wrap-collapsed', !anyVisible); }); } function attachHubspotFormCollapseObserver(formEl) { if (!formEl || formEl._aplosHsCollapseAttached) return; if (typeof MutationObserver === 'undefined') return; formEl._aplosHsCollapseAttached = true; var timer; var obs = new MutationObserver(function () { clearTimeout(timer); timer = setTimeout(function () { collapseHiddenHubspotFields(formEl); }, 60); }); obs.observe(formEl, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); } function injectHubSpotForm() { if (state.hubspotFormCreated) return; var portalId = parseData(root, 'data-hs-portal-id', ''); var formId = parseData(root, 'data-hs-form-id', ''); el.hubspotTarget.innerHTML = ''; state.hsScriptRequested = true; loadScript('https://js.hsforms.net/forms/embed/v2.js', function (err) { if (err || !window.hbspt || !window.hbspt.forms) { el.hubspotTarget.innerHTML = '

The form could not load. Use the print option, or share this page with your team.

'; return; } var vals = buildHubspotMappedValues(); window.hbspt.forms.create({ portalId: portalId, formId: formId, target: '#aplos-hubspot-target', css: '', cssClass: 'aplos-hs-form', onFormReady: function ($form) { applyValuesToHubspotForm($form, vals); var elForm = $form && $form.jquery ? $form[0] : $form; function runCollapse() { collapseHiddenHubspotFields($form); } runCollapse(); window.requestAnimationFrame(runCollapse); [150, 400, 800].forEach(function (ms) { setTimeout(runCollapse, ms); }); attachHubspotFormCollapseObserver(elForm); }, onFormSubmitted: function () { var payload = { portalId: portalId, formId: formId, values: vals }; window.dispatchEvent( new CustomEvent('aplos:lead-captured', { detail: { mode: 'hubspot-form', payload: payload } }) ); closeModal(); } }); state.hubspotFormCreated = true; }); } function webhookSubmit() { var email = (el.webhookEmail.value || '').trim(); var err = document.getElementById('aplos-webhook-email-error'); el.webhookMsg.hidden = true; el.webhookFail.hidden = true; if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { err.textContent = 'Enter a valid email address.'; el.webhookEmail.setAttribute('aria-invalid', 'true'); return; } el.webhookEmail.setAttribute('aria-invalid', 'false'); err.textContent = ''; var url = parseData(root, 'data-webhook-url', ''); if (!url) { el.webhookFail.hidden = false; el.webhookFail.textContent = 'Webhook URL is not configured.'; return; } var body = { email: email, submitted_at: new Date().toISOString(), source: 'aplos-qb-calculator', page_url: window.location.href, inputs: state.lastInputs, results: { qb_subscription_monthly: state.lastResults.qb_subscription_monthly, workaround_labor_monthly: state.lastResults.workaround_labor_monthly, reporting_overhead_monthly: state.lastResults.reporting_overhead_monthly, addons_monthly: state.lastResults.addons_monthly, external_accountant_monthly: state.lastResults.external_accountant_monthly, true_monthly_cost: state.lastResults.true_monthly_cost, annual_cost: state.lastResults.annual_cost, aplos_plan_monthly: APLOS_PLAN_MONTHLY, estimated_annual_savings: state.lastResults.estimated_annual_savings, risk_tier: state.lastResults.risk_tier } }; fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }) .then(function (res) { if (res.ok) { el.webhookMsg.hidden = false; el.webhookMsg.textContent = 'Sent. Check your inbox shortly.'; window.dispatchEvent( new CustomEvent('aplos:lead-captured', { detail: { mode: 'webhook', payload: body } }) ); } else { throw new Error('status ' + res.status); } }) .catch(function () { el.webhookFail.hidden = false; var subject = encodeURIComponent('My QuickBooks true cost estimate'); var mail = 'mailto:?subject=' + subject + '&body=' + encodeURIComponent(JSON.stringify(body.results, null, 2)); el.webhookFail.innerHTML = 'Something went wrong. Email yourself a copy instead.'; }); } el.qbPlan.addEventListener('change', setPlanPrice); document.getElementById('aplos-ext-yes').addEventListener('change', toggleExternal); document.getElementById('aplos-ext-no').addEventListener('change', toggleExternal); el.btnNext.addEventListener('click', goNext); el.btnBack.addEventListener('click', goBack); el.btnSkip.addEventListener('click', goSkip); el.btnRestart.addEventListener('click', restart); el.ctaPrint.addEventListener('click', function () { window.print(); }); el.ctaDemo.href = parseData(root, 'data-demo-url', 'https://www.aplos.com/demorequest'); el.ctaEmail.addEventListener('click', openModal); el.modalClose.addEventListener('click', closeModal); el.modal.addEventListener('click', function (e) { if (e.target === el.modal) closeModal(); }); el.webhookSubmit.addEventListener('click', webhookSubmit); document.addEventListener('keydown', function (e) { if (e.key === 'Escape' && !el.modal.hidden) closeModal(); }); setupAddonToggles(); setPlanPrice(); document.getElementById('aplos-hourly_rate').value = '30'; toggleExternal(); updateProgress(); window[NS] = { version: parseData(root, 'data-calculator-version', '1.0.0'), FIELD_MAP: FIELD_MAP, LOGO_URLS: { printSm: APLOS_LOGO_PRINT_SM, print: APLOS_LOGO_PRINT, dataUriTxt: APLOS_LOGO_DATAURI_TXT_URL }, getState: function () { return { step: state.step, inputs: state.lastInputs, results: state.lastResults }; } }; })();