NS BAGS Advanced Invoice Generator NS BAGS Login
Access Denied: Invalid ID or Password.
NS BAGS
Address: Ground Floor No 02 Balepete SM Road,
Opp Baghsavar Masjid Balepete Bengaluru,
Bengaluru Urban, Karnataka 560053
State: Karnataka (State Code: 29)
Phone: 9986038850 | Email: Nishanbag.Trades@Gmail.Com
Website: WWW.NSBAGS.IN
GSTIN: 29AFAPA1092F1ZX
Tax Invoice
Invoice No: NSB-1001
Date:
BILLED TO:
State:
Phone:
Email:
GSTIN:
SHIPPED TO (Details):
State:
Phone:
| S.No | Name of Items | HSN Code | Qty | Base Rate | CGST | SGST | IGST | Total (Rs) |
|---|
| TOTAL | 0 | | Rs. 0.00 | Rs. 0.00 | Rs. 0.00 | Rs. 0.00 |
BANK DETAILS
| Account Name: | |
| A/c No: | |
| Bank Name: | |
| IFSC Code: | |
| Branch: | |
| Sub Total (Excl. GST): | Rs. 0.00 |
| Total GST Amount: | Rs. 0.00 |
| Grand Total: | Rs. 0.00 |
For NS BAGS
(Authorized Signatory)
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);
}