Inventory Management Cost Tracker

Setup Information

Enter all subsequent costs based on this defined tracking period.

Holding Costs (Carrying Costs)

Ordering Costs

Shortage Costs (Stockout Costs)

Cost Summary

Please enter costs in the respective tabs. The summary will be calculated here.

Error: Tool UI elements missing.

"; return; } imcOpenTab(null, imcTabContents[0].id); imcUpdateNavButtons(); }); function imcOpenTab(event, tabId) { let targetButton = null; imcTabContents.forEach(tc => { tc.style.display = "none"; tc.classList.remove('imc-active'); }); imcTabButtons.forEach((btn, index) => { btn.classList.remove('imc-active'); if (btn.getAttribute('onclick').includes(tabId)) { targetButton = btn; imcCurrentTabIndex = index;} }); const targetTab = document.getElementById(tabId); if (targetTab) { targetTab.style.display = "block"; targetTab.classList.add('imc-active');} if (event && event.currentTarget) event.currentTarget.classList.add('imc-active'); else if (targetButton) targetButton.classList.add('imc-active'); imcUpdateNavButtons(); if (tabId === 'imcTabSummary' && typeof imcCalculateAndDisplay === 'function') imcCalculateAndDisplay(); } function imcNavigateTab(direction) { let newIdx = imcCurrentTabIndex; if (direction === 'next') newIdx = (imcCurrentTabIndex + 1) % imcTabButtons.length; else if (direction === 'prev') newIdx = (imcCurrentTabIndex - 1 + imcTabButtons.length) % imcTabButtons.length; const targetTabId = imcTabContents[newIdx].id; imcOpenTab({currentTarget: imcTabButtons[newIdx]}, targetTabId); } function imcUpdateNavButtons() { if (!imcPrevButton || !imcNextButton || imcTabButtons.length === 0) return; imcPrevButton.disabled = (imcCurrentTabIndex === 0); imcNextButton.disabled = (imcCurrentTabIndex === imcTabButtons.length - 1); } function imcGetNum(id) { const el = imcAllInputElements[id]; if (!el) return 0; const val = parseFloat(el.value); return isNaN(val) || val < 0 ? 0 : val; } function imcFormat(value) { return `$${value.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2})}`; } function imcCalculateCosts() { const businessName = imcBusinessNameElem.value || "Your Business"; const periodName = imcPeriodNameElem.value || "Selected Period"; let totalHolding = 0; imcHoldingCostIds.forEach(id => totalHolding += imcGetNum(id)); let totalOrdering = 0; imcOrderingCostIds.forEach(id => totalOrdering += imcGetNum(id)); let totalShortage = 0; imcShortageCostIds.forEach(id => totalShortage += imcGetNum(id)); const grandTotal = totalHolding + totalOrdering + totalShortage; const holdingPercent = grandTotal > 0 ? (totalHolding / grandTotal) * 100 : 0; const orderingPercent = grandTotal > 0 ? (totalOrdering / grandTotal) * 100 : 0; const shortagePercent = grandTotal > 0 ? (totalShortage / grandTotal) * 100 : 0; return { businessName, periodName, totalHolding, totalOrdering, totalShortage, grandTotal, holdingPercent, orderingPercent, shortagePercent }; } function imcCalculateAndDisplay() { if (!imcSummaryOutputDiv || !imcDownloadPdfButtonElem) return; const results = imcCalculateCosts(); imcSummaryOutputDiv.innerHTML = `

Cost Summary for ${results.businessName} (${results.periodName})

Total Holding Costs: ${imcFormat(results.totalHolding)}
Total Ordering Costs: ${imcFormat(results.totalOrdering)}
Total Shortage Costs: ${imcFormat(results.totalShortage)}

Grand Total Inventory Costs: ${imcFormat(results.grandTotal)}
Cost Category Percentages:
Holding Costs: ${results.holdingPercent.toFixed(1)}%
Ordering Costs: ${results.orderingPercent.toFixed(1)}%
Shortage Costs: ${results.shortagePercent.toFixed(1)}%
`; imcDownloadPdfButtonElem.style.display = 'inline-block'; } async function imcDownloadPDF() { const { jsPDF } = window.jspdf; if (typeof html2canvas === 'undefined' || typeof jsPDF === 'undefined') { alert('Error: PDF generation libraries not loaded.'); return; } const results = imcCalculateCosts(); const pdfContentWrapper = document.createElement('div'); pdfContentWrapper.className = 'imc-pdf-content-wrapper'; let inputsHTML = `

Inventory Cost Details for ${results.businessName} (${results.periodName})

`; inputsHTML += `
Holding Costs:
`; imcHoldingCostIds.forEach(id => { const label = document.querySelector(`label[for='${id}']`).childNodes[0].textContent.trim(); inputsHTML += `
${label} ${imcFormat(imcGetNum(id))}
`; }); inputsHTML += `
Total Holding Costs: ${imcFormat(results.totalHolding)}
`; inputsHTML += `
Ordering Costs:
`; imcOrderingCostIds.forEach(id => { const label = document.querySelector(`label[for='${id}']`).childNodes[0].textContent.trim(); inputsHTML += `
${label} ${imcFormat(imcGetNum(id))}
`; }); inputsHTML += `
Total Ordering Costs: ${imcFormat(results.totalOrdering)}
`; inputsHTML += `
Shortage Costs:
`; imcShortageCostIds.forEach(id => { const label = document.querySelector(`label[for='${id}']`).childNodes[0].textContent.trim(); inputsHTML += `
${label} ${imcFormat(imcGetNum(id))}
`; }); inputsHTML += `
Total Shortage Costs: ${imcFormat(results.totalShortage)}
`; inputsHTML += `
Grand Total & Percentages:
`; inputsHTML += `
Grand Total Inventory Costs: ${imcFormat(results.grandTotal)}
`; inputsHTML += `
Holding Cost %: ${results.holdingPercent.toFixed(1)}%
`; inputsHTML += `
Ordering Cost %: ${results.orderingPercent.toFixed(1)}%
`; inputsHTML += `
Shortage Cost %: ${results.shortagePercent.toFixed(1)}%
`; pdfContentWrapper.innerHTML = `

Inventory Management Cost Report

${inputsHTML}

Report generated on: ${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}

`; document.body.appendChild(pdfContentWrapper); try { const canvas = await html2canvas(pdfContentWrapper, { scale: 2, useCORS: true, backgroundColor: '#ffffff' }); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'p', unit: 'pt', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const imgProps = pdf.getImageProperties(imgData); const ratio = Math.min((pdfWidth - 40) / imgProps.width, (pdfHeight - 40) / imgProps.height); pdf.addImage(imgData, 'PNG', (pdfWidth - imgProps.width * ratio) / 2, 20, imgProps.width * ratio, imgProps.height * ratio); pdf.save('Inventory_Cost_Report.pdf'); } catch (error) { console.error("Error during PDF generation:", error); alert("An error occurred while generating the PDF."); } finally { document.body.removeChild(pdfContentWrapper); } }
Scroll to Top