${firm.firmName}
${firm.firmAddress.replace(/\n/g, '
')}
${firm.firmEmail}
${firm.firmPhone}
${firm.firmAddress.replace(/\n/g, '
')}
${firm.firmEmail}
${firm.firmPhone}
BILL TO:
${client.name}
${client.contact}
${client.email}
${client.name}
${client.contact}
${client.email}
Total Amount Due:
${formatCurrency(totalAmount)}
Professional Services
| Date | Description | Hours | Rate | Amount |
|---|---|---|---|---|
| ${e.date} | ${e.description} | ${e.hours.toFixed(2)} | ${formatCurrency(firm.defaultRate)} | ${formatCurrency(e.hours * firm.defaultRate)} |
| Subtotal | ${formatCurrency(timeSubtotal)} | |||
Expenses
| Date | Description | Amount | |
|---|---|---|---|
| ${e.date} | ${e.description} | ${formatCurrency(e.amount)} | |
| Subtotal | ${formatCurrency(expenseSubtotal)} | ||
| Services Total | ${formatCurrency(timeSubtotal)} |
|---|---|
| Expenses Total | ${formatCurrency(expenseSubtotal)} |
| TOTAL DUE | ${formatCurrency(totalAmount)} |
Notes: Please make payment within 30 days. Thank you for your business.
Invoice has been processed. Generate a new one.
`; document.getElementById('download-btn-container').style.display = 'none'; currentInvoiceData = null; } } // --- INITIALIZATION --- nextBtn.addEventListener('click', () => changeTab(currentTab + 1)); prevBtn.addEventListener('click', () => changeTab(currentTab - 1)); tabButtons.forEach(button => button.addEventListener('click', () => changeTab(parseInt(button.dataset.tab)))); renderAll(); renderConfigForm(); // Populate config form on load updateTabDisplay(); });