@opengis/fastify-table
Version:
core-plugins
332 lines (331 loc) • 12 kB
JavaScript
/* eslint-disable prefer-destructuring */
function saveEval(jsCode, context = {}) {
// TODO eval
const addcontext = Object.keys(context)
.map((key) => `let ${key}=context["${key}"];`)
.join("");
// eslint-disable-next-line no-eval
return eval(addcontext + jsCode);
}
const mapNumbers = {
ua: {
0: [2, 1, "нуль"],
1: [0, 2, "одна", "один"],
2: [1, 2, "дві", "два", "дві"],
3: [1, 1, "три"],
4: [1, 1, "чотири"],
5: [2, 1, "п'ять"],
6: [2, 1, "шість"],
7: [2, 1, "сім"],
8: [2, 1, "вісім"],
9: [2, 1, "дев'ять"],
10: [2, 1, "десять"],
11: [2, 1, "одинадцять"],
12: [2, 1, "дванадцять"],
13: [2, 1, "тринадцять"],
14: [2, 1, "чотирнадцять"],
15: [2, 1, "п'ятнадцять"],
16: [2, 1, "шістнадцять"],
17: [2, 1, "сімнадцять"],
18: [2, 1, "вісімнадцять"],
19: [2, 1, "дев'ятнадцять"],
20: [2, 1, "двадцять"],
30: [2, 1, "тридцять"],
40: [2, 1, "сорок"],
50: [2, 1, "п'ятдесят"],
60: [2, 1, "шістдесят"],
70: [2, 1, "сімдесят"],
80: [2, 1, "вісімдесят"],
90: [2, 1, "дев'яносто"],
100: [2, 1, "сто"],
200: [2, 1, "двісті"],
300: [2, 1, "триста"],
400: [2, 1, "чотириста"],
500: [2, 1, "п'ятсот"],
600: [2, 1, "шістсот"],
700: [2, 1, "сімсот"],
800: [2, 1, "вісімсот"],
900: [2, 1, "дев'ятсот"],
},
ru: {
0: [2, 1, "ноль"],
1: [0, 2, "одна", "один"],
2: [1, 2, "две", "два", "две"],
3: [1, 1, "три"],
4: [1, 1, "четыре"],
5: [2, 1, "пять"],
6: [2, 1, "шесть"],
7: [2, 1, "семь"],
8: [2, 1, "восемь"],
9: [2, 1, "девять"],
10: [2, 1, "десять"],
11: [2, 1, "одинадцать"],
12: [2, 1, "двенадцать"],
13: [2, 1, "тринадцать"],
14: [2, 1, "четырнадцать"],
15: [2, 1, "пятнадцать"],
16: [2, 1, "шестнадцать"],
17: [2, 1, "семнадцать"],
18: [2, 1, "восемнадцать"],
19: [2, 1, "девятнадцать"],
20: [2, 1, "двадцать"],
30: [2, 1, "тридцать"],
40: [2, 1, "сорок"],
50: [2, 1, "пятьдесят"],
60: [2, 1, "шестьдесят"],
70: [2, 1, "семьдесят"],
80: [2, 1, "восемьдесят"],
90: [2, 1, "девяносто"],
100: [2, 1, "сто"],
200: [2, 1, "двести"],
300: [2, 1, "триста"],
400: [2, 1, "четыреста"],
500: [2, 1, "пятьсот"],
600: [2, 1, "шестьсот"],
700: [2, 1, "семьсот"],
800: [2, 1, "восемьсот"],
900: [2, 1, "девятьсот"],
},
};
const mapOrders = {
ua: [
{ Gender: true, arrStates: ["", "", ""] },
{ Gender: true, arrStates: ["тисяча", "тисячі", "тисяч"] },
{ Gender: false, arrStates: ["мільйон", "мільйона", "мільйонів"] },
{ Gender: false, arrStates: ["мільярд", "мільярда", "мільярдів"] },
{ Gender: false, arrStates: ["триліон", "триліона", "триліонів"] },
{
Gender: true,
arrStates: {
uah: ["грн.", "грн.", "грн."],
rur: ["руб.", "руб.", "руб."],
},
bAddZeroWord: true,
},
{
Gender: true,
arrStates: ["ціла", "цілих", "цілих"],
bAddZeroWord: true,
},
{ Gender: true, arrStates: ["", "", ""], bAddZeroWord: true },
{
Gender: true,
arrStates: ["дол.", "дол.", "дол."],
bAddZeroWord: true,
},
{
Gender: true,
arrStates: ["грн.", "грн.", "грн."],
bAddZeroWord: true,
},
],
ru: [
{ Gender: true, arrStates: ["", "", ""] },
{ Gender: true, arrStates: ["тысяча", "тысячи", "тысяч"] },
{ Gender: false, arrStates: ["миллион", "миллиона", "миллионов"] },
{ Gender: false, arrStates: ["миллиард", "миллиарда", "миллиардов"] },
{ Gender: false, arrStates: ["триллион", "триллиона", "триллионов"] },
{
Gender: true,
arrStates: {
uah: ["грн.", "грн.", "грн."],
rur: ["руб.", "руб.", "руб."],
usd: ["дол.", "дол.", "дол."],
},
bAddZeroWord: true,
},
{
Gender: true,
arrStates: ["целых", "целых", "целых"],
bAddZeroWord: true,
},
{ Gender: true, arrStates: ["", "", ""], bAddZeroWord: true },
{
Gender: true,
arrStates: ["дол.", "дол.", "дол."],
bAddZeroWord: true,
},
],
};
const objCur = {
Gender: false,
arrStates: {
uah: ["грн.", "грн.", "грн."],
rur: ["руб.", "руб.", "руб."],
usd: ["дол.", "дол.", "дол."],
num: { ru: "цел.", ua: "ціл.", en: "int." },
},
};
const objCoin = {
Gender: false,
arrStates: {
uah: "коп.",
rur: "коп.",
usd: "цен.",
num: { ru: "сот.", ua: "сот.", en: "hund." },
},
};
// функции которые отвечают за форматирование
/**
* Formatting from number to string
*
* @example
* // returns 'дві'
* value(2, true, 'ua');
* @example
* // returns 'два'
* value(2, false, 'ua');
* @param {Number} dVal
* @param {Any} bGender
* @param {String} lang
* @returns {String} Returns a formatted string
*/
function value(dVal, bGender, lang) {
const dValNew = dVal || 0;
const xVal = mapNumbers[lang][dValNew];
if (xVal[1] === 1) {
return xVal[2];
}
return xVal[2 + (bGender ? 0 : 1)];
}
/**
* Add a number to array(arrRet) in capital form
*
* @example
* // returns null
* from0To999(arrRet, 404,
* oObjDesc:
* {
* Gender: true,
* bAddZeroWord: undefined,
* arrStates: ['','',''],
* },
* lang: 'ru'
* })
* @param {Array} arrRet
* @param {Number} fValue
* @param {Object} [oObjDesc.Gender]
* @param {Object} [oObjDesc.bAddZeroWord]
* @param {Object} [oObjDesc.arrStates]
* @param oObjDesc
* @param {String} lang
*/
function from0To999(arrRet, fValue, oObjDesc, lang) {
let fValueNew = fValue || 0;
let nCurrState = 2;
if (Math.floor(fValueNew / 100) > 0) {
const fCurr = Math.floor(fValueNew / 100) * 100;
arrRet.push(value(fCurr, oObjDesc.Gender, lang));
nCurrState = mapNumbers[lang][fCurr][0];
fValueNew -= fCurr;
}
if (fValueNew === 0) {
arrRet.push(value(fValueNew, oObjDesc.Gender, lang));
nCurrState = mapNumbers[lang][fValueNew][0];
}
else if (fValueNew < 20) {
if (Math.floor(fValueNew) > 0 || oObjDesc.bAddZeroWord) {
arrRet.push(value(fValueNew, oObjDesc.Gender, lang));
nCurrState = mapNumbers[lang][fValueNew][0];
}
}
else {
const fCurr = Math.floor(fValueNew / 10) * 10;
arrRet.push(value(fCurr, oObjDesc.Gender, lang));
nCurrState = mapNumbers[lang][fCurr][0];
fValueNew -= fCurr;
if (Math.floor(fValueNew) > 0) {
arrRet.push(value(fValueNew, oObjDesc.Gender, lang));
nCurrState = mapNumbers[lang][fValueNew][0];
}
}
arrRet.push(oObjDesc.arrStates[nCurrState]);
}
/**
* Formatting from number to string
*
* @example
* // returns '404 (четыреста четыре) руб. 101 (сто одна) коп.'
* floatToSamplesInWordsUkr(404.1011001001, '%d (%dt) %curr %f (%ft) %coin', 3, 'ru', 'rur');
* @returns {String|Number} fAmount
* @param {String} resultStr
* @param {Number} exp
* @param {String} lang
* @param {String} currency
* @returns {String} Returns a formatted string
*/
function floatToSamplesInWordsUkr(fAmount, resultStr, exp, lang, currency) {
let resultStrNew = resultStr;
let fInt = Math.floor(parseInt(fAmount, 10) + 0.005); // ціла частина
const fDec = Math.floor((fAmount - fInt) * exp + 0.5); // дробова частина
let arrRet = [];
const arrSouthands = [];
for (; fInt > 0.9999; fInt /= 1000) {
arrSouthands.push(Math.floor(fInt % 1000));
}
if (arrSouthands.length === 0) {
arrSouthands.push(0);
}
for (let iSouth = arrSouthands.length - 1; iSouth >= 0; iSouth -= 1) {
from0To999(arrRet, arrSouthands[iSouth], mapOrders[lang][iSouth], lang);
}
// опрацювуЇмо формат
resultStrNew = resultStrNew.replace(/%dt/, arrRet.join(" ").replace(" )", ")").trim());
resultStrNew = resultStrNew.replace(/%d/, Math.floor(parseInt(fAmount, 10) + 0.005));
if (currency !== "num" && objCur.arrStates[currency]) {
resultStrNew = resultStrNew.replace(/%curr/, objCur.arrStates[currency][0]);
}
else {
resultStrNew = resultStrNew.replace(/%curr/, objCur.arrStates[lang === "ru" ? "rur" : lang][0]);
}
arrRet = [];
from0To999(arrRet, fDec, mapOrders[lang][0], lang);
resultStrNew = resultStrNew.replace(/%ft/, arrRet.join(" ").replace(" )", ")").trim());
resultStrNew = resultStrNew.replace(/%f/, fDec);
if (currency !== "num" && objCur.arrStates[currency]) {
resultStrNew = resultStrNew.replace(/%coin/, objCoin.arrStates[currency]);
}
else {
resultStrNew = resultStrNew.replace(/%coin/, objCoin.arrStates[lang === "ru" ? "rur" : lang]);
}
return resultStrNew;
}
/**
* Formatting from number to string
*
* @summary Formatting from number to string
* @priority 0
* @deprecated true
* @type helper
* @alias formatNum
* @param {Number} round Округлення
* @param {String} currency Валюта
* @param {String} lang Мова на якій видати інформацію
* @param {String} format Шаблон вигляду результату
* @param {String|Number} data Число для форматування
* @returns {String} Returns HTML
*/
export default function formatNum(data, options = {}) {
let name = data;
if (!name) {
name = 0;
} // в случае значения NULL
if (typeof name === "string" && !name.match(/^[a-zA-Z0-9.]+$/g)) {
let exec = name;
exec = exec.replace(/([a-zA-Z_.]{3,100}[0-9]*)/g, "options.data.root.$1");
name = saveEval(exec);
name = name ? parseFloat(name) : 0;
if (options.hash?.round) {
name = name.toFixed(options.hash.round);
}
}
const opt = options.hash; // додатков≥ опц≥њ
const currency = opt.currency || "uah";
const lang = opt.lang || "ua";
// if(['ru','ua'].indexOf(lang)==-1)
// lang=(['ru','ua'].indexOf(window.lang)>-1?window.lang:'ua');
const round = opt.round || 2;
const exp = 10 ** round; // к≥льк≥сть знак≥в псл¤ коми
const resultStr = opt.format || "%d (%dt) %curr %f (%ft) %coin";
return floatToSamplesInWordsUkr(name, resultStr, exp, lang, currency);
}