Calculate software development team's ROI

by andypotanin

HTML

<div class="p-6 max-w-4xl mx-auto">
  <h1 class="text-2xl font-bold mb-4">Software Logistics ROI Calculator</h1>

  <div id="sliders" class="space-y-6">
    <div>
      <label class="block font-semibold">Engineering Team Size</label>
      <input id="teamSize" type="range" min="50" max="5000" step="50" value="500" class="w-full">
      <p class="text-sm mt-1">Value: <span id="valTeamSize">500</span></p>
    </div>

    <div>
      <label class="block font-semibold">Monthly Deployments</label>
      <input id="deployments" type="range" min="100" max="20000" step="100" value="2000" class="w-full">
      <p class="text-sm mt-1">Value: <span id="valDeployments">2000</span></p>
    </div>

    <div>
      <label class="block font-semibold">Current Deployment Time (hrs)</label>
      <input id="deployTime" type="range" min="0.5" max="12" step="0.5" value="10" class="w-full">
      <p class="text-sm mt-1">Value: <span id="valDeployTime">10</span> hrs</p>
    </div>

    <div>
      <label class="block font-semibold">Engineer Hourly Cost ($)</label>
      <input id="hourlyCost" type="range" min="20" max="150" step="5" value="75" class="w-full">
      <p class="text-sm mt-1">Value: $<span id="valHourlyCost">75</span></p>
    </div>

    <div>
      <label class="block font-semibold">Secrets Rotated per Month</label>
      <input id="secrets" type="range" min="100" max="20000" step="100" value="5000" class="w-full">
      <p class="text-sm mt-1">Value: <span id="valSecrets">5000</span></p>
    </div>

    <div>
      <label class="block font-semibold">Annual Audit Cost ($)</label>
      <input id="audit" type="range" min="250000" max="5000000" step="250000" value="3000000" class="w-full">
      <p class="text-sm mt-1">Value: $<span id="valAudit">3000000</span></p>
    </div>

    <div>
      <label class="block font-semibold">Annual Incident Cost ($)</label>
      <input id="incidents" type="range" min="100000" max="10000000" step="500000" value="2000000" class="w-full">
 ...

JavaScript

function formatUSD(num) {
  return num.toLocaleString('en-US');
}

$(function () {
  // Update live slider values
  $('input[type=range]').on('input', function () {
    $('#val' + this.id.charAt(0).toUpperCase() + this.id.slice(1)).text(this.value);
  });

  $('#calculate').on('click', function () {
    const teamSize = parseInt($('#teamSize').val());
    const deployments = parseInt($('#deployments').val());
    const deployTime = parseFloat($('#deployTime').val());
    const hourlyCost = parseFloat($('#hourlyCost').val());
    const secrets = parseInt($('#secrets').val());
    const audit = parseInt($('#audit').val());
    const incidents = parseInt($('#incidents').val());

    const months = 11;
    const timeSaved = deployTime - 0.33; // Target is 20 mins
    const hoursSavedPerMonth = deployments * timeSaved;
    const deploySavings = hoursSavedPerMonth * hourlyCost * months;

    const secretSavings = secrets * 1.5 * hourlyCost * months;

    const auditSavings = audit * 0.997;
    const incidentSavings = incidents * 0.8;

    const total = deploySavings + secretSavings + auditSavings + incidentSavings;

    $('#outDeploySavings').text(formatUSD(Math.round(deploySavings)));
    $('#outSecretsSavings').text(formatUSD(Math.round(secretSavings)));
    $('#outAuditSavings').text(formatUSD(Math.round(auditSavings)));
    $('#outIncidentSavings').text(formatUSD(Math.round(incidentSavings)));
    $('#outTotal').text(formatUSD(Math.round(total)));

    $('#results').removeClass('hidden');
  });
});