@jackiemacklein/nettz-utils
Version:
Serviços de imagem, e-mail, códigos de barras, utilitários numéricos e componentes React para apps Node.js com TypeScript
73 lines (72 loc) • 2.78 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.toInteger = toInteger;
exports.fromInteger = fromInteger;
/**
* Utilidades numéricas — salva tudo como inteiro (centavos, gramas, etc.)
* Escala padrão = 2 (dinheiro). Use 3 para miligramas/gramas, etc.
* Aceita:
* • vírgula ou ponto como separador decimal
* • qualquer combinação de separadores de milhar
* • sinal “-” ou parênteses contábeis para negativos
*
* Ex.: toInteger("1.100.098,90") → 110009890
* fromInteger(110009890, 2, "pt-BR", "BRL") → "R$ 1.100.098,90"
*/
function toInteger(raw, scale = 2 // 2 = centavos, 3 = milésimos
) {
if (raw == null || raw === "")
return 0;
const factor = 10 ** scale;
/* ---------- NUMERIC ALREADY ---------- */
if (typeof raw === "number") {
// evita ponto-flutuante multiplicando + arredondando
return Math.round(raw * factor);
}
/* ---------- STRING TRATAMENTO ---------- */
let txt = String(raw)
.trim()
.replace(/\u00A0|\s/g, ""); // remove espaços e
// guarda se é negativo via "-" ou parênteses
const isNegative = /^-|\(/.test(txt);
// remove tudo que não for dígito, vírgula ou ponto
txt = txt.replace(/[^\d.,]/g, "");
// encontra o separador decimal (último . ou ,)
const lastDot = txt.lastIndexOf(".");
const lastComma = txt.lastIndexOf(",");
const decPos = Math.max(lastDot, lastComma); // -1 se não existir
let intPart = txt;
let decPart = "";
if (decPos !== -1) {
intPart = txt.slice(0, decPos);
decPart = txt.slice(decPos + 1);
}
// remove separadores de milhar restantes
intPart = intPart.replace(/[.,]/g, "");
decPart = decPart.replace(/[^\d]/g, ""); // só dígitos
// ajusta decPart ao tamanho desejado
decPart = decPart.slice(0, scale).padEnd(scale, "0");
const combined = (intPart || "0") + decPart;
const result = parseInt(combined, 10);
return isNegative ? -result : result;
}
/**
* Converte inteiro de volta para string formatada.
*
* @param value Inteiro salvo (ex.: centavos)
* @param scale Casas decimais que o inteiro representa
* @param locale Locale p/ Intl (default "pt-BR")
* @param currency Se quiser formato monetário, passe "BRL", "USD", etc.
*/
function fromInteger(value, scale = 2, locale = "pt-BR", currency) {
const sign = value < 0 ? "-" : "";
const factor = 10 ** scale;
const abs = Math.abs(value) / factor;
const opts = {
minimumFractionDigits: scale,
maximumFractionDigits: scale,
};
if (currency)
Object.assign(opts, { style: "currency", currency });
return sign + new Intl.NumberFormat(locale, opts).format(abs);
}