Skip to content

fix(invoice): count on from an invoice number of more than 15 digits - #448

Merged
anurag629 merged 1 commit into
codercops:developfrom
Saifjafri212213:fix/invoice-number-long-digits
Oct 31, 2026
Merged

anurag629 merged 1 commit into
codercops:developfrom
Saifjafri212213:fix/invoice-number-long-digits

Conversation

@Saifjafri212213

@Saifjafri212213 Saifjafri212213 commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

nextInvoiceNumber() now counts on from a number of any length. Before, a number of more than 15 digits lost precision and the next one could come back lower than the one before.

Closes #445

Cause

nextInvoiceNumber() (lib/invoice-types.ts) read the trailing digits with parseInt(match[2], 10) and wrote String(highest.value + 1) back. That is a JavaScript number, which holds a whole number exactly only up to 2^53 (16 digits at most, and 15 to be safe). So:

  • 20261031143012345 (a timestamp with milliseconds) gave 20261031143012344, one lower.
  • INV-9007199254740993 gave INV-9007199254740992.
  • INV-9999999999999999999999 (22 digits) gave INV-000000000000000001e+22.

The "New invoice" and "Duplicate" buttons both call it, so the number field would show one of those.

What changed

  • The value is a BigInt: BigInt(match[2]) picks the highest (same rule as before, the later one wins a tie), and String(highest.value + BigInt(1)) is padded to the same width as before. The prefix and zero-padding rules from Invoice generator: the next number adds INV to plain numbers and changes the padding #220 are untouched. I wrote BigInt(1) and not 1n, since tsconfig targets ES2017, the same as lib/time-difference.ts does.
  • No other code changed.

How I Tested This

  • Added tests to lib/__tests__/invoice-types.test.ts first, and 7 of the new ones failed on the old code: 20261031143012345, INV-9007199254740993, INV-9007199254740992, the 22-digit INV-9999999999999999999999, a 29-digit number, the pick of the highest between numbers a JS number can't tell apart (in both orders, and with three long numbers one of which is zero-padded), and a 40-digit number of nines giving 1 followed by 40 zeros. The other new ones are guards that passed before as well: a 20-digit number whose old result happened to be right, and zero-padded long numbers with a small value (INV-0000000000000000000007, 2026-00000000000000000099).
  • Mutated the code in 5 ways (comparing with parseInt, adding with a JS number, no padding, the first number always winning, the lowest winning); a test fails for each.
  • npx tsc --noEmit is clean, lint is at develop's 11 warnings, and all 2,534 tests pass (the existing invoice number tests from Invoice generator: the next number adds INV to plain numbers and changes the padding #220 included).
  • I ran the function in Node 22 with Vitest, not in a browser, and I did not run next build here, so CI will be the first to build it. BigInt is already used in lib/time-difference.ts, so it is in the supported browsers.

AI assistance

An AI coding assistant helped write the fix and the tests. I ran the checks listed above.

…osing digits (codercops#445)

nextInvoiceNumber() read the trailing digits with parseInt and wrote value + 1
back as a JS number, so a number of more than 15 digits lost precision (a
17-digit number came back one lower) and one of 22 digits or more was printed
as 1e+22. It now uses BigInt, and keeps the prefix and the zero-padding.
@anurag629 anurag629 added the hacktoberfest-accepted PR counts for Hacktoberfest label Oct 31, 2026
@anurag629
anurag629 merged commit 09b2c9c into codercops:develop Oct 31, 2026
5 checks passed
@github-actions github-actions Bot added the codercops-accepted Merged PR that counts on the monthly leaderboard (oss.codercops.com) label Oct 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

codercops-accepted Merged PR that counts on the monthly leaderboard (oss.codercops.com) hacktoberfest-accepted PR counts for Hacktoberfest

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Invoice generator: the next invoice number is wrong when the number has more than 15 digits

2 participants