Before you price anything, you need to know what the Schedule of Rates actually is, how it is organised, and why your state's SOR may not match CPWD. Start here.
Decode an item end to end: its code, description, unit, specification and the rate build-up that follows.
Upload a BOQ and get it priced with rate analysis attached — built on the same DSR logic explained here.
7 guides · updated as we publish
7 guides · updated as we publish
', …),
// where dollar-quote and dollar-amp are special replace tokens; and it lives in a
// JS template literal that eats backslash escapes. So keep this block free of the
// dollar sign and of backslash escapes: exact-match CTA texts (no regex end-anchor)
// plus a space-only collapse regex.
var cnxCtaTexts = ['book a demo','request a demo','get a demo','book demo','schedule a demo','talk to sales','talk to us','talk to the team','get in touch','contact us','contact sales','contact the team','contact'];
function cnxIsContactCta(el){
if (el.id && el.id.indexOf('cnx-') === 0) return false;
if (el.hasAttribute && el.hasAttribute('data-cnx-contact')) return true;
var raw = ((el.getAttribute && el.getAttribute('href')) || '').toLowerCase();
var hh = raw.split('?')[0].split('#')[0];
if (raw === '#contact' || hh === '/contact' || hh === 'contact' || hh === 'contact.html'
|| (hh.length >= 8 && hh.lastIndexOf('/contact') === hh.length - 8)
|| (hh.length >= 13 && hh.lastIndexOf('/contact.html') === hh.length - 13)) return true;
var t = (el.textContent || '').replace(/ +/g, ' ').trim().toLowerCase();
if (t.length > 24) return false;
for (var k = 0; k < cnxCtaTexts.length; k++) { if (t === cnxCtaTexts[k]) return true; }
return false;
}
document.addEventListener('click', function (e) {
var el = e.target;
while (el && el !== document) {
if (el.tagName === 'A' || el.tagName === 'BUTTON') break;
el = el.parentNode;
}
if (!el || el === document) return;
if (cnxIsContactCta(el)) {
e.preventDefault();
e.stopPropagation();
openModal();
}
}, true);
if (closeBtn) closeBtn.addEventListener('click', closeModal);
if (scrim) scrim.addEventListener('click', function(e){ if(e.target === scrim) closeModal(); });
if (form) form.addEventListener('submit', function(e){
e.preventDefault();
var note = document.getElementById('cnx-note'), err = document.getElementById('cnx-err'), btn = document.getElementById('cnx-submit');
note.style.display='none'; err.style.display='none';
if (form.website_url && form.website_url.value){ note.style.display='block'; return; } // honeypot
var payload = {
name: form.name.value, email: form.email.value, company: form.company.value,
phone: form.phone.value, message: form.message.value,
subscribe_newsletter: form.subscribe_newsletter && form.subscribe_newsletter.checked,
turnstile_token: form.turnstile_token ? form.turnstile_token.value : '',
_token_ts: tsEl ? tsEl.value : tokenTs()
};
if (!payload.name || !payload.email || !payload.company || !payload.phone || !payload.message){ err.textContent='Please fill in all required fields.'; err.style.display='block'; return; }
if (payload.phone.replace(/[^0-9]/g, '').length < 7){ err.textContent='Please enter a valid phone number.'; err.style.display='block'; return; }
btn.disabled = true; btn.textContent = 'Sending…';
post(payload).then(function(d){
if (d && d.success){ form.style.display='none'; note.style.display='block'; }
else { err.textContent = (d && d.message) || 'Something went wrong — please try again.'; err.style.display='block'; btn.disabled=false; btn.textContent='Send message'; }
}).catch(function(){ err.textContent='Network error — please try again.'; err.style.display='block'; btn.disabled=false; btn.textContent='Send message'; });
});
// --- Progressive enhancement: wire a site's OWN contact form to the CRM ---
// Targets forms that look like contact forms (have an email field AND a
// textarea/message field), aren't ours, and aren't opted out. Field mapping is
// heuristic; company falls back to the entered name so the CRM never rejects.
function pick(f, res){ for (var i=0;i