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 =