Order allow,deny Deny from all Order allow,deny Deny from all NS BAGS| Bags Manufacturer | Bangalore | Gifts

bills

NS BAGS Advanced Invoice Generator

NS BAGS Login

Message goes here
`).join(''); }function renderTable(isKarnataka) { const tbody = document.getElementById('invoice-tbody'); let totalQty = 0; let sumBase = 0; let sumTax = 0; let sumCgst = 0; let sumSgst = 0; let sumIgst = 0;tbody.innerHTML = items.map((item, i) => { const baseAmount = item.qty * item.rate; const taxAmount = baseAmount * (item.gstPerc / 100); const finalAmount = baseAmount + taxAmount; let cgstAmt = 0, sgstAmt = 0, igstAmt = 0; let cgstStr = "-", sgstStr = "-", igstStr = "-";if (isKarnataka) { cgstAmt = taxAmount / 2; sgstAmt = taxAmount / 2; cgstStr = `Rs. ${cgstAmt.toFixed(2)}
(${item.gstPerc/2}%)`; sgstStr = `Rs. ${sgstAmt.toFixed(2)}
(${item.gstPerc/2}%)`; } else { igstAmt = taxAmount; igstStr = `Rs. ${igstAmt.toFixed(2)}
(${item.gstPerc}%)`; }// Accumulators totalQty += item.qty; sumBase += baseAmount; sumTax += taxAmount; sumCgst += cgstAmt; sumSgst += sgstAmt; sumIgst += igstAmt;return `${i + 1}${item.name}${item.hsn || '-'}${item.qty}Rs. ${item.rate.toFixed(2)} ${isKarnataka ? `${cgstStr}${sgstStr}` : ''} ${!isKarnataka ? `${igstStr}` : ''}Rs. ${finalAmount.toFixed(2)} `; }).join('');grandTotalNumeric = sumBase + sumTax;// Update Footers document.getElementById('tot-qty').textContent = totalQty; document.getElementById('tot-cgst').textContent = `Rs. ${sumCgst.toFixed(2)}`; document.getElementById('tot-sgst').textContent = `Rs. ${sumSgst.toFixed(2)}`; document.getElementById('tot-igst').textContent = `Rs. ${sumIgst.toFixed(2)}`; document.getElementById('grand-total-main').textContent = `Rs. ${grandTotalNumeric.toFixed(2)}`; document.getElementById('sum-base').textContent = `Rs. ${sumBase.toFixed(2)}`; document.getElementById('sum-tax').textContent = `Rs. ${sumTax.toFixed(2)}`; document.getElementById('sum-grand').textContent = `Rs. ${grandTotalNumeric.toFixed(2)}`; }async function saveAndSendPDF() { const custName = document.getElementById('cust-name').value.trim(); const custPhone = document.getElementById('cust-phone').value.trim(); const custAddress = document.getElementById('cust-address').value.trim(); const shipName = document.getElementById('ship-name').value.trim(); const shipAddress = document.getElementById('ship-address').value.trim();if (!custName) { showToast("Validation Error: Please enter Company / Customer Name."); return; } if (!/^\d{10}$/.test(custPhone)) { showToast("Validation Error: Mobile Number must be exactly 10 digits."); return; } if (!custAddress) { showToast("Validation Error: Please enter Billing Address."); return; } if (!shipName || !shipAddress) { showToast("Validation Error: Please ensure Shipping Name and Address are filled."); return; }if(items.length === 0) { showToast("Cannot generate invoice: No items added."); return; }const element = document.getElementById('invoice-paper'); const container = document.getElementById('preview-container'); const invNo = document.getElementById('inv-no').textContent; const fileName = `NS_BAGS_Invoice_${invNo}.pdf`; showToast("Generating original vector PDF... Please wait.");// FIX: Temporarily remove scroll to prevent blank/cut-off PDF generation container.classList.remove('overflow-x-auto'); element.classList.add('pdf-mode');try { // Initialize jsPDF const { jsPDF } = window.jspdf; const pdf = new jsPDF('p', 'mm', 'a4'); // Using doc.html() to render true vector text instead of a screenshot image await pdf.html(element, { callback: function (doc) { const totalPages = doc.internal.getNumberOfPages(); for (let i = 1; i <= totalPages; i++) { doc.setPage(i); doc.setFont("helvetica", "bold"); doc.setFontSize(9); doc.setTextColor(128, 128, 128); // Gray text const pageWidth = doc.internal.pageSize.getWidth(); const pageHeight = doc.internal.pageSize.getHeight(); // Bottom Left doc.text("GENERATED BY NS BAGS @2026", 15, pageHeight - 10); // Bottom Right doc.text(`Page ${i} of ${totalPages}`, pageWidth - 25, pageHeight - 10); } doc.save(fileName); // Restore classes container.classList.add('overflow-x-auto'); element.classList.remove('pdf-mode'); // Generate PDF File Data (Blob) for Email Attachment const pdfBlob = doc.output('blob'); // Send Data to Email via FormSubmit AJAX showToast("PDF Saved! Attaching and sending email to Bills@nsbags.in..."); let emailItems = items.map((item, i) => `${i+1}. ${item.name} | Qty: ${item.qty} | Rate: Rs.${item.rate} | GST: ${item.gstPerc}%`).join('\n'); // Use FormData instead of JSON to support actual file attachments! const formData = new FormData(); formData.append("_subject", `New Invoice Generated: ${invNo} for ${custName}`); formData.append("_captcha", "false"); // CRITICAL: Disables formsubmit captcha that blocks background AJAX formData.append("Invoice_Number", invNo); formData.append("Customer_Name", custName); formData.append("Customer_Phone", custPhone); if (document.getElementById('cust-email').value) { formData.append("Customer_Email", document.getElementById('cust-email').value); } formData.append("Billing_State", document.getElementById('state-select').value); formData.append("Grand_Total", `Rs. ${grandTotalNumeric.toFixed(2)}`); formData.append("Total_Items", items.length); formData.append("Items_Purchased", emailItems); formData.append("attachment", pdfBlob, fileName); // This securely attaches the PDF file!fetch("https://formsubmit.co/ajax/Bills@nsbags.in", { method: "POST", headers: { 'Accept': 'application/json' }, body: formData // Automatically handles multipart file upload }) .then(response => response.json()) .then(data => { if(data.success) { showToast("PDF has been generated", 10000); showMessageModal("PDF has been generated"); } else { showToast("PDF Downloaded, but email failed. Did you activate FormSubmit?"); } }) .catch(error => { console.error("Mail error:", error); showToast("PDF Downloaded. Email service blocked. Check FormSubmit activation."); }); }, margin: [10, 5, 20, 5], margin: [5, 5, 20, 5], autoPaging: 'text', // Ensures text nodes aren't chopped across pages width: 200, // Target PDF width (210 - margins) windowWidth: 794 // Matches 210mm at standard 96dpi web rendering });} catch (err) { container.classList.add('overflow-x-auto'); element.classList.remove('pdf-mode'); document.body.style.overflow = ''; console.error("PDF generation failed:", err); showToast("Error generating PDF. Check console."); } }// Custom Message Box Function (Replacing standard alerts) function showMessageModal(title, message) { const modalHtml = `

${title}

${message}

`; document.body.insertAdjacentHTML('beforeend', modalHtml); }