Rebuild the Classic template on the engine with A4/Letter and a template harness
Classic now renders through buildRenderModel, computeFrame, the template and renderCore, with S.No and HSN/SAC columns, GST slots only through checked Slot components, taxable value, reverse-charge line, cancelled tag, continuation band and Page n of N. Letter absorbs its height deficit in elastic gaps. A harness runs 15 fixtures on A4 and Letter plus an item sweep and asserts zero audit errors, repeated headers, no split blocks, rupee extraction and deterministic output. The legacy InvoiceDocument is removed.
This commit is contained in:
@@ -97,7 +97,7 @@ describe("unregistered invoice", () => {
|
||||
expect(m.docTitle).toBe("Invoice");
|
||||
expect(m.docType).toBe("invoice");
|
||||
expect(m.pdfTitle).toBe("Invoice INV-0001");
|
||||
expect(m.slots).toEqual({ gstin: false, clientGstin: false, pos: false, hsn: true, taxRows: false });
|
||||
expect(m.slots).toEqual({ gstin: false, clientGstin: false, pos: false, hsn: true, taxRows: false, reverseCharge: false });
|
||||
expect(m.totals).toMatchObject({
|
||||
subtotalText: "₹5,500.50",
|
||||
discountText: null,
|
||||
@@ -119,7 +119,7 @@ describe("unregistered invoice", () => {
|
||||
expect(m.client.addressLines).toEqual(["1 Main Road", "Mumbai"]);
|
||||
expect(m.client.poNumber).toBeNull();
|
||||
expect(m.notesLines).toEqual(["Thanks", "Pay in 30 days"]);
|
||||
expect(m.meta).toEqual({ numberLabel: "Invoice No.", number: "INV-0001", date: "15 Sept 2026", dueDate: "05 Oct 2026" });
|
||||
expect(m.meta).toEqual({ numberLabel: "Invoice No.", number: "INV-0001", date: "15 Sept 2026", isoDate: "2026-09-15", dueDate: "05 Oct 2026" });
|
||||
});
|
||||
it("builds items with rate, quantity and em-dash fallback", () => {
|
||||
expect(m.items[0]).toEqual({
|
||||
@@ -179,16 +179,24 @@ describe("CGST + SGST tax invoice", () => {
|
||||
expect(m.totals.discountText).toBe("₹500.50");
|
||||
expect(m.totals.taxableText).toBe("₹5,000.00");
|
||||
expect(m.totals.totalText).toBe("₹5,250.00");
|
||||
expect(m.slots).toEqual({ gstin: true, clientGstin: true, pos: true, hsn: true, taxRows: true });
|
||||
expect(m.slots).toEqual({ gstin: true, clientGstin: true, pos: true, hsn: true, taxRows: true, reverseCharge: true });
|
||||
expect(m.client.posLabel).toBe("29 – Karnataka");
|
||||
expect(m.client.gstin).toBe("29ABCDE1234F1Z5");
|
||||
expect(m.client.poNumber).toBe("PO-77");
|
||||
expect(m.supplier.showGstin).toBe(true);
|
||||
expect(m.reverseCharge).toMatch(/reverse charge/i);
|
||||
expect(m.reverseCharge).toBe("Tax is payable on reverse charge: Yes");
|
||||
expect(m.signature).toMatchObject({ name: "A. Person", designation: "Proprietor" });
|
||||
});
|
||||
});
|
||||
|
||||
describe("reverse charge line", () => {
|
||||
it("is always present on a tax invoice (Yes or No) and absent on a plain invoice", () => {
|
||||
expect(make({ docType: "tax_invoice", reverseCharge: false }).reverseCharge).toBe("Tax is payable on reverse charge: No");
|
||||
expect(make({ docType: "tax_invoice", reverseCharge: true }).reverseCharge).toBe("Tax is payable on reverse charge: Yes");
|
||||
expect(make({ docType: "invoice", reverseCharge: true }).reverseCharge).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("IGST", () => {
|
||||
const m = make({ docType: "tax_invoice", taxType: "igst", taxRate: 18, igstAmount: 990.09, total: 6490.59, placeOfSupplyStateCode: "27" });
|
||||
it("has one IGST row at the full rate", () => {
|
||||
|
||||
Reference in New Issue
Block a user