diff --git a/src/index.html b/src/index.html index fce0a74..9c95c3f 100644 --- a/src/index.html +++ b/src/index.html @@ -2350,7 +2350,7 @@ function closeRelatorioModal() { window._editMode = false; } -// Toggle modo de edição — pede senha admin +// Toggle modo de edição — pede senha admin via modal (não via prompt) window.toggleEditConsulta = async function() { if (window._editMode) { // Cancela edição @@ -2362,17 +2362,47 @@ window.toggleEditConsulta = async function() { } const pw = config.admin_password; - let ok = true; - if (pw) { - const input = prompt('🔐 Digite a senha admin para editar este registro:'); - ok = (input === pw); - if (!ok) { alert('Senha incorreta.'); return; } + if (!pw) { + window._editMode = true; + document.getElementById('edit-section').style.display = 'block'; + document.getElementById('btn-salvar-consulta').style.display = 'block'; + document.getElementById('btn-edit-consulta').textContent = '✕ Cancelar'; + return; } - window._editMode = true; - document.getElementById('edit-section').style.display = 'block'; - document.getElementById('btn-salvar-consulta').style.display = 'block'; - document.getElementById('btn-edit-consulta').textContent = '✕ Cancelar'; + // Modal com senha oculta + const overlay = document.createElement('div'); + overlay.style.cssText = 'position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.5);z-index:999999;display:flex;align-items:center;justify-content:center;'; + overlay.id = 'pw-modal'; + overlay.innerHTML = ` +
+
🔐 Senha Admin
+ + +
+ + +
+
`; + document.body.appendChild(overlay); + const inp = document.getElementById('pw-input'); + inp.focus(); + inp.addEventListener('keydown', e => { if (e.key === 'Enter') document.getElementById('pw-ok-btn').click(); }); + document.getElementById('pw-ok-btn').addEventListener('click', () => { + const val = document.getElementById('pw-input').value; + const err = document.getElementById('pw-error'); + if (val === pw) { + document.getElementById('pw-modal').remove(); + window._editMode = true; + document.getElementById('edit-section').style.display = 'block'; + document.getElementById('btn-salvar-consulta').style.display = 'block'; + document.getElementById('btn-edit-consulta').textContent = '✕ Cancelar'; + } else { + err.style.display = 'block'; + inp.value = ''; + inp.focus(); + } + }); }; // Salva edições de volta ao Supabase @@ -2410,24 +2440,151 @@ window.salvarEdicaoConsulta = async function() { } }; -// Imprime o relatório (abre janela de impressão do navegador) +// Converte o registro "full" do Supabase para o formato usado pelo buildPrintHTML +function consultaToPrintData(full) { + const cartCred = parseFloat(full.saldo_credito || 0); + const cartDeb = parseFloat(full.saldo_debito || 0); + const cartAli = parseFloat(full.saldo_alimentacao || 0); + const cartPix = parseFloat(full.total_cartao_pix || 0); + const pixCnpj = parseFloat(full.total_pixcnpj || 0); + const vales = parseFloat(full.saldo_vales || 0); + const receber = parseFloat(full.saldo_areceber || 0); + const troco = parseFloat(full.saldo_troco || 0); + const sysTotal = troco + cartCred + cartDeb + cartAli + cartPix + pixCnpj + vales + receber; + const fd = parseFloat(full.fechamento_dinheiro || 0); + const fc = parseFloat(full.fechamento_cartoes || 0); + const fr = parseFloat(full.fechamento_areceber || 0); + const ftotal = fd + fc + fr; + const saldoEsp = parseFloat(full.saldo_esperado || 0); + const diferenca = parseFloat(full.diferenca || 0); + const diffOk = diferenca === 0; + const diffStr = diferenca >= 0 ? `+${fmtDiff(diferenca)}` : fmtDiffNeg(diferenca); + const dados = full.dados || {}; + const fmtDiff = v => 'R$ ' + Math.abs(v || 0).toFixed(2).replace('.', ','); + const fmtDiffNeg = v => (v < 0 ? '-' : '') + 'R$ ' + Math.abs(v || 0).toFixed(2).replace('.', ','); + const fmt = v => 'R$ ' + (v || 0).toFixed(2).replace('.', ','); + + const despesas_arr = (dados.despesas || []).map(d => ({ desc: d.desc || '', obs: d.obs || '', valor: parseFloat(d.valor || 0) })); + const sangrias_arr = (dados.sangrias || []).map(s => ({ hora: s.hora || '', retirada: parseFloat(s.retirada || 0), gerente: s.gerente || '', valor: parseFloat(s.valor || 0) })); + const pixcnpj_arr = (dados.pixcnpj || []).map(p => ({ nome: p.nome || '', valor: parseFloat(p.valor || 0) })); + const vales_arr = (dados.vales || []).map(v => ({ nome: v.nome || '', obs: v.obs || '', valor: parseFloat(v.valor || 0) })); + const receber_arr = (dados.receber || []).map(r => ({ nome: r.nome || '', valor: parseFloat(r.valor || 0) })); + const cancelamentos_arr = (dados.cancelamentos || []).map(c => ({ numero: c.numero || '', valor: parseFloat(c.valor || 0), motivo: c.motivo || '' })); + const cartoes_credito = (full.cartoes_credito || []).map(v => parseFloat(v || 0)); + const cartoes_debito = (full.cartoes_debito || []).map(v => parseFloat(v || 0)); + const cartoes_alimentacao = (full.cartoes_alimentacao || []).map(v => parseFloat(v || 0)); + const cartoes_pix = (full.cartoes_pix || []).map(v => parseFloat(v || 0)); + const totalSangrias = sangrias_arr.reduce((s, r) => s + r.retirada + r.valor, 0); + const totalDespesas = despesas_arr.reduce((s, r) => s + r.valor, 0); + const totalPixCnpj = pixcnpj_arr.reduce((s, r) => s + r.valor, 0); + const totalVales = vales_arr.reduce((s, r) => s + r.valor, 0); + const totalReceber = receber_arr.reduce((s, r) => s + r.valor, 0); + const totalCancel = cancelamentos_arr.reduce((s, r) => s + r.valor, 0); + const totalCartoes = cartCred + cartDeb + cartAli + cartPix; + + return { + loja: full.loja || '?', + data: full.data || '?', + operador: full.operador || '?', + turno: full.turno || '?', + saldo_troco: troco, + saldo_esperado: saldoEsp, + fechamento: ftotal, + diferenca: diferenca, + sys_total: sysTotal, + fechamento_dinheiro: fd, + fechamento_cartoes: fc, + fechamento_areceber: fr, + credito: cartCred, + debito: cartDeb, + alimentacao: cartAli, + voucher: cartPix, + pixcnpj: pixCnpj, + vales: vales, + areceber: receber, + cancelamentos: totalCancel, + despesas_arr, + sangrias_arr, + pixcnpj_arr, + vales_arr, + receber_arr, + cancelamentos_arr, + cartoes_credito, + cartoes_debito, + cartoes_alimentacao, + cartoes_pix, + totalSangrias, + totalDespesas, + totalPixCnpj, + totalVales, + totalReceber, + totalCancel, + totalCartoes, + sysTotal, + saldoEsperado: saldoEsp, + diffStr, + diffOk, + fdin: fd, + fcarts: fc, + frec: fr, + ftotal, + observacoes: full.observacoes || '', + clientes: full.clientes || 0, + frango: full.frango || 0, + }; +} + +// Imprime o relatório — usa iframe como openPrintPreview (Tauri não bloqueia) window.printRelatorio = function() { - const inner = document.getElementById('relatorio-inner'); - if (!inner) return; - const Win = window.open('', '', 'width=600,height=700'); - Win.document.write(`Relatorio Fechamento${inner.innerHTML}`); - Win.document.close(); - Win.focus(); - setTimeout(() => { Win.print(); Win.close(); }, 500); + const full = window._currentConsulta; + if (!full) return; + const data = consultaToPrintData(full); + const html = buildPrintHTML(data); + const previewStyle = ` + `; + const fullHtml = `Recibo${previewStyle}${html}`; + + const existing = document.getElementById('print-preview-overlay'); + if (existing) document.body.removeChild(existing); + const overlay = document.createElement('div'); + overlay.id = 'print-preview-overlay'; + overlay.style.cssText = 'position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.85);z-index:99999;display:flex;flex-direction:column;align-items:center;font-family:\'Courier New\',monospace;'; + const iframe = document.createElement('iframe'); + iframe.style.cssText = 'width:360px;height:600px;border:2px solid #555;margin-top:16px;background:#fff;'; + iframe.id = 'print-iframe'; + const btnFechar = document.createElement('button'); + btnFechar.textContent = '✕ Fechar'; + btnFechar.style.cssText = 'margin-top:12px;padding:10px 32px;background:#444;color:#fff;border:none;border-radius:6px;font-size:15px;cursor:pointer;'; + btnFechar.onclick = () => document.body.removeChild(overlay); + const btnImprimir = document.createElement('button'); + btnImprimir.textContent = '🖨️ Imprimir'; + btnImprimir.style.cssText = 'margin-top:8px;padding:10px 32px;background:#e65100;color:#fff;border:none;border-radius:6px;font-size:15px;cursor:pointer;'; + btnImprimir.onclick = () => { iframe.contentWindow.focus(); iframe.contentWindow.print(); }; + overlay.appendChild(iframe); + overlay.appendChild(btnFechar); + overlay.appendChild(btnImprimir); + document.body.appendChild(overlay); + iframe.srcdoc = fullHtml; }; // Intercepta o envio — se sync_status=editing, faz PATCH