diff --git a/fechamento-caixa-v1.2.7.tar.gz b/fechamento-caixa-v1.2.7.tar.gz
new file mode 100644
index 0000000..c7b0680
Binary files /dev/null and b/fechamento-caixa-v1.2.7.tar.gz differ
diff --git a/fechamento-caixa.exe b/fechamento-caixa.exe
index 803dae0..2bc5af6 100755
Binary files a/fechamento-caixa.exe and b/fechamento-caixa.exe differ
diff --git a/src/index.html b/src/index.html
index f636ea6..cb246b2 100644
--- a/src/index.html
+++ b/src/index.html
@@ -1047,7 +1047,6 @@ function buildEstadoForBackend() {
saldo_troco: parseNum(val('sys-troco')), // troco do sistema
saldo_esperado: parseNum(val('f-saldo-esperado')),
fechamento: parseNum(val('f-fech-dinheiro')) + parseNum(val('f-fech-cartoes')) + parseNum(val('f-fech-receber')),
- diferenca: parseNum(val('f-saldo-esperado')) - (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: r.retirada || 0, gerente: r.gerente || '' })),
pixcnpj: estado.pixcnpj.map(r => ({ nome: r.nome || '', valor: r.valor || 0 })),
@@ -1085,8 +1084,44 @@ function loadState() {
const raw = localStorage.getItem(LS_KEY);
if (!raw) return false;
const saved = JSON.parse(raw);
- // Merge carefully (cartoes may be in old format)
- Object.assign(estado, saved);
+ // Restore simple fields
+ estado.uuid = saved.uuid || estado.uuid;
+ estado.id_local = saved.id_local !== undefined ? saved.id_local : null;
+ estado.loja = saved.loja || estado.loja;
+ estado.data = saved.data || estado.data;
+ estado.operador = saved.operador || estado.operador;
+ estado.turno = saved.turno || estado.turno;
+ estado.saldo_troco = saved.saldo_troco || 0;
+ estado.saldo_esperado = saved.saldo_esperado || 0;
+ estado.fechamento = saved.fechamento || 0;
+ estado.observacoes = saved.observacoes || '';
+ estado.sync_status = saved.sync_status || 'local';
+ // Restore tables (always as arrays of objects)
+ estado.despesas = Array.isArray(saved.despesas) ? saved.despesas : [];
+ estado.sangrias = Array.isArray(saved.sangrias) ? saved.sangrias : [];
+ estado.pixcnpj = Array.isArray(saved.pixcnpj) ? saved.pixcnpj : [];
+ estado.vales = Array.isArray(saved.vales) ? saved.vales : [];
+ estado.receber = Array.isArray(saved.receber) ? saved.receber : [];
+ estado.cancelamentos = Array.isArray(saved.cancelamentos) ? saved.cancelamentos : [];
+ // Restore cartoes — each entry must be { valor: number }
+ if (saved.cartoes) {
+ estado.cartoes.credito = Array.isArray(saved.cartoes.credito)
+ ? saved.cartoes.credito.map(v => ({ valor: typeof v === 'object' && v !== null ? (v.valor || 0) : (parseNum(v) || 0) }))
+ : [];
+ estado.cartoes.debito = Array.isArray(saved.cartoes.debito)
+ ? saved.cartoes.debito.map(v => ({ valor: typeof v === 'object' && v !== null ? (v.valor || 0) : (parseNum(v) || 0) }))
+ : [];
+ estado.cartoes.alimentacao = Array.isArray(saved.cartoes.alimentacao)
+ ? saved.cartoes.alimentacao.map(v => ({ valor: typeof v === 'object' && v !== null ? (v.valor || 0) : (parseNum(v) || 0) }))
+ : [];
+ estado.cartoes.pix = Array.isArray(saved.cartoes.pix)
+ ? saved.cartoes.pix.map(v => ({ valor: typeof v === 'object' && v !== null ? (v.valor || 0) : (parseNum(v) || 0) }))
+ : [];
+ }
+ // Restore fechamento_contado
+ if (saved.fechamento_contado) {
+ estado.fechamento_contado = saved.fechamento_contado;
+ }
setVal('f-data', estado.data || '');
setVal('f-operador', estado.operador || '');
setVal('f-turno', estado.turno || '');
@@ -1094,9 +1129,10 @@ function loadState() {
setVal('f-obs', estado.observacoes || '');
setVal('f-saldo-esperado', estado.saldo_esperado === 0 ? '' : fmtNum(estado.saldo_esperado));
setVal('sys-troco', estado.saldo_troco === 0 ? '' : fmtNum(estado.saldo_troco));
- setVal('f-fech-dinheiro', estado.fechamento_contado && estado.fechamento_contado.dinheiro ? fmtNum(estado.fechamento_contado.dinheiro) : '');
- setVal('f-fech-cartoes', estado.fechamento_contado && estado.fechamento_contado.cartoes ? fmtNum(estado.fechamento_contado.cartoes) : '');
- setVal('f-fech-receber', estado.fechamento_contado && estado.fechamento_contado.receber ? fmtNum(estado.fechamento_contado.receber) : '');
+ const fc = estado.fechamento_contado || {};
+ setVal('f-fech-dinheiro', fc.dinheiro ? fmtNum(fc.dinheiro) : '');
+ setVal('f-fech-cartoes', fc.cartoes ? fmtNum(fc.cartoes) : '');
+ setVal('f-fech-receber', fc.receber ? fmtNum(fc.receber) : '');
syncHeader();
PRE_FILL_TABLES.forEach(ensureOneRow);
Object.keys(TABLES).forEach(renderTable);
@@ -1201,6 +1237,13 @@ function buildPrintHTML(data) {
const diffColor = diferenca === 0 ? '#2e7d32' : (diferenca > 0 ? '#e65100' : '#c0272d');
let rows = '';
+ // Cancelamentos (sum the array first — single cancelamentos is a float total, array is from confirm-print)
+ const cancelTotal = Array.isArray(data.cancelamentos)
+ ? data.cancelamentos.reduce((s, c) => s + (parseNum(c.valor || 0) || 0), 0)
+ : (data.cancelamentos || 0);
+ // PIX total (flat number from tauriRecibo; pixcnpj is also flat total)
+ const pixTotal = data.pix || data.voucher || 0;
+ const pixCnpjTotal = typeof data.pixcnpj === 'number' ? data.pixcnpj : 0;
// 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||''} |
`; });
@@ -1217,13 +1260,13 @@ function buildPrintHTML(data) {
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)} | |
`; });
+ // PIX CNPJ (flat total, not array)
+ if (pixCnpjTotal > 0) {
+ rows += `| PIX CNPJ | ${fmt(pixCnpjTotal)} | |
`;
}
// 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||''} |
`; });
+ if (cancelTotal > 0) {
+ rows += `| Cancelamentos | ${fmt(cancelTotal)} | |
`;
}
return `
@@ -1273,11 +1316,11 @@ ${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)}
+Crédito:${fmt(data.credito||0)}
+Débito:${fmt(data.debito||0)}
+Alimentação:${fmt(data.alimentacao||0)}
+PIX Cartão:${fmt(pixTotal)}
+Cancelamentos:${fmt(cancelTotal)}
DIFERENÇA: ${diffStr}
@@ -1340,7 +1383,6 @@ async function tauriRecibo() {
const fechamentoCounted = parseNum(val('f-fech-dinheiro')) + parseNum(val('f-fech-cartoes')) + parseNum(val('f-fech-receber'));
const saldoEsp = parseNum(val('f-saldo-esperado'));
const sysTroco = parseNum(val('sys-troco'));
- const fechamentoCounted = parseNum(val('f-fech-dinheiro')) + parseNum(val('f-fech-cartoes')) + parseNum(val('f-fech-receber'));
const data = {
uuid: estado.uuid,
id_local: estado.id_local,
@@ -1351,15 +1393,8 @@ async function tauriRecibo() {
saldo_troco: sysTroco,
saldo_esperado: saldoEsp,
fechamento: fechamentoCounted,
- diferenca: fechamentoCounted - saldoEsp, // CORRIGIDO: diferenca = fechamento - esperado
- 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||'' })),
- cartoes: { credito: cartCred, debito: cartDeb, alimentacao: cartAli, pix: cartPix },
- // Flat totals for ReciboData struct (Rust)
+ diferenca: fechamentoCounted - saldoEsp,
+ // Flat totals for ReciboData struct (Rust) — must be numbers
credito: cartCred,
debito: cartDeb,
alimentacao: cartAli,
@@ -1370,6 +1405,14 @@ async function tauriRecibo() {
vales: valesTotal,
areceber: receberTotal,
cancelamentos: cancelTotal,
+ // Full arrays for backend/storage
+ despesas_arr: estado.despesas.map(r => ({ desc: r.desc||'', obs: r.obs||'', valor: r.valor||0 })),
+ sangrias_arr: estado.sangrias.map(r => ({ hora: r.hora||'', retirada: parseNum(r.retirada)||0, gerente: r.gerente||'' })),
+ pixcnpj_arr: estado.pixcnpj.map(r => ({ nome: r.nome||'', valor: r.valor||0 })),
+ vales_arr: estado.vales.map(r => ({ nome: r.nome||'', obs: r.obs||'', valor: r.valor||0 })),
+ receber_arr: estado.receber.map(r => ({ nome: r.nome||'', valor: r.valor||0 })),
+ cancelamentos_arr: estado.cancelamentos.map(r => ({ numero: r.numero||'', valor: r.valor||0, motivo: r.motivo||'' })),
+ cartoes: { credito: cartCred, debito: cartDeb, alimentacao: cartAli, pix: cartPix },
observacoes: estado.observacoes,
sync_status: estado.sync_status,
};
@@ -1468,6 +1511,7 @@ document.getElementById('confirm-print').addEventListener('click', async () => {
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,
+ pix: cartPix, // flat float for buildPrintHTML
cartoes: { credito: estado.cartoes.credito, debito: estado.cartoes.debito, alimentacao: estado.cartoes.alimentacao, pix: estado.cartoes.pix },
observacoes: estado.observacoes,
};
@@ -1531,30 +1575,42 @@ document.getElementById('btn-limpar').addEventListener('click', () => {
document.getElementById('btn-anterior').addEventListener('click', async () => {
const loja = val('f-loja') || 'União';
- // Carrega lista de datas recentes do Supabase
- let datas = [];
+ // Carrega lista de fechamentos recentes do Supabase com uuid
+ let recentList = [];
try {
- const lista = await window.__TAURI__.core.invoke('sb_listar_recentes', { loja, limite: 20 });
- if (lista && lista.length > 0) {
- // Extrai datas únicas e já ordenadas
- datas = [...new Set(lista.map(l => l.data).filter(Boolean))].sort().reverse();
- }
+ recentList = await window.__TAURI__.core.invoke('sb_listar_recentes', { loja, limite: 20 });
} catch(e) {
console.warn('sb_listar_recentes falhou:', e);
}
+ // Extrai datas únicas ordenadas + mapeamento data→id
+ const dateIdMap = {};
+ const dateList = [];
+ if (recentList && recentList.length > 0) {
+ recentList.forEach(item => {
+ if (item.data && !dateIdMap[item.data]) {
+ dateIdMap[item.data] = item.id;
+ dateList.push(item.data);
+ }
+ });
+ dateList.sort().reverse();
+ }
+
let selectedDate = null;
- if (datas.length > 0) {
- // Mostra seletor com as datas disponíveis
- const msg = datas.map((d, i) => `${i + 1}) ${d}`).join('\n');
+ let selectedId = null;
+ if (dateList.length > 0) {
+ const msg = dateList.map((d, i) => `${i + 1}) ${d}`).join('\n');
const escolha = prompt(`Selecione o número do dia anterior:\n${msg}\n\n(Deixe em branco e clique Cancelar para ver só o dia anterior automático)`);
if (escolha !== null && escolha.trim() !== '') {
const idx = parseInt(escolha) - 1;
- if (idx >= 0 && idx < datas.length) selectedDate = datas[idx];
+ if (idx >= 0 && idx < dateList.length) {
+ selectedDate = dateList[idx];
+ selectedId = dateIdMap[selectedDate];
+ }
}
}
- // Se não escolheu data, usa dia anterior automático
+ // Se não escolheu data, usa dia anterior automático (sem id — carrega por data)
if (!selectedDate) {
const d = new Date(estado.data); d.setDate(d.getDate() - 1);
selectedDate = d.toISOString().split('T')[0];
@@ -1567,11 +1623,19 @@ document.getElementById('btn-anterior').addEventListener('click', async () => {
estado.id_local = null;
syncHeader();
- // Tenta Supabase primeiro, senão local
+ // Tenta Supabase primeiro (com id se disponível), senão local
let rascunho = null;
- try {
- rascunho = await window.__TAURI__.core.invoke('sb_carregar_rascunho', { loja, data: selectedDate });
- } catch(e) { console.warn('sb_carregar_rascunho falhou:', e); }
+ if (selectedId) {
+ // Usa sb_buscar_por_id para buscar por id numérico do Supabase
+ try {
+ rascunho = await window.__TAURI__.core.invoke('sb_buscar_por_id', { id: selectedId });
+ } catch(e) { console.warn('sb_buscar_por_id falhou:', e); }
+ }
+ if (!rascunho) {
+ try {
+ rascunho = await window.__TAURI__.core.invoke('sb_carregar_rascunho', { loja, data: selectedDate });
+ } catch(e) { console.warn('sb_carregar_rascunho falhou:', e); }
+ }
if (!rascunho) {
try {