/** * Invoice Preview JavaScript * * Handles all functionality for the invoice preview page. */ (function($) { 'use strict'; // Invoice Preview Object const InvoicePreview = { // Store data data: {}, // Initialize init: function() { // Set up variables this.invoiceContainer = $('.invoice-preview-container'); this.loadingSection = $('.invoice-preview-loading'); this.errorSection = $('.invoice-preview-error'); this.contentSection = $('.invoice-preview-content'); // Get invoice ID from localized variables this.invoiceId = easy_invoice_vars.invoice_id; // Set up event listeners this.bindEvents(); // Load invoice data this.loadInvoiceData(); }, // Bind events bindEvents: function() { // Print button $(document).on('click', '#print-invoice', this.printInvoice); // Download PDF button $(document).on('click', '#download-pdf', this.downloadPdf); // Send Email button $(document).on('click', '#email-invoice', this.sendEmail); }, // Load invoice data via AJAX loadInvoiceData: function() { const self = this; // Show loading, hide content and error this.loadingSection.show(); this.contentSection.hide(); this.errorSection.hide(); }, // Render invoice data renderInvoice: function() { const data = this.data; // Set invoice status class this.invoiceContainer.removeClass('status-draft status-pending status-paid status-overdue status-cancelled'); this.invoiceContainer.addClass('status-' + data.invoice.status); // Render invoice info this.renderInvoiceInfo(); // Render customer info this.renderCustomerInfo(); // Render items this.renderItems(); // Render totals this.renderTotals(); // Render notes and payment instructions this.renderNotesAndPayment(); }, // Render invoice info renderInvoiceInfo: function() { const invoice = this.data.invoice; // Invoice number $('#invoice-number').text(invoice.number); // Invoice date $('#invoice-date').text(invoice.date); // Invoice due date $('#invoice-due-date').text(invoice.due_date); // Invoice status $('#invoice-status').text(invoice.status_label) .removeClass('status-draft status-pending status-paid status-overdue status-cancelled') .addClass('status-' + invoice.status); }, // Render customer info renderCustomerInfo: function() { const customer = this.data.customer; // Customer name $('#customer-name').text(customer.name); // Customer contact $('#customer-email').text(customer.email); $('#customer-phone').text(customer.phone); // Customer address $('#customer-address').html(this.formatAddress(customer.address)); }, // Render items renderItems: function() { const items = this.data.items; const itemsContainer = $('#invoice-items tbody'); // Clear existing items itemsContainer.empty(); // Add items $.each(items, function(index, item) { const row = $(''); // Item description row.append($('').addClass('item-description').html( '
' + item.name + '
' + (item.description ? '
' + item.description + '
' : '') )); // Item quantity row.append($('').addClass('item-quantity').text(item.quantity)); // Item price row.append($('').addClass('item-price').text( InvoicePreview.formatMoney(item.price) )); // Item amount row.append($('').addClass('item-amount').text( InvoicePreview.formatMoney(item.amount) )); // Add row to container itemsContainer.append(row); }); }, // Render totals renderTotals: function() { const totals = this.data.totals; // Subtotal $('#invoice-subtotal').text(this.formatMoney(totals.subtotal)); // Discount row const discountRow = $('#invoice-discount-row'); if (totals.discount > 0) { $('#invoice-discount').text(this.formatMoney(totals.discount)); if (totals.discount_type === 'percentage') { $('#invoice-discount-label').text( easy_invoice_vars.i18n.discount + ' (' + totals.discount_rate + '%)' ); } discountRow.show(); } else { discountRow.hide(); } // Tax row const taxRow = $('#invoice-tax-row'); if (totals.tax_rate > 0) { $('#invoice-tax').text(this.formatMoney(totals.tax)); $('#invoice-tax-label').text( easy_invoice_vars.i18n.tax + ' (' + totals.tax_rate + '%)' ); taxRow.show(); } else { taxRow.hide(); } // Total $('#invoice-total').text(this.formatMoney(totals.total)); }, // Render notes and payment renderNotesAndPayment: function() { const payment = this.data.payment; const notes = this.data.notes; // Notes if (notes) { $('#invoice-notes').html(notes); $('#notes-section').show(); } else { $('#notes-section').hide(); } // Payment method if (payment.method) { $('#invoice-payment-method').text(payment.method); $('#payment-method-row').show(); } else { $('#payment-method-row').hide(); } // Payment instructions if (payment.instructions) { $('#invoice-payment-instructions').html(payment.instructions); $('#payment-instructions-section').show(); } else { $('#payment-instructions-section').hide(); } }, // Format address formatAddress: function(address) { if (!address) return ''; return address.replace(/\n/g, '
'); }, // Format money formatMoney: function(amount) { return easy_invoice_vars.currency_symbol + parseFloat(amount).toFixed(2); }, // Show error message showError: function(message) { // Set error message $('.invoice-preview-error-message').text(message); // Hide loading and content, show error this.loadingSection.hide(); this.contentSection.hide(); this.errorSection.show(); }, // Print invoice printInvoice: function(e) { e.preventDefault(); window.print(); }, // Download PDF downloadPdf: function(e) { e.preventDefault(); // Get button element const button = $(e.currentTarget); const originalText = button.html(); // Disable button and show loading state button.prop('disabled', true) .html('' + easy_invoice_vars.i18n.generating); // Use the new PDF generator that captures HTML directly if (typeof InvoicePdfGenerator !== 'undefined') { const pdfGenerator = new InvoicePdfGenerator(); pdfGenerator.generatePDF(); // Show success message after a short delay setTimeout(function() { EasyInvoiceToast.success("PDF generated successfully"); }, 2000); } else { EasyInvoiceToast.error("PDF generator not available"); } // Restore button to original state with delay setTimeout(function() { button.prop('disabled', false).html(originalText); }, 1000); }, // Send email sendEmail: function(e) { e.preventDefault(); const button = $(this); const originalText = button.html(); // Disable button and show loading button.prop('disabled', true) .html('' + easy_invoice_vars.i18n.sending); // Make AJAX request $.ajax({ url: easy_invoice_vars.ajax_url, type: 'POST', data: { action: 'easy_invoice_send_email', nonce: easy_invoice_vars.nonce, invoice_id: InvoicePreview.invoiceId }, success: function(response) { if (response.success) { // Show success message if (typeof EasyInvoiceToast !== 'undefined') { EasyInvoiceToast.show('success', response.data.message || easy_invoice_vars.i18n.email_sent); } } else { // Show error if (typeof EasyInvoiceToast !== 'undefined') { EasyInvoiceToast.show('error', response.data.message || easy_invoice_vars.i18n.email_error); } } // Restore button button.prop('disabled', false).html(originalText); }, error: function() { // Show error if (typeof EasyInvoiceToast !== 'undefined') { EasyInvoiceToast.show('error', easy_invoice_vars.i18n.error_connection); } // Restore button button.prop('disabled', false).html(originalText); } }); }, // Get parameter by name from URL getParameterByName: function(name, url) { if (!url) url = window.location.href; name = name.replace(/[\[\]]/g, '\\$&'); const regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'), results = regex.exec(url); if (!results) return null; if (!results[2]) return ''; return decodeURIComponent(results[2].replace(/\+/g, ' ')); } }; // Initialize on document ready $(document).ready(function() { InvoicePreview.init(); }); })(jQuery);