A bill of quantities is where the DSR meets your project. Here is how to build one from DSR items — and automate the parts that don't need a human.
Map drawings and measured quantities to the right DSR items — without missing scope or double-counting.
EstimateNext automates the slowest parts of estimating — matching each line to the correct DSR/SOR code, pulling the rate analysis build-up and computing amounts. Tasks that take an estimator days of manual lookups and cross-checking are compressed into minutes, letting you focus on reviewing rates instead of assembling them.
You can upload your BOQ as standard spreadsheet files — Excel (.xlsx, .xls) and CSV are supported. The AI reads the item descriptions and quantities directly from the sheet, so there is no rigid template to follow.
Upload your BOQ as a spreadsheet and EstimateNext's AI reads every line, matches each item to the correct CPWD DSR or state SOR entry, and attaches a full rate analysis build-up automatically — no manual code-hunting.
From there it returns a complete priced bid package: priced BOQ, item-wise rate analysis and a submission-ready abstract. What normally takes an estimator days of lookups and cross-checking is compressed into minutes, so you can focus on reviewing rates rather than assembling them.
AI construction estimation uses machine learning to read item descriptions, match each one to the correct CPWD DSR or state SOR code, and build up rates automatically. EstimateNext handles the lookups, cross-checking and amount calculations that estimators normally do by hand — turning days of manual work into minutes while leaving the final rate review in your control.
Traditional construction bid software expects you to build every line item, hunt for the right DSR/SOR code and key in rates yourself. EstimateNext flips that: you upload a BOQ spreadsheet and it returns a priced BOQ, item-wise rate analysis and a submission-ready abstract — matched, built up and totalled automatically — so you spend your time reviewing the bid rather than assembling it.
Yes. By pulling rates directly from the published DSR/SOR and applying consistent rate-analysis build-ups, EstimateNext removes the copy-paste and transcription errors that creep into manual bids. Faster turnaround also means you can respond to more tenders and refine pricing strategy instead of racing deadlines.
Upload a BOQ → get a priced BOQ, rate analysis and abstract back, ready to review.
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