Dynamics 365 Licensing Calculator
License each person once, then attach. Count who uses which Dynamics 365 app. People who need two Customer Engagement apps pay full price for one and the much cheaper attach price for the other; light users get Team Members.
How Dynamics 365 licensing works
Base and attach licenses
Each person needs one base license at full price. If they also use another qualifying app, that second app is bought as an attach license, a fraction of the full price. The base must be the more expensive app.
Team Members
Team Members lets people read data, approve, log time and expenses, and update records they own. Anyone who works cases or opportunities needs a full license.
Business Central
Business Central is licensed separately from the Customer Engagement apps: Essentials covers finance, sales, purchasing and inventory; Premium adds manufacturing and service management.
window.C2N = (function () { function esc(s) { return String(s).replace(/[&<>"]/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"' }[c]; }); } function fire(el) { el.dispatchEvent(new Event('input', { bubbles: true })); el.dispatchEvent(new Event('change', { bubbles: true })); } function enhance(form) { [].forEach.call(form.querySelectorAll('select[data-seg]'), function (sel) { var seg = document.createElement('div'); seg.className = 'c2n-seg'; seg.setAttribute('role', 'radiogroup'); seg.style.gridTemplateColumns = 'repeat(' + Math.min(sel.options.length, +sel.dataset.seg || sel.options.length) + ',1fr)'; [].forEach.call(sel.options, function (o) { var b = document.createElement('button'); b.type = 'button'; b.textContent = o.textContent; b.dataset.v = o.value; b.setAttribute('role', 'radio'); b.addEventListener('click', function () { sel.value = o.value; sync(form); fire(sel); }); seg.appendChild(b); }); sel.hidden = true; sel.parentNode.insertBefore(seg, sel.nextSibling); }); [].forEach.call(form.querySelectorAll('input[data-range]'), function (num) { var r = num.dataset.range.split(','), rg = document.createElement('input'); rg.type = 'range'; rg.min = r[0]; rg.max = r[1]; rg.step = r[2] || 1; rg.className = 'c2n-range'; rg.setAttribute('aria-label', num.name); rg.addEventListener('input', function (e) { e.stopPropagation(); num.value = rg.value; fire(num); }); num.parentNode.appendChild(rg); }); } function sync(form) { [].forEach.call(form.querySelectorAll('select[data-seg]'), function (sel) { [].forEach.call(sel.nextSibling.children, function (b) { var on = b.dataset.v === sel.value; b.classList.toggle('on', on); b.setAttribute('aria-checked', on); }); }); [].forEach.call(form.querySelectorAll('input[data-range]'), function (num) { num.parentNode.querySelector('.c2n-range').value = num.value; }); } function render(el, r) { var h = '<div class="c2n-cx-bar"><span>Results · ' + esc(r.title) + (r.unit === undefined ? ' · USD' : r.unit) + '</span><span class="c2n-cx-live">Live</span></div>'; if (r.lead) h += '<p class="c2n-cx-lead">' + r.lead + '</p>'; if (r.kpis) h += '<div class="c2n-cx-kpis">' + r.kpis.map(function (k, i) { return '<div class="c2n-cx-kpi' + (i ? '' : ' on') + '"><small>' + esc(k[0]) + '</small><b>' + k[1] + '</b><span>' + (k[2] || '') + '</span></div>'; }).join('') + '</div>'; if (r.rows) { var cell = function (tag) { return function (c, i) { return '<' + tag + (i ? ' class="n"' : '') + '>' + c + '</' + tag + '>'; }; }; h += '<div class="c2n-cx-scroll"><table class="c2n-cx-table">' + (r.head ? '<tr>' + r.head.map(cell('th')).join('') + '</tr>' : '') + r.rows.map(function (row) { return '<tr>' + row.map(cell('td')).join('') + '</tr>'; }).join('') + (r.total ? '<tr class="t">' + r.total.map(cell('td')).join('') + '</tr>' : '') + '</table></div>'; } h += '<div class="c2n-cx-foot"><p>' + (r.note || '') + '</p>' + (r.cta ? '<a class="c2n-cx-btn" href="' + esc(r.cta[1]) + '">' + esc(r.cta[0]) + '</a>' : '') + '</div>'; el.innerHTML = h; } function money(n, d) { return (n < 0 ? '-$' : '$') + Math.abs(n).toLocaleString('en-US', { minimumFractionDigits: d || 0, maximumFractionDigits: d || 0 }); } function values(form) { var v = {}; [].forEach.call(form.elements, function (el) { if (el.name) v[el.name] = el.type === 'number' ? Math.max(0, +el.value || 0) : el.value; }); return v; } function restore(form) { var q = new URLSearchParams(location.search); [].forEach.call(form.elements, function (el) { if (el.name) { if (q.has(el.name)) el.value = q.get(el.name); } }); } function save(form) { var o = {}; [].forEach.call(form.elements, function (el) { if (el.name) o[el.name] = el.value; }); history.replaceState(null, '', '?' + new URLSearchParams(o)); } function mount(form, calc) { enhance(form); restore(form); var run = function () { sync(form); calc(values(form)); save(form); }; form.addEventListener('input', run); form.addEventListener('submit', function (e) { e.preventDefault(); }); run(); } return { mount: mount, render: render, money: money, esc: esc, sync: sync, enhance: enhance }; })(); (function () { var P = {"Dynamics 365 Sales Professional":{"c":[780,68.25,78,["P3Y","Annual",780],["P3Y","Triennial",2340],["P3Y","Monthly",68.25]]},"Dynamics 365 Sales Enterprise Edition":{"c":[1260,110.25,126,["P3Y","Annual",1260],["P3Y","Triennial",3780],["P3Y","Monthly",110.25]]},"Dynamics 365 Customer Service Professional":{"c":[600,52.5,60,["P3Y","Annual",600],["P3Y","Triennial",1800],["P3Y","Monthly",52.5]]},"Dynamics 365 Customer Service Enterprise":{"c":[1260,110.25,126,["P3Y","Annual",1260],["P3Y","Triennial",3780],["P3Y","Monthly",110.25]]},"Dynamics 365 Field Service":{"c":[1260,110.25,126,["P3Y","Annual",1260],["P3Y","Triennial",3780],["P3Y","Monthly",110.25]]},"Dynamics 365 Sales Enterprise Attach to Qualifying Dynamics 365 Base Offer":{"c":[240,21,24,["P3Y","Annual",240],["P3Y","Triennial",720],["P3Y","Monthly",21]]},"Dynamics 365 Finance":{"c":[2520,220.5,252,["P3Y","Annual",2520],["P3Y","Triennial",7560],["P3Y","Monthly",220.5]]},"Dynamics 365 Supply Chain Management":{"c":[2520,220.5,252,["P3Y","Annual",2520],["P3Y","Triennial",7560],["P3Y","Monthly",220.5]]},"Dynamics 365 Business Central Essentials":{"c":[960,84,96,["P3Y","Annual",960],["P3Y","Triennial",2880],["P3Y","Monthly",84]]},"Dynamics 365 Business Central Premium":{"c":[1320,115.5,132,["P3Y","Annual",1320],["P3Y","Triennial",3960],["P3Y","Monthly",115.5]]},"Dynamics 365 Team Members":{"c":[96,8.4,9.6,["P3Y","Annual",96],["P3Y","Triennial",288],["P3Y","Monthly",8.4]]},"Dynamics 365 Business Central Team Members":{"c":[96,8.4,9.6,["P3Y","Annual",96],["P3Y","Triennial",288],["P3Y","Monthly",8.4]]}}; var $ = C2N.money; function mo(name) { return P['Dynamics 365 ' + name].c[0] / 12; } var APPS = [['sp', 'Sales Professional', 'Sales Professional'], ['se', 'Sales Enterprise', 'Sales Enterprise Edition'], ['cp', 'Customer Service Professional', 'Customer Service Professional'], ['ce', 'Customer Service Enterprise', 'Customer Service Enterprise'], ['fs', 'Field Service', 'Field Service'], ['fin', 'Finance', 'Finance'], ['scm', 'Supply Chain Management', 'Supply Chain Management'], ['bce', 'Business Central Essentials', 'Business Central Essentials'], ['bcp', 'Business Central Premium', 'Business Central Premium'], ['tm', 'Team Members', 'Team Members'], ['bctm', 'Business Central Team Members', 'Business Central Team Members']]; C2N.mount(document.getElementById('dy'), function (v) { var rows = [], total = 0, attach = mo('Sales Enterprise Attach to Qualifying Dynamics 365 Base Offer'); var entUsers = v.se + v.ce + v.fs, both = Math.min(v.both, Math.floor(entUsers / 2)); var cheaperEnt = Math.min.apply(null, [['se', mo('Sales Enterprise Edition')], ['ce', mo('Customer Service Enterprise')], ['fs', mo('Field Service')]].filter(function (a) { return v[a[0]]; }).map(function (a) { return a[1]; }).concat([Infinity])); APPS.forEach(function (a) { var n = v[a[0]]; if (!n) return; var p = mo(a[2]); total += n * p; rows.push([n + ' x ' + a[1], $(p, 2), $(n * p, 2)]); }); var save = both && isFinite(cheaperEnt) ? both * (cheaperEnt - attach) : 0; if (save) { rows.push([both + ' x second Enterprise app as attach', '-' + $(cheaperEnt - attach, 2), '-' + $(save, 2)]); total -= save; } var people = APPS.reduce(function (s, a) { return s + v[a[0]]; }, 0) - both; C2N.render(document.getElementById('dy-out'), { title: 'Dynamics 365', lead: rows.length ? '<strong>' + $(total) + ' a month</strong> for ' + people + ' people.' + (save ? ' Attach licensing saves ' + $(save) + ' a month for the ' + both + ' people on two Enterprise apps.' : '') : 'Enter users on the left to see your licensing.', kpis: [['Per month', $(total), 'annual commitment'], ['Per year', $(total * 12), people + ' people licensed']], head: ['License', 'Each / mo', 'Monthly'], rows: rows.length ? rows : [['No users entered', '', '']], total: ['Total per month', '', $(total, 2)], note: 'Microsoft US list price, Commercial, annual commitment, current month. Minimum seat counts and capacity add-ons are not included. A person confirms every quote.', cta: ['Request a quote', '/tools/forms/?f=quote&items=' + encodeURIComponent(APPS.filter(function (a) { return v[a[0]]; }).map(function (a) { return v[a[0]] + ' x Dynamics 365 ' + a[1]; }).join('; ') + (both ? '; ' + both + ' attach' : ''))] }); }); })();