/* ════════════════════════════════════════════════════════════════
QIP Diagnostic Imaging Accreditation Registration
qip-diagnostic-imaging-registration.js
Stripe integration mirrors AGPAL / ADA / SPAP pattern exactly:
1. waitForToken / dataversePost / fetchLeadRef / spinner
2. diaSubmit: validates page 7, then createAllRecords()
Lead → Contact → PaymentEvidence → redirect to /agpal-stripe-checkout
3. Stripe return handled by shared /agpal-stripe-return — no changes.
Lead subject = page title:
"QIP Diagnostic Imaging Registration – {practiceName}"
Content Snippets required:
dia/cc-surcharge-rate 0.01927
dia/gst-rate 0.10
agpal/contact-type-id GUID (shared)
stripe/flow-url Power Automate checkout flow (shared)
stripe/flow-url-verify Power Automate verify flow (shared)
sessionStorage keys (distinct from AGPAL/ADA/SPAP):
dia_registration_lead_id
dia_registration_lead_ref
dia_registration_evidence_id
dia_payment_in_progress
════════════════════════════════════════════════════════════════ */
(function () {
'use strict';
/* ── Config ──────────────────────────────────────── */
var TOTAL_PAGES = 7;
var LABELS = {
1: 'Contact', 2: 'Details', 3: 'Practice',
4: 'Address', 5: 'Modalities', 6: 'Standards', 7: 'Submit'
};
var FEE_MATRIX = {
entry: { single: 590, '2-3': 975, '4-6': 1155, '7-9': 1635 },
full: { single: 1765, '2-3': 2925, '4-6': 3470, '7-9': 4900 }
};
var PC = window.portalContext || {};
var config = {
ccSurchargeRate: parseFloat(PC.diaCCSurchargeRate) || 0.01927,
gstRate: parseFloat(PC.diaGSTRate) || 0.10,
contactTypeId: PC.contactTypeId || ''
};
var state = {
currentPage: 1,
sigCtx: null,
sigDrawing: false,
isBusy: false,
leadId: null,
leadRef: null,
paymentEvidenceId: null,
leadIdKey: 'dia_registration_lead_id',
leadRefKey: 'dia_registration_lead_ref',
evidenceIdKey: 'dia_registration_evidence_id',
paymentInProgressKey: 'dia_payment_in_progress'
};
/* ════════════════════════════════════════════════════════════
SPINNER
════════════════════════════════════════════════════════════ */
function injectSpinner() {
if (document.getElementById('dia-spinner-overlay')) return;
var style = document.createElement('style');
style.textContent =
'@keyframes dia-spin{to{transform:rotate(360deg)}}' +
'#dia-spinner-overlay{display:none;position:fixed;inset:0;background:rgba(26,58,74,0.65);' +
'z-index:99999;align-items:center;justify-content:center;flex-direction:column;gap:18px;}';
document.head.appendChild(style);
var overlay = document.createElement('div');
overlay.id = 'dia-spinner-overlay';
overlay.setAttribute('aria-live', 'assertive');
overlay.innerHTML =
'
' +
'Please wait\u2026
';
document.body.appendChild(overlay);
}
function setBusy(busy, msg) {
state.isBusy = busy;
var overlay = document.getElementById('dia-spinner-overlay');
var msgEl = document.getElementById('dia-spinner-msg');
if (overlay) overlay.style.display = busy ? 'flex' : 'none';
if (msgEl && msg) msgEl.textContent = msg;
if (msgEl && !busy) msgEl.textContent = 'Please wait\u2026';
document.querySelectorAll('button').forEach(function (btn) {
if (busy) {
btn.setAttribute('data-was-disabled', btn.disabled ? '1' : '0');
btn.disabled = true;
} else {
btn.disabled = btn.getAttribute('data-was-disabled') === '1';
}
});
}
/* ════════════════════════════════════════════════════════════
CSRF TOKEN
════════════════════════════════════════════════════════════ */
function waitForToken() {
return new Promise(function (resolve, reject) {
var pc = window.portalContext || {};
var cached = pc.csrfToken || pc.requestVerificationToken;
if (cached && cached.length > 20) { resolve(cached); return; }
var domEl = document.querySelector('input[name="__RequestVerificationToken"]');
if (domEl && domEl.value) { resolve(domEl.value); return; }
var csrfEl = document.getElementById('csrf-token-value');
if (csrfEl && csrfEl.value && csrfEl.value.length > 20) { resolve(csrfEl.value); return; }
var attempts = 0;
var poll = setInterval(function () {
attempts++;
var pv = (window.portalContext || {}).csrfToken;
if (pv && pv.length > 20) { clearInterval(poll); resolve(pv); return; }
var el = document.getElementById('csrf-token-value');
if (el && el.value && el.value.length > 20) { clearInterval(poll); resolve(el.value); return; }
if (attempts >= 30) {
clearInterval(poll);
fetch('/Account/Login', { credentials: 'same-origin', headers: { 'Accept': 'text/html' } })
.then(function (r) { return r.text(); })
.then(function (html) {
var m = html.match(/name="__RequestVerificationToken"[^>]*value="([^"]+)"/);
if (!m) m = html.match(/value="([^"]{40,})"[^>]*name="__RequestVerificationToken"/);
if (m && m[1]) { resolve(m[1]); } else { reject(new Error('CSRF token not found')); }
})
.catch(function (e) { reject(new Error('CSRF fetch failed: ' + e.message)); });
}
}, 150);
});
}
/* ════════════════════════════════════════════════════════════
DATAVERSE API
════════════════════════════════════════════════════════════ */
function extractEntityId(data, response) {
if (data && typeof data === 'object') {
var fromBody = data.leadid || data.contactid || data.ongc_paymentevidenceid;
if (!fromBody && data['@odata.id']) {
var m = data['@odata.id'].match(/\(([0-9a-f-]{36})\)/i);
if (m) fromBody = m[1];
}
if (fromBody) return fromBody;
}
var headerVal = '';
if (response && typeof response.headers === 'object' && typeof response.headers.get === 'function') {
headerVal = response.headers.get('OData-EntityId') || '';
}
if (headerVal) {
var m2 = headerVal.match(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i);
if (m2) return m2[0];
}
return null;
}
async function dataversePost(entitySet, payload) {
var url = '/_api/' + entitySet;
var token = await waitForToken();
var response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'__RequestVerificationToken': token,
'OData-MaxVersion': '4.0',
'OData-Version': '4.0',
'Prefer': 'return=representation'
},
body: JSON.stringify(payload)
});
if (!response.ok) {
var errMsg = 'API error ' + response.status;
try { var errJson = await response.json(); errMsg = (errJson && errJson.error && errJson.error.message) || errMsg; } catch (e) { }
throw new Error(errMsg);
}
var data = {};
try { data = await response.json(); } catch (e) { }
return { id: extractEntityId(data, response), data: data };
}
async function fetchLeadRef(leadId) {
try {
var token = await waitForToken();
var r = await fetch('/_api/leads(' + leadId + ')?$select=ongc_leadrefid,ongc_clientid', {
method: 'GET',
headers: { '__RequestVerificationToken': token, 'OData-MaxVersion': '4.0', 'OData-Version': '4.0', 'Accept': 'application/json' }
});
if (!r.ok) return null;
var d = await r.json();
return (d && (d.ongc_leadrefid || d.ongc_clientid)) || null;
} catch (e) { return null; }
}
/* ════════════════════════════════════════════════════════════
SESSION STORAGE
════════════════════════════════════════════════════════════ */
function clearSession() {
[state.leadIdKey, state.leadRefKey, state.evidenceIdKey, state.paymentInProgressKey].forEach(function (k) {
try { sessionStorage.removeItem(k); } catch (e) { }
});
state.leadId = null; state.leadRef = null; state.paymentEvidenceId = null;
}
function saveSession() {
try {
if (state.leadId) sessionStorage.setItem(state.leadIdKey, state.leadId);
if (state.leadRef) sessionStorage.setItem(state.leadRefKey, state.leadRef);
if (state.paymentEvidenceId) sessionStorage.setItem(state.evidenceIdKey, state.paymentEvidenceId);
} catch (e) { }
}
/* ════════════════════════════════════════════════════════════
HELPERS
════════════════════════════════════════════════════════════ */
function round2(n) { return Math.round(n * 100) / 100; }
function gVal(id) { var el = document.getElementById(id); return el ? el.value.trim() : ''; }
function stripEmpty(payload) {
Object.keys(payload).forEach(function (k) {
if (payload[k] === '' || payload[k] === null || payload[k] === undefined) delete payload[k];
});
return payload;
}
/* ════════════════════════════════════════════════════════════
FEE CALCULATION
════════════════════════════════════════════════════════════ */
function getFeeBase() {
var lvl = gVal('standardsLevel');
var cnt = gVal('entryModalityCount') || gVal('fullModalityCount');
return (lvl && cnt && FEE_MATRIX[lvl] && FEE_MATRIX[lvl][cnt]) ? FEE_MATRIX[lvl][cnt] : 0;
}
function calcFees() {
var base = getFeeBase();
var surcharge = round2(base * config.ccSurchargeRate);
var gst = round2((base + surcharge) * config.gstRate);
var total = round2(base + surcharge + gst);
return { base: round2(base), surcharge: surcharge, gst: gst, total: total };
}
function diaUpdateFee() {
var base = getFeeBase();
var el = document.getElementById('diaFeeAmount');
if (el) el.textContent = base > 0
? base.toLocaleString('en-AU', { minimumFractionDigits: 2 })
: '0.00';
}
/* ════════════════════════════════════════════════════════════
PROGRESS BAR
════════════════════════════════════════════════════════════ */
function buildProgress() {
var c = document.getElementById('diaProgressSteps');
if (!c) return;
c.innerHTML = '';
for (var i = 1; i <= TOTAL_PAGES; i++) {
var div = document.createElement('div');
div.className = 'dia-step-item' +
(state.currentPage === i ? ' active' : '') +
(state.currentPage > i ? ' done' : '');
div.innerHTML =
'' + (state.currentPage > i ? '✓' : i) + '
' +
'' + (LABELS[i] || i) + '
';
c.appendChild(div);
}
}
/* ════════════════════════════════════════════════════════════
PAGE NAVIGATION
════════════════════════════════════════════════════════════ */
function showPage(n) {
if (state.isBusy && typeof n === 'number') return;
document.querySelectorAll('.dia-form-page').forEach(function (el) { el.classList.remove('active'); });
var target = (n === 'success')
? document.getElementById('diaSuccess')
: document.querySelector('.dia-form-page[data-page="' + n + '"]');
if (target) { target.classList.add('active'); window.scrollTo({ top: 0, behavior: 'smooth' }); }
if (typeof n === 'number') state.currentPage = n;
buildProgress();
if (n === 6) { diaUpdateFee(); }
if (n === 7) { initSig(); diaUpdateFee(); }
}
function diaNextPage(n) { if (!state.isBusy && validatePage(n)) showPage(n + 1); }
function diaPrevPage(n) { if (!state.isBusy) showPage(n - 1); }
/* ════════════════════════════════════════════════════════════
VALIDATION
════════════════════════════════════════════════════════════ */
function req(id, errId) {
var el = document.getElementById(id);
var err = document.getElementById(errId);
var ok = el && el.value.trim() !== '';
if (err) err.classList.toggle('visible', !ok);
return ok;
}
function validatePage(n) {
var ok = true;
if (n === 1) {
ok = req('contactFirstName', 'err_contactFirstName') && ok;
ok = req('contactLastName', 'err_contactLastName') && ok;
ok = req('contactPosition', 'err_contactPosition') && ok;
ok = req('contactPhone', 'err_contactPhone') && ok;
ok = req('contactEmail', 'err_contactEmail') && ok;
}
if (n === 2) {
ok = req('lspnNumber', 'err_lspnNumber') && ok;
ok = req('registeringType', 'err_registeringType') && ok;
ok = req('providingType', 'err_providingType') && ok;
ok = req('corporateGroup', 'err_corporateGroup') && ok;
if (gVal('corporateGroup') === 'yes') ok = req('corporateName', 'err_corporateName') && ok;
ok = req('previouslyAccredited', 'err_previouslyAccredited') && ok;
if (gVal('previouslyAccredited') === 'yes') {
ok = req('previousProvider', 'err_previousProvider') && ok;
ok = req('previousExpiryDate', 'err_previousExpiryDate') && ok;
}
ok = req('sector', 'err_sector') && ok;
if (gVal('sector') === 'other') ok = req('sectorOther', 'err_sectorOther') && ok;
}
if (n === 3) {
ok = req('practiceName', 'err_practiceName') && ok;
ok = req('practiceABN', 'err_practiceABN') && ok;
ok = req('practicePhone', 'err_practicePhone') && ok;
ok = req('practiceEmail', 'err_practiceEmail') && ok;
}
if (n === 4) {
var cityOk = document.getElementById('streetCity') && document.getElementById('streetCity').value.trim();
var stateOk = document.getElementById('streetState') && document.getElementById('streetState').value;
var pcOk = document.getElementById('streetPostcode') && document.getElementById('streetPostcode').value.trim();
var addrOk = cityOk && stateOk && pcOk;
var addrErr = document.getElementById('err_streetAddress');
if (addrErr) addrErr.classList.toggle('visible', !addrOk);
ok = !!addrOk && ok;
var postalYes = document.getElementById('postalYes');
if (postalYes && postalYes.checked) {
var pCityOk = document.getElementById('postalCity') && document.getElementById('postalCity').value.trim();
var pStateOk = document.getElementById('postalState') && document.getElementById('postalState').value;
var pPcOk = document.getElementById('postalPostcode') && document.getElementById('postalPostcode').value.trim();
var postalOk = pCityOk && pStateOk && pPcOk;
var postalErr = document.getElementById('err_postalAddress');
if (postalErr) postalErr.classList.toggle('visible', !postalOk);
ok = !!postalOk && ok;
}
}
if (n === 5) {
var selected = document.querySelectorAll('.dia-modality-cb:checked').length > 0;
var modErr = document.getElementById('err_modalities');
if (modErr) modErr.classList.toggle('visible', !selected);
ok = selected && ok;
ok = req('equipmentUnits', 'err_equipmentUnits') && ok;
}
if (n === 6) {
ok = req('standardsLevel', 'err_standardsLevel') && ok;
var lvl = gVal('standardsLevel');
if (lvl === 'entry') ok = req('entryModalityCount', 'err_entryModalityCount') && ok;
if (lvl === 'full') ok = req('fullModalityCount', 'err_fullModalityCount') && ok;
}
if (!ok) {
var first = document.querySelector('.dia-error-msg.visible');
if (first) first.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
return ok;
}
/* ════════════════════════════════════════════════════════════
CONDITIONALS
════════════════════════════════════════════════════════════ */
function diaCorporateChange() { toggle('grp_corporateName', gVal('corporateGroup') === 'yes'); }
function diaPrevAccreditedChange() { toggle('grp_previousDetails', gVal('previouslyAccredited') === 'yes'); }
function diaSectorChange() { toggle('grp_sectorOther', gVal('sector') === 'other'); }
function diaPostalToggle(val) { toggle('grp_postalAddress', val === 'yes'); }
function diaStandardsChange() {
var v = gVal('standardsLevel');
toggle('grp_entryModalityCount', v === 'entry');
toggle('grp_fullModalityCount', v === 'full');
diaUpdateFee();
}
function toggle(id, show) { var el = document.getElementById(id); if (el) el.classList.toggle('show', show); }
/* ════════════════════════════════════════════════════════════
MODALITY CARDS
════════════════════════════════════════════════════════════ */
function bindModalityCards() {
document.querySelectorAll('.dia-modality-card').forEach(function (card) {
card.addEventListener('click', function () {
var cb = card.querySelector('.dia-modality-cb');
if (cb) { cb.checked = !cb.checked; card.classList.toggle('selected', cb.checked); }
updateModCount();
});
});
}
function updateModCount() {
var count = document.querySelectorAll('.dia-modality-cb:checked').length;
var el = document.getElementById('diaModCount');
if (el) el.textContent = count + ' modalit' + (count === 1 ? 'y' : 'ies') + ' selected';
}
/* ════════════════════════════════════════════════════════════
SIGNATURE CANVAS
════════════════════════════════════════════════════════════ */
function initSig() {
var c = document.getElementById('diaSignatureCanvas');
if (!c) return;
var fresh = c.cloneNode(true);
c.parentNode.replaceChild(fresh, c);
c = fresh;
c.width = c.parentElement.clientWidth || 680;
c.height = 120;
state.sigCtx = c.getContext('2d');
state.sigCtx.strokeStyle = '#1A3A4A';
state.sigCtx.lineWidth = 2.2;
state.sigCtx.lineCap = 'round';
state.sigCtx.lineJoin = 'round';
var ctx = state.sigCtx;
function pos(e) { var r = c.getBoundingClientRect(); var pt = e.touches ? e.touches[0] : e; return { x: pt.clientX - r.left, y: pt.clientY - r.top }; }
c.addEventListener('mousedown', function (e) { state.sigDrawing = true; ctx.beginPath(); var p = pos(e); ctx.moveTo(p.x, p.y); });
c.addEventListener('mousemove', function (e) { if (!state.sigDrawing) return; var p = pos(e); ctx.lineTo(p.x, p.y); ctx.stroke(); });
c.addEventListener('mouseup', function () { state.sigDrawing = false; });
c.addEventListener('mouseleave', function () { state.sigDrawing = false; });
c.addEventListener('touchstart', function (e) { e.preventDefault(); state.sigDrawing = true; ctx.beginPath(); var p = pos(e); ctx.moveTo(p.x, p.y); }, { passive: false });
c.addEventListener('touchmove', function (e) { e.preventDefault(); if (!state.sigDrawing) return; var p = pos(e); ctx.lineTo(p.x, p.y); ctx.stroke(); }, { passive: false });
c.addEventListener('touchend', function () { state.sigDrawing = false; });
}
function diaClearSig() {
var c = document.getElementById('diaSignatureCanvas');
if (state.sigCtx && c) state.sigCtx.clearRect(0, 0, c.width, c.height);
}
function isSigEmpty() {
var c = document.getElementById('diaSignatureCanvas');
if (!c || !state.sigCtx) return true;
var d = state.sigCtx.getImageData(0, 0, c.width, c.height).data;
for (var i = 3; i < d.length; i += 4) { if (d[i] > 0) return false; }
return true;
}
/* ════════════════════════════════════════════════════════════
PAYLOAD BUILDERS
════════════════════════════════════════════════════════════ */
function buildLeadPayload() {
var practiceName = gVal('practiceName');
var postalDiff = document.getElementById('postalYes') && document.getElementById('postalYes').checked;
var selected = [];
document.querySelectorAll('.dia-modality-cb:checked').forEach(function (cb) { selected.push(cb.value); });
var payload = {
subject: 'QIP Diagnostic Imaging Registration \u2013 ' + practiceName,
firstname: gVal('contactFirstName'),
lastname: gVal('contactLastName') || practiceName,
jobtitle: gVal('contactPosition'),
emailaddress1: gVal('contactEmail'),
telephone1: gVal('contactPhone'),
companyname: practiceName,
websiteurl: gVal('practiceWebsite'),
leadsourcecode: 8,
/* Street address */
address1_line1: gVal('streetAddr0'),
address1_line2: gVal('streetAddr1'),
address1_city: gVal('streetCity'),
address1_stateorprovince: gVal('streetState'),
address1_postalcode: gVal('streetPostcode'),
address1_country: 'Australia',
/* Postal */
address2_line1: postalDiff ? gVal('postalAddr0') : '',
address2_line2: postalDiff ? gVal('postalAddr1') : '',
address2_city: postalDiff ? gVal('postalCity') : '',
address2_stateorprovince: postalDiff ? gVal('postalState') : '',
address2_postalcode: postalDiff ? gVal('postalPostcode') : '',
address2_country: postalDiff ? 'Australia' : '',
/* Custom ONGC fields */
ongc_enquirytype: 4, /* 4 = Diagnostic Imaging */
ongc_practicename: practiceName,
ongc_practiceabn: gVal('practiceABN'),
ongc_practicephone: gVal('practicePhone'),
ongc_postalsameasstreet: !postalDiff,
ongc_corporateentity: gVal('corporateName'),
/* Diagnostic Imaging specific — stored in description */
description: JSON.stringify({
lspn: gVal('lspnNumber'),
registeringType: gVal('registeringType'),
providingType: gVal('providingType'),
corporateGroup: gVal('corporateGroup'),
previouslyAccredited: gVal('previouslyAccredited'),
previousProvider: gVal('previousProvider'),
previousExpiryDate: gVal('previousExpiryDate'),
sector: gVal('sector'),
sectorOther: gVal('sectorOther'),
standardsLevel: gVal('standardsLevel'),
modalities: selected.join(', '),
equipmentUnits: gVal('equipmentUnits')
})
};
return stripEmpty(payload);
}
function buildContactPayload() {
var payload = {
firstname: gVal('contactFirstName'),
lastname: gVal('contactLastName'),
jobtitle: gVal('contactPosition'),
emailaddress1: gVal('contactEmail'),
telephone1: gVal('contactPhone'),
mobilephone: gVal('practicePhone')
};
if (state.leadId) {
payload['originatingleadid@odata.bind'] = '/leads(' + state.leadId + ')';
}
if (config.contactTypeId) {
payload['ongc_ContactType@odata.bind'] = '/ongc_contacttypes(' + config.contactTypeId + ')';
}
return stripEmpty(payload);
}
function buildPaymentEvidencePayload() {
var fees = calcFees();
var payload = {
ongc_payername: (gVal('contactFirstName') + ' ' + gVal('contactLastName')).trim(),
ongc_paymentamount: fees.base,
ongc_surchargefee: fees.surcharge,
ongc_gst: fees.gst,
ongc_totalamount: fees.total,
ongc_paymentstatus: 'pending-cc',
ongc_transactionstatus: 'pending',
ongc_paymentdate: new Date().toISOString(),
ongc_responsemessage: 'Pending \u2013 QIP Diagnostic Imaging Stripe credit-card checkout initiated'
};
if (state.leadId) {
payload['ongc_Lead@odata.bind'] = '/leads(' + state.leadId + ')';
}
return stripEmpty(payload);
}
/* ════════════════════════════════════════════════════════════
RECORD CREATION CHAIN
════════════════════════════════════════════════════════════ */
async function createAllRecords() {
/* 1. Lead — critical */
setBusy(true, 'Creating registration record\u2026');
var lead = await dataversePost('leads', buildLeadPayload());
state.leadId = lead.id;
if (!state.leadId) throw new Error('Lead created but GUID not returned. Check Dataverse Web API permissions.');
console.log('[DIA] Lead created:', state.leadId);
/* 2. Fetch autonumber leadRef */
setBusy(true, 'Fetching registration reference\u2026');
var fetchedRef = await fetchLeadRef(state.leadId);
state.leadRef = fetchedRef || null;
console.log('[DIA] leadRef:', state.leadRef);
saveSession();
/* 3. Contact — non-blocking */
setBusy(true, 'Creating contact record\u2026');
try {
var cr = await Promise.allSettled([dataversePost('contacts', buildContactPayload())]);
if (cr[0].status === 'rejected') console.warn('[DIA] Contact failed (non-fatal):', cr[0].reason && cr[0].reason.message);
else console.log('[DIA] Contact created:', cr[0].value && cr[0].value.id);
} catch (e) { console.warn('[DIA] Contact error (non-fatal):', e.message); }
/* 4. PaymentEvidence — critical */
setBusy(true, 'Creating payment record\u2026');
var evidence = await dataversePost('ongc_paymentevidences', buildPaymentEvidencePayload());
if (evidence && evidence.id) {
state.paymentEvidenceId = evidence.id;
console.log('[DIA] Evidence created:', evidence.id);
} else {
console.warn('[DIA] Evidence GUID not returned — return page will create fallback record');
}
saveSession();
}
/* ════════════════════════════════════════════════════════════
STRIPE REDIRECT (shared /agpal-stripe-checkout)
════════════════════════════════════════════════════════════ */
function initiateStripePayment() {
var fees = calcFees();
var params = new URLSearchParams({
leadId: state.leadId || '',
leadRef: state.leadRef || '',
paymentEvidenceId: state.paymentEvidenceId || '',
amount: fees.total.toFixed(2),
base: fees.base.toFixed(2),
surcharge: fees.surcharge.toFixed(2),
gst: fees.gst.toFixed(2),
email: gVal('contactEmail'),
name: (gVal('contactFirstName') + ' ' + gVal('contactLastName')).trim(),
ref: 'QIP Diagnostic Imaging Registration \u2013 ' + gVal('practiceName'),
returnUrl: window.location.href.split('?')[0]
});
try {
sessionStorage.setItem(state.paymentInProgressKey, '1');
if (state.leadId) sessionStorage.setItem(state.leadIdKey, state.leadId);
if (state.leadRef) sessionStorage.setItem(state.leadRefKey, state.leadRef);
if (state.paymentEvidenceId) sessionStorage.setItem(state.evidenceIdKey, state.paymentEvidenceId);
} catch (e) { }
/* location.replace so Back can't return to mid-payment form */
window.location.replace('/agpal-stripe-checkout?' + params.toString());
}
/* ════════════════════════════════════════════════════════════
SUBMIT ENTRY POINT
════════════════════════════════════════════════════════════ */
async function diaSubmit() {
/* Validate declarations */
var auth = document.getElementById('authCheck') && document.getElementById('authCheck').checked;
var tc = document.getElementById('termsCheck') && document.getElementById('termsCheck').checked;
var confirm = document.getElementById('confirmCheck') && document.getElementById('confirmCheck').checked;
var af = gVal('authFirstName');
var al = gVal('authLastName');
var sigOk = !isSigEmpty();
var errEl = document.getElementById('diaSubmitError');
document.getElementById('err_authCheck') && document.getElementById('err_authCheck').classList.toggle('visible', !auth);
document.getElementById('err_termsCheck') && document.getElementById('err_termsCheck').classList.toggle('visible', !tc);
document.getElementById('err_confirmCheck') && document.getElementById('err_confirmCheck').classList.toggle('visible', !confirm);
document.getElementById('err_signature') && document.getElementById('err_signature').classList.toggle('visible', !sigOk);
document.getElementById('err_authFirstName') && document.getElementById('err_authFirstName').classList.toggle('visible', !af);
document.getElementById('err_authLastName') && document.getElementById('err_authLastName').classList.toggle('visible', !al);
if (!auth || !tc || !confirm || !sigOk || !af || !al) {
if (errEl) errEl.classList.add('visible');
var first = document.querySelector('.dia-error-msg.visible');
if (first) first.scrollIntoView({ behavior: 'smooth', block: 'center' });
return;
}
if (errEl) errEl.classList.remove('visible');
try {
await createAllRecords();
setBusy(true, 'Redirecting to payment\u2026');
initiateStripePayment();
} catch (err) {
console.error('[DIA] Submit failed:', err);
if (errEl) {
errEl.classList.add('visible');
errEl.textContent = 'Could not submit registration: ' + (err.message || 'Unknown error') + '. Please try again.';
errEl.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
setBusy(false);
}
}
/* ════════════════════════════════════════════════════════════
SAVE (placeholder) & TOAST
════════════════════════════════════════════════════════════ */
function diaSave() { showToast('Progress saved.', 'success'); }
function showToast(msg, type) {
var el = document.getElementById('diaToast');
if (!el) return;
el.textContent = msg;
el.className = 'dia-toast ' + (type || '') + ' show';
setTimeout(function () { el.classList.remove('show'); }, 3000);
}
/* ════════════════════════════════════════════════════════════
INIT
════════════════════════════════════════════════════════════ */
document.addEventListener('DOMContentLoaded', function () {
injectSpinner();
clearSession();
buildProgress();
bindModalityCards();
diaUpdateFee();
['standardsLevel', 'entryModalityCount', 'fullModalityCount'].forEach(function (id) {
var el = document.getElementById(id);
if (el) el.addEventListener('change', diaUpdateFee);
});
});
window.addEventListener('resize', function () { if (state.sigCtx) initSig(); });
/* ── Expose globals for inline onclick ── */
window.diaNextPage = diaNextPage;
window.diaPrevPage = diaPrevPage;
window.diaSave = diaSave;
window.diaSubmit = diaSubmit;
window.diaClearSig = diaClearSig;
window.diaUpdateFee = diaUpdateFee;
window.diaCorporateChange = diaCorporateChange;
window.diaPrevAccreditedChange = diaPrevAccreditedChange;
window.diaSectorChange = diaSectorChange;
window.diaPostalToggle = diaPostalToggle;
window.diaStandardsChange = diaStandardsChange;
}());