Invoice Financing Calculator
Enter Invoice and Financing Details:
$
%
% per
days
$
Financing Summary:
Advance Amount (Cash Upfront):
$0.00
Amount Held in Reserve:
$0.00
Total Discount Fee:
$0.00
Other Fees:
$0.00
Total Cost of Financing:
$0.00
Rebate (Amount received after customer payment, less fees from reserve):
$0.00
Total Net Cash Received by Business:
$0.00
Effective Annual Rate (APR):
0.00%
Error: Tool failed to load. Required elements missing.
"; } return; } function formatCurrency(amount) { return `$${Number(amount).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,')}`; } function formatPercentage(amount) { return `${Number(amount).toFixed(2)}%`; } function getNumericValue(element, defaultValue = 0) { if (!element) return defaultValue; const value = parseFloat(element.value); return isNaN(value) || value < 0 ? defaultValue : value; } function calculateAndDisplayIFC() { const invoiceAmount = getNumericValue(ifcInvoiceAmount, 0); const advanceRate = getNumericValue(ifcAdvanceRate, 0) / 100; // Convert percentage to decimal const discountRate = getNumericValue(ifcDiscountRate, 0) / 100; // Convert percentage to decimal const discountRatePeriod = getNumericValue(ifcDiscountRatePeriod, 30); // Default 30 days const paymentPeriod = getNumericValue(ifcPaymentPeriod, 1); // Default 1 day, must be >0 for APR const otherFees = getNumericValue(ifcOtherFees, 0); const advanceAmount = invoiceAmount * advanceRate; const reserveAmount = invoiceAmount - advanceAmount; let numberOfDiscountPeriods = 0; if (discountRatePeriod > 0 && paymentPeriod > 0) { numberOfDiscountPeriods = Math.ceil(paymentPeriod / discountRatePeriod); } const discountFee = invoiceAmount * discountRate * numberOfDiscountPeriods; const totalFinancingCost = discountFee + otherFees; // Rebate is the portion of the reserve returned after all fees are covered from the total invoice collection. // Or more simply: Invoice Amount - Advance Amount - Total Financing Cost const rebateAmount = invoiceAmount - advanceAmount - totalFinancingCost; const netCashReceived = invoiceAmount - totalFinancingCost; // This can also be seen as: advanceAmount + rebateAmount. // If rebateAmount is negative (fees > reserve), then netCashReceived = advanceAmount - abs(rebateAmount) let effectiveAPR = 0; if (advanceAmount > 0 && paymentPeriod > 0 && totalFinancingCost > 0) { effectiveAPR = (totalFinancingCost / advanceAmount) * (365 / paymentPeriod) * 100; } // Update display if(ifcAdvanceAmountValue) ifcAdvanceAmountValue.textContent = formatCurrency(advanceAmount); if(ifcReserveAmountValue) ifcReserveAmountValue.textContent = formatCurrency(reserveAmount); if(ifcDiscountFeeValue) ifcDiscountFeeValue.textContent = formatCurrency(discountFee); if(ifcOtherFeesValue) ifcOtherFeesValue.textContent = formatCurrency(otherFees); if(ifcTotalFinancingCost) ifcTotalFinancingCost.textContent = formatCurrency(totalFinancingCost); if(ifcRebateAmountValue) ifcRebateAmountValue.textContent = formatCurrency(rebateAmount); if(ifcNetCashReceived) ifcNetCashReceived.textContent = formatCurrency(netCashReceived); if(ifcEffectiveAPR) ifcEffectiveAPR.textContent = formatPercentage(effectiveAPR); } allInputs.forEach(input => { if (input) { input.addEventListener('input', calculateAndDisplayIFC); input.addEventListener('change', calculateAndDisplayIFC); // For number spinners } }); function generateIfcPdf() { const { jsPDF } = window.jspdf; if (!jsPDF || !jsPDF.API.autoTable) { alert("Error: PDF generation library (jsPDF with autoTable) not loaded."); return; } const doc = new jsPDF(); const invoiceAmount = getNumericValue(ifcInvoiceAmount); const advanceRatePercent = getNumericValue(ifcAdvanceRate); const discountRatePercent = getNumericValue(ifcDiscountRate); const discountRatePeriodDays = getNumericValue(ifcDiscountRatePeriod, 30); const paymentPeriodDays = getNumericValue(ifcPaymentPeriod, 1); const otherFeesInput = getNumericValue(ifcOtherFees); // Re-calculate for PDF to ensure fresh data const advanceAmount = invoiceAmount * (advanceRatePercent / 100); const reserveAmount = invoiceAmount - advanceAmount; const numberOfDiscountPeriods = (discountRatePeriodDays > 0 && paymentPeriodDays > 0) ? Math.ceil(paymentPeriodDays / discountRatePeriodDays) : 0; const discountFee = invoiceAmount * (discountRatePercent / 100) * numberOfDiscountPeriods; const totalFinancingCost = discountFee + otherFeesInput; const rebateAmount = invoiceAmount - advanceAmount - totalFinancingCost; const netCashReceived = invoiceAmount - totalFinancingCost; let effectiveAPR = 0; if (advanceAmount > 0 && paymentPeriodDays > 0 && totalFinancingCost > 0) { effectiveAPR = (totalFinancingCost / advanceAmount) * (365 / paymentPeriodDays) * 100; } let yPos = 20; const leftMargin = 15; doc.setFontSize(18); doc.text("Invoice Financing Calculation Report", doc.internal.pageSize.width / 2, yPos, { align: 'center' }); yPos += 10; doc.setFontSize(10); doc.text(`Report Generated: ${new Date().toLocaleDateString()}`, leftMargin, yPos); yPos += 10; doc.setFontSize(14); doc.text("Input Summary", leftMargin, yPos); yPos += 5; const inputData = [ ["Total Invoice Amount:", formatCurrency(invoiceAmount)], ["Advance Rate:", `${advanceRatePercent}%`], ["Discount Rate:", `${discountRatePercent}% per ${discountRatePeriodDays} days`], ["Expected Payment Period:", `${paymentPeriodDays} days`], ["Other Fees:", formatCurrency(otherFeesInput)] ]; doc.autoTable({ startY: yPos, head: [['Parameter', 'Value']], body: inputData, theme: 'striped', headStyles: { fillColor: [75, 75, 75] }, // Dark grey header margin: { left: leftMargin, right: 15 } }); yPos = doc.lastAutoTable.finalY + 10; doc.setFontSize(14); doc.text("Financing Results", leftMargin, yPos); yPos += 5; const outputData = [ ["Advance Amount (Cash Upfront):", formatCurrency(advanceAmount)], ["Amount Held in Reserve:", formatCurrency(reserveAmount)], ["Total Discount Fee:", formatCurrency(discountFee)], ["Other Fees:", formatCurrency(otherFeesInput)], ["Total Cost of Financing:", formatCurrency(totalFinancingCost)], ["Rebate (from reserve, after fees):", formatCurrency(rebateAmount)], ["Total Net Cash Received by Business:", formatCurrency(netCashReceived)], ["Effective Annual Rate (APR):", formatPercentage(effectiveAPR)] ]; doc.autoTable({ startY: yPos, head: [['Description', 'Amount / Rate']], body: outputData, theme: 'grid', headStyles: { fillColor: [52, 152, 219] }, // Blue header columnStyles: { 0: { cellWidth: 'auto'}, 1: { halign: 'right'} }, didParseCell: function (data) { const boldRows = [4, 6, 7]; // Total Cost, Net Cash, APR if (data.section === 'body' && boldRows.includes(data.row.index)) { data.cell.styles.fontStyle = 'bold'; } if (data.section === 'body' && data.row.index === 4) { // Total Cost data.cell.styles.textColor = [192, 57, 43]; // Reddish for cost } if (data.section === 'body' && data.row.index === 6) { // Net Cash data.cell.styles.textColor = [39, 174, 96]; // Green for net cash } if (data.section === 'body' && data.row.index === 7) { // APR data.cell.styles.textColor = [192, 57, 43]; // Reddish for APR } }, margin: { left: leftMargin, right: 15 } }); doc.save('Invoice_Financing_Calculation.pdf'); } if (ifcPdfDownloadButton) { ifcPdfDownloadButton.addEventListener('click', generateIfcPdf); } // Initial calculation on load calculateAndDisplayIFC(); });