Files
Voiced/src/lib/numberToWords.ts
T
xavierkandCommandCodeBot 3af9f3f66f Initial commit: Voiced invoice desktop app
Offline-first invoicing app for Arun P, built by Bongbetic.

- Tauri v2 (Rust) + React/TypeScript + IBM Carbon Design System UI
- SQLite (rusqlite) storage with a persistent invoice-number series
- Guided first-run setup, pre-filled vendor/bank details
- Fixed-amount or rate x quantity line items (per sec/min/hour/session/unit)
- GST as CGST+SGST or IGST, Indian amount-in-words
- Optional signature, with a computer-generated note as fallback
- Print-ready PDF export via @react-pdf/renderer
- Windows cross-compile via cargo-xwin (NSIS installer)

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-10-03 23:07:51 +05:30

76 lines
1.9 KiB
TypeScript

const ONES = [
"",
"One",
"Two",
"Three",
"Four",
"Five",
"Six",
"Seven",
"Eight",
"Nine",
"Ten",
"Eleven",
"Twelve",
"Thirteen",
"Fourteen",
"Fifteen",
"Sixteen",
"Seventeen",
"Eighteen",
"Nineteen",
];
const TENS = ["", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"];
function twoDigits(n: number): string {
if (n < 20) return ONES[n];
const tens = Math.floor(n / 10);
const ones = n % 10;
return TENS[tens] + (ones ? " " + ONES[ones] : "");
}
function threeDigits(n: number): string {
const hundreds = Math.floor(n / 100);
const rest = n % 100;
let out = "";
if (hundreds > 0) out += ONES[hundreds] + " Hundred";
if (rest > 0) out += (out ? " " : "") + twoDigits(rest);
return out;
}
/** Whole-number to words using the Indian numbering system (thousand, lakh, crore). */
function wholeToWords(n: number): string {
if (n === 0) return "Zero";
const parts: string[] = [];
const crore = Math.floor(n / 10000000);
let rest = n % 10000000;
if (crore > 0) parts.push(`${wholeToWords(crore)} Crore`);
const lakh = Math.floor(rest / 100000);
rest %= 100000;
if (lakh > 0) parts.push(`${twoDigits(lakh)} Lakh`);
const thousand = Math.floor(rest / 1000);
rest %= 1000;
if (thousand > 0) parts.push(`${twoDigits(thousand)} Thousand`);
if (rest > 0) parts.push(threeDigits(rest));
return parts.join(" ");
}
/** e.g. 25000 -> "Indian Rupees Twenty Five Thousand Only" */
export function amountInWords(amount: number, currency = "Indian Rupees"): string {
const value = Number.isFinite(amount) ? Math.abs(amount) : 0;
const rupees = Math.floor(value);
const paise = Math.round((value - rupees) * 100);
let out = "";
if (currency) out += `${currency} `;
out += wholeToWords(rupees);
if (paise > 0) out += ` and ${twoDigits(paise)} Paise`;
return `${out} Only`;
}