File manager - Edit - /home2/zetasolve/hello.shayantraders.com/scripts/invoices.js
Back
// Invoice Management let currentInvoice = null; document.addEventListener('DOMContentLoaded', async () => { // Check if there's a temporary transaction preview from billing const tempTransaction = sessionStorage.getItem('tempTransactionPreview'); if (tempTransaction) { const transaction = JSON.parse(tempTransaction); // Remove the temp data sessionStorage.removeItem('tempTransactionPreview'); // Display the temporary transaction as an invoice displayTempInvoice(transaction); } else { // Set current date document.getElementById('invoiceDate').textContent = app.formatDate(new Date().toISOString()); // Load recent invoices (from transactions) await loadRecentInvoices(); // Generate invoice number generateInvoiceNumber(); } }); function generateInvoiceNumber() { const date = new Date(); const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const random = Math.floor(Math.random() * 1000).toString().padStart(3, '0'); const invoiceNum = `INV-${year}${month}-${random}`; document.getElementById('invoiceNumber').textContent = invoiceNum; return invoiceNum; } async function loadRecentInvoices() { try { const transactions = await app.apiGet('/transactions'); const tbody = document.getElementById('invoiceListBody'); if (transactions.length === 0) { tbody.innerHTML = '<tr><td colspan="6" class="loading">No invoices found</td></tr>'; return; } tbody.innerHTML = transactions.slice(0, 20).map(transaction => ` <tr> <td><strong>INV-${transaction.id.toString().padStart(4, '0')}</strong></td> <td>${app.formatDate(transaction.transaction_date)}</td> <td>${transaction.customer_name}</td> <td><strong>${app.formatCurrency(transaction.total_amount)}</strong></td> <td><span class="badge badge-${transaction.payment_type.toLowerCase()}">${transaction.payment_type}</span></td> <td> <button class="btn btn-secondary" onclick="viewInvoice(${transaction.id})" style="padding: 0.5rem 1rem; font-size: 0.875rem; margin-right: 0.5rem;"> View </button> <button class="btn btn-danger" onclick="deleteInvoice(${transaction.id})" style="padding: 0.5rem 1rem; font-size: 0.875rem;"> Delete </button> </td> </tr> `).join(''); } catch (error) { console.error('Error loading invoices:', error); document.getElementById('invoiceListBody').innerHTML = '<tr><td colspan="6" class="loading">Failed to load invoices</td></tr>'; } } async function viewInvoice(transactionId) { try { const transaction = await app.apiGet(`/transactions/${transactionId}`); // Populate invoice document.getElementById('invoiceNumber').textContent = `INV-${transactionId.toString().padStart(4, '0')}`; document.getElementById('invoiceDate').textContent = app.formatDate(transaction.transaction_date); document.getElementById('customerName').textContent = transaction.customer_name; // Display payment type and amount information let paymentInfo = transaction.payment_type; if (transaction.amount_paid !== undefined && transaction.total_amount) { const totalAfterDiscount = transaction.total_amount - (transaction.discount_amount || 0); if (transaction.payment_type === 'Cash') { // For cash payments, show the amount paid if (transaction.amount_paid > totalAfterDiscount) { paymentInfo = `Cash<br><small>Total: ${app.formatCurrency(totalAfterDiscount)}, Paid: ${app.formatCurrency(transaction.amount_paid)}, Change: ${app.formatCurrency(transaction.amount_paid - totalAfterDiscount)}</small>`; } else if (transaction.amount_paid < totalAfterDiscount) { paymentInfo = `Cash<br><small>Total: ${app.formatCurrency(totalAfterDiscount)}, Paid: ${app.formatCurrency(transaction.amount_paid)}, Shortage: ${app.formatCurrency(totalAfterDiscount - transaction.amount_paid)}</small>`; } else { paymentInfo = `Cash<br><small>Total: ${app.formatCurrency(totalAfterDiscount)}, Paid: ${app.formatCurrency(transaction.amount_paid)}</small>`; } } else if (transaction.payment_type === 'Credit' && transaction.amount_paid < totalAfterDiscount) { paymentInfo = `Partial Credit<br><small>Total: ${app.formatCurrency(totalAfterDiscount)}, Paid: ${app.formatCurrency(transaction.amount_paid)}, Remaining: ${app.formatCurrency(totalAfterDiscount - transaction.amount_paid)}</small>`; } } document.getElementById('paymentType').innerHTML = paymentInfo; // Populate items const tbody = document.getElementById('invoiceItems'); tbody.innerHTML = transaction.items.map((item, index) => ` <tr> <td>${index + 1}</td> <td>${item.product_name} ${item.flavour} - ${item.weight}</td> <td style="text-align: center;">${item.quantity}</td> <td style="text-align: right;">${app.formatCurrency(item.unit_price)}</td> <td style="text-align: right;">${app.formatCurrency(item.subtotal)}</td> </tr> `).join(''); // Update totals with proper discount display document.getElementById('invoiceSubtotal').textContent = app.formatCurrency(transaction.total_amount); // Display discount information if applicable if (transaction.discount_amount > 0) { document.getElementById('invoiceDiscountRow').style.display = 'table-row'; document.getElementById('invoiceDiscountPercentage').textContent = transaction.discount_percentage; document.getElementById('invoiceDiscountAmount').textContent = `-${app.formatCurrency(transaction.discount_amount)}`; document.getElementById('invoiceTotal').textContent = app.formatCurrency(transaction.total_amount - transaction.discount_amount); } else { document.getElementById('invoiceDiscountRow').style.display = 'none'; document.getElementById('invoiceTotal').textContent = app.formatCurrency(transaction.total_amount); } document.getElementById('invoiceTax').textContent = 'PKR 0'; // Scroll to invoice document.getElementById('invoiceContent').scrollIntoView({ behavior: 'smooth' }); currentInvoice = transaction; } catch (error) { console.error('Error loading invoice:', error); app.showNotification('Failed to load invoice', 'error'); } } function generateInvoice() { // Reset invoice generateInvoiceNumber(); document.getElementById('invoiceDate').textContent = app.formatDate(new Date().toISOString()); document.getElementById('customerName').textContent = 'Customer Name'; document.getElementById('customerAddress').textContent = 'Address'; document.getElementById('customerPhone').textContent = 'Phone'; document.getElementById('paymentType').innerHTML = 'Cash<br><small>No amount specified</small>'; document.getElementById('dueDate').textContent = '-'; // Clear items document.getElementById('invoiceItems').innerHTML = ` <tr> <td colspan="5" class="text-center" style="padding: 2rem; color: var(--text-muted);"> No items added. Create a sale from the Billing page to generate an invoice. </td> </tr> `; document.getElementById('invoiceSubtotal').textContent = 'PKR 0'; document.getElementById('invoiceTax').textContent = 'PKR 0'; document.getElementById('invoiceTotal').textContent = 'PKR 0'; // Scroll to invoice document.getElementById('invoiceContent').scrollIntoView({ behavior: 'smooth' }); } // Function to display temporary invoice from billing cart function displayTempInvoice(transaction) { // Populate invoice document.getElementById('invoiceNumber').textContent = `PREVIEW-${Date.now()}`; document.getElementById('invoiceDate').textContent = app.formatDate(transaction.transaction_date); document.getElementById('customerName').textContent = transaction.customer_name; // Display payment type and amount information let paymentInfo = transaction.payment_type; if (transaction.amount_paid !== undefined && transaction.total_amount) { const totalAfterDiscount = transaction.total_amount - (transaction.discount_amount || 0); if (transaction.payment_type === 'Cash') { // For cash payments, show the amount paid if (transaction.amount_paid > totalAfterDiscount) { paymentInfo = `Cash<br><small>Total: ${app.formatCurrency(totalAfterDiscount)}, Paid: ${app.formatCurrency(transaction.amount_paid)}, Change: ${app.formatCurrency(transaction.amount_paid - totalAfterDiscount)}</small>`; } else if (transaction.amount_paid < totalAfterDiscount) { paymentInfo = `Cash<br><small>Total: ${app.formatCurrency(totalAfterDiscount)}, Paid: ${app.formatCurrency(transaction.amount_paid)}, Shortage: ${app.formatCurrency(totalAfterDiscount - transaction.amount_paid)}</small>`; } else { paymentInfo = `Cash<br><small>Total: ${app.formatCurrency(totalAfterDiscount)}, Paid: ${app.formatCurrency(transaction.amount_paid)}</small>`; } } else if (transaction.payment_type === 'Credit' && transaction.amount_paid < totalAfterDiscount) { paymentInfo = `Partial Credit<br><small>Total: ${app.formatCurrency(totalAfterDiscount)}, Paid: ${app.formatCurrency(transaction.amount_paid)}, Remaining: ${app.formatCurrency(totalAfterDiscount - transaction.amount_paid)}</small>`; } } document.getElementById('paymentType').innerHTML = paymentInfo; // Populate items const tbody = document.getElementById('invoiceItems'); tbody.innerHTML = transaction.items.map((item, index) => ` <tr> <td>${index + 1}</td> <td>${item.product_name} ${item.flavour} - ${item.weight}</td> <td style="text-align: center;">${item.quantity}</td> <td style="text-align: right;">${app.formatCurrency(item.unit_price)}</td> <td style="text-align: right;">${app.formatCurrency(item.subtotal || item.quantity * item.unit_price)}</td> </tr> `).join(''); // Update totals with proper discount display document.getElementById('invoiceSubtotal').textContent = app.formatCurrency(transaction.total_amount); // Display discount information if applicable if (transaction.discount_amount > 0) { document.getElementById('invoiceDiscountRow').style.display = 'table-row'; document.getElementById('invoiceDiscountPercentage').textContent = transaction.discount_percentage; document.getElementById('invoiceDiscountAmount').textContent = `-${app.formatCurrency(transaction.discount_amount)}`; document.getElementById('invoiceTotal').textContent = app.formatCurrency(transaction.total_amount - transaction.discount_amount); } else { document.getElementById('invoiceDiscountRow').style.display = 'none'; document.getElementById('invoiceTotal').textContent = app.formatCurrency(transaction.total_amount); } document.getElementById('invoiceTax').textContent = 'PKR 0'; // Scroll to invoice document.getElementById('invoiceContent').scrollIntoView({ behavior: 'smooth' }); currentInvoice = transaction; } // Function to go back to billing while preserving cart state function goToBilling() { // If there's a current cart state that needs to be restored in billing if (currentInvoice && currentInvoice.id !== 'preview') { // This is an existing transaction, not a preview, so we don't want to affect billing cart window.location.href = '../pages/billing.html'; } else { // This was a preview, so we should restore the original billing state // For now, just go back to billing window.location.href = '../pages/billing.html'; } } // Print invoice window.addEventListener('beforeprint', () => { document.title = `Invoice - ${document.getElementById('invoiceNumber').textContent}`; }); // Delete invoice function async function deleteInvoice(transactionId) { if (!confirm('Are you sure you want to delete this invoice? This will also reverse the stock changes and cannot be undone.')) { return; } try { // Call the backend API to delete the transaction await app.apiDelete(`/transactions/${transactionId}`); // Show success message app.showNotification('Invoice deleted successfully', 'success'); // Reload the invoice list await loadRecentInvoices(); // If we're viewing this invoice, clear the display const currentInvoiceNumber = document.getElementById('invoiceNumber').textContent; const deletingInvoiceNumber = `INV-${transactionId.toString().padStart(4, '0')}`; if (currentInvoiceNumber === deletingInvoiceNumber) { clearInvoiceDisplay(); } } catch (error) { console.error('Error deleting invoice:', error); app.showNotification('Failed to delete invoice: ' + (error.message || 'Unknown error'), 'error'); } } // Clear invoice display function clearInvoiceDisplay() { document.getElementById('invoiceNumber').textContent = ''; document.getElementById('invoiceDate').textContent = ''; document.getElementById('customerName').textContent = ''; document.getElementById('customerAddress').textContent = 'Address'; document.getElementById('customerPhone').textContent = 'Phone'; document.getElementById('paymentType').textContent = 'Cash'; document.getElementById('dueDate').textContent = '-'; // Clear items document.getElementById('invoiceItems').innerHTML = ` <tr> <td colspan="5" class="text-center" style="padding: 2rem; color: var(--text-muted);"> No items added. Create a sale from the Billing page to generate an invoice. </td> </tr> `; document.getElementById('invoiceSubtotal').textContent = 'PKR 0'; document.getElementById('invoiceTax').textContent = 'PKR 0'; document.getElementById('invoiceTotal').textContent = 'PKR 0'; } window.addEventListener('afterprint', () => { document.title = 'Invoices - Shayan Food'; });
| ver. 1.4 |
Github
|
.
| PHP 8.2.31 | Generation time: 0.27 |
proxy
|
phpinfo
|
Settings