UNPKG

thb-text

Version:

Thai Baht Text converter - converts numbers to Thai text representation for currency amounts

268 lines (267 loc) 9.68 kB
"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); }; }