working form16

function downloadForm16PDF(taxRegime = 'OLD') { // 1. Safety Checks - Ensure jsPDF library is loaded if (typeof window.jspdf === 'undefined') { alert("jsPDF library is missing. Please ensure it is loaded."); return; } const selectedRegime = (taxRegime || 'OLD').toUpperCase(); try { const { jsPDF } = window.jspdf; const doc = new jsPDF('p', 'pt', 'a4'); // --- CONFIG --- const PG_W = 595.28; const PG_H = 841.89; const LM = 25; // Left Margin const RM = 570; // Right Margin const CW = RM - LM; // Content Width let y = 30; // Vertical Cursor const ROW_H_M = 18; // Minimum Row Height const SECTION_SPACING = 6; // extra spacing between sections // --- HELPERS --- const font = (style, size) => { doc.setFont("helvetica", style); doc.setFontSize(size); }; const safeNum = v => { if (v === null || v === undefined || v === "") return 0; const n = Number(String(v).replace(/,/g, '')); return isNaN(n) ? 0 : Math.round(n); }; const fmt = (n) => { const v = safeNum(n); return v === 0 ? "0" : v.toLocaleString('en-IN'); }; const txt = (str, x, yy, options = {}) => { if (str === null || str === undefined) return; doc.text(String(str), x, yy, options); }; const right = (str, x, yy) => { if (str === null || str === undefined) return; doc.text(String(str), x, yy, { align: "right" }); }; const center = (str, yy) => { if (str === null || str === undefined) return; doc.text(String(str), PG_W / 2, yy, { align: "center" }); }; // --- LOAD APP DATA (window.latestStatement) --- const S = window.latestStatement || {}; const _meta = S.meta || {}; const _totals = S.totals || {}; const _inputs = S.inputs || {}; const _adv = Array.isArray(S.advTax) ? S.advTax.map(v => safeNum(v)) : null; // --- METADATA (fallbacks kept minimal) --- const METADATA = { nameEmp: _meta.employer || _meta.workplace || "" , nameDesig: _meta.employee || _meta.name || "", panDed: _meta.panDed || _meta.panDeductor || "PANNOTREQD", tanDed: _meta.tanNo || _meta.tan || _meta.tanDeductor || "", panEmp: _meta.panno || _meta.panEmp || _meta.pan || "", cit: _meta.cit || _meta.citTDS || "The Commissioner of Income Tax (TDS)\nRoom No. 411, Income Tax Towers, 10-2-3 A.C. Guard.", fy: _meta.fy || "2025-26", ay: _meta.ay || "2026-27", periodFrom: _meta.periodFrom || "01/04/2025", periodTo: _meta.periodTo || "31/03/2026", footer: _meta.footer || "Designed By: K.SANYASI NAIDU, SGT, VISAKHAPATNAM", date: _meta.date || _meta.generatedDate || "31/03/2026", city: _meta.city || "PADMANABHAM" }; // --- DATA MAPPING --- const mapped = { gross: safeNum(_totals.totalGross || _totals.gross || _totals.totalPay || _inputs.gross || 0), hraExemption: safeNum(_totals.hraExemption || _totals.hraEx || _inputs.hraExemption), pt: safeNum(_totals.totalPtax || _totals.pt || _inputs.pt), stdDed: safeNum(_totals.stdDeduction || _inputs.stdDeduction || _totals.stdDed || 50000), s80c_gross: safeNum(_totals.sec80C_Allowed || _totals.S80C_TotalGross || _inputs.S80C_TotalGross || _totals.s80c), s80c_ded: safeNum(_totals.sec80C_Allowed || _totals.S80C_Deductible || _inputs.S80C_Deductible || _totals.s80c), s13_ewf_gross: safeNum(_totals.S13_EWF_Gross || _inputs.S13_EWF_Gross || _totals.EWF), s13_80d_gross: safeNum(_totals.S13_80D_Gross || _inputs.S13_80D_Gross || _totals.S13_80D), s13_ewf_ded: safeNum(_totals.S13_EWF_Deductible || _inputs.S13_EWF_Deductible || _totals.EWF_Ded), s13_80d_ded: safeNum(_totals.S13_80D_Deductible || _inputs.S13_80D_Deductible || _totals.S13_80D_Ded), oldTaxOnIncome: safeNum(_totals.oldTax || _totals.taxOnIncomeOld || _totals.taxOnIncome || 0), newTaxOnIncome: safeNum(_totals.newTax || _totals.taxOnIncomeNew || _totals.taxOnIncome || 0), totalTDS: safeNum(_totals.totalTDS || _totals.totalAdvTax || _totals.totalTaxDeducted || 0), totalPaid: safeNum(_totals.totalPay || _totals.gross || _inputs.gross || 0), rebate: safeNum(_totals.rebate || 0) }; // --- Regime-specific zeroing --- let DATA = null; if (selectedRegime === 'NEW') { DATA = { slabLabel: "NEW IT SLAB", gross: mapped.gross, hraExemption: 0, pt: 0, standardDeduction: mapped.stdDed || 75000, S80C_TotalGross: 0, S80C_Deductible: 0, S13_EWF_Gross: 0, S13_80D_Gross: 0, S13_EWF_Deductible: 0, S13_80D_Deductible: 0, taxOnIncome: mapped.newTaxOnIncome, rebate: mapped.rebate, taxPayableFinal: safeNum(_totals.totalTaxNew || _totals.totalTax || 0), qtrData: [], totalTDS: mapped.totalTDS, totalPaid: mapped.totalPaid }; } else { DATA = { slabLabel: "OLD IT SLAB", gross: mapped.gross, hraExemption: mapped.hraExemption, pt: mapped.pt, standardDeduction: mapped.stdDed || 50000, S80C_TotalGross: mapped.s80c_gross, S80C_Deductible: mapped.s80c_ded, S13_EWF_Gross: mapped.s13_ewf_gross, S13_80D_Gross: mapped.s13_80d_gross, S13_EWF_Deductible: mapped.s13_ewf_ded, S13_80D_Deductible: mapped.s13_80d_ded, taxOnIncome: mapped.oldTaxOnIncome, rebate: mapped.rebate, taxPayableFinal: safeNum(_totals.totalTax || _totals.oldTotalTax || 0), qtrData: [], totalTDS: mapped.totalTDS, totalPaid: mapped.totalPaid }; } // --- Build quarter advance tax data --- if (_adv && _adv.length >= 12) { const q0 = _adv.slice(0, 3).reduce((a, b) => a + b, 0); const q1 = _adv.slice(3, 6).reduce((a, b) => a + b, 0); const q2 = _adv.slice(6, 9).reduce((a, b) => a + b, 0); const q3 = _adv.slice(9, 12).reduce((a, b) => a + b, 0); const paidEach = Math.round(DATA.totalPaid / 4) || 0; DATA.qtrData = [ { paid: paidEach, deducted: q0, deposited: q0 }, { paid: paidEach, deducted: q1, deposited: q1 }, { paid: paidEach, deducted: q2, deposited: q2 }, { paid: paidEach, deducted: q3, deposited: q3 } ]; } else { const paidEach = Math.round(DATA.totalPaid / 4) || 0; const tds = DATA.totalTDS || 0; const per = Math.floor(tds / 4); DATA.qtrData = [ { paid: paidEach, deducted: per, deposited: per }, { paid: paidEach, deducted: per, deposited: per }, { paid: paidEach, deducted: per, deposited: per }, { paid: paidEach, deducted: tds - per * 3, deposited: tds - per * 3 } ]; } // --- DERIVED CALCULATIONS --- const grossTotal = DATA.gross || 0; const balance = grossTotal - (DATA.hraExemption || 0); const totalDeductionsU16 = (DATA.standardDeduction || 0) + (DATA.pt || 0); const incSal = balance - totalDeductionsU16; const gti = incSal; const S11_TotalSavings = DATA.S80C_Deductible || 0; const taxableIncome_S12 = gti - S11_TotalSavings; const S13_OtherTotalGross = (DATA.S13_EWF_Gross || 0) + (DATA.S13_80D_Gross || 0); const aggregateDeductibleS13 = (DATA.S13_EWF_Deductible || 0) + (DATA.S13_80D_Deductible || 0); const S14_TotalDeductions = S11_TotalSavings + aggregateDeductibleS13; const totalIncome = gti - S14_TotalDeductions; const taxOnIncome = DATA.taxOnIncome || 0; const rebate = DATA.rebate || 0; const taxAfterRebate = Math.max(0, taxOnIncome - rebate); const cess = Math.round(taxAfterRebate * 0.04); const taxPayableRounded = Math.round(taxAfterRebate + cess); const taxPayableFinal = DATA.taxPayableFinal || taxPayableRounded; const taxPayableResult = taxPayableFinal - (DATA.totalTDS || 0); const verifiedAmount = taxPayableFinal; const annexureA_Total = taxPayableFinal; // --- DRAWING HELPERS --- const cx1 = RM - 180; const cx2 = RM - 95; const bRow = (sl, desc, v1, v2, v3, h = ROW_H_M, boldRow = false) => { const wrapped = doc.splitTextToSize(String(desc || ""), cx1 - LM - 35); const lines = Math.max(1, wrapped.length); const height = Math.max(h, lines * 12 + 6); doc.rect(LM, y, CW, height); font(boldRow ? "bold" : "normal", 8); const textY = y + (height / 2) + 3; if (sl) txt(sl, LM + 6, textY, { baseline: 'middle' }); doc.text(wrapped, LM + 30, textY, { baseline: 'middle' }); if (v1 !== null && v1 !== undefined) { txt("Rs:", cx1 - 18, textY, { baseline: 'middle' }); right(fmt(v1), cx1 - 6, textY, { baseline: 'middle' }); } if (v2 !== null && v2 !== undefined) { txt("Rs:", cx2 - 18, textY, { baseline: 'middle' }); right(fmt(v2), cx2 - 6, textY, { baseline: 'middle' }); } if (v3 !== null && v3 !== undefined) { txt("Rs:", RM - 18, textY, { baseline: 'middle' }); right(fmt(v3), RM - 6, textY, { baseline: 'middle' }); } y += height; return height; }; const xGross = LM + 330; const xQual = LM + 425; const xDed = RM - 90; const viaRow = (sl, l, vG, vQ, vD, h = 15, boldRow = false, rs = false) => { const wrapped = doc.splitTextToSize(String(l || ""), xGross - LM - 35); const lines = Math.max(1, wrapped.length); const height = Math.max(h, lines * 12 + 6); doc.rect(LM, y, CW, height); font(boldRow ? "bold" : "normal", 8); const textY = y + (height / 2) + 3; if (sl) txt(sl, LM + 6, textY, { baseline: 'middle' }); doc.text(wrapped, LM + 30, textY, { baseline: 'middle' }); if (rs && vG !== null && vG !== undefined) { txt("Rs:", xGross - 18, textY, { baseline: 'middle' }); right(fmt(vG), xGross - 6, textY, { baseline: 'middle' }); } if (vQ !== null && vQ !== undefined) { txt("Rs:", xQual - 18, textY, { baseline: 'middle' }); right(fmt(vQ), xQual - 6, textY, { baseline: 'middle' }); } if (vD !== null && vD !== undefined) { txt("Rs:", RM - 18, textY, { baseline: 'middle' }); right(fmt(vD), RM - 6, textY, { baseline: 'middle' }); } y += height; return height; }; // --- PAGE 1 DRAWING START --- // PART A Headers & Grids doc.setLineWidth(0.6); doc.rect(LM - 5, 20, CW + 10, 30); font("bold", 12); center("FORM NO.16", y + 12); y += 20; doc.rect(LM - 5, y, CW + 10, 16); font("normal", 10); center(`(${DATA.slabLabel}) [See rule 31(1)(a)]`, y + 10); y += 16; doc.rect(LM - 5, y, CW + 10, 16); font("bold", 12); center("PART-A", y + 10); y += 16; doc.rect(LM - 5, y, CW + 10, 16); font("normal", 10); center("Certificate under section 203 of the Income-tax Act, 1961 for Tax deducted at source on Salary", y + 12); y += 20; const nameGridH = 50; const nameGridMidX = LM + (CW / 2); doc.setLineWidth(0.5); doc.rect(LM - 5, y, CW + 10, nameGridH); doc.line(nameGridMidX, y, nameGridMidX, y + nameGridH); font("normal", 8); txt("Name and address of the Employer", LM + 6, y + 14); txt("Name and designation of the employee", nameGridMidX + 6, y + 14); font("bold", 9); doc.text(doc.splitTextToSize(METADATA.nameEmp, (CW / 2) - 12), LM + 6, y + 30); doc.text(doc.splitTextToSize(METADATA.nameDesig, (CW / 2) - 12), nameGridMidX + 6, y + 30); y += nameGridH + 4; const panGridH = 40; const panGridCol1 = LM + 105; const panGridCol3 = LM + 400; doc.rect(LM - 5, y, CW + 10, panGridH); doc.line(panGridCol1, y, panGridCol1, y + panGridH); doc.line(panGridCol3, y, panGridCol3, y + panGridH); doc.line(LM - 5, y + 24, RM + 5, y + 24); font("normal", 8); txt("PAN no. of the Deductor", LM + 6, y + 12); txt("TAN No. of the Deductor", panGridCol1 + 6, y + 12); txt("PAN NO. of the Employee", panGridCol3 + 6, y + 12); font("bold", 9); txt(METADATA.panDed || _meta.panDed || "PANNOTREQD", LM + 6, y + 36); txt(METADATA.tanDed, panGridCol1 + 6, y + 36); txt(METADATA.panEmp, panGridCol3 + 6, y + 36); y += panGridH + 4; const citGridH = 50; doc.rect(LM - 5, y, CW + 10, citGridH); doc.line(nameGridMidX, y, nameGridMidX, y + citGridH); doc.line(nameGridMidX, y + 30, RM + 5, y + 30); font("normal", 8); txt("CIT (TDS)", LM + 6, y + 12); doc.text(doc.splitTextToSize(METADATA.cit, (CW / 2) - 12), LM + 6, y + 26); txt("FINANCE YEAR", nameGridMidX + 6, y + 12); txt("Period", nameGridMidX + 110, y + 12); font("bold", 9); txt(METADATA.fy, nameGridMidX + 6, y + 26); font("normal", 8); txt("Assessment Year", nameGridMidX + 6, y + 38); font("bold", 9); txt(METADATA.ay, nameGridMidX + 6, y + 50); txt(METADATA.periodFrom, nameGridMidX + 110, y + 50); txt(METADATA.periodTo, nameGridMidX + 190, y + 50); y += citGridH + 6; font("normal", 8); txt("Summary of tax deducted at source", LM + 6, y + 12); y += 14; const qtrTblCols = [LM, LM + 50, LM + 180, LM + 320, LM + 450, RM]; const qtrRowH = 18; doc.rect(LM, y, CW, qtrRowH); qtrTblCols.forEach((x, i) => { if (i > 0) doc.line(x, y, x, y + qtrRowH + (4 * qtrRowH)); }); font("bold", 7); txt("Quarter", qtrTblCols[0] + 4, y + 12); txt("Receipt Numbers of", qtrTblCols[1] + 4, y + 12); txt("Amount paid / Credited", qtrTblCols[2] + 4, y + 12); txt("Amount of tax deducted", qtrTblCols[3] + 4, y + 12); txt("Amount of tax deposited /", qtrTblCols[4] + 4, y + 12); y += qtrRowH; font("normal", 8); txt("remitted in Central Govt.", qtrTblCols[4] + 4, y + 2); y += 6; DATA.qtrData.forEach((qtr, i) => { doc.rect(LM, y, CW, qtrRowH); font("normal", 8); txt(`Q${i + 1}`, qtrTblCols[0] + 6, y + 12); txt("-", qtrTblCols[1] + 6, y + 12); right(fmt(qtr.paid), qtrTblCols[3] - 6, y + 12); right(fmt(qtr.deducted), qtrTblCols[4] - 6, y + 12); right(fmt(qtr.deposited), RM - 6, y + 12); y += qtrRowH; }); doc.rect(LM, y, CW, qtrRowH); font("bold", 8); txt("Total", qtrTblCols[0] + 6, y + 12); right(fmt(DATA.totalPaid), qtrTblCols[3] - 6, y + 12); right(fmt(DATA.totalTDS), qtrTblCols[4] - 6, y + 12); right(fmt(DATA.totalTDS), RM - 6, y + 12); y += qtrRowH + SECTION_SPACING; // --- PART B: SALARY DETAILS (S.No 1 to 8) --- font("bold", 11); txt("PART-B (Refer Note 1)", LM + 6, y + 10); y += 12; font("normal", 8); txt("Details of Salary paid and any other income and tax deducted", LM + 6, y + 8); y += 14; const salaryBlockY = y; // S.No 1 (Gross Salary) doc.rect(LM, y, CW, ROW_H_M); font("bold", 8); txt("1", LM + 6, y + 10); txt("Gross Salary", LM + 30, y + 10); y += ROW_H_M; // Rows 1(a), (b), (c), TOTAL (using bRow helper defined inline) bRow(null, "(a) Salary as per provisions contained in section 17(1)", grossTotal, null, null, ROW_H_M, false); bRow(null, "(b) Value of perquisites under section 17(2)", 0, null, null, ROW_H_M, false); bRow(null, "(c) Profits in lieu of salary under section 17(3)", 0, null, null, ROW_H_M, false); bRow(null, "TOTAL (a+b+c)", null, grossTotal, grossTotal, ROW_H_M, true); // S.No 2: Exemptions u/s 10 doc.rect(LM, y, CW, ROW_H_M); font("bold", 8); txt("2", LM + 6, y + 10); txt("Less: Exempted Allowance u/s 10:", LM + 30, y + 10); y += ROW_H_M; bRow("A)", "House Rent Allowance vis 10 (2A)13(A) (Exempted only in Old Tax)", DATA.hraExemption || 0, DATA.hraExemption || 0, null, ROW_H_M, false); bRow("B)", "Intrest On Housing Loan ADVANCE U/S 24 (B)", 0, 0, null, ROW_H_M, false); // S.No 3: Balance (1-2) bRow("3", "Balance (1-2)", null, null, balance, ROW_H_M, true); // S.No 4: Deductions U/s 16 doc.rect(LM, y, CW, ROW_H_M); font("bold", 8); txt("4", LM + 6, y + 10); txt("Deductions U/s 16:", LM + 30, y + 10); y += ROW_H_M; bRow(null, "(a) Standard Deduction U/s 16(ia) (Common in New/Old Tax)", DATA.standardDeduction || 0, null, null, ROW_H_M, false); bRow(null, "(b) Professional Tax U/s 16(iii) (Only in Old Tax)", DATA.pt || 0, null, null, ROW_H_M, false); bRow(null, "(c) Entertainment Allowance U/s 16(ii)", 0, null, null, ROW_H_M, false); bRow("5", "Aggregate of 4(a) to (c)", null, totalDeductionsU16, null, ROW_H_M, true); bRow("6", "Income chargeable under the head 'salaries' (3-5)", null, null, incSal, ROW_H_M, true); bRow("7", "Add: Any other income reported by the employee", 0, null, null, ROW_H_M, false); bRow("8", "Gross total income (6+7)", null, null, gti, ROW_H_M, true); doc.line(LM + 25, salaryBlockY, LM + 25, y); doc.line(cx1, salaryBlockY, cx1, y); doc.line(cx2, salaryBlockY, cx2, y); y += SECTION_SPACING; // --- CHAPTER VI-A (9..12) --- font("bold", 10); txt("9", LM + 6, y + 12); txt("Deductions under Chapter VIA", LM + 32, y + 12); y += 16; const chapterVIA_Y = y; doc.rect(LM, y, CW, 16); doc.line(xGross, y, xGross, y + 16); doc.line(xQual, y, xQual, y + 16); doc.line(xDed, y, xDed, y + 16); font("bold", 8); txt("10", LM + 6, y + 12); txt("Savings U/s 80CCE (80C, 80CCC and 80CCD (i))", LM + 32, y + 12); txt("Gross Amount", xGross + 4, y + 12); txt("Qualifying amount", xQual + 4, y + 12); txt("Deductible Amount Rs.", xDed + 4, y + 12); y += 16; viaRow("A)", "Section 80 C (Only in Old Tax)", null, null, null, 15, true); viaRow("a)", "PPF/LIC/Tuition Fee/Home Loan Principle", DATA.S80C_TotalGross || 0, S11_TotalSavings, S11_TotalSavings, 15, false, true); doc.rect(LM, y, CW, ROW_H_M); doc.line(xGross, y, xGross, y + ROW_H_M); doc.line(xQual, y, xQual, y + ROW_H_M); doc.line(xDed, y, xDed, y + ROW_H_M); font("bold", 9); txt("11", LM + 6, y + 12); txt("Total Deductible Savings (A+B+C+D)", LM + 32, y + 12); txt("Rs:", xGross - 18, y + 12); right(fmt(S11_TotalSavings), xGross - 6, y + 12); txt("Rs:", xQual - 18, y + 12); right(fmt(S11_TotalSavings), xQual - 6, y + 12); txt("Rs:", RM - 18, y + 12); right(fmt(S11_TotalSavings), RM - 6, y + 12); y += ROW_H_M + 4; doc.rect(LM, y, CW, ROW_H_M); doc.line(xDed, y, xDed, y + ROW_H_M); font("bold", 9); txt("12", LM + 6, y + 12); txt("Taxable income (8 - 11)", LM + 32, y + 12); txt("Rs:", RM - 18, y + 12); right(fmt(taxableIncome_S12), RM - 6, y + 12); y += ROW_H_M + 8; doc.line(LM + 25, chapterVIA_Y, LM + 25, y - (ROW_H_M + 8) + (ROW_H_M + 4)); // -------------------- PAGE 2 -------------------- doc.addPage(); y = 30; font("bold", 9); txt("13", LM + 6, y + 12); txt("Other Sections (80CCG, 80D, 80DDB, 80E, 80G etc) under Chapter VI-A (Only in Old Tax)", LM + 32, y + 12); y += 16; const otherSection_Y = y; const xG_O = LM + 330; const xQ_O = LM + 425; const xD_O = RM - 90; doc.rect(LM, y, CW, 16); doc.line(xG_O, y, xG_O, y + 16); doc.line(xQ_O, y, xQ_O, y + 16); doc.line(xD_O, y, xD_O, y + 16); font("bold", 8); txt("Gross Amount", xG_O + 6, y + 12); txt("Qualify amount", xQ_O + 6, y + 12); txt("Deductible Amount Rs.", xD_O + 6, y + 12); y += 16; const oRow = (sl, l, vG, vQ, h = 15) => { const wrapped = doc.splitTextToSize(String(l || ""), xG_O - LM - 35); const lines = Math.max(1, wrapped.length); const height = Math.max(h, lines * 12 + 6); doc.rect(LM, y, CW, height); font("normal", 8); const textY = y + (height / 2) + 3; if (sl) txt(sl, LM + 6, textY, { baseline: 'middle' }); doc.text(wrapped, LM + 30, textY, { baseline: 'middle' }); if (vG !== null && vG !== undefined) { txt("Rs:", xG_O - 18, textY, { baseline: 'middle' }); right(fmt(vG), xG_O - 6, textY, { baseline: 'middle' }); } if (vQ !== null && vQ !== undefined) { txt("Rs:", xQ_O - 18, textY, { baseline: 'middle' }); right(fmt(vQ), xQ_O - 6, textY, { baseline: 'middle' }); } y += height; return height; }; oRow("a)", "E.W.F, & S.W.F, Kerala flood, Titli relief fund", DATA.S13_EWF_Gross || 0, DATA.S13_EWF_Deductible || 0); oRow("b)", "80D-Medical Insurance Premium-Self, Spouse & Children", DATA.S13_80D_Gross || 0, DATA.S13_80D_Deductible || 0); oRow("c)", "80E-Interest on Educational Loan", 0, 0); oRow("d)", "80G-Donation to certain funds", 0, 0); oRow("e)", "Others", 0, 0); doc.rect(LM, y, CW, ROW_H_M); doc.line(xG_O, y, xG_O, y + ROW_H_M); doc.line(xQ_O, y, xQ_O, y + ROW_H_M); doc.line(xD_O, y, xD_O, y + ROW_H_M); font("bold", 8); txt("TOTAL (a+b+c+d+e)", LM + 32, y + 12); txt("Rs:", xG_O - 18, y + 12); right(fmt(S13_OtherTotalGross), xG_O - 6, y + 12); txt("Rs:", xQ_O - 18, y + 12); right(fmt(aggregateDeductibleS13), xQ_O - 6, y + 12); y += ROW_H_M + 6; doc.line(LM + 25, otherSection_Y, LM + 25, y - 6); doc.line(xG_O, otherSection_Y + 16, xG_O, y - 6); doc.line(xQ_O, otherSection_Y + 16, xQ_O, y - 6); doc.line(xD_O, otherSection_Y + 16, xD_O, y - 6); doc.rect(LM, y, CW, ROW_H_M); doc.line(xD_O, y, xD_O, y + ROW_H_M); font("bold", 9); txt("14", LM + 6, y + 12); txt("Aggregate of deductible amount under Chap. VIA (11+13)", LM + 32, y + 12); txt("Rs:", RM - 18, y + 12); right(fmt(S14_TotalDeductions), RM - 6, y + 12); y += ROW_H_M + 8; const taxBlock_Y = y; const taxRow = (sl, d, v, boldRow = false) => { const height = ROW_H_M; doc.rect(LM, y, CW, height); font(boldRow ? "bold" : "normal", 8); const textY = y + 12; if (sl) txt(sl, LM + 6, textY); doc.text(doc.splitTextToSize(d, RM - 120 - LM), LM + 28, textY); if (v !== null && v !== undefined) { txt("Rs:", RM - 30, textY); right(fmt(v), RM - 6, textY); } y += height; return height; }; taxRow("15", "Total Income (8 - 14)", totalIncome, true); taxRow("16", "Tax on total income", taxOnIncome, false); taxRow("17", "Rebate U/S 87A (Old Tax: <=5Lakh, New Tax: <=7Lakh)", DATA.rebate || 0, false); taxRow("18", "Surcharge", 0, false); taxRow("19", `Education & health cess @4% on (Tax after Rebate x 4%)`, cess, false); taxRow("20", "Tax payable (After Rebate & Cess, Rounded off)", taxPayableRounded, true); taxRow("21", "Less Relief U/s 89(1) (attach details)", 0, false); taxRow("22", `${DATA.slabLabel} Total Tax Payable (Rounded off)`, taxPayableFinal, true); doc.line(RM - 110, taxBlock_Y, RM - 110, y); y += 6; const xTDS = RM - 110; const xTDS_Rs = RM - 6; doc.rect(LM, y, CW, ROW_H_M); font("normal", 8); txt("23", LM + 6, y + 12); txt("Less:(a) Tax deducted at source U/s 192(1)", LM + 28, y + 12); doc.line(xTDS, y, xTDS, y + ROW_H_M); txt("Rs:", xTDS - 18, y + 12); right(fmt(DATA.totalTDS || 0), xTDS - 6, y + 12); txt("Rs:", xTDS_Rs - 18, y + 12); right(fmt(DATA.totalTDS || 0), xTDS_Rs, y + 12); y += ROW_H_M + 6; doc.rect(LM, y, CW, ROW_H_M); doc.line(xTDS, y, xTDS, y + ROW_H_M); font("normal", 8); txt("  (b)", LM + 28, y + 12); doc.text("Tax paid by the employer on behalf of the employee U/s 192 (1A) on perquisited U/s 17 (2)", LM + 48, y + 12); y += ROW_H_M + 6; doc.rect(LM, y, CW, ROW_H_M); doc.line(xTDS, y, xTDS, y + ROW_H_M); font("bold", 9); txt("24", LM + 6, y + 12); txt("TAX PAYABLE / REFUNDABLE (22-23)", LM + 28, y + 12); txt("Rs:", xTDS_Rs - 18, y + 12); right(fmt(taxPayableResult), xTDS_Rs, y + 12); y += ROW_H_M + 8; font("bold", 11); txt("Verification", LM + 6, y + 12); y += 16; font("normal", 9); const empShort = (METADATA.nameDesig || "").split('\n')[0] || METADATA.nameDesig; const empCapacity = (METADATA.nameDesig || "").split('\n')[1] || ""; const verifText = `I Sri/Smt.: ${empShort.replace(/^Sri\.\s*/i, '')}, Son/Daughter of Sri/smt. working in the capacity of ${empCapacity.trim() || ''}, do hereby certify that the sum of Rs: ${fmt(verifiedAmount)} /- has been deducted and deposited to the credit of the Central Government as per ${DATA.slabLabel}.`; doc.text(doc.splitTextToSize(verifText, CW), LM + 6, y); y += 30; doc.rect(LM, y, CW / 2 - 6, 50); doc.rect(LM + CW / 2 + 6, y, CW / 2 - 6, 50); font("normal", 9); txt("Place:-", LM + 10, y + 14); txt(METADATA.city, LM + 80, y + 14); txt("Date:-", LM + 10, y + 30); txt(METADATA.date || METADATA.periodTo || "31/03/2026", LM + 80, y + 30); txt("Designation:", LM + 10, y + 46); doc.text(doc.splitTextToSize(METADATA.nameEmp.split('\n')[1] || METADATA.nameDesig, 180), LM + 90, y + 46); right("Signature of person responsible for deduction of tax", RM - 6, y + 26); right(`Full Name: ${METADATA.nameEmp.split('\n')[0] || METADATA.nameEmp}`, RM - 6, y + 46); y += 64; // --- ANNEXURE A (Book Entry) --- font("bold", 10); center("ANNEXURE A (Book Entry)", y); y += 14; const ac = [LM, LM + 40, LM + 170, LM + 270, LM + 400, RM]; const aRowH = 14; doc.rect(LM, y, CW, aRowH); ac.forEach((x, i) => { if (i > 0) doc.line(x, y, x, y + aRowH + (10 * aRowH)); }); font("bold", 7); txt("Sl.No", ac[0] + 6, y + 10); doc.text("Tax Deposited in respect\non of the employee (Rs.)", ac[1] + 6, y + 6); doc.text("Receipt Numbers of Form No 24G", ac[2] + 6, y + 10); doc.text("DDO Sequence Number in the\nBook Adjustment Mini Statement", ac[3] + 6, y + 6); doc.text("Date on which tax deposited\n(dd/mm/yy)", ac[4] + 6, y + 6); y += aRowH; for (let i = 1; i <= 12; i++) { doc.rect(LM, y, CW, aRowH); font("normal", 8); txt(`${i}.`, ac[0] + 6, y + 10); if (i === 12) { right(fmt(DATA.taxPayableFinal || 0), ac[2] - 6, y + 10); txt("0", ac[3] + 6, y + 10); txt("0", ac[4] + 6, y + 10); txt(METADATA.periodTo || "31/03/2026", ac[4] + 60, y + 10); } else { right("0", ac[2] - 6, y + 10); txt("-", ac[3] + 6, y + 10); txt("-", ac[4] + 6, y + 10); txt("-", ac[4] + 60, y + 10); } y += aRowH; } doc.rect(LM, y, CW, aRowH); font("bold", 8); txt("Total", ac[0] + 6, y + 10); right(fmt(annexureA_Total), ac[2] - 6, y + 10); y += aRowH + 10; // --- ANNEXURE B (Challan) --- font("bold", 10); center("ANNEXURE B (Challan)", y); y += 14; const bc = [LM, LM + 40, LM + 170, LM + 270, LM + 390, RM]; const bRowH = 14; doc.rect(LM, y, CW, bRowH); bc.forEach((x, i) => { if (i > 0) doc.line(x, y, x, y + bRowH + (4 * bRowH)); }); font("bold", 7); txt("Sl.No", bc[0] + 6, y + 10); doc.text("Challan Serial No", bc[1] + 6, y + 10); doc.text("BSR Code of Bank Branch", bc[2] + 6, y + 10); doc.text("Date of Deposit\n(dd/mm/yy)", bc[3] + 6, y + 6); doc.text("Amount of Tax Deposited (Rs.)", bc[4] + 6, y + 10); y += bRowH; DATA.qtrData.forEach((row, i) => { doc.rect(LM, y, CW, bRowH); font("normal", 8); txt(`${i + 1}.`, bc[0] + 6, y + 10); txt(`${i + 1}`, bc[1] + 6, y + 10); txt("0000000", bc[2] + 6, y + 10); const yr = (METADATA.periodTo || "31/03/2026").split('/').pop() || "2026"; txt(`31/03/${yr}`, bc[3] + 6, y + 10); right(fmt(row.deducted || 0), RM - 6, y + 10); y += bRowH; }); doc.rect(LM, y, CW, bRowH); font("bold", 8); txt("Total", bc[0] + 6, y + 10); right(fmt(DATA.totalTDS || 0), RM - 6, y + 10); y += bRowH + 10; // Footer font("normal", 8); center(METADATA.footer, y); y += 8; // Final outer borders (thin) const pages = doc.internal.getNumberOfPages(); for (let i = 1; i <= pages; i++) { doc.setPage(i); doc.setLineWidth(0.6); doc.rect(LM - 5, 20, CW + 10, PG_H - 40); doc.setLineWidth(0.4); doc.rect(LM - 2, 23, CW + 4, PG_H - 46); } const empLabelRaw = (_meta.name || METADATA.nameDesig || "Employee").toString(); const empLabel = empLabelRaw.replace(/\s+/g, '_').replace(/[^\w\-_.]/g, ''); doc.save(`Form16_${selectedRegime}_${empLabel || 'Employee'}.pdf`); } catch (e) { console.error(e); alert(`Error generating PDF: ${e && e.message ? e.message : e}. Check console.`); } }

About TeacherAp

This is a short description in the author block about the author. You edit it by entering text in the "Biographical Info" field in the user admin panel.

0 Comments:

Post a Comment