@zenuinebit/invoice-number
v0.1.0
Published
Sequential invoice numbers with financial-year resets and GST-compliant format checks.
Downloads
172
Readme
@zenuinebit/invoice-number
Sequential invoice numbers that restart each financial year, plus a check for the Indian GST format rule. No dependencies. Dates are "YYYY-MM-DD" strings.
import { next, checkGstFormat, financialYear } from "@zenuinebit/invoice-number";
const format = { pattern: "INV/{FY}/{SEQ:4}" }; // reset defaults to "financial-year"
// First invoice: no counter yet
let r = next(null, "2025-04-01", format); // { number: "INV/2025-26/0001", counter: { period: "2025-26", seq: 1 } }
r = next(r.counter, "2025-09-10", format); // "INV/2025-26/0002"
r = next(r.counter, "2026-04-01", format); // "INV/2026-27/0001" - new financial year
checkGstFormat("INV/2025-26/0042"); // { valid: true, problems: [] }
financialYear("2025-03-31"); // "2024-25"Pattern tokens: {FY} 2025-26, {FY2} 2526, {YYYY}, {YY}, {MM}, {SEQ:n} (sequence padded to n digits) and {SEQ}.
Reset: "financial-year" (default), "calendar-year", "month", "never". fyStartMonth defaults to 4 (April).
Use it safely
- The package keeps no state. Store the counter in your database and call
nextinside the same transaction (or with a row lock) that saves the invoice. Two requests reading the same counter would otherwise issue the same number. - A back-dated invoice is fine inside the current period but refused if it falls in an earlier one, so it cannot reuse a number.
checkGstFormattests Rule 46: at most 16 characters, only letters, digits,/and-.INV/2025-26/00042is 17 characters and fails, so size your pattern for it.
Not included: credit-note or debit-note series, multiple series per branch (use one counter per series), and gap detection.
