inr-num-words 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +141 -2
- package/dist/index.cjs +299 -0
- package/dist/index.d.cts +87 -0
- package/dist/index.d.ts +87 -0
- package/dist/index.js +271 -0
- package/package.json +53 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pirapaakaran Pirathapan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,142 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 🇮🇳 inr-num-words
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Zero-dependency TypeScript utility for converting numbers and Indian Rupee (INR) amounts into words (English & Tamil) with Lakhs, Crores, Paise, Cheque formatting, and GST calculation.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/inr-num-words)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## ✨ Features
|
|
12
|
+
|
|
13
|
+
- 🏛️ **Indian Numbering System** — Formats accurately with **Lakhs** (1,00,000) and **Crores** (1,00,00,000), not Western millions/billions.
|
|
14
|
+
- 🧾 **Invoice & Cheque Ready** — Automatically appends `"Rupees"`, `"Paise"`, and `"Only"` (standard for bank cheques & billing apps).
|
|
15
|
+
- 🇮🇳 **Tamil Language Support (தமிழ்)** — Convert any number or currency directly to Tamil words (`இலட்சம்`, `கோடி`, `ரூபாய்`, `பைசா`).
|
|
16
|
+
- 💰 **GST Tax Calculator** — Calculate CGST + SGST (Intra-state) or IGST (Inter-state) and receive total with words in one call.
|
|
17
|
+
- 🪙 **Indian Currency Formatter** — Easy comma grouping (`₹ 15,00,000.00`).
|
|
18
|
+
- ⚡ **Zero Dependencies** — Ultra-lightweight (~3 KB), purely native JavaScript/TypeScript.
|
|
19
|
+
- 📦 **Dual ESM & CommonJS** — Works in Node.js, Next.js, React, React Native, Vite, Express, and browsers.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 📥 Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install inr-num-words
|
|
27
|
+
```
|
|
28
|
+
or with Yarn / pnpm:
|
|
29
|
+
```bash
|
|
30
|
+
pnpm add inr-num-words
|
|
31
|
+
# or
|
|
32
|
+
yarn add inr-num-words
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 🚀 Quick Start
|
|
38
|
+
|
|
39
|
+
### 1. Bank Cheque & Invoice Format (English)
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { numberToIndianWords } from 'inr-num-words';
|
|
43
|
+
|
|
44
|
+
console.log(numberToIndianWords(150000));
|
|
45
|
+
// "One Lakh Fifty Thousand Rupees Only"
|
|
46
|
+
|
|
47
|
+
console.log(numberToIndianWords(125450.75));
|
|
48
|
+
// "One Lakh Twenty-Five Thousand Four Hundred Fifty Rupees and Seventy-Five Paise Only"
|
|
49
|
+
|
|
50
|
+
console.log(numberToIndianWords(25000000));
|
|
51
|
+
// "Two Crore Fifty Lakh Rupees Only"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
### 2. Tamil Words Output (தமிழ்)
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { numberToTamilWords } from 'inr-num-words';
|
|
60
|
+
|
|
61
|
+
console.log(numberToTamilWords(1500));
|
|
62
|
+
// "ஆயிரத்து ஐந்நூறு ரூபாய் மட்டும்"
|
|
63
|
+
|
|
64
|
+
console.log(numberToTamilWords(100000));
|
|
65
|
+
// "ஒன்று இலட்சம் ரூபாய் மட்டும்"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
### 3. Currency Comma Formatter (`formatINR`)
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { formatINR } from 'inr-num-words';
|
|
74
|
+
|
|
75
|
+
console.log(formatINR(1234567.89));
|
|
76
|
+
// "₹ 12,34,567.89"
|
|
77
|
+
|
|
78
|
+
console.log(formatINR(50000, { symbol: false }));
|
|
79
|
+
// "50,000.00"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
### 4. GST Breakdown & Invoice Helper
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import { calculateGST } from 'inr-num-words';
|
|
88
|
+
|
|
89
|
+
// Intra-state (Within Tamil Nadu): 18% GST splits into 9% CGST + 9% SGST
|
|
90
|
+
const invoice = calculateGST(10000, 18, false);
|
|
91
|
+
|
|
92
|
+
console.log(invoice);
|
|
93
|
+
/*
|
|
94
|
+
{
|
|
95
|
+
baseAmount: 10000,
|
|
96
|
+
gstRate: 18,
|
|
97
|
+
isInterState: false,
|
|
98
|
+
cgstAmount: 900,
|
|
99
|
+
sgstAmount: 900,
|
|
100
|
+
igstAmount: 0,
|
|
101
|
+
totalTax: 1800,
|
|
102
|
+
totalAmount: 11800,
|
|
103
|
+
totalInWords: "Eleven Thousand Eight Hundred Rupees Only"
|
|
104
|
+
}
|
|
105
|
+
*/
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## ⚙️ Options Reference
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
numberToIndianWords(amount, options)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
| Option | Type | Default | Description |
|
|
117
|
+
|---|---|---|---|
|
|
118
|
+
| `currency` | `boolean` | `true` | Appends "Rupees" or "ரூபாய்". |
|
|
119
|
+
| `includePaise` | `boolean` | `true` | Formats decimal cents as "Paise" / "பைசா". |
|
|
120
|
+
| `suffixOnly` | `boolean` | `true` | Appends "Only" / "மட்டும்" at the end. |
|
|
121
|
+
| `language` | `'en' \| 'ta'` | `'en'` | Output language (`'en'` for English, `'ta'` for Tamil). |
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 🛠 Development & Testing
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Install dependencies
|
|
129
|
+
npm install
|
|
130
|
+
|
|
131
|
+
# Run unit tests
|
|
132
|
+
npm test
|
|
133
|
+
|
|
134
|
+
# Build dual ESM/CJS bundles + .d.ts types
|
|
135
|
+
npm run build
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 📄 License
|
|
141
|
+
|
|
142
|
+
MIT © 2026 Pirapaakaran Pirathapan
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
calculateGST: () => calculateGST,
|
|
24
|
+
formatINR: () => formatINR,
|
|
25
|
+
numberToIndianWords: () => numberToIndianWords,
|
|
26
|
+
numberToTamilWords: () => numberToTamilWords
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(index_exports);
|
|
29
|
+
var EN_ONES = [
|
|
30
|
+
"",
|
|
31
|
+
"One",
|
|
32
|
+
"Two",
|
|
33
|
+
"Three",
|
|
34
|
+
"Four",
|
|
35
|
+
"Five",
|
|
36
|
+
"Six",
|
|
37
|
+
"Seven",
|
|
38
|
+
"Eight",
|
|
39
|
+
"Nine",
|
|
40
|
+
"Ten",
|
|
41
|
+
"Eleven",
|
|
42
|
+
"Twelve",
|
|
43
|
+
"Thirteen",
|
|
44
|
+
"Fourteen",
|
|
45
|
+
"Fifteen",
|
|
46
|
+
"Sixteen",
|
|
47
|
+
"Seventeen",
|
|
48
|
+
"Eighteen",
|
|
49
|
+
"Nineteen"
|
|
50
|
+
];
|
|
51
|
+
var EN_TENS = [
|
|
52
|
+
"",
|
|
53
|
+
"",
|
|
54
|
+
"Twenty",
|
|
55
|
+
"Thirty",
|
|
56
|
+
"Forty",
|
|
57
|
+
"Fifty",
|
|
58
|
+
"Sixty",
|
|
59
|
+
"Seventy",
|
|
60
|
+
"Eighty",
|
|
61
|
+
"Ninety"
|
|
62
|
+
];
|
|
63
|
+
function convertThreeDigitEnglish(n) {
|
|
64
|
+
let str = "";
|
|
65
|
+
if (n >= 100) {
|
|
66
|
+
str += EN_ONES[Math.floor(n / 100)] + " Hundred ";
|
|
67
|
+
n %= 100;
|
|
68
|
+
}
|
|
69
|
+
if (n >= 20) {
|
|
70
|
+
const tens = EN_TENS[Math.floor(n / 10)];
|
|
71
|
+
n %= 10;
|
|
72
|
+
if (n > 0) {
|
|
73
|
+
str += `${tens}-${EN_ONES[n]} `;
|
|
74
|
+
n = 0;
|
|
75
|
+
} else {
|
|
76
|
+
str += `${tens} `;
|
|
77
|
+
}
|
|
78
|
+
} else if (n > 0) {
|
|
79
|
+
str += EN_ONES[n] + " ";
|
|
80
|
+
}
|
|
81
|
+
return str.trim();
|
|
82
|
+
}
|
|
83
|
+
function convertIntegerToIndianWordsEn(num) {
|
|
84
|
+
if (num === 0) return "Zero";
|
|
85
|
+
const parts = [];
|
|
86
|
+
const crores = Math.floor(num / 1e7);
|
|
87
|
+
num %= 1e7;
|
|
88
|
+
const lakhs = Math.floor(num / 1e5);
|
|
89
|
+
num %= 1e5;
|
|
90
|
+
const thousands = Math.floor(num / 1e3);
|
|
91
|
+
num %= 1e3;
|
|
92
|
+
const remaining = Math.floor(num);
|
|
93
|
+
if (crores > 0) {
|
|
94
|
+
const croreWords = crores >= 100 ? convertIntegerToIndianWordsEn(crores) : convertThreeDigitEnglish(crores);
|
|
95
|
+
parts.push(`${croreWords} Crore`);
|
|
96
|
+
}
|
|
97
|
+
if (lakhs > 0) {
|
|
98
|
+
parts.push(`${convertThreeDigitEnglish(lakhs)} Lakh`);
|
|
99
|
+
}
|
|
100
|
+
if (thousands > 0) {
|
|
101
|
+
parts.push(`${convertThreeDigitEnglish(thousands)} Thousand`);
|
|
102
|
+
}
|
|
103
|
+
if (remaining > 0) {
|
|
104
|
+
parts.push(convertThreeDigitEnglish(remaining));
|
|
105
|
+
}
|
|
106
|
+
return parts.join(" ").trim();
|
|
107
|
+
}
|
|
108
|
+
var TA_ONES = [
|
|
109
|
+
"",
|
|
110
|
+
"\u0B92\u0BA9\u0BCD\u0BB1\u0BC1",
|
|
111
|
+
"\u0B87\u0BB0\u0BA3\u0BCD\u0B9F\u0BC1",
|
|
112
|
+
"\u0BAE\u0BC2\u0BA9\u0BCD\u0BB1\u0BC1",
|
|
113
|
+
"\u0BA8\u0BBE\u0BA9\u0BCD\u0B95\u0BC1",
|
|
114
|
+
"\u0B90\u0BA8\u0BCD\u0BA4\u0BC1",
|
|
115
|
+
"\u0B86\u0BB1\u0BC1",
|
|
116
|
+
"\u0B8F\u0BB4\u0BC1",
|
|
117
|
+
"\u0B8E\u0B9F\u0BCD\u0B9F\u0BC1",
|
|
118
|
+
"\u0B92\u0BA9\u0BCD\u0BAA\u0BA4\u0BC1",
|
|
119
|
+
"\u0BAA\u0BA4\u0BCD\u0BA4\u0BC1",
|
|
120
|
+
"\u0BAA\u0BA4\u0BBF\u0BA9\u0BCA\u0BA9\u0BCD\u0BB1\u0BC1",
|
|
121
|
+
"\u0BAA\u0BA9\u0BCD\u0BA9\u0BBF\u0BB0\u0BA3\u0BCD\u0B9F\u0BC1",
|
|
122
|
+
"\u0BAA\u0BA4\u0BBF\u0BA9\u0BCD\u0BAE\u0BC2\u0BA9\u0BCD\u0BB1\u0BC1",
|
|
123
|
+
"\u0BAA\u0BA4\u0BBF\u0BA9\u0BBE\u0BA9\u0BCD\u0B95\u0BC1",
|
|
124
|
+
"\u0BAA\u0BA4\u0BBF\u0BA9\u0BC8\u0BA8\u0BCD\u0BA4\u0BC1",
|
|
125
|
+
"\u0BAA\u0BA4\u0BBF\u0BA9\u0BBE\u0BB1\u0BC1",
|
|
126
|
+
"\u0BAA\u0BA4\u0BBF\u0BA9\u0BC7\u0BB4\u0BC1",
|
|
127
|
+
"\u0BAA\u0BA4\u0BBF\u0BA9\u0BC6\u0B9F\u0BCD\u0B9F\u0BC1",
|
|
128
|
+
"\u0BAA\u0BA4\u0BCD\u0BA4\u0BCA\u0BA9\u0BCD\u0BAA\u0BA4\u0BC1"
|
|
129
|
+
];
|
|
130
|
+
var TA_TENS_PREFIX = [
|
|
131
|
+
"",
|
|
132
|
+
"",
|
|
133
|
+
"\u0B87\u0BB0\u0BC1\u0BAA\u0BA4\u0BCD\u0BA4\u0BC1 ",
|
|
134
|
+
"\u0BAE\u0BC1\u0BAA\u0BCD\u0BAA\u0BA4\u0BCD\u0BA4\u0BC1 ",
|
|
135
|
+
"\u0BA8\u0BBE\u0BB1\u0BCD\u0BAA\u0BA4\u0BCD\u0BA4\u0BC1 ",
|
|
136
|
+
"\u0B90\u0BAE\u0BCD\u0BAA\u0BA4\u0BCD\u0BA4\u0BC1 ",
|
|
137
|
+
"\u0B85\u0BB1\u0BC1\u0BAA\u0BA4\u0BCD\u0BA4\u0BC1 ",
|
|
138
|
+
"\u0B8E\u0BB4\u0BC1\u0BAA\u0BA4\u0BCD\u0BA4\u0BC1 ",
|
|
139
|
+
"\u0B8E\u0BA3\u0BCD\u0BAA\u0BA4\u0BCD\u0BA4\u0BC1 ",
|
|
140
|
+
"\u0BA4\u0BCA\u0BA3\u0BCD\u0BA3\u0BC2\u0BB1\u0BCD\u0BB1\u0BC1 "
|
|
141
|
+
];
|
|
142
|
+
var TA_TENS_EXACT = [
|
|
143
|
+
"",
|
|
144
|
+
"",
|
|
145
|
+
"\u0B87\u0BB0\u0BC1\u0BAA\u0BA4\u0BC1",
|
|
146
|
+
"\u0BAE\u0BC1\u0BAA\u0BCD\u0BAA\u0BA4\u0BC1",
|
|
147
|
+
"\u0BA8\u0BBE\u0BB1\u0BCD\u0BAA\u0BA4\u0BC1",
|
|
148
|
+
"\u0B90\u0BAE\u0BCD\u0BAA\u0BA4\u0BC1",
|
|
149
|
+
"\u0B85\u0BB1\u0BC1\u0BAA\u0BA4\u0BC1",
|
|
150
|
+
"\u0B8E\u0BB4\u0BC1\u0BAA\u0BA4\u0BC1",
|
|
151
|
+
"\u0B8E\u0BA3\u0BCD\u0BAA\u0BA4\u0BC1",
|
|
152
|
+
"\u0BA4\u0BCA\u0BA3\u0BCD\u0BA3\u0BC2\u0BB1\u0BC1"
|
|
153
|
+
];
|
|
154
|
+
var TA_HUNDREDS = [
|
|
155
|
+
"",
|
|
156
|
+
"\u0BA8\u0BC2\u0BB1\u0BC1",
|
|
157
|
+
"\u0B87\u0BB0\u0BC1\u0BA8\u0BC2\u0BB1\u0BC1",
|
|
158
|
+
"\u0BAE\u0BC1\u0BA8\u0BCD\u0BA8\u0BC2\u0BB1\u0BC1",
|
|
159
|
+
"\u0BA8\u0BBE\u0BA9\u0BC2\u0BB1\u0BC1",
|
|
160
|
+
"\u0B90\u0BA8\u0BCD\u0BA8\u0BC2\u0BB1\u0BC1",
|
|
161
|
+
"\u0B85\u0BB1\u0BC1\u0BA8\u0BC2\u0BB1\u0BC1",
|
|
162
|
+
"\u0B8E\u0BB4\u0BC1\u0BA8\u0BC2\u0BB1\u0BC1",
|
|
163
|
+
"\u0B8E\u0BA3\u0BCD\u0BA3\u0BC2\u0BB1\u0BC1",
|
|
164
|
+
"\u0BA4\u0BCA\u0BB3\u0BCD\u0BB3\u0BBE\u0BAF\u0BBF\u0BB0\u0BAE\u0BCD"
|
|
165
|
+
];
|
|
166
|
+
function convertThreeDigitTamil(n) {
|
|
167
|
+
let str = "";
|
|
168
|
+
if (n >= 100) {
|
|
169
|
+
const h = Math.floor(n / 100);
|
|
170
|
+
n %= 100;
|
|
171
|
+
if (n === 0) {
|
|
172
|
+
str += TA_HUNDREDS[h] + " ";
|
|
173
|
+
} else {
|
|
174
|
+
const prefix = ["\u0BA8\u0BC2\u0BB1\u0BCD\u0BB1\u0BC1 ", "\u0B87\u0BB0\u0BC1\u0BA8\u0BC2\u0BB1\u0BCD\u0BB1\u0BC1 ", "\u0BAE\u0BC1\u0BA8\u0BCD\u0BA8\u0BC2\u0BB1\u0BCD\u0BB1\u0BC1 ", "\u0BA8\u0BBE\u0BA9\u0BC2\u0BB1\u0BCD\u0BB1\u0BC1 ", "\u0B90\u0BA8\u0BCD\u0BA8\u0BC2\u0BB1\u0BCD\u0BB1\u0BC1 ", "\u0B85\u0BB1\u0BC1\u0BA8\u0BC2\u0BB1\u0BCD\u0BB1\u0BC1 ", "\u0B8E\u0BB4\u0BC1\u0BA8\u0BC2\u0BB1\u0BCD\u0BB1\u0BC1 ", "\u0B8E\u0BA3\u0BCD\u0BA3\u0BC2\u0BB1\u0BCD\u0BB1\u0BC1 ", "\u0BA4\u0BCA\u0BB3\u0BCD\u0BB3\u0BBE\u0BAF\u0BBF\u0BB0\u0BA4\u0BCD\u0BA4\u0BC1 "];
|
|
175
|
+
str += prefix[h - 1];
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (n >= 20) {
|
|
179
|
+
const t = Math.floor(n / 10);
|
|
180
|
+
n %= 10;
|
|
181
|
+
if (n === 0) {
|
|
182
|
+
str += TA_TENS_EXACT[t] + " ";
|
|
183
|
+
} else {
|
|
184
|
+
str += TA_TENS_PREFIX[t];
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (n > 0) {
|
|
188
|
+
str += TA_ONES[n] + " ";
|
|
189
|
+
}
|
|
190
|
+
return str.trim();
|
|
191
|
+
}
|
|
192
|
+
function convertIntegerToTamilWords(num) {
|
|
193
|
+
if (num === 0) return "\u0BAA\u0BC2\u0B9C\u0BCD\u0B9C\u0BBF\u0BAF\u0BAE\u0BCD";
|
|
194
|
+
const parts = [];
|
|
195
|
+
const crores = Math.floor(num / 1e7);
|
|
196
|
+
num %= 1e7;
|
|
197
|
+
const lakhs = Math.floor(num / 1e5);
|
|
198
|
+
num %= 1e5;
|
|
199
|
+
const thousands = Math.floor(num / 1e3);
|
|
200
|
+
num %= 1e3;
|
|
201
|
+
const remaining = Math.floor(num);
|
|
202
|
+
if (crores > 0) {
|
|
203
|
+
const croreWords = crores >= 100 ? convertIntegerToTamilWords(crores) : convertThreeDigitTamil(crores);
|
|
204
|
+
parts.push(`${croreWords} \u0B95\u0BCB\u0B9F\u0BBF`);
|
|
205
|
+
}
|
|
206
|
+
if (lakhs > 0) {
|
|
207
|
+
parts.push(`${convertThreeDigitTamil(lakhs)} \u0B87\u0BB2\u0B9F\u0BCD\u0B9A\u0BAE\u0BCD`);
|
|
208
|
+
}
|
|
209
|
+
if (thousands > 0) {
|
|
210
|
+
parts.push(`${convertThreeDigitTamil(thousands)} \u0B86\u0BAF\u0BBF\u0BB0\u0BAE\u0BCD`);
|
|
211
|
+
}
|
|
212
|
+
if (remaining > 0) {
|
|
213
|
+
parts.push(convertThreeDigitTamil(remaining));
|
|
214
|
+
}
|
|
215
|
+
return parts.join(" ").trim();
|
|
216
|
+
}
|
|
217
|
+
function numberToIndianWords(amount, options = {}) {
|
|
218
|
+
const {
|
|
219
|
+
currency = true,
|
|
220
|
+
includePaise = true,
|
|
221
|
+
suffixOnly = true,
|
|
222
|
+
language = "en"
|
|
223
|
+
} = options;
|
|
224
|
+
if (isNaN(amount)) {
|
|
225
|
+
return language === "ta" ? "\u0B9A\u0BC6\u0BB2\u0BCD\u0BB2\u0BC1\u0BAA\u0B9F\u0BBF\u0BAF\u0BBE\u0B95\u0BBE\u0BA4 \u0B8E\u0BA3\u0BCD" : "Invalid Number";
|
|
226
|
+
}
|
|
227
|
+
const isNegative = amount < 0;
|
|
228
|
+
const absAmount = Math.abs(amount);
|
|
229
|
+
const integerPart = Math.floor(absAmount);
|
|
230
|
+
const decimalPart = Math.round((absAmount - integerPart) * 100);
|
|
231
|
+
if (language === "ta") {
|
|
232
|
+
let result2 = convertIntegerToTamilWords(integerPart);
|
|
233
|
+
if (currency) {
|
|
234
|
+
result2 += " \u0BB0\u0BC2\u0BAA\u0BBE\u0BAF\u0BCD";
|
|
235
|
+
}
|
|
236
|
+
if (includePaise && decimalPart > 0) {
|
|
237
|
+
const paiseWord = convertThreeDigitTamil(decimalPart);
|
|
238
|
+
result2 += ` ${paiseWord} \u0BAA\u0BC8\u0B9A\u0BBE`;
|
|
239
|
+
}
|
|
240
|
+
if (suffixOnly) {
|
|
241
|
+
result2 += " \u0BAE\u0B9F\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD";
|
|
242
|
+
}
|
|
243
|
+
return (isNegative ? "\u0BAE\u0BC8\u0BA9\u0BB8\u0BCD " : "") + result2.trim();
|
|
244
|
+
}
|
|
245
|
+
let result = convertIntegerToIndianWordsEn(integerPart);
|
|
246
|
+
if (currency) {
|
|
247
|
+
result += integerPart === 1 ? " Rupee" : " Rupees";
|
|
248
|
+
}
|
|
249
|
+
if (includePaise && decimalPart > 0) {
|
|
250
|
+
const paiseWord = convertThreeDigitEnglish(decimalPart);
|
|
251
|
+
result += ` and ${paiseWord} Paise`;
|
|
252
|
+
}
|
|
253
|
+
if (suffixOnly) {
|
|
254
|
+
result += " Only";
|
|
255
|
+
}
|
|
256
|
+
return (isNegative ? "Minus " : "") + result.trim();
|
|
257
|
+
}
|
|
258
|
+
function numberToTamilWords(amount, options = {}) {
|
|
259
|
+
return numberToIndianWords(amount, { ...options, language: "ta" });
|
|
260
|
+
}
|
|
261
|
+
function formatINR(amount, options = {}) {
|
|
262
|
+
const { symbol = true, decimals = 2 } = options;
|
|
263
|
+
const formatted = new Intl.NumberFormat("en-IN", {
|
|
264
|
+
minimumFractionDigits: decimals,
|
|
265
|
+
maximumFractionDigits: decimals
|
|
266
|
+
}).format(amount);
|
|
267
|
+
return symbol ? `\u20B9 ${formatted}` : formatted;
|
|
268
|
+
}
|
|
269
|
+
function calculateGST(baseAmount, gstRatePercent, isInterState = false) {
|
|
270
|
+
const totalTax = Number((baseAmount * gstRatePercent / 100).toFixed(2));
|
|
271
|
+
const totalAmount = Number((baseAmount + totalTax).toFixed(2));
|
|
272
|
+
let cgstAmount = 0;
|
|
273
|
+
let sgstAmount = 0;
|
|
274
|
+
let igstAmount = 0;
|
|
275
|
+
if (isInterState) {
|
|
276
|
+
igstAmount = totalTax;
|
|
277
|
+
} else {
|
|
278
|
+
cgstAmount = Number((totalTax / 2).toFixed(2));
|
|
279
|
+
sgstAmount = Number((totalTax / 2).toFixed(2));
|
|
280
|
+
}
|
|
281
|
+
return {
|
|
282
|
+
baseAmount,
|
|
283
|
+
gstRate: gstRatePercent,
|
|
284
|
+
isInterState,
|
|
285
|
+
cgstAmount,
|
|
286
|
+
sgstAmount,
|
|
287
|
+
igstAmount,
|
|
288
|
+
totalTax,
|
|
289
|
+
totalAmount,
|
|
290
|
+
totalInWords: numberToIndianWords(totalAmount)
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
294
|
+
0 && (module.exports = {
|
|
295
|
+
calculateGST,
|
|
296
|
+
formatINR,
|
|
297
|
+
numberToIndianWords,
|
|
298
|
+
numberToTamilWords
|
|
299
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* inr-num-words
|
|
3
|
+
* Zero-dependency utility for converting numbers and Indian Rupee (INR) amounts
|
|
4
|
+
* into words (English & Tamil) with Lakhs, Crores, Paise, and Invoice/Cheque formatting.
|
|
5
|
+
*/
|
|
6
|
+
interface IndianWordsOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Whether to include currency wording ("Rupees" or "ரூபாய்").
|
|
9
|
+
* @default true
|
|
10
|
+
*/
|
|
11
|
+
currency?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Whether to include the decimal fractional part as Paise ("Fifty Paise" or "ஐம்பது பைசா").
|
|
14
|
+
* @default true
|
|
15
|
+
*/
|
|
16
|
+
includePaise?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Whether to append "Only" / "மட்டும்" at the end (standard for cheques and invoices).
|
|
19
|
+
* @default true
|
|
20
|
+
*/
|
|
21
|
+
suffixOnly?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Language for word conversion: 'en' for English, 'ta' for Tamil.
|
|
24
|
+
* @default 'en'
|
|
25
|
+
*/
|
|
26
|
+
language?: 'en' | 'ta';
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Converts a number to words in the Indian numbering system.
|
|
30
|
+
* Supports English and Tamil outputs, Lakhs, Crores, Paise, and Invoice format.
|
|
31
|
+
*
|
|
32
|
+
* @param amount Numeric value to convert (can include decimals)
|
|
33
|
+
* @param options Configuration for currency words, paise, language, suffix
|
|
34
|
+
* @returns Fully formatted words string
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* numberToIndianWords(125450.50)
|
|
38
|
+
* // "One Lakh Twenty-Five Thousand Four Hundred Fifty Rupees and Fifty Paise Only"
|
|
39
|
+
*
|
|
40
|
+
* numberToIndianWords(1500, { language: 'ta' })
|
|
41
|
+
* // "ஆயிரத்து ஐந்நூறு ரூபாய் மட்டும்"
|
|
42
|
+
*/
|
|
43
|
+
declare function numberToIndianWords(amount: number, options?: IndianWordsOptions): string;
|
|
44
|
+
/**
|
|
45
|
+
* Shorthand helper for Tamil words conversion.
|
|
46
|
+
*/
|
|
47
|
+
declare function numberToTamilWords(amount: number, options?: Omit<IndianWordsOptions, 'language'>): string;
|
|
48
|
+
interface FormatINROptions {
|
|
49
|
+
/**
|
|
50
|
+
* Whether to include the Rupee symbol ₹.
|
|
51
|
+
* @default true
|
|
52
|
+
*/
|
|
53
|
+
symbol?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Number of decimal places.
|
|
56
|
+
* @default 2
|
|
57
|
+
*/
|
|
58
|
+
decimals?: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Formats a number with Indian comma grouping (Lakhs and Crores).
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* formatINR(1234567.89) // "₹ 12,34,567.89"
|
|
65
|
+
*/
|
|
66
|
+
declare function formatINR(amount: number, options?: FormatINROptions): string;
|
|
67
|
+
interface GSTCalculationResult {
|
|
68
|
+
baseAmount: number;
|
|
69
|
+
gstRate: number;
|
|
70
|
+
isInterState: boolean;
|
|
71
|
+
cgstAmount: number;
|
|
72
|
+
sgstAmount: number;
|
|
73
|
+
igstAmount: number;
|
|
74
|
+
totalTax: number;
|
|
75
|
+
totalAmount: number;
|
|
76
|
+
totalInWords: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Calculates GST breakdown (CGST + SGST or IGST) and provides total in words.
|
|
80
|
+
*
|
|
81
|
+
* @param baseAmount The pre-tax taxable amount
|
|
82
|
+
* @param gstRatePercent GST rate (e.g., 5, 12, 18, 28)
|
|
83
|
+
* @param isInterState If true, IGST is applied instead of CGST + SGST
|
|
84
|
+
*/
|
|
85
|
+
declare function calculateGST(baseAmount: number, gstRatePercent: number, isInterState?: boolean): GSTCalculationResult;
|
|
86
|
+
|
|
87
|
+
export { type FormatINROptions, type GSTCalculationResult, type IndianWordsOptions, calculateGST, formatINR, numberToIndianWords, numberToTamilWords };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* inr-num-words
|
|
3
|
+
* Zero-dependency utility for converting numbers and Indian Rupee (INR) amounts
|
|
4
|
+
* into words (English & Tamil) with Lakhs, Crores, Paise, and Invoice/Cheque formatting.
|
|
5
|
+
*/
|
|
6
|
+
interface IndianWordsOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Whether to include currency wording ("Rupees" or "ரூபாய்").
|
|
9
|
+
* @default true
|
|
10
|
+
*/
|
|
11
|
+
currency?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Whether to include the decimal fractional part as Paise ("Fifty Paise" or "ஐம்பது பைசா").
|
|
14
|
+
* @default true
|
|
15
|
+
*/
|
|
16
|
+
includePaise?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Whether to append "Only" / "மட்டும்" at the end (standard for cheques and invoices).
|
|
19
|
+
* @default true
|
|
20
|
+
*/
|
|
21
|
+
suffixOnly?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Language for word conversion: 'en' for English, 'ta' for Tamil.
|
|
24
|
+
* @default 'en'
|
|
25
|
+
*/
|
|
26
|
+
language?: 'en' | 'ta';
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Converts a number to words in the Indian numbering system.
|
|
30
|
+
* Supports English and Tamil outputs, Lakhs, Crores, Paise, and Invoice format.
|
|
31
|
+
*
|
|
32
|
+
* @param amount Numeric value to convert (can include decimals)
|
|
33
|
+
* @param options Configuration for currency words, paise, language, suffix
|
|
34
|
+
* @returns Fully formatted words string
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* numberToIndianWords(125450.50)
|
|
38
|
+
* // "One Lakh Twenty-Five Thousand Four Hundred Fifty Rupees and Fifty Paise Only"
|
|
39
|
+
*
|
|
40
|
+
* numberToIndianWords(1500, { language: 'ta' })
|
|
41
|
+
* // "ஆயிரத்து ஐந்நூறு ரூபாய் மட்டும்"
|
|
42
|
+
*/
|
|
43
|
+
declare function numberToIndianWords(amount: number, options?: IndianWordsOptions): string;
|
|
44
|
+
/**
|
|
45
|
+
* Shorthand helper for Tamil words conversion.
|
|
46
|
+
*/
|
|
47
|
+
declare function numberToTamilWords(amount: number, options?: Omit<IndianWordsOptions, 'language'>): string;
|
|
48
|
+
interface FormatINROptions {
|
|
49
|
+
/**
|
|
50
|
+
* Whether to include the Rupee symbol ₹.
|
|
51
|
+
* @default true
|
|
52
|
+
*/
|
|
53
|
+
symbol?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Number of decimal places.
|
|
56
|
+
* @default 2
|
|
57
|
+
*/
|
|
58
|
+
decimals?: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Formats a number with Indian comma grouping (Lakhs and Crores).
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* formatINR(1234567.89) // "₹ 12,34,567.89"
|
|
65
|
+
*/
|
|
66
|
+
declare function formatINR(amount: number, options?: FormatINROptions): string;
|
|
67
|
+
interface GSTCalculationResult {
|
|
68
|
+
baseAmount: number;
|
|
69
|
+
gstRate: number;
|
|
70
|
+
isInterState: boolean;
|
|
71
|
+
cgstAmount: number;
|
|
72
|
+
sgstAmount: number;
|
|
73
|
+
igstAmount: number;
|
|
74
|
+
totalTax: number;
|
|
75
|
+
totalAmount: number;
|
|
76
|
+
totalInWords: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Calculates GST breakdown (CGST + SGST or IGST) and provides total in words.
|
|
80
|
+
*
|
|
81
|
+
* @param baseAmount The pre-tax taxable amount
|
|
82
|
+
* @param gstRatePercent GST rate (e.g., 5, 12, 18, 28)
|
|
83
|
+
* @param isInterState If true, IGST is applied instead of CGST + SGST
|
|
84
|
+
*/
|
|
85
|
+
declare function calculateGST(baseAmount: number, gstRatePercent: number, isInterState?: boolean): GSTCalculationResult;
|
|
86
|
+
|
|
87
|
+
export { type FormatINROptions, type GSTCalculationResult, type IndianWordsOptions, calculateGST, formatINR, numberToIndianWords, numberToTamilWords };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
var EN_ONES = [
|
|
3
|
+
"",
|
|
4
|
+
"One",
|
|
5
|
+
"Two",
|
|
6
|
+
"Three",
|
|
7
|
+
"Four",
|
|
8
|
+
"Five",
|
|
9
|
+
"Six",
|
|
10
|
+
"Seven",
|
|
11
|
+
"Eight",
|
|
12
|
+
"Nine",
|
|
13
|
+
"Ten",
|
|
14
|
+
"Eleven",
|
|
15
|
+
"Twelve",
|
|
16
|
+
"Thirteen",
|
|
17
|
+
"Fourteen",
|
|
18
|
+
"Fifteen",
|
|
19
|
+
"Sixteen",
|
|
20
|
+
"Seventeen",
|
|
21
|
+
"Eighteen",
|
|
22
|
+
"Nineteen"
|
|
23
|
+
];
|
|
24
|
+
var EN_TENS = [
|
|
25
|
+
"",
|
|
26
|
+
"",
|
|
27
|
+
"Twenty",
|
|
28
|
+
"Thirty",
|
|
29
|
+
"Forty",
|
|
30
|
+
"Fifty",
|
|
31
|
+
"Sixty",
|
|
32
|
+
"Seventy",
|
|
33
|
+
"Eighty",
|
|
34
|
+
"Ninety"
|
|
35
|
+
];
|
|
36
|
+
function convertThreeDigitEnglish(n) {
|
|
37
|
+
let str = "";
|
|
38
|
+
if (n >= 100) {
|
|
39
|
+
str += EN_ONES[Math.floor(n / 100)] + " Hundred ";
|
|
40
|
+
n %= 100;
|
|
41
|
+
}
|
|
42
|
+
if (n >= 20) {
|
|
43
|
+
const tens = EN_TENS[Math.floor(n / 10)];
|
|
44
|
+
n %= 10;
|
|
45
|
+
if (n > 0) {
|
|
46
|
+
str += `${tens}-${EN_ONES[n]} `;
|
|
47
|
+
n = 0;
|
|
48
|
+
} else {
|
|
49
|
+
str += `${tens} `;
|
|
50
|
+
}
|
|
51
|
+
} else if (n > 0) {
|
|
52
|
+
str += EN_ONES[n] + " ";
|
|
53
|
+
}
|
|
54
|
+
return str.trim();
|
|
55
|
+
}
|
|
56
|
+
function convertIntegerToIndianWordsEn(num) {
|
|
57
|
+
if (num === 0) return "Zero";
|
|
58
|
+
const parts = [];
|
|
59
|
+
const crores = Math.floor(num / 1e7);
|
|
60
|
+
num %= 1e7;
|
|
61
|
+
const lakhs = Math.floor(num / 1e5);
|
|
62
|
+
num %= 1e5;
|
|
63
|
+
const thousands = Math.floor(num / 1e3);
|
|
64
|
+
num %= 1e3;
|
|
65
|
+
const remaining = Math.floor(num);
|
|
66
|
+
if (crores > 0) {
|
|
67
|
+
const croreWords = crores >= 100 ? convertIntegerToIndianWordsEn(crores) : convertThreeDigitEnglish(crores);
|
|
68
|
+
parts.push(`${croreWords} Crore`);
|
|
69
|
+
}
|
|
70
|
+
if (lakhs > 0) {
|
|
71
|
+
parts.push(`${convertThreeDigitEnglish(lakhs)} Lakh`);
|
|
72
|
+
}
|
|
73
|
+
if (thousands > 0) {
|
|
74
|
+
parts.push(`${convertThreeDigitEnglish(thousands)} Thousand`);
|
|
75
|
+
}
|
|
76
|
+
if (remaining > 0) {
|
|
77
|
+
parts.push(convertThreeDigitEnglish(remaining));
|
|
78
|
+
}
|
|
79
|
+
return parts.join(" ").trim();
|
|
80
|
+
}
|
|
81
|
+
var TA_ONES = [
|
|
82
|
+
"",
|
|
83
|
+
"\u0B92\u0BA9\u0BCD\u0BB1\u0BC1",
|
|
84
|
+
"\u0B87\u0BB0\u0BA3\u0BCD\u0B9F\u0BC1",
|
|
85
|
+
"\u0BAE\u0BC2\u0BA9\u0BCD\u0BB1\u0BC1",
|
|
86
|
+
"\u0BA8\u0BBE\u0BA9\u0BCD\u0B95\u0BC1",
|
|
87
|
+
"\u0B90\u0BA8\u0BCD\u0BA4\u0BC1",
|
|
88
|
+
"\u0B86\u0BB1\u0BC1",
|
|
89
|
+
"\u0B8F\u0BB4\u0BC1",
|
|
90
|
+
"\u0B8E\u0B9F\u0BCD\u0B9F\u0BC1",
|
|
91
|
+
"\u0B92\u0BA9\u0BCD\u0BAA\u0BA4\u0BC1",
|
|
92
|
+
"\u0BAA\u0BA4\u0BCD\u0BA4\u0BC1",
|
|
93
|
+
"\u0BAA\u0BA4\u0BBF\u0BA9\u0BCA\u0BA9\u0BCD\u0BB1\u0BC1",
|
|
94
|
+
"\u0BAA\u0BA9\u0BCD\u0BA9\u0BBF\u0BB0\u0BA3\u0BCD\u0B9F\u0BC1",
|
|
95
|
+
"\u0BAA\u0BA4\u0BBF\u0BA9\u0BCD\u0BAE\u0BC2\u0BA9\u0BCD\u0BB1\u0BC1",
|
|
96
|
+
"\u0BAA\u0BA4\u0BBF\u0BA9\u0BBE\u0BA9\u0BCD\u0B95\u0BC1",
|
|
97
|
+
"\u0BAA\u0BA4\u0BBF\u0BA9\u0BC8\u0BA8\u0BCD\u0BA4\u0BC1",
|
|
98
|
+
"\u0BAA\u0BA4\u0BBF\u0BA9\u0BBE\u0BB1\u0BC1",
|
|
99
|
+
"\u0BAA\u0BA4\u0BBF\u0BA9\u0BC7\u0BB4\u0BC1",
|
|
100
|
+
"\u0BAA\u0BA4\u0BBF\u0BA9\u0BC6\u0B9F\u0BCD\u0B9F\u0BC1",
|
|
101
|
+
"\u0BAA\u0BA4\u0BCD\u0BA4\u0BCA\u0BA9\u0BCD\u0BAA\u0BA4\u0BC1"
|
|
102
|
+
];
|
|
103
|
+
var TA_TENS_PREFIX = [
|
|
104
|
+
"",
|
|
105
|
+
"",
|
|
106
|
+
"\u0B87\u0BB0\u0BC1\u0BAA\u0BA4\u0BCD\u0BA4\u0BC1 ",
|
|
107
|
+
"\u0BAE\u0BC1\u0BAA\u0BCD\u0BAA\u0BA4\u0BCD\u0BA4\u0BC1 ",
|
|
108
|
+
"\u0BA8\u0BBE\u0BB1\u0BCD\u0BAA\u0BA4\u0BCD\u0BA4\u0BC1 ",
|
|
109
|
+
"\u0B90\u0BAE\u0BCD\u0BAA\u0BA4\u0BCD\u0BA4\u0BC1 ",
|
|
110
|
+
"\u0B85\u0BB1\u0BC1\u0BAA\u0BA4\u0BCD\u0BA4\u0BC1 ",
|
|
111
|
+
"\u0B8E\u0BB4\u0BC1\u0BAA\u0BA4\u0BCD\u0BA4\u0BC1 ",
|
|
112
|
+
"\u0B8E\u0BA3\u0BCD\u0BAA\u0BA4\u0BCD\u0BA4\u0BC1 ",
|
|
113
|
+
"\u0BA4\u0BCA\u0BA3\u0BCD\u0BA3\u0BC2\u0BB1\u0BCD\u0BB1\u0BC1 "
|
|
114
|
+
];
|
|
115
|
+
var TA_TENS_EXACT = [
|
|
116
|
+
"",
|
|
117
|
+
"",
|
|
118
|
+
"\u0B87\u0BB0\u0BC1\u0BAA\u0BA4\u0BC1",
|
|
119
|
+
"\u0BAE\u0BC1\u0BAA\u0BCD\u0BAA\u0BA4\u0BC1",
|
|
120
|
+
"\u0BA8\u0BBE\u0BB1\u0BCD\u0BAA\u0BA4\u0BC1",
|
|
121
|
+
"\u0B90\u0BAE\u0BCD\u0BAA\u0BA4\u0BC1",
|
|
122
|
+
"\u0B85\u0BB1\u0BC1\u0BAA\u0BA4\u0BC1",
|
|
123
|
+
"\u0B8E\u0BB4\u0BC1\u0BAA\u0BA4\u0BC1",
|
|
124
|
+
"\u0B8E\u0BA3\u0BCD\u0BAA\u0BA4\u0BC1",
|
|
125
|
+
"\u0BA4\u0BCA\u0BA3\u0BCD\u0BA3\u0BC2\u0BB1\u0BC1"
|
|
126
|
+
];
|
|
127
|
+
var TA_HUNDREDS = [
|
|
128
|
+
"",
|
|
129
|
+
"\u0BA8\u0BC2\u0BB1\u0BC1",
|
|
130
|
+
"\u0B87\u0BB0\u0BC1\u0BA8\u0BC2\u0BB1\u0BC1",
|
|
131
|
+
"\u0BAE\u0BC1\u0BA8\u0BCD\u0BA8\u0BC2\u0BB1\u0BC1",
|
|
132
|
+
"\u0BA8\u0BBE\u0BA9\u0BC2\u0BB1\u0BC1",
|
|
133
|
+
"\u0B90\u0BA8\u0BCD\u0BA8\u0BC2\u0BB1\u0BC1",
|
|
134
|
+
"\u0B85\u0BB1\u0BC1\u0BA8\u0BC2\u0BB1\u0BC1",
|
|
135
|
+
"\u0B8E\u0BB4\u0BC1\u0BA8\u0BC2\u0BB1\u0BC1",
|
|
136
|
+
"\u0B8E\u0BA3\u0BCD\u0BA3\u0BC2\u0BB1\u0BC1",
|
|
137
|
+
"\u0BA4\u0BCA\u0BB3\u0BCD\u0BB3\u0BBE\u0BAF\u0BBF\u0BB0\u0BAE\u0BCD"
|
|
138
|
+
];
|
|
139
|
+
function convertThreeDigitTamil(n) {
|
|
140
|
+
let str = "";
|
|
141
|
+
if (n >= 100) {
|
|
142
|
+
const h = Math.floor(n / 100);
|
|
143
|
+
n %= 100;
|
|
144
|
+
if (n === 0) {
|
|
145
|
+
str += TA_HUNDREDS[h] + " ";
|
|
146
|
+
} else {
|
|
147
|
+
const prefix = ["\u0BA8\u0BC2\u0BB1\u0BCD\u0BB1\u0BC1 ", "\u0B87\u0BB0\u0BC1\u0BA8\u0BC2\u0BB1\u0BCD\u0BB1\u0BC1 ", "\u0BAE\u0BC1\u0BA8\u0BCD\u0BA8\u0BC2\u0BB1\u0BCD\u0BB1\u0BC1 ", "\u0BA8\u0BBE\u0BA9\u0BC2\u0BB1\u0BCD\u0BB1\u0BC1 ", "\u0B90\u0BA8\u0BCD\u0BA8\u0BC2\u0BB1\u0BCD\u0BB1\u0BC1 ", "\u0B85\u0BB1\u0BC1\u0BA8\u0BC2\u0BB1\u0BCD\u0BB1\u0BC1 ", "\u0B8E\u0BB4\u0BC1\u0BA8\u0BC2\u0BB1\u0BCD\u0BB1\u0BC1 ", "\u0B8E\u0BA3\u0BCD\u0BA3\u0BC2\u0BB1\u0BCD\u0BB1\u0BC1 ", "\u0BA4\u0BCA\u0BB3\u0BCD\u0BB3\u0BBE\u0BAF\u0BBF\u0BB0\u0BA4\u0BCD\u0BA4\u0BC1 "];
|
|
148
|
+
str += prefix[h - 1];
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (n >= 20) {
|
|
152
|
+
const t = Math.floor(n / 10);
|
|
153
|
+
n %= 10;
|
|
154
|
+
if (n === 0) {
|
|
155
|
+
str += TA_TENS_EXACT[t] + " ";
|
|
156
|
+
} else {
|
|
157
|
+
str += TA_TENS_PREFIX[t];
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (n > 0) {
|
|
161
|
+
str += TA_ONES[n] + " ";
|
|
162
|
+
}
|
|
163
|
+
return str.trim();
|
|
164
|
+
}
|
|
165
|
+
function convertIntegerToTamilWords(num) {
|
|
166
|
+
if (num === 0) return "\u0BAA\u0BC2\u0B9C\u0BCD\u0B9C\u0BBF\u0BAF\u0BAE\u0BCD";
|
|
167
|
+
const parts = [];
|
|
168
|
+
const crores = Math.floor(num / 1e7);
|
|
169
|
+
num %= 1e7;
|
|
170
|
+
const lakhs = Math.floor(num / 1e5);
|
|
171
|
+
num %= 1e5;
|
|
172
|
+
const thousands = Math.floor(num / 1e3);
|
|
173
|
+
num %= 1e3;
|
|
174
|
+
const remaining = Math.floor(num);
|
|
175
|
+
if (crores > 0) {
|
|
176
|
+
const croreWords = crores >= 100 ? convertIntegerToTamilWords(crores) : convertThreeDigitTamil(crores);
|
|
177
|
+
parts.push(`${croreWords} \u0B95\u0BCB\u0B9F\u0BBF`);
|
|
178
|
+
}
|
|
179
|
+
if (lakhs > 0) {
|
|
180
|
+
parts.push(`${convertThreeDigitTamil(lakhs)} \u0B87\u0BB2\u0B9F\u0BCD\u0B9A\u0BAE\u0BCD`);
|
|
181
|
+
}
|
|
182
|
+
if (thousands > 0) {
|
|
183
|
+
parts.push(`${convertThreeDigitTamil(thousands)} \u0B86\u0BAF\u0BBF\u0BB0\u0BAE\u0BCD`);
|
|
184
|
+
}
|
|
185
|
+
if (remaining > 0) {
|
|
186
|
+
parts.push(convertThreeDigitTamil(remaining));
|
|
187
|
+
}
|
|
188
|
+
return parts.join(" ").trim();
|
|
189
|
+
}
|
|
190
|
+
function numberToIndianWords(amount, options = {}) {
|
|
191
|
+
const {
|
|
192
|
+
currency = true,
|
|
193
|
+
includePaise = true,
|
|
194
|
+
suffixOnly = true,
|
|
195
|
+
language = "en"
|
|
196
|
+
} = options;
|
|
197
|
+
if (isNaN(amount)) {
|
|
198
|
+
return language === "ta" ? "\u0B9A\u0BC6\u0BB2\u0BCD\u0BB2\u0BC1\u0BAA\u0B9F\u0BBF\u0BAF\u0BBE\u0B95\u0BBE\u0BA4 \u0B8E\u0BA3\u0BCD" : "Invalid Number";
|
|
199
|
+
}
|
|
200
|
+
const isNegative = amount < 0;
|
|
201
|
+
const absAmount = Math.abs(amount);
|
|
202
|
+
const integerPart = Math.floor(absAmount);
|
|
203
|
+
const decimalPart = Math.round((absAmount - integerPart) * 100);
|
|
204
|
+
if (language === "ta") {
|
|
205
|
+
let result2 = convertIntegerToTamilWords(integerPart);
|
|
206
|
+
if (currency) {
|
|
207
|
+
result2 += " \u0BB0\u0BC2\u0BAA\u0BBE\u0BAF\u0BCD";
|
|
208
|
+
}
|
|
209
|
+
if (includePaise && decimalPart > 0) {
|
|
210
|
+
const paiseWord = convertThreeDigitTamil(decimalPart);
|
|
211
|
+
result2 += ` ${paiseWord} \u0BAA\u0BC8\u0B9A\u0BBE`;
|
|
212
|
+
}
|
|
213
|
+
if (suffixOnly) {
|
|
214
|
+
result2 += " \u0BAE\u0B9F\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD";
|
|
215
|
+
}
|
|
216
|
+
return (isNegative ? "\u0BAE\u0BC8\u0BA9\u0BB8\u0BCD " : "") + result2.trim();
|
|
217
|
+
}
|
|
218
|
+
let result = convertIntegerToIndianWordsEn(integerPart);
|
|
219
|
+
if (currency) {
|
|
220
|
+
result += integerPart === 1 ? " Rupee" : " Rupees";
|
|
221
|
+
}
|
|
222
|
+
if (includePaise && decimalPart > 0) {
|
|
223
|
+
const paiseWord = convertThreeDigitEnglish(decimalPart);
|
|
224
|
+
result += ` and ${paiseWord} Paise`;
|
|
225
|
+
}
|
|
226
|
+
if (suffixOnly) {
|
|
227
|
+
result += " Only";
|
|
228
|
+
}
|
|
229
|
+
return (isNegative ? "Minus " : "") + result.trim();
|
|
230
|
+
}
|
|
231
|
+
function numberToTamilWords(amount, options = {}) {
|
|
232
|
+
return numberToIndianWords(amount, { ...options, language: "ta" });
|
|
233
|
+
}
|
|
234
|
+
function formatINR(amount, options = {}) {
|
|
235
|
+
const { symbol = true, decimals = 2 } = options;
|
|
236
|
+
const formatted = new Intl.NumberFormat("en-IN", {
|
|
237
|
+
minimumFractionDigits: decimals,
|
|
238
|
+
maximumFractionDigits: decimals
|
|
239
|
+
}).format(amount);
|
|
240
|
+
return symbol ? `\u20B9 ${formatted}` : formatted;
|
|
241
|
+
}
|
|
242
|
+
function calculateGST(baseAmount, gstRatePercent, isInterState = false) {
|
|
243
|
+
const totalTax = Number((baseAmount * gstRatePercent / 100).toFixed(2));
|
|
244
|
+
const totalAmount = Number((baseAmount + totalTax).toFixed(2));
|
|
245
|
+
let cgstAmount = 0;
|
|
246
|
+
let sgstAmount = 0;
|
|
247
|
+
let igstAmount = 0;
|
|
248
|
+
if (isInterState) {
|
|
249
|
+
igstAmount = totalTax;
|
|
250
|
+
} else {
|
|
251
|
+
cgstAmount = Number((totalTax / 2).toFixed(2));
|
|
252
|
+
sgstAmount = Number((totalTax / 2).toFixed(2));
|
|
253
|
+
}
|
|
254
|
+
return {
|
|
255
|
+
baseAmount,
|
|
256
|
+
gstRate: gstRatePercent,
|
|
257
|
+
isInterState,
|
|
258
|
+
cgstAmount,
|
|
259
|
+
sgstAmount,
|
|
260
|
+
igstAmount,
|
|
261
|
+
totalTax,
|
|
262
|
+
totalAmount,
|
|
263
|
+
totalInWords: numberToIndianWords(totalAmount)
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
export {
|
|
267
|
+
calculateGST,
|
|
268
|
+
formatINR,
|
|
269
|
+
numberToIndianWords,
|
|
270
|
+
numberToTamilWords
|
|
271
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,55 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "inr-num-words",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Converts numbers and Indian Rupee (INR) amounts into words (English & Tamil) with Lakhs, Crores, Paise, and Invoice/Cheque formatting.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"README.md",
|
|
24
|
+
"LICENSE"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"test:watch": "vitest",
|
|
30
|
+
"prepublishOnly": "npm run build && npm test"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"inr",
|
|
34
|
+
"indian-rupee",
|
|
35
|
+
"number-to-words",
|
|
36
|
+
"numbers-to-words",
|
|
37
|
+
"currency",
|
|
38
|
+
"cheque",
|
|
39
|
+
"invoice",
|
|
40
|
+
"billing",
|
|
41
|
+
"lakh",
|
|
42
|
+
"crore",
|
|
43
|
+
"tamil",
|
|
44
|
+
"finance",
|
|
45
|
+
"typescript"
|
|
46
|
+
],
|
|
47
|
+
"author": "Pirapaakaran Pirathapan <pirapaakaranpirathapan@gmail.com>",
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/node": "^22.13.0",
|
|
51
|
+
"tsup": "^8.3.6",
|
|
52
|
+
"typescript": "^5.7.3",
|
|
53
|
+
"vitest": "^3.0.5"
|
|
54
|
+
}
|
|
55
|
+
}
|