From 5641de21f80ee96d9bf7ba48d15fa9fa2e472bb0 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 1 Jul 2026 20:10:54 +0000 Subject: [PATCH] feat: modal edicao com saldo caixa e diferenca em tempo real + oninput nos campos-chave --- src/index.html | 268 +++++++++++++------------------------------------ 1 file changed, 67 insertions(+), 201 deletions(-) diff --git a/src/index.html b/src/index.html index 83ef315..c3960ec 100644 --- a/src/index.html +++ b/src/index.html @@ -1872,12 +1872,9 @@ function buildReciboData() { const receberTotal = estado.receber.reduce((s,r) => s+(parseNum(r.valor||0)||0), 0); const cancelTotal = estado.cancelamentos.reduce((s,r) => s+(parseNum(r.valor||0)||0), 0); - // Lê do DOM (campos do formulário principal — preenchidos pelo updateTotals após edição) - // Fallback: se DOM vazio, usa estado (registro anterior carregado mas updateTotals ainda não chamou) + // Lê do DOM — mas se estiver vazio usa estado (registro anterior) const trocoDom = parseNum(val('sys-troco')); const saldoTroco = trocoDom || estado.saldo_troco || 0; - // Os campos readonly sys-credito/sys-debito etc. só têm valor se updateTotals foi chamado - // — em edição sem confirmação, ficam vazios e,我们必须 usar cartDeb etc. do estado const saldoCred = parseNum(val('sys-credito')) || cartCred; const saldoDeb = parseNum(val('sys-debito')) || cartDeb; const saldoAli = parseNum(val('sys-alimentacao')) || cartAli; @@ -1892,7 +1889,7 @@ function buildReciboData() { const fechamentoCounted = fechamentoDinheiro + fechamentoCartoes + fechamentoReceber; const saldoEsperado = parseNum(val('f-saldo-esperado')) || estado.saldo_esperado || 0; - // Saldo de Caixa (Sistema) = troco + crédito + débito + alimentação + pix cartão + pixcnpj + vales + receber + // Saldo de Caixa (Sistema) = troco + crédito + débito + alimentação + voucher pix + pixcnpj + vales + receber const sysTotal = saldoTroco + cartCred + cartDeb + cartAli + cartPix + pixCnpjTotal + valesTotal + receberTotal; // Diferença = saldo de caixa (sistema) - saldo_esperado - cancelamentos const diferenca = sysTotal - saldoEsperado - cancelTotal; @@ -2206,130 +2203,32 @@ function buildConsultaModal(recentList) { }).join(''); overlay.innerHTML = ` -
+
-

📅 Consultar Fechamentos

+

📅 Consultar Fechamentos Anteriores

-
- - -
-
-
- - - - - - - - - - - - - -
DATAOPERADORTURNOSALDO CAIXAESPERADOSTATUSAÇÃO
-
-
`; - - // Store original list for filtering - window._consultaList = recentList; - window._consultaAll = recentList; - window._recentList = recentList; // keep for legacy openConsultaRegistro(idx) - - const fmtDate = d => { - if (!d) return ''; - const [y,m,day] = d.split('-'); - return `${day}/${m}/${y}`; - }; - const fmtMoney = v => v != null ? `R$ ${parseFloat(v).toFixed(2).replace('.', ',')}` : 'R$ 0,00'; - const statusBadge = s => { - if (s === 'ok') return '✓ OK'; - if (s === 'sobrando') return '⚠ SOBRANDO'; - if (s === 'faltando') return '⚠ FALTANDO'; - return s || '?'; - }; - const syncBadge = s => { - const colors = { synced: '#2e7d32', local: '#e65100', syncing: '#f57f17', error: '#c0272d' }; - const labels = { synced: '✓ Sync', local: '⚠ Local', syncing: '⏳ Sync', error: '✗ Erro' }; - return `${labels[s]||s||'?'}`; - }; - - function renderConsultaRows(list) { - const tbody = document.getElementById('consulta-tbody'); - if (!list || list.length === 0) { - tbody.innerHTML = `Nenhum fechamento encontrado.`; - document.getElementById('consulta-count').textContent = '0 registros'; - return; - } - const count = document.getElementById('consulta-count'); - if (count) count.textContent = `${list.length} registro${list.length !== 1 ? 's' : ''}`; - tbody.innerHTML = list.map((item, i) => { - const sysTotal = (parseFloat(item.saldo_troco)||0) - + (parseFloat(item.saldo_credito)||0) - + (parseFloat(item.saldo_debito)||0) - + (parseFloat(item.saldo_alimentacao)||0) - + (parseFloat(item.saldo_vales)||0) - + (parseFloat(item.saldo_areceber)||0) - + (parseFloat(item.total_pixcnpj)||0) - + (parseFloat(item.total_cartao_pix)||0); - return ` - ${fmtDate(item.data)} - ${item.operador||'?'} - ${item.turno||'?'} - ${fmtMoney(sysTotal)} - ${fmtMoney(item.saldo_esperado)} - ${statusBadge(item.status_diferenca)} - - - - `; - }).join(''); - } - - // Initial: filter to last 2 days - const today = new Date(); - const cutoff = new Date(today); - cutoff.setDate(today.getDate() - 2); - const cutoffStr = cutoff.toISOString().split('T')[0]; - const twoDays = recentList.filter(item => item.data >= cutoffStr); - renderConsultaRows(twoDays); - window._consultaFiltered = twoDays; - - // Search handler — filters by data, operador, or turno - document.getElementById('consulta-search').addEventListener('input', e => { - const q = e.target.value.toLowerCase().trim(); - const turno = (document.getElementById('consulta-turno')?.value || '').toLowerCase(); - const filtered = recentList.filter(item => { - const matchQ = !q || (item.data||'').includes(q) || (item.operador||'').toLowerCase().includes(q) || (item.turno||'').toLowerCase().includes(q); - const matchTurno = !turno || (item.turno||'').toLowerCase() === turno; - return matchQ && matchTurno; - }); - renderConsultaRows(filtered); - window._consultaFiltered = filtered; - }); - - document.getElementById('consulta-turno').addEventListener('change', e => { - const q = (document.getElementById('consulta-search')?.value || '').toLowerCase().trim(); - const turno = e.target.value.toLowerCase(); - const filtered = recentList.filter(item => { - const matchQ = !q || (item.data||'').includes(q) || (item.operador||'').toLowerCase().includes(q) || (item.turno||'').toLowerCase().includes(q); - const matchTurno = !turno || (item.turno||'').toLowerCase() === turno; - return matchQ && matchTurno; - }); - renderConsultaRows(filtered); - window._consultaFiltered = filtered; - }); +

Clique em um registro para ver o relatório ou clique em Editar para abrir a janela de edição.

+ + + + + + + + + + + + + + ${rows} +
DATAOPERADORTURNOSALDO CAIXAESPERADOSTATUSSYNCAÇÃO
+
+ `; document.body.appendChild(overlay); - overlay.addEventListener('click', e => { if (e.target === overlay) closeConsultaModal(); }); + window._recentList = recentList; } // Abre a janela de edição completa de um registro pelo índice na lista @@ -2373,79 +2272,6 @@ function closeConsultaModal() { window._currentConsulta = null; } -// Abre o relatório pelo elemento (evita dependência de índice) -window.openConsultaRegistroByItem = async function(tr) { - const dataAttr = tr ? tr.dataset.item : null; - let item = null; - if (dataAttr) { - try { item = JSON.parse(dataAttr); } catch(e) {} - } - if (!item) { - // Fallback: busca pelo texto da primeira célula (data) - const dataText = tr.cells[0]?.textContent?.trim(); - if (dataText) { - const [d,m,y] = dataText.split('/'); - const dataKey = `${y}-${m}-${d}`; - item = window._consultaAll?.find(it => it.data === dataKey); - } - } - if (!item) { alert('Registro não encontrado.'); return; } - closeConsultaModal(); - - const hasTauri = !!(window.__TAURI__ && window.__TAURI__.core); - if (!hasTauri) { alert('Tauri não disponível.'); return; } - - let full = null; - try { - if (item.id) { try { full = await window.__TAURI__.core.invoke('sb_buscar_por_id', { id: item.id }); } catch(e) {} } - if (!full && item.uuid) { try { full = await window.__TAURI__.core.invoke('sb_buscar_por_uuid', { uuid: item.uuid }); } catch(e) {} } - if (!full && item.id_fechamento) { try { full = await window.__TAURI__.core.invoke('sb_buscar_por_id_fechamento', { idFechamento: item.id_fechamento }); } catch(e) {} } - } catch(e) { console.warn('Erro buscando registro:', e); } - - if (!full) { alert('Registro não encontrado.'); return; } - window._currentConsulta = full; - buildRelatorioModal(full); -}; - -// Abre a edição pelo elemento (evita dependência de índice) -window.abrirEditaFechamentoByItem = async function(tr) { - const dataAttr = tr ? tr.dataset.item : null; - let item = null; - if (dataAttr) { - try { item = JSON.parse(dataAttr); } catch(e) {} - } - if (!item) { - const dataText = tr.cells[0]?.textContent?.trim(); - if (dataText) { - const [d,m,y] = dataText.split('/'); - const dataKey = `${y}-${m}-${d}`; - item = window._consultaAll?.find(it => it.data === dataKey); - } - } - if (!item) { alert('Registro não encontrado.'); return; } - - const hasTauri = !!(window.__TAURI__ && window.__TAURI__.core); - if (!hasTauri) { alert('Tauri não disponível.'); return; } - - let full = null; - try { - if (item.id) { try { full = await window.__TAURI__.core.invoke('sb_buscar_por_id', { id: item.id }); } catch(e) {} } - if (!full && item.uuid) { try { full = await window.__TAURI__.core.invoke('sb_buscar_por_uuid', { uuid: item.uuid }); } catch(e) {} } - if (!full && item.id_fechamento) { try { full = await window.__TAURI__.core.invoke('sb_buscar_por_id_fechamento', { idFechamento: item.id_fechamento }); } catch(e) {} } - } catch(e) { console.warn('Erro buscando registro:', e); } - - if (!full) { alert('Registro não encontrado.'); return; } - window._currentConsulta = full; - closeConsultaModal(); - closeRelatorioModal(); - - const pw = localStorage.getItem('admin_pw') || '1234'; - const granted = await askPassword(pw); - if (!granted) return; - - openEditModal(full); -}; - // Abre o relatório de um registro selecionado window.openConsultaRegistro = async function(idx) { const item = window._recentList[idx]; @@ -2890,7 +2716,35 @@ window._recalcEditTotals = function() { if (el('tot-areceber')) el('tot-areceber').textContent = fmtTot(recv_tot); if (el('tot-sangrias')) el('tot-sangrias').textContent = fmtTot(sang_tot); if (el('tot-despesas')) el('tot-despesas').textContent = fmtTot(desp_tot); - if (el('tot-cancel')) el('tot-cancel').textContent = fmtTot(canc_tot); + if (el('tot-cancel')) el('tot-cancel').textContent = fmtTot(canc_tot); + + // Atualiza campos readonly do saldo de caixa com totais calculados + const setReadonly = (id, v) => { if (el(id)) el(id).value = fmtTot(v); }; + setReadonly('edit-sld-credito', cartCred_tot); + setReadonly('edit-sld-debito', cartDeb_tot); + setReadonly('edit-sld-alimentacao', cartAli_tot); + setReadonly('edit-sld-vales', vales_tot); + setReadonly('edit-sld-pixcnpj', pixcnpj_tot); + setReadonly('edit-sld-areceber', recv_tot); + setReadonly('edit-sld-pixcartao', cartPix_tot); + + // Calcula Saldo Caixa e Diferença em tempo real + const trocoVal = parseNum(el('edit-troco')?.value || '0'); + const esperadoVal = parseNum(el('edit-esperado')?.value || '0'); + const saldoCaixa = trocoVal + cartCred_tot + cartDeb_tot + cartAli_tot + cartPix_tot + pixcnpj_tot + vales_tot + recv_tot; + const diferenca = saldoCaixa - esperadoVal - canc_tot; + + if (el('edit-saldo-caixa')) { + el('edit-saldo-caixa').textContent = saldoCaixa > 0 ? fmtTot(saldoCaixa) : 'R$ 0,00'; + } + if (el('edit-diferenca')) { + const fmtDif = v => v >= 0 ? `R$ ${v.toLocaleString('pt-BR', { minimumFractionDigits: 2 })}` : `-R$ ${Math.abs(v).toLocaleString('pt-BR', { minimumFractionDigits: 2 })}`; + el('edit-diferenca').textContent = fmtDif(diferenca); + // Alerta visual se diferença != 0 + if (el('edit-diferenca-box')) { + el('edit-diferenca-box').style.background = diferenca === 0 ? '#e8f5e9' : diferenca > 0 ? '#fff3e0' : '#ffebee'; + } + } }; // Modal de edição completo com todas as grades @@ -3109,7 +2963,8 @@ function openEditModal(full) {
💰 Saldo de Caixa (apenas Troco é editável)
-
+
+
@@ -3118,14 +2973,23 @@ function openEditModal(full) {
+
+
+ SALDO CAIXA: + R$ 0,00 +
+
+ DIFERENÇA: + R$ 0,00 +
+
-
+
-
@@ -3141,6 +3005,8 @@ function openEditModal(full) {
`; document.body.appendChild(overlay); + // Calcula totais iniciais após renderizar o DOM + setTimeout(() => window._recalcEditTotals(), 50); } // Formata campo de dinheiro brasileiro