thb-text
Version:
Thai Baht Text converter - converts numbers to Thai text representation for currency amounts
268 lines (267 loc) • 9.68 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ThaiBahtTextUtil = exports.Unit = void 0;
exports.thaiBahtText = thaiBahtText;
exports.registerNumberPrototype = registerNumberPrototype;
var Unit;
(function (Unit) {
Unit[Unit["Baht"] = 0] = "Baht";
Unit[Unit["Million"] = 1] = "Million";
Unit[Unit["Billion"] = 2] = "Billion";
Unit[Unit["Trillion"] = 3] = "Trillion";
})(Unit || (exports.Unit = Unit = {}));
class ThaiBahtTextUtil {
static thaiBahtText(amount, optionsOrUnit, decimalPlaces = 2, appendBahtOnly = true) {
const actualAmount = amount ?? 0;
let actualUnit;
let actualDecimalPlaces;
let actualAppendBahtOnly;
if (typeof optionsOrUnit === 'object' && optionsOrUnit !== null) {
actualUnit = optionsOrUnit.unit ?? Unit.Baht;
actualDecimalPlaces = optionsOrUnit.decimalPlaces ?? 2;
actualAppendBahtOnly = optionsOrUnit.appendBahtOnly ?? true;
}
else {
actualUnit = optionsOrUnit ?? Unit.Baht;
actualDecimalPlaces = decimalPlaces;
actualAppendBahtOnly = appendBahtOnly;
}
if (actualAmount === 0) {
let result = "";
switch (actualUnit) {
case Unit.Baht:
result = "ศูนย์บาท";
break;
case Unit.Million:
result = "ศูนย์ล้านบาท";
break;
case Unit.Billion:
result = "ศูนย์พันล้านบาท";
break;
case Unit.Trillion:
result = "ศูนย์ล้านล้านบาท";
break;
}
if (actualAppendBahtOnly) {
result += this.THAI_ONLY;
}
return result;
}
const isBaht = actualUnit === Unit.Baht;
let processedAmount = actualAmount;
if (!isBaht) {
switch (actualUnit) {
case Unit.Million:
processedAmount /= 1000000;
break;
case Unit.Billion:
processedAmount /= 1000000000;
break;
case Unit.Trillion:
processedAmount /= 1000000000000;
break;
}
switch (actualDecimalPlaces) {
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
default:
actualDecimalPlaces = 2;
break;
}
}
else {
actualDecimalPlaces = 2;
}
// Round away from zero like .NET MidpointRounding.AwayFromZero
const multiplier = Math.pow(10, actualDecimalPlaces);
processedAmount = processedAmount >= 0
? Math.floor(processedAmount * multiplier + 0.5) / multiplier
: Math.ceil(processedAmount * multiplier - 0.5) / multiplier;
if (processedAmount < this.MIN_VALUE || processedAmount > this.MAX_VALUE) {
throw new Error("Amount out of supported range");
}
let result = "";
if (processedAmount < 0) {
result += this.THAI_NEGATION;
processedAmount = -processedAmount;
}
const text = processedAmount.toFixed(actualDecimalPlaces);
const parts = this.decompose(text);
if (parts[0].length > 0) {
result += this.speakTo(parts[0]);
result += this.THAI_MILLION;
}
if (parts[1].length > 0) {
result += this.speakTo(parts[1]);
result += this.THAI_MILLION;
}
if (parts[2].length > 0) {
result += this.speakTo(parts[2]);
if (isBaht)
result += this.THAI_BAHT;
}
else if (parts[1].length > 0) {
if (isBaht)
result += this.THAI_BAHT;
}
if (parts[3].length > 0) {
if (isBaht) {
result += this.speakTo(parts[3]);
result += this.THAI_SATANG;
}
else {
if (parseInt(parts[3]) !== 0) {
result += this.speakDotTo(parts[3]);
}
switch (actualUnit) {
case Unit.Million:
result += "ล้านบาท";
break;
case Unit.Billion:
result += "พันล้านบาท";
break;
case Unit.Trillion:
result += "ล้านล้านบาท";
break;
}
}
}
else {
if (!isBaht) {
switch (actualUnit) {
case Unit.Million:
result += "ล้านบาท";
break;
case Unit.Billion:
result += "พันล้านบาท";
break;
case Unit.Trillion:
result += "ล้านล้านบาท";
break;
}
}
if (actualAppendBahtOnly) {
result += this.THAI_ONLY;
}
}
return result;
}
static decompose(text) {
let s1 = "";
let s2 = "";
let s3;
let s4;
const position = text.indexOf(".");
s3 = text.substring(0, position);
s4 = text.substring(position + 1);
if (s4 === "00") {
s4 = "";
}
let length = s3.length;
if (length > 6) {
s2 = s3.substring(0, length - 6);
s3 = s3.substring(length - 6);
}
length = s2.length;
if (length > 6) {
s1 = s2.substring(0, length - 6);
s2 = s2.substring(length - 6);
}
if (s3.length > 0 && parseInt(s3) === 0) {
s3 = "";
}
return [s1, s2, s3, s4];
}
static speakDotTo(text) {
let result = this.THAI_PERIOD;
// Remove trailing zeros but keep internal zeros
let trimmedText = text.replace(/0+$/, '');
if (trimmedText === '') {
trimmedText = '0';
}
for (let i = 0; i < trimmedText.length; i++) {
const c = parseInt(trimmedText[i]);
result += this.thaiNumbers[c];
}
return result;
}
static speakTo(text) {
const length = text.length;
let result = "";
let lastc = -1;
let negative = false;
for (let i = 0; i < length; i++) {
if (text[i] === "-") {
negative = true;
}
else {
const c = parseInt(text[i]);
if (i === length - 1 && c === 1) {
if (length === 1 ||
(negative && length === 2) ||
(length === 2 && lastc === 0)) {
result += this.THAI_ONE;
return result;
}
// Use TensOnly logic: only use เอ็ด for tens place
if (lastc === 0) {
result += this.THAI_ONE;
}
else {
result += this.THAI_ET;
}
}
else if (i === length - 2 && c === 2) {
result += this.THAI_TWENTY;
}
else if (i === length - 2 && c === 1) {
result += this.THAI_TEN;
}
else if (c !== 0) {
result += this.thaiNumbers[c] + this.thaiPlaces[length - i];
}
lastc = c;
}
}
return result;
}
}
exports.ThaiBahtTextUtil = ThaiBahtTextUtil;
ThaiBahtTextUtil.MAX_VALUE = 999999999999.99;
ThaiBahtTextUtil.MIN_VALUE = -999999999999.99;
ThaiBahtTextUtil.THAI_MILLION = "ล้าน";
ThaiBahtTextUtil.THAI_BAHT = "บาท";
ThaiBahtTextUtil.THAI_SATANG = "สตางค์";
ThaiBahtTextUtil.THAI_ONE = "หนึ่ง";
ThaiBahtTextUtil.THAI_ET = "เอ็ด";
ThaiBahtTextUtil.THAI_NEGATION = "ลบ";
ThaiBahtTextUtil.THAI_TEN = "สิบ";
ThaiBahtTextUtil.THAI_TWENTY = "ยี่สิบ";
ThaiBahtTextUtil.THAI_PERIOD = "จุด";
ThaiBahtTextUtil.THAI_ONLY = "ถ้วน";
ThaiBahtTextUtil.thaiPlaces = [
"", "", "สิบ", "ร้อย", "พัน", "หมื่น", "แสน", "ล้าน"
];
ThaiBahtTextUtil.thaiNumbers = [
"ศูนย์", "หนึ่ง", "สอง", "สาม", "สี่", "ห้า", "หก", "เจ็ด", "แปด", "เก้า"
];
function thaiBahtText(amount, optionsOrUnit, decimalPlaces, appendBahtOnly) {
return ThaiBahtTextUtil.thaiBahtText(amount, optionsOrUnit, decimalPlaces, appendBahtOnly);
}
function registerNumberPrototype() {
Number.prototype.thaiBahtText = function (optionsOrUnit, decimalPlaces, appendBahtOnly) {
return ThaiBahtTextUtil.thaiBahtText(this, optionsOrUnit, decimalPlaces, appendBahtOnly);
};
}