Enterprise Invoice Generator

Create, calculate, and download professional PDF invoices instantly.

INVOICE

Invoice #
Date
Due Date

Billed To

Description
Qty
Price
Total

Notes / Terms

Subtotal $0.00
Tax (%)
Discount ($)
Total $0.00
+ subtotal.toFixed(2); document.getElementById('display-total').innerText = '
WhatsApp Free Consultation
+ Math.max(0, total).toFixed(2); } // Event listeners for total calculations document.getElementById('inv-tax-rate').addEventListener('input', calculateTotals); document.getElementById('inv-discount').addEventListener('input', calculateTotals); // API URL - Uses the backend we created const API_URL = '../api/invoice.php'; function showStatus(msg, isError = false) { const statusEl = document.getElementById('status-message'); statusEl.innerText = msg; statusEl.className = 'px-6 py-3 text-sm font-bold text-center block ' + (isError ? 'bg-red-100 text-red-700' : 'bg-emerald-100 text-emerald-800'); setTimeout(() => { statusEl.classList.add('hidden'); statusEl.classList.remove('block'); }, 4000); } document.getElementById('btn-save').addEventListener('click', async () => { document.getElementById('btn-save').innerHTML = 'Saving...'; const subtotal = items.reduce((sum, item) => sum + (item.qty * item.price), 0); const taxRate = parseFloat(document.getElementById('inv-tax-rate').value) || 0; const taxAmount = subtotal * (taxRate / 100); const discountAmount = parseFloat(document.getElementById('inv-discount').value) || 0; const totalAmount = subtotal + taxAmount - discountAmount; const payload = { invoice_number: document.getElementById('inv-number').value, client_name: document.getElementById('inv-client-name').value, client_email: document.getElementById('inv-client-email').value, client_address: document.getElementById('inv-client-address').value, date_issued: document.getElementById('inv-date').value, due_date: document.getElementById('inv-due').value, notes: document.getElementById('inv-notes').value, subtotal: subtotal, tax_amount: taxAmount, discount_amount: discountAmount, total_amount: Math.max(0, totalAmount), items: items.map(i => ({ description: i.desc, quantity: i.qty, unit_price: i.price, total: i.qty * i.price })) }; try { const res = await fetch(API_URL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); const data = await res.json(); if (data.status === 'success') { showStatus('✅ Invoice saved to database (ID: ' + data.invoice_id + ')'); } else { showStatus('❌ Error: ' + data.message, true); } } catch (err) { showStatus('❌ Connection error. Is the PHP server running?', true); } document.getElementById('btn-save').innerHTML = ' Save to Cloud'; }); document.getElementById('btn-download').addEventListener('click', () => { const element = document.getElementById('invoice-document'); // Hide no-print elements temporarily const noPrint = document.querySelectorAll('.no-print'); noPrint.forEach(el => el.style.display = 'none'); // Transform inputs to text for cleaner PDF const inputs = element.querySelectorAll('input, textarea'); const backups = []; inputs.forEach(input => { const span = document.createElement('span'); span.className = input.className + ' inline-block border-none bg-transparent'; span.innerText = input.value; if(input.tagName === 'TEXTAREA') { span.innerHTML = input.value.replace(/\n/g, '
'); } backups.push({ parent: input.parentNode, input: input, span: span }); input.style.display = 'none'; input.parentNode.insertBefore(span, input); }); const opt = { margin: [0, 0, 0, 0], filename: document.getElementById('inv-number').value + '.pdf', image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2, useCORS: true }, jsPDF: { unit: 'in', format: 'a4', orientation: 'portrait' } }; html2pdf().set(opt).from(element).save().then(() => { // Restore inputs backups.forEach(b => { b.parent.removeChild(b.span); b.input.style.display = ''; }); noPrint.forEach(el => el.style.display = ''); showStatus('✅ PDF Downloaded Successfully'); }); }); // Initialize renderItems();
WhatsApp Free Consultation