diff --git a/src/index.html b/src/index.html
index b0aa3d9..0e4386e 100644
--- a/src/index.html
+++ b/src/index.html
@@ -577,21 +577,23 @@ let estado = {
// ─── Helpers ──────────────────────────────────────────────────────────────
const fmt = v => 'R$ ' + (parseFloat(v) || 0).toLocaleString('pt-BR', { minimumFractionDigits: 2 });
const parseNum = v => {
- const s = String(v || '0');
- // Handle empty or whitespace
- if (!s.trim()) return 0;
+ // Already a number? Return directly (don't treat '.' as thousand separator)
+ if (typeof v === 'number') return isNaN(v) ? 0 : v;
+ const s = String(v || '0').trim();
+ if (!s) return 0;
// Brazilian format: 1.234,56 → 1234.56
- // Strategy: remove thousand dots, replace decimal comma with dot
- // "10,55" → "1055,00" (wrong) → fix: split on comma first
- // "1.055,00" → parts=["1.055","00"] → intPart="1055", decPart="00" → 1055.00
+ // Strategy: if string has comma, treat as BRL (decimal comma)
+ // If no comma but has dot, treat as US (decimal dot)
const lastComma = s.lastIndexOf(',');
- if (lastComma === -1) {
- // No comma: just remove thousand separators (dots)
- return parseFloat(s.replace(/,/g, '').replace(/\./g, '')) || 0;
+ const lastDot = s.lastIndexOf('.');
+ const hasCommaDecimal = lastComma > lastDot;
+ if (hasCommaDecimal) {
+ const intPart = s.slice(0, lastComma).replace(/\./g, '').replace(/,/g, '');
+ const decPart = s.slice(lastComma + 1);
+ return parseFloat(intPart + '.' + decPart) || 0;
}
- const intPart = s.slice(0, lastComma).replace(/\./g, '').replace(/,/g, '');
- const decPart = s.slice(lastComma + 1);
- return parseFloat(intPart + '.' + decPart) || 0;
+ // No comma: US-style number, just strip any dots (thousand sep)
+ return parseFloat(s.replace(/,/g, '').replace(/\./g, '')) || 0;
};
const setText = (id, t) => { const e = document.getElementById(id); if (e) e.textContent = t; };
const setVal = (id, v) => { const e = document.getElementById(id); if (e) e.value = v; };
@@ -773,7 +775,7 @@ document.querySelectorAll('.add-btn[data-tbl]').forEach(btn => {
// ─── Totals ────────────────────────────────────────────────────────────────
function updateTotals() {
// ── Sangrias ──
- const sangriasTotal = estado.sangrias.reduce((s, r) => s + (parseFloat(r['retirada'] || 0) || 0), 0);
+ const sangriasTotal = estado.sangrias.reduce((s, r) => s + (parseNum(r['retirada'] || 0) || 0), 0);
setText('total-sangrias', fmt(sangriasTotal));
// ── Tabelas de valor ──
@@ -782,7 +784,7 @@ function updateTotals() {
'tbl-receber':'receber', 'tbl-cancelamentos':'cancelamentos',
};
Object.entries(map).forEach(([tblId, fieldName]) => {
- const total = estado[fieldName].reduce((s, r) => s + (parseFloat(r['valor'] || 0) || 0), 0);
+ const total = estado[fieldName].reduce((s, r) => s + (parseNum(r['valor'] || 0) || 0), 0);
setText(tblId.replace('tbl-','total-'), fmt(total));
});
@@ -808,13 +810,13 @@ function updateTotals() {
// Alimentação = total cartão alimentação
document.getElementById('sys-alimentacao').value = cartAli > 0 ? fmtNum(cartAli) : '';
// PIX = total cartão PIX + total PIX CNPJ
- const pixCnpjTotal = estado.pixcnpj.reduce((s, r) => s + (parseFloat(r['valor'] || 0) || 0), 0);
+ const pixCnpjTotal = estado.pixcnpj.reduce((s, r) => s + (parseNum(r['valor'] || 0) || 0), 0);
document.getElementById('sys-pix').value = (cartPix + pixCnpjTotal) > 0 ? fmtNum(cartPix + pixCnpjTotal) : '';
// Vales = total vales
- const valesTotal = estado.vales.reduce((s, r) => s + (parseFloat(r['valor'] || 0) || 0), 0);
+ const valesTotal = estado.vales.reduce((s, r) => s + (parseNum(r['valor'] || 0) || 0), 0);
document.getElementById('sys-vales').value = valesTotal > 0 ? fmtNum(valesTotal) : '';
// À Receber = total receber
- const receberTotal = estado.receber.reduce((s, r) => s + (parseFloat(r['valor'] || 0) || 0), 0);
+ const receberTotal = estado.receber.reduce((s, r) => s + (parseNum(r['valor'] || 0) || 0), 0);
document.getElementById('sys-receber').value = receberTotal > 0 ? fmtNum(receberTotal) : '';
// SYS total
@@ -1175,11 +1177,11 @@ function openConfirmModal() {
const cartDeb = estado.cartoes.debito.reduce((s,r) => s+(r.valor||0), 0);
const cartAli = estado.cartoes.alimentacao.reduce((s,r) => s+(r.valor||0), 0);
const cartPix = estado.cartoes.pix.reduce((s,r) => s+(r.valor||0), 0);
- const sangrias = estado.sangrias.reduce((s,r) => s+(parseFloat(r.retirada||0)||0), 0);
- const despesas = estado.despesas.reduce((s,r) => s+(r.valor||0), 0);
- const vales = estado.vales.reduce((s,r) => s+(r.valor||0), 0);
- const receber = estado.receber.reduce((s,r) => s+(r.valor||0), 0);
- const cancelamentos = estado.cancelamentos.reduce((s,r) => s+(r.valor||0), 0);
+ const sangrias = estado.sangrias.reduce((s,r) => s+(parseNum(r.retirada||0)||0), 0);
+ const despesas = estado.despesas.reduce((s,r) => s+(parseNum(r.valor||0)||0), 0);
+ const vales = estado.vales.reduce((s,r) => s+(parseNum(r.valor||0)||0), 0);
+ const receber = estado.receber.reduce((s,r) => s+(parseNum(r.valor||0)||0), 0);
+ const cancelamentos = estado.cancelamentos.reduce((s,r) => s+(parseNum(r.valor||0)||0), 0);
const fechamento = parseNum(val('f-fech-dinheiro')) + parseNum(val('f-fech-cartoes')) + parseNum(val('f-fech-receber'));
const saldoEsp = parseNum(val('f-saldo-esperado'));
document.getElementById('confirm-summary').innerHTML =