diff --git a/fechamento-caixa-v1.2.0.tar.gz b/fechamento-caixa-v1.2.0.tar.gz
new file mode 100644
index 0000000..5f6974a
Binary files /dev/null and b/fechamento-caixa-v1.2.0.tar.gz differ
diff --git a/fechamento-caixa.exe b/fechamento-caixa.exe
new file mode 100755
index 0000000..f2294da
Binary files /dev/null and b/fechamento-caixa.exe differ
diff --git a/src-tauri/src/plugins/printer.rs b/src-tauri/src/plugins/printer.rs
index 5f5985b..fda3199 100644
--- a/src-tauri/src/plugins/printer.rs
+++ b/src-tauri/src/plugins/printer.rs
@@ -122,7 +122,6 @@ impl ReciboData {
// Corta papel
out.extend(escpos::FEED_CUT);
- out.extend(escpos::CUT);
out
}
diff --git a/src/index.html b/src/index.html
index 0eb4e95..2300f66 100644
--- a/src/index.html
+++ b/src/index.html
@@ -1191,6 +1191,112 @@ async function tauriEnviar() {
}
}
+// ─── Print Preview Window ──────────────────────────────────────────────────
+function buildPrintHTML(data) {
+ const fmt = v => 'R$ ' + (v || 0).toFixed(2).replace('.', ',');
+ const diff = (data.saldo_troco - data.saldo_esperado);
+ const diffStr = diff >= 0 ? `+${fmt(diff)}` : fmt(diff);
+ const diffColor = diff === 0 ? '#2e7d32' : (diff > 0 ? '#e65100' : '#c0272d');
+
+ let rows = '';
+ // Sangrias
+ if (data.sangrias && data.sangrias.length > 0) {
+ data.sangrias.forEach(s => { if (s.hora || s.retirada) rows += `
| ${s.hora||''} | ${fmt(s.retirada)} | ${s.gerente||''} |
`; });
+ }
+ // Despesas
+ if (data.despesas && data.despesas.length > 0) {
+ data.despesas.forEach(d => { if (d.desc || d.valor) rows += `| ${d.desc||''} | ${fmt(d.valor)} | ${d.obs||''} |
`; });
+ }
+ // Vales
+ if (data.vales && data.vales.length > 0) {
+ data.vales.forEach(v => { if (v.nome || v.valor) rows += `| ${v.nome||''} | ${fmt(v.valor)} | ${v.obs||''} |
`; });
+ }
+ // Receber
+ if (data.receber && data.receber.length > 0) {
+ data.receber.forEach(r => { if (r.nome || r.valor) rows += `| ${r.nome||''} | ${fmt(r.valor)} | |
`; });
+ }
+ // PIX CNPJ
+ if (data.pixcnpj && data.pixcnpj.length > 0) {
+ data.pixcnpj.forEach(p => { if (p.nome || p.valor) rows += `| PIX: ${p.nome||''} | ${fmt(p.valor)} | |
`; });
+ }
+ // Cancelamentos
+ if (data.cancelamentos && data.cancelamentos.length > 0) {
+ data.cancelamentos.forEach(c => { if (c.numero || c.valor) rows += `| ${c.numero||''} | ${fmt(c.valor)} | ${c.motivo||''} |
`; });
+ }
+
+ return `
+
+
+Relatório de Fechamento
+
+
+
+
+Data:${data.data}
+Operador:${data.operador}
+Turno:${data.turno}
+
+ENTRADAS
+Saldo Troco:${fmt(data.saldo_troco)}
+Fechamento:${fmt(data.fechamento)}
+Saldo Esperado:${fmt(data.saldo_esperado)}
+
+${rows ? `DETALHES
` : ''}
+
+${data.observacoes ? `Obs: ${data.observacoes}
` : ''}
+
+
+CARTÕES
+Crédito:${fmt(data.credito)}
+Débito:${fmt(data.debito)}
+Alimentação:${fmt(data.alimentacao)}
+PIX Cartão:${fmt(data.cartoes?.pix||0)}
+Cancelamentos:${fmt(data.cancelamentos)}
+
+
+DIFERENÇA: ${diffStr}
+
+`;
+}
+
+function openPrintPreview(data) {
+ const html = buildPrintHTML(data);
+ const win = window.open('', 'print_preview', 'width=400,height=700,scrollbars=yes,resizable=yes');
+ if (!win) { alert('Bloqueador de pop-up impediu abrir a pré-visualização.'); return; }
+ win.document.write(html);
+ win.document.close();
+}
+
+function triggerWindowPrint() {
+ // Chama window.print() na janela pai (o próprio app)
+ window.print();
+}
+
+// ─── Recibo 80mm via Tauri (ESC/POS USB) ─────────────────────────────────
async function tauriRecibo() {
// Build flat totals for the Rust ReciboData struct
const cartCred = estado.cartoes.credito.reduce((s,r) => s+(r.valor||0), 0);
@@ -1239,7 +1345,15 @@ async function tauriRecibo() {
observacoes: estado.observacoes,
sync_status: estado.sync_status,
};
- return await window.__TAURI__.core.invoke('imprimir_recibo', { estado: JSON.stringify(data) });
+
+ // Tenta ESC/POS via Tauri primeiro; se falhar, abre preview
+ try {
+ return await window.__TAURI__.core.invoke('imprimir_recibo', { estado: JSON.stringify(data) });
+ } catch(e) {
+ console.warn('ESC/POS falhou, abrindo preview:', e);
+ openPrintPreview(data);
+ throw e;
+ }
}
async function tauriCarregarRascunho() {
@@ -1303,19 +1417,30 @@ document.getElementById('confirm-close').addEventListener('click', closeConfirmM
document.getElementById('confirm-cancel').addEventListener('click', closeConfirmModal);
document.getElementById('modal-confirm').addEventListener('click', e => { if (e.target.id === 'modal-confirm') closeConfirmModal(); });
-// Print from confirm modal
+// Print from confirm modal — abre preview no navegador
document.getElementById('confirm-print').addEventListener('click', async () => {
closeConfirmModal();
- const btn = document.getElementById('btn-recibo');
- btn.disabled = true;
- try {
- await tauriRecibo();
- alert('✅ Impressão enviada!');
- } catch(e) {
- alert('Erro ao imprimir: ' + (e.message || e));
- } finally {
- btn.disabled = false;
- }
+ // Reconstrói os mesmos dados do tauriRecibo e abre preview
+ const cartCred = estado.cartoes.credito.reduce((s,r) => s+(r.valor||0), 0);
+ 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 data = {
+ loja: estado.loja, data: estado.data, operador: estado.operador, turno: estado.turno,
+ saldo_troco: parseNum(val('sys-troco')) || 0,
+ saldo_esperado: parseNum(val('f-saldo-esperado')) || 0,
+ fechamento: parseNum(val('f-fech-dinheiro')) + parseNum(val('f-fech-cartoes')) + parseNum(val('f-fech-receber')),
+ despesas: estado.despesas.map(r => ({ desc: r.desc||'', obs: r.obs||'', valor: r.valor||0 })),
+ sangrias: estado.sangrias.map(r => ({ hora: r.hora||'', retirada: parseNum(r.retirada)||0, gerente: r.gerente||'' })),
+ pixcnpj: estado.pixcnpj.map(r => ({ nome: r.nome||'', valor: r.valor||0 })),
+ vales: estado.vales.map(r => ({ nome: r.nome||'', obs: r.obs||'', valor: r.valor||0 })),
+ receber: estado.receber.map(r => ({ nome: r.nome||'', valor: r.valor||0 })),
+ cancelamentos: estado.cancelamentos.map(r => ({ numero: r.numero||'', valor: r.valor||0, motivo: r.motivo||'' })),
+ credito: cartCred, debito: cartDeb, alimentacao: cartAli,
+ cartoes: { pix: cartPix },
+ observacoes: estado.observacoes,
+ };
+ openPrintPreview(data);
});
// Confirm send
@@ -1347,10 +1472,13 @@ document.getElementById('btn-recibo').addEventListener('click', async () => {
const btn = document.getElementById('btn-recibo');
btn.disabled = true;
try {
+ // Tenta ESC/POS primeiro; se falhar, abre preview no navegador
await tauriRecibo();
- alert('✅ Impressão enviada!');
+ // Se chegou aqui sem erro, ESC/POS funcionou
} catch(e) {
- alert('Erro ao imprimir: ' + (e.message || e));
+ // ESC/POS falhou — openPrintPreview já foi chamado dentro de tauriRecibo
+ // Só mostra alerta se nem o preview abriu
+ console.warn('Recibo:', e);
} finally {
btn.disabled = false;
}