diff --git a/src/index.html b/src/index.html index 9bf0fe6..3128f7d 100644 --- a/src/index.html +++ b/src/index.html @@ -2514,75 +2514,300 @@ function askPassword() { }); } -// Modal de edição separado e compacto +// Monta HTML de uma grade editável dentro do modal +function editTableHTML(id, headers, rows, numericCols) { + const hdr = headers.map((h,i) => `${h}`).join(''); + const body = rows.map((row, ri) => { + const cells = row.map((val, ci) => { + const isNum = numericCols.includes(ci); + const displayVal = (val !== null && val !== undefined && val !== '') + ? (isNum ? fmtMoney(val) : val) + : ''; + return ``; + }).join(''); + return `${cells}`; + }).join(''); + return `${hdr}${body}
`; +} + +// Monta uma grade vazia com N linhas editáveis +function editTableEmpty(id, headers, nRows, numericCols) { + const emptyRows = Array.from({length: nRows}, () => headers.map(() => '')); + return editTableHTML(id, headers, emptyRows, numericCols); +} + +// Adiciona linha a uma grade editável no modal +window._editAddRow = function(tblId) { + const container = document.getElementById('tbl-edit-' + tblId); + if (!container) return; + const tbl = container.querySelector('table'); + if (!tbl) return; + const numericCols = container.dataset.numeric ? JSON.parse(container.dataset.numeric) : []; + const cols = tbl.querySelector('tr').cells.length; + const newRowIdx = tbl.rows.length; + const row = tbl.insertRow(-1); + for (let c = 0; c < cols; c++) { + const td = row.insertCell(-1); + const isNum = numericCols.includes(c); + td.innerHTML = ``; + } +}; + +// Lê todos os dados das grades editáveis do modal +function readEditTables() { + const inputs = document.querySelectorAll('#modal-edit input[data-tbl]'); + const tables = {}; + inputs.forEach(inp => { + const tbl = inp.dataset.tbl; + const row = parseInt(inp.dataset.row); + const col = parseInt(inp.dataset.col); + if (!tables[tbl]) tables[tbl] = []; + while (tables[tbl].length <= row) tables[tbl].push([]); + tables[tbl][row][col] = inp.value; + }); + // Converte valores numéricos + const numericCols = { + 'credito': [0], 'debito': [0], 'alimentacao': [0], 'pix': [0], + 'vales': [1], 'despesas': [2], 'sangrias': [1], + 'cancelamentos': [1], 'pixcnpj': [1], 'receber': [1] + }; + Object.keys(tables).forEach(tbl => { + const ncols = numericCols[tbl] || []; + tables[tbl] = tables[tbl].filter(row => row.some(c => c !== '' && c != null)); + tables[tbl] = tables[tbl].map(row => row.map((val, ci) => { + if (ncols.includes(ci)) return parseNum(val); + return (val || '').trim(); + })); + }); + return tables; +} + +// Modal de edição completo com todas as grades function openEditModal(full) { window._editModalOpen = true; const dados = full.dados || {}; - const fmtM = v => parseFloat(v||0).toFixed(2).replace('.', ','); - const fmtMR = v => 'R$ ' + fmtM(v); + + // helper para fmt dinheiro + const fmtMR = v => { + const n = parseFloat(v||0); + if (isNaN(n) || n === 0) return ''; + return 'R$ ' + n.toLocaleString('pt-BR', { minimumFractionDigits: 2 }); + }; + + // helper para fmt table cell + const fmtCell = (v, isNum) => { + if (v === null || v === undefined || v === '') return ''; + if (isNum) return fmtMoney(v); + return v; + }; + const editedInfo = full.edited_at ? `
⚠️ Última edição: ${full.edited_at.replace('T',' ').substring(0,16)} por ${full.edited_by||'?'}
` : ''; - const troco = parseFloat(full.saldo_troco||0); - const credito = parseFloat(full.saldo_credito||0); - const debito = parseFloat(full.saldo_debito||0); - const alimentacao = parseFloat(full.saldo_alimentacao||0); - const vales = parseFloat(full.saldo_vales||0); - const pixcnpj = parseFloat(full.total_pixcnpj||0); - const areceber = parseFloat(full.saldo_areceber||0); - const clientes = dados.clientes ?? full.clientes ?? 0; - const frango = dados.frango ?? full.frango ?? 0; - const vendas = dados.vendas ?? full.vendas ?? 0; - const saldo_esperado = parseFloat(full.saldo_esperado||0); - const obs = full.observacoes||''; + // --- Cartões --- + const cartCred_rows = (dados.cartoes?.credito || full.cartoes_credito || []).map((r, i) => [fmtCell(typeof r === 'object' ? r.valor : r, true)]); + const cartDeb_rows = (dados.cartoes?.debito || full.cartoes_debito || []).map((r, i) => [fmtCell(typeof r === 'object' ? r.valor : r, true)]); + const cartAli_rows = (dados.cartoes?.alimentacao || full.cartoes_alimentacao || []).map((r, i) => [fmtCell(typeof r === 'object' ? r.valor : r, true)]); + const cartPix_rows = (dados.cartoes?.pix || full.cartoes_pix || []).map((r, i) => [fmtCell(typeof r === 'object' ? r.valor : r, true)]); + + const cartCredHTML = editTableHTML('credito', ['Valor (R$)'], cartCred_rows.length ? cartCred_rows : [['']], [0]); + const cartDebHTML = editTableHTML('debito', ['Valor (R$)'], cartDeb_rows.length ? cartDeb_rows : [['']], [0]); + const cartAliHTML = editTableHTML('alimentacao', ['Valor (R$)'], cartAli_rows.length ? cartAli_rows : [['']], [0]); + const cartPixHTML = editTableHTML('pix', ['Valor (R$)'], cartPix_rows.length ? cartPix_rows : [['']], [0]); + + // --- Vales --- + const vales_rows = (full.vales || []).map(r => [r.nome||r.Nome||'', fmtCell(r.valor, true), r.obs||r.Obs||'']); + const valesHTML = editTableHTML('vales', ['Nome', 'Valor (R$)', 'Obs'], vales_rows.length ? vales_rows : [['','','']], [1]); + + // --- Despesas --- + const despesas_rows = (full.despesas || []).map(r => [r.desc||r.Desc||'', r.obs||r.Obs||'', fmtCell(r.valor, true)]); + const despesasHTML = editTableHTML('despesas', ['Descrição', 'Obs', 'Valor (R$)'], despesas_rows.length ? despesas_rows : [['','','']], [2]); + + // --- Sangrias --- + const sangrias_rows = (full.sangrias || []).map(r => [r.hora||r.Hora||'', fmtCell(r.retirada, true), r.gerente||r.Gerente||'']); + const sangriasHTML = editTableHTML('sangrias', ['Hora', 'Valor (R$)', 'Gerente'], sangrias_rows.length ? sangrias_rows : [['','','']], [1]); + + // --- Cancelamentos --- + const cancel_rows = (full.cancelamentos || []).map(r => [r.numero||r.Numero||'', fmtCell(r.valor, true), r.motivo||r.Motivo||'']); + const cancelHTML = editTableHTML('cancelamentos', ['Número', 'Valor (R$)', 'Motivo'], cancel_rows.length ? cancel_rows : [['','','']], [1]); + + // --- PIX CNPJ --- + const pixcnpj_rows = (full.pixcnpj || []).map(r => [r.nome||r.Nome||'', fmtCell(r.valor, true)]); + const pixcnpjHTML = editTableHTML('pixcnpj', ['Nome', 'Valor (R$)'], pixcnpj_rows.length ? pixcnpj_rows : [['','']], [1]); + + // --- A Receber --- + const receber_rows = (full.receber || []).map(r => [r.nome||r.Nome||'', fmtCell(r.valor, true)]); + const receberHTML = editTableHTML('receber', ['Nome', 'Valor (R$)'], receber_rows.length ? receber_rows : [['','']], [1]); + + // --- Totais (só leitura formatado) --- + const totaisInfo = ` +
+
Total Crédito: ${fmtMR(full.total_cartao_credito||0)}
+
Total Débito: ${fmtMR(full.total_cartao_debito||0)}
+
Total Alimentação: ${fmtMR(full.total_cartao_alimentacao||0)}
+
Total PIX: ${fmtMR(full.total_cartao_pix||0)}
+
Total Sangrias: ${fmtMR(full.total_sangrias||0)}
+
Total Despesas: ${fmtMR(full.total_despesas||0)}
+
Total Vales: ${fmtMR(full.total_vales||0)}
+
Total PIX CNPJ: ${fmtMR(full.total_pixcnpj||0)}
+
`; const overlay = document.createElement('div'); overlay.id = 'modal-edit'; - overlay.style.cssText = 'position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.6);z-index:99998;display:flex;align-items:center;justify-content:center;'; + overlay.style.cssText = 'position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.6);z-index:99998;overflow-y:auto'; overlay.innerHTML = ` -
-
-

✏️ Editar Fechamento — ${full.loja||''} ${full.data||''}

- +
+
+

✏️ Editar Fechamento Completo

+
${editedInfo} -
-
📅 Data: ${full.data||'?'}   Turno: ${full.turno||'?'}   Operador: ${full.operador||'?'}
+ +
+
+
+
+ +
+
+ +
+
+
- + + ${totaisInfo} -
-
-
-
-
-
-
-
-
-
-
+ +
+
+ 💳 Cartão de Crédito + +
+
${cartCredHTML}
-
-
-
-
-
-
-
+ +
+
+ 💳 Cartão de Débito + +
+
${cartDebHTML}
-
+ +
+
+ 🍽️ Alimentação + +
+
${cartAliHTML}
+
+ + +
+
+ 📱 PIX + +
+
${cartPixHTML}
+
+ + +
+
+ 📋 Vales + +
+
${valesHTML}
+
+ + +
+
+ 💸 Despesas + +
+
${despesasHTML}
+
+ + +
+
+ 🏧 Sangrias + +
+
${sangriasHTML}
+
+ + +
+
+ PIX CNPJ + +
+
${pixcnpjHTML}
+
+ + +
+
+ 📬 A Receber + +
+
${receberHTML}
+
+ + +
+
+ ❌ Cancelamentos + +
+
${cancelHTML}
+
+ + +
+ 💰 Saldo de Caixa +
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+ + +
- +
@@ -2608,7 +2833,7 @@ function closeEditModal() { window._editModalOpen = false; } -// Salva edições do modal de edição separado +// Salva edições do modal de edição completo window.salvarEdicaoModal = async function() { const full = window._currentConsulta; if (!full) return; @@ -2616,27 +2841,92 @@ window.salvarEdicaoModal = async function() { const p = v => parseNum(v); const inp = id => { const el = document.getElementById(id); return el ? el.value : ''; }; + // Lê todas as grades editáveis + const tables = readEditTables(); + + // Calcula totais dos cartões + const cartCred_tot = (tables.credito || []).reduce((s, r) => s + (r[0] || 0), 0); + const cartDeb_tot = (tables.debito || []).reduce((s, r) => s + (r[0] || 0), 0); + const cartAli_tot = (tables.alimentacao || []).reduce((s, r) => s + (r[0] || 0), 0); + const cartPix_tot = (tables.pix || []).reduce((s, r) => s + (r[0] || 0), 0); + const vales_tot = (tables.vales || []).reduce((s, r) => s + (r[1] || 0), 0); + const desp_tot = (tables.despesas || []).reduce((s, r) => s + (r[2] || 0), 0); + const sang_tot = (tables.sangrias || []).reduce((s, r) => s + (r[1] || 0), 0); + const pixcnpj_tot = (tables.pixcnpj || []).reduce((s, r) => s + (r[1] || 0), 0); + const recv_tot = (tables.receber || []).reduce((s, r) => s + (r[1] || 0), 0); + const canc_tot = (tables.cancelamentos || []).reduce((s, r) => s + (r[1] || 0), 0); + + // Monta estruturas de volta + const cartoes = { + credito: (tables.credito || []).map(r => r[0]), + debito: (tables.debito || []).map(r => r[0]), + alimentacao: (tables.alimentacao || []).map(r => r[0]), + pix: (tables.pix || []).map(r => r[0]), + }; + + const vales = (tables.vales || []).map(r => ({ nome: r[0], valor: r[1], obs: r[2]||'' })); + const despesas = (tables.despesas || []).map(r => ({ desc: r[0], obs: r[1]||'', valor: r[2] })); + const sangrias = (tables.sangrias || []).map(r => ({ hora: r[0], retirada: r[1], gerente: r[2]||'' })); + const cancelamentos = (tables.cancelamentos || []).map(r => ({ numero: r[0], valor: r[1], motivo: r[2]||'' })); + const pixcnpj = (tables.pixcnpj || []).map(r => ({ nome: r[0], valor: r[1] })); + const receber = (tables.receber || []).map(r => ({ nome: r[0], valor: r[1] })); + const now = new Date().toISOString(); const operador = estado.operador || full.operador || ''; const updates = { - saldo_troco: p(inp('edit-troco')), - saldo_credito: p(inp('edit-credito')), - saldo_debito: p(inp('edit-debito')), - saldo_alimentacao: p(inp('edit-alimentacao')), - saldo_vales: p(inp('edit-vales')), - total_pixcnpj: p(inp('edit-pixcnpj')), - saldo_areceber: p(inp('edit-areceber')), - fechamento_dinheiro: p(inp('edit-fd')), - fechamento_cartoes: p(inp('edit-fc')), - fechamento_areceber: p(inp('edit-fr')), - total_sangrias: p(inp('edit-sangrias')), - total_despesas: p(inp('edit-despesas')), + // Identificação + loja: inp('edit-loja'), + data: inp('edit-data'), + turno: inp('edit-turno'), + operador: inp('edit-operador'), + + // Cartões (como arrays de números crus) + cartoes_credito: cartoes.credito, + cartoes_debito: cartoes.debito, + cartoes_alimentacao: cartoes.alimentacao, + cartoes_pix: cartoes.pix, + + // Totais de cartões + total_cartao_credito: cartCred_tot, + total_cartao_debito: cartDeb_tot, + total_cartao_alimentacao: cartAli_tot, + total_cartao_pix: cartPix_tot, + + // Saldo de caixa (editável via tabela saldo) + saldo_troco: p(inp('edit-troco')), + saldo_credito: p(inp('edit-sld-credito')), + saldo_debito: p(inp('edit-sld-debito')), + saldo_alimentacao: p(inp('edit-sld-alimentacao')), + saldo_vales: p(inp('edit-sld-vales')), + total_pixcnpj: p(inp('edit-sld-pixcnpj')), + saldo_areceber: p(inp('edit-sld-areceber')), + + // Totais + total_vales: vales_tot, + total_despesas: desp_tot, + total_sangrias: sang_tot, + total_areceber: recv_tot, + total_cancelamentos: canc_tot, + + // Lançamentos detalhados + vales: vales, + despesas: despesas, + sangrias: sangrias, + cancelamentos: cancelamentos, + pixcnpj: pixcnpj, + receber: receber, + + // Contadores clientes: parseInt(inp('edit-clientes') || '0'), frango: parseInt(inp('edit-frango') || '0'), vendas: p(inp('edit-vendas')), + + // Meta saldo_esperado: p(inp('edit-esperado')), observacoes: inp('edit-obs'), + + // Edit log edited_at: now, edited_by: operador, }; @@ -2645,7 +2935,7 @@ window.salvarEdicaoModal = async function() { if (!hasTauri) { alert('Tauri não disponível.'); return; } try { - const id = document.getElementById('edit-id').value || full.id; + const id = inp('edit-id') || full.id; if (!id) { alert('ID do registro não encontrado.'); return; } await window.__TAURI__.core.invoke('sb_atualizar_fechamento', { id, updates });