UNPKG

@potchangelo/money-to-thai-word

Version:

Convert money in currency Baht and Satang to Thai word (Thai or English locale).

181 lines (162 loc) 5.31 kB
const { getBahtAndSatang } = require('./shared'); /** * Convert base 10, 100, 1000, 10000, 100000 to word. * @param {10|100|1000|10000|100000} base Number in 10, 100, ..., 100000. */ function baseToWord(base) { if (base === 1e5) return 'แสน'; if (base === 1e4) return 'หมื่น'; if (base === 1e3) return 'พัน'; if (base === 1e2) return 'ร้อย'; if (base === 1e1) return 'สิบ'; return ''; } /** * Convert front number and its base number to word. * @param {number} front Integer number between 1-9. * @param {1|10|100|1000|10000|100000} base Number in 1, 10, ..., 100000. * @param {boolean} [hasTen=false] Is x (this front number) behind ten-order number like 1x, 2x * @example * frontAndBaseToWord(2, 10) * // "ยี่" + "สิบ" * @example * frontAndBaseToWord(7, 100) * // "เจ็ด" + "ร้อย" * @example * frontAndBaseToWord(5) * // "ห้า" */ function frontAndBaseToWord(front, base, hasTen = false) { let frontWord = ''; if (base === 1e1 && front === 2) { frontWord = 'ยี่'; } else if (base === 1e1 && front === 1) { frontWord = ''; } else if (base === 1 && front === 1 && hasTen) { frontWord = 'เอ็ด'; } else { if (front === 9) frontWord = 'เก้า'; if (front === 8) frontWord = 'แปด'; if (front === 7) frontWord = 'เจ็ด'; if (front === 6) frontWord = 'หก'; if (front === 5) frontWord = 'ห้า'; if (front === 4) frontWord = 'สี่'; if (front === 3) frontWord = 'สาม'; if (front === 2) frontWord = 'สอง'; if (front === 1) frontWord = 'หนึ่ง'; } return frontWord + baseToWord(base); } /** * Convert number (1-999999) to word. * @param {number} n Integer number between 1-999999. * @example * numberToWord(357) * // "สามร้อยห้าสิบเจ็ด" * @example * numberToWord(51215) * // "ห้าหมื่นหนึ่งพันสองร้อยสิบห้า" */ function numberToWord(n) { if (n < 1 || n > 999999) return ''; let word = ''; let nClone = n; let hasTen = false; for (let j = `${n}`.length - 1; j >= 0; j--) { const base = 10 ** j; const dividedMoney = nClone / base; if (dividedMoney >= 1) { const front = Math.floor(dividedMoney); const moneyWord = frontAndBaseToWord(front, base, hasTen); word += moneyWord; nClone %= base; hasTen = base === 1e1; } } return word; } /** * Convert baht to ordered sub-bahts (Array of numbers between 0-999999). * @param {number} baht Integer baht value. * @example * bahtToSubBahts(10200300) * // [10, 200300] */ function bahtToSubBahts(baht) { // Empty array for zero baht if (baht === 0) return []; // Slice baht string to sub-bahts (6 digits) array const bahtString = `${baht}`; const subBahts = []; const subBathsCount = Math.ceil(bahtString.length / 6); for (let i = 1; i <= Math.min(subBathsCount, 6); i++) { let subBaht = ''; if (i === 1) { subBaht = bahtString.slice(-6 * i); } else { subBaht = bahtString.slice(-6 * i, -6 * (i - 1)); } if (subBaht === '') break; subBahts.unshift(+subBaht); } return subBahts; } /** * Convert sub-bahts to word. * @param {number[]} subBahts Array of integer numbers between 0-999999. * @example * subBahtToWord([10, 200300]) * // "สิบล้าน" + "สอนแสนสามร้อย" + "บาท" */ function subBahtToWord(subBahts) { // Empty string for zero baht if (subBahts.length === 0) return ''; // Convert each ordered sub-bahts to word const word = subBahts.reduce((prevWord, subBaht, index) => { let currentWord = numberToWord(subBaht); if (index !== subBahts.length - 1) { currentWord += 'ล้าน'; } return prevWord + currentWord; }, ''); return word + 'บาท'; } /** * Convert satang to word. * @param {number} satang Integer satang value between 1-99. * @example * satangToWord(75); * // "เจ็ดสิบห้า" + "สตางค์" */ function satangToWord(satang) { return satang > 0 ? numberToWord(satang) + 'สตางค์' : ''; } /** * @typedef {object} ThaiWordOptions * @property {boolean} showActual */ /** * @type ThaiWordOptions */ const defaultOptions = { showActual: true, }; /** * Convert money (number) to Thai word (string). * @param {number} money Input money. * @param {ThaiWordOptions} [options] Optional configurations. */ function moneyToThaiWord(money, options = {}) { let { showActual } = { ...defaultOptions, ...options }; // Lt. zero or mte. quintillion cases if (money < 0 || money >= 1e18) return ''; let { baht, satang } = getBahtAndSatang(money); // Zero case if (baht === 0 && satang === 0) return `ศูนย์บาท${showActual ? 'ถ้วน' : ''}`; // Build baht and satang word let word = subBahtToWord(bahtToSubBahts(baht)); word += satangToWord(satang); word += satang === 0 && showActual ? 'ถ้วน' : ''; return word; } module.exports = moneyToThaiWord;