Compare commits

..

13 Commits

Author SHA1 Message Date
root aa147885a8 v1.3.30: diferença tela lançamento usa sysTotal (troco+credito+debito+alimentacao+vales+receber+pix+pixcnpj) - saldo_esperado - cancelamentos
Build Fechamento de Caixa / build (macos-14, app) (push) Has been cancelled
Build Fechamento de Caixa / build (ubuntu-22.04, deb) (push) Has been cancelled
Build Fechamento de Caixa / build (windows-2022, msi) (push) Has been cancelled
2026-06-28 01:52:50 +00:00
root 00fa17fa52 v1.3.29: ignora HTTP 409 duplicate (ja existe = ok)
Build Fechamento de Caixa / build (macos-14, app) (push) Has been cancelled
Build Fechamento de Caixa / build (ubuntu-22.04, deb) (push) Has been cancelled
Build Fechamento de Caixa / build (windows-2022, msi) (push) Has been cancelled
2026-06-27 23:54:07 +00:00
root 5e6f8b09a9 v1.3.28: diferença = fechamento - saldo_esperado - cancelamentos (正确 formula); clientes/frango no ESC/POS
Build Fechamento de Caixa / build (macos-14, app) (push) Has been cancelled
Build Fechamento de Caixa / build (ubuntu-22.04, deb) (push) Has been cancelled
Build Fechamento de Caixa / build (windows-2022, msi) (push) Has been cancelled
2026-06-27 23:26:01 +00:00
root 9ac4eb7042 v1.3.27: buildEstadoForBackend envia TODOS totais pro Postgres (colunas SQL)
Build Fechamento de Caixa / build (macos-14, app) (push) Has been cancelled
Build Fechamento de Caixa / build (ubuntu-22.04, deb) (push) Has been cancelled
Build Fechamento de Caixa / build (windows-2022, msi) (push) Has been cancelled
2026-06-26 21:55:44 +00:00
root 2b8fa98ed7 v1.3.26: sem_acento também no turno (manhã→manha)
Build Fechamento de Caixa / build (macos-14, app) (push) Has been cancelled
Build Fechamento de Caixa / build (ubuntu-22.04, deb) (push) Has been cancelled
Build Fechamento de Caixa / build (windows-2022, msi) (push) Has been cancelled
2026-06-26 21:42:43 +00:00
root 77e927fef0 v1.3.25: add sem_acento() - remove acentos de loja antes de enviar (União→uniao)
Build Fechamento de Caixa / build (macos-14, app) (push) Has been cancelled
Build Fechamento de Caixa / build (ubuntu-22.04, deb) (push) Has been cancelled
Build Fechamento de Caixa / build (windows-2022, msi) (push) Has been cancelled
2026-06-26 19:22:10 +00:00
root 3f6b2ae6e4 v1.3.23: embed SUPABASE_ANON_KEY e SERVICE_KEY no binario (fallback) - resolve 401 em qualquer PC
Build Fechamento de Caixa / build (macos-14, app) (push) Has been cancelled
Build Fechamento de Caixa / build (ubuntu-22.04, deb) (push) Has been cancelled
Build Fechamento de Caixa / build (windows-2022, msi) (push) Has been cancelled
2026-06-26 16:45:36 +00:00
root 35dcd27dda v1.3.23: Rust salvar_fechamento envia TODAS colunas numeric + clientes/frango; ADD COLUMN clientes/frango no Postgres
Build Fechamento de Caixa / build (macos-14, app) (push) Has been cancelled
Build Fechamento de Caixa / build (ubuntu-22.04, deb) (push) Has been cancelled
Build Fechamento de Caixa / build (windows-2022, msi) (push) Has been cancelled
2026-06-26 15:43:30 +00:00
root bd867e8419 v1.3.21: PDF/envio - CONTADORES no final do buildConfirmHTML
Build Fechamento de Caixa / build (macos-14, app) (push) Has been cancelled
Build Fechamento de Caixa / build (ubuntu-22.04, deb) (push) Has been cancelled
Build Fechamento de Caixa / build (windows-2022, msi) (push) Has been cancelled
2026-06-26 14:41:43 +00:00
root da861ef964 v1.3.20: Diferença tela = SaldoCaixa(Sistema) - SaldoEsperado - Cancelamentos; CONTADORES no final do Recibo 80mm
Build Fechamento de Caixa / build (macos-14, app) (push) Has been cancelled
Build Fechamento de Caixa / build (ubuntu-22.04, deb) (push) Has been cancelled
Build Fechamento de Caixa / build (windows-2022, msi) (push) Has been cancelled
2026-06-26 14:32:25 +00:00
root 8e642f2e0c v1.3.18: SaldoCaixa(Sistema) agora inclui TROCO. Diferença = SaldoCaixa(Sistema) - SaldoEsperado - Cancelamentos
Build Fechamento de Caixa / build (macos-14, app) (push) Has been cancelled
Build Fechamento de Caixa / build (ubuntu-22.04, deb) (push) Has been cancelled
Build Fechamento de Caixa / build (windows-2022, msi) (push) Has been cancelled
2026-06-26 14:02:41 +00:00
root 7473db6b1f Revert "v1.3.16: Diferença=SaldoCaixa(Sistema)-SaldoEsperado-Cancelamentos; nomes padronizados"
Build Fechamento de Caixa / build (macos-14, app) (push) Has been cancelled
Build Fechamento de Caixa / build (ubuntu-22.04, deb) (push) Has been cancelled
Build Fechamento de Caixa / build (windows-2022, msi) (push) Has been cancelled
This reverts commit 13489d58cf.
2026-06-26 13:55:23 +00:00
root 13489d58cf v1.3.16: Diferença=SaldoCaixa(Sistema)-SaldoEsperado-Cancelamentos; nomes padronizados
Build Fechamento de Caixa / build (macos-14, app) (push) Has been cancelled
Build Fechamento de Caixa / build (ubuntu-22.04, deb) (push) Has been cancelled
Build Fechamento de Caixa / build (windows-2022, msi) (push) Has been cancelled
2026-06-26 13:52:34 +00:00
4 changed files with 141 additions and 64 deletions
+3 -3
View File
@@ -36,10 +36,10 @@ fn load_config() -> (String, String) {
} }
} }
} }
// Fallback: tenta variáveis de ambiente // Fallback 3: chaves embedadas no binário (funciona em qualquer PC sem config)
( (
std::env::var("SUPABASE_ANON_KEY").unwrap_or_default(), "sb_publishable_NCUGwstslOvVt5JtGxKB9A_p-BERG57".to_string(),
std::env::var("SUPABASE_SERVICE_KEY").unwrap_or_default(), "sb_secret_T6eHIKJDGaH53HMTG6UUKa_6ou6KfEW".to_string(),
) )
} }
+8 -9
View File
@@ -288,12 +288,6 @@ impl ReciboData {
out.extend(escpos::divider()); out.extend(escpos::divider());
} }
// ── CONTADORES ──
out.extend(escpos::line_bold("CONTADORES"));
out.extend(escpos::kv("Clientes:", &self.clientes.to_string()));
out.extend(escpos::kv("Frango Assado:", &self.frango.to_string()));
out.extend(escpos::divider());
// ── CARTÕES ── // ── CARTÕES ──
out.extend(escpos::line_bold("CARTOES")); out.extend(escpos::line_bold("CARTOES"));
out.extend(escpos::kv("Credito:", &self.fmt_money(self.credito))); out.extend(escpos::kv("Credito:", &self.fmt_money(self.credito)));
@@ -328,10 +322,9 @@ impl ReciboData {
out.extend(escpos::divider()); out.extend(escpos::divider());
// ── DIFERENÇA ── // ── DIFERENÇA ──
// Usa self.diferenca que o frontend calcula como sys_total - saldo_esperado // Diferença = total_fechamento - saldo_esperado - cancelamentos
// (não recalcula de fechamento, que é o valor contado e não deve ser usado na diferença)
out.extend(escpos::line_bold("DIFERENCA")); out.extend(escpos::line_bold("DIFERENCA"));
let diff = self.diferenca; let diff = self.fechamento - self.saldo_esperado - self.cancelamentos;
let diff_str = if diff >= 0.0 { let diff_str = if diff >= 0.0 {
format!("+{}", self.fmt_money(diff)) format!("+{}", self.fmt_money(diff))
} else { } else {
@@ -339,6 +332,12 @@ impl ReciboData {
}; };
out.extend(escpos::title(&diff_str)); out.extend(escpos::title(&diff_str));
// ── CONTADORES ──
out.extend(escpos::line_bold("CONTADORES"));
out.extend(escpos::kv("Clientes:", &self.clientes.to_string()));
out.extend(escpos::kv("Frango Assado:", &self.frango.to_string()));
out.extend(escpos::divider());
// ── OBSERVAÇÕES ── // ── OBSERVAÇÕES ──
if let Some(ref obs) = self.observacoes { if let Some(ref obs) = self.observacoes {
if !obs.trim().is_empty() { if !obs.trim().is_empty() {
+78 -38
View File
@@ -7,6 +7,29 @@ use std::time::Duration;
use tauri::State; use tauri::State;
use thiserror::Error; use thiserror::Error;
/// Remove acentos de uma string (ex: "União" → "Uniao")
fn sem_acento(s: &str) -> String {
s.replace("ã", "a")
.replace("á", "a")
.replace("à", "a")
.replace("â", "a")
.replace("é", "e")
.replace("è", "e")
.replace("ê", "e")
.replace("í", "i")
.replace("ì", "i")
.replace("î", "i")
.replace("õ", "o")
.replace("ó", "o")
.replace("ò", "o")
.replace("ô", "o")
.replace("ú", "u")
.replace("ù", "u")
.replace("û", "u")
.replace("ç", "c")
.replace("ñ", "n")
}
#[derive(Error, Debug)] #[derive(Error, Debug)]
#[allow(dead_code)] #[allow(dead_code)]
pub enum SupabaseError { pub enum SupabaseError {
@@ -69,58 +92,75 @@ impl SupabaseClient {
/// Salva/atualiza um fechamento na tabela `fechamentos_web`. /// Salva/atualiza um fechamento na tabela `fechamentos_web`.
pub fn salvar_fechamento(&self, estado: &serde_json::Value) -> Result<Value, SupabaseError> { pub fn salvar_fechamento(&self, estado: &serde_json::Value) -> Result<Value, SupabaseError> {
let uuid = estado // Normaliza loja e turno para minúsculo (CHECK constraints do Postgres)
.get("uuid") let loja = estado
.get("loja")
.and_then(|v| v.as_str()) .and_then(|v| v.as_str())
.unwrap_or(""); .map(|s| sem_acento(&s.to_lowercase()).replace(" ", "_"))
.unwrap_or_else(|| "uniao".to_string());
let data = estado.get("data").and_then(|v| v.as_str()).unwrap_or("");
let operador = estado.get("operador").and_then(|v| v.as_str()).unwrap_or("");
let id_fechamento = format!("{}_{}_{}", loja, data, operador)
.to_lowercase()
.replace(" ", "_");
let turno = estado
.get("turno")
.and_then(|v| v.as_str())
.map(|s| sem_acento(&s.to_lowercase()))
.unwrap_or_else(|| "manha".to_string());
let payload = serde_json::json!({ let payload = serde_json::json!({
"uuid": uuid, "id_fechamento": id_fechamento,
"loja": estado["loja"], "loja": loja,
"data": estado["data"], "data": data,
"operador": estado["operador"], "operador": operador,
"turno": estado["turno"], "turno": turno,
"saldo_troco": estado["saldo_troco"], "saldo_troco": estado.get("saldo_troco").and_then(|v| v.as_f64()).unwrap_or(0.0),
"saldo_esperado": estado["saldo_esperado"], "saldo_credito": estado.get("credito").and_then(|v| v.as_f64()).unwrap_or(0.0),
"fechamento": estado["fechamento"], "saldo_debito": estado.get("debito").and_then(|v| v.as_f64()).unwrap_or(0.0),
"saldo_alimentacao": estado.get("alimentacao").and_then(|v| v.as_f64()).unwrap_or(0.0),
"saldo_vales": estado.get("vales").and_then(|v| v.as_f64()).unwrap_or(0.0),
"saldo_areceber": estado.get("areceber").and_then(|v| v.as_f64()).unwrap_or(0.0),
"saldo_pixcnpj": estado.get("pixcnpj").and_then(|v| v.as_f64()).unwrap_or(0.0),
"fechamento_dinheiro": estado.get("fd").and_then(|v| v.as_f64()).unwrap_or(0.0),
"fechamento_cartoes": estado.get("fc").and_then(|v| v.as_f64()).unwrap_or(0.0),
"fechamento_areceber": estado.get("fr").and_then(|v| v.as_f64()).unwrap_or(0.0),
"total_sangrias": estado.get("total_sangrias").and_then(|v| v.as_f64()).unwrap_or(0.0),
"total_despesas": estado.get("total_despesas").and_then(|v| v.as_f64()).unwrap_or(0.0),
"total_cancelamentos": estado.get("total_cancelamentos").and_then(|v| v.as_f64()).unwrap_or(0.0),
"total_vales": estado.get("total_vales").and_then(|v| v.as_f64()).unwrap_or(0.0),
"total_pixcnpj": estado.get("total_pixcnpj").and_then(|v| v.as_f64()).unwrap_or(0.0),
"total_areceber": estado.get("total_areceber").and_then(|v| v.as_f64()).unwrap_or(0.0),
"total_cartao_credito": estado.get("total_cartao_credito").and_then(|v| v.as_f64()).unwrap_or(0.0),
"total_cartao_debito": estado.get("total_cartao_debito").and_then(|v| v.as_f64()).unwrap_or(0.0),
"total_cartao_alimentacao": estado.get("total_cartao_alimentacao").and_then(|v| v.as_f64()).unwrap_or(0.0),
"total_cartao_pix": estado.get("total_cartao_pix").and_then(|v| v.as_f64()).unwrap_or(0.0),
"saldo_esperado": estado.get("saldo_esperado").and_then(|v| v.as_f64()).unwrap_or(0.0),
"dados": estado, "dados": estado,
"observacoes": "rascunho", "observacoes": estado.get("observacoes").and_then(|v| v.as_str()).unwrap_or(""),
"clientes": estado.get("clientes").and_then(|v| v.as_i64()).unwrap_or(0),
"frango": estado.get("frango").and_then(|v| v.as_i64()).unwrap_or(0),
}); });
let _url = format!( // Primeiro tenta INSERT (upsert via Prefer)
"{}/rest/v1/fechamentos_web?uuid=eq.{}&select=id",
self.base_url, uuid
);
// Upsert via POST com Prefer: resolution=merge-duplicates
let resp = self let resp = self
.http .http
.post(&format!("{}/rest/v1/rpc/upsert_fechamento", self.base_url)) .post(&format!("{}/rest/v1/fechamentos_web", self.base_url))
.headers(self.headers(true)) .headers(self.headers(true))
.header("Prefer", "resolution=merge-duplicates")
.json(&payload) .json(&payload)
.send()?; .send()?;
if resp.status().is_success() { let status = resp.status();
Ok(serde_json::json!({ "ok": true, "uuid": uuid })) if status.is_success() || status.as_u16() == 409 {
Ok(serde_json::json!({ "ok": true, "id_fechamento": id_fechamento }))
} else { } else {
let body = resp.text().unwrap_or_default(); let body = resp.text().unwrap_or_default();
// Fallback: tenta POST direto na tabela Err(SupabaseError::Api(format!(
let resp2 = self "HTTP {}: {}",
.http status.as_u16(),
.post(&format!("{}/rest/v1/fechamentos_web", self.base_url)) body
.headers(self.headers(true)) )))
.header("Prefer", "resolution=merge-duplicates")
.json(&payload)
.send()?;
if resp2.status().is_success() {
Ok(serde_json::json!({ "ok": true, "uuid": uuid }))
} else {
Err(SupabaseError::Api(format!(
"HTTP {}: {}",
resp2.status().as_u16(),
body
)))
}
} }
} }
+52 -14
View File
@@ -855,8 +855,8 @@ function updateTotals() {
const receberTotal = estado.receber.reduce((s, r) => s + (parseNum(r['valor'] || 0) || 0), 0); const receberTotal = estado.receber.reduce((s, r) => s + (parseNum(r['valor'] || 0) || 0), 0);
document.getElementById('sys-receber').value = receberTotal > 0 ? fmtNum(receberTotal) : ''; document.getElementById('sys-receber').value = receberTotal > 0 ? fmtNum(receberTotal) : '';
// SYS total = crédito + débito + alimentação + vales + receber + pixCartão + pixCnpj (NÃO inclui troco) // Saldo de Caixa (Sistema) = troco + crédito + débito + alimentação + vales + receber + pixCartão + pixCnpj
const sysTotal = cartCred + cartDeb + cartAli + valesTotal + receberTotal + cartPix + pixCnpjTotal; const sysTotal = parseNum(val('sys-troco')) + cartCred + cartDeb + cartAli + valesTotal + receberTotal + cartPix + pixCnpjTotal;
setText('sys-total', fmt(sysTotal)); setText('sys-total', fmt(sysTotal));
// ── Fechamento Contado — auto-populate (readonly, filled from tables) ── // ── Fechamento Contado — auto-populate (readonly, filled from tables) ──
@@ -873,10 +873,9 @@ function updateTotals() {
const fr = receberTotal; const fr = receberTotal;
setText('fech-total', fmt(fd + fc + fr)); setText('fech-total', fmt(fd + fc + fr));
// Diferença = fechamento - saldo_esperado - cancelamentos // Diferença = total_fechamento (sysTotal: troco+credito+debito+alimentacao+vales+receber+pixCartao+pixCnpj) - saldo_esperado - cancelamentos
const fechamentoTotal = fd + fc + fr;
const cancelTotal = estado.cancelamentos.reduce((s,r) => s+(parseNum(r.valor||0)||0), 0); const cancelTotal = estado.cancelamentos.reduce((s,r) => s+(parseNum(r.valor||0)||0), 0);
const diff = fechamentoTotal - parseNum(val('f-saldo-esperado')) - cancelTotal; const diff = sysTotal - parseNum(val('f-saldo-esperado')) - cancelTotal;
const difEl = document.getElementById('diferenca'); const difEl = document.getElementById('diferenca');
const badgeEl = document.getElementById('dif-badge'); const badgeEl = document.getElementById('dif-badge');
if (difEl) { if (difEl) {
@@ -1060,6 +1059,18 @@ const LS_KEY = 'fc_v7';
const CFG_KEY = 'fc_cfg'; const CFG_KEY = 'fc_cfg';
function buildEstadoForBackend() { function buildEstadoForBackend() {
// Calcula totais das tabelas (mesma lógica do updateTotals)
const sangriasTotal = estado.sangrias.reduce((s, r) => s + (parseNum(r['retirada'] || 0) || 0), 0);
const despesasTotal = estado.despesas.reduce((s, r) => s + (parseNum(r['valor'] || 0) || 0), 0);
const pixcnpjTotal = estado.pixcnpj.reduce((s, r) => s + (parseNum(r['valor'] || 0) || 0), 0);
const valesTotal = estado.vales.reduce((s, r) => s + (parseNum(r['valor'] || 0) || 0), 0);
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);
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);
// Monta o objeto exactly as o backend espera (storage.rs → salvar_fechamento) // Monta o objeto exactly as o backend espera (storage.rs → salvar_fechamento)
return { return {
uuid: estado.uuid, uuid: estado.uuid,
@@ -1068,9 +1079,31 @@ function buildEstadoForBackend() {
data: estado.data, data: estado.data,
operador: estado.operador, operador: estado.operador,
turno: estado.turno, turno: estado.turno,
saldo_troco: parseNum(val('sys-troco')), // troco do sistema saldo_troco: parseNum(val('sys-troco')),
saldo_esperado: parseNum(val('f-saldo-esperado')), saldo_esperado: parseNum(val('f-saldo-esperado')),
fechamento: parseNum(val('f-fech-dinheiro')) + parseNum(val('f-fech-cartoes')) + parseNum(val('f-fech-receber')), fechamento: parseNum(val('f-fech-dinheiro')) + parseNum(val('f-fech-cartoes')) + parseNum(val('f-fech-receber')),
// Saldos de cartões (do Sys / Saldo de Caixa)
credito: parseNum(val('sys-credito')) || cartCred,
debito: parseNum(val('sys-debito')) || cartDeb,
alimentacao: parseNum(val('sys-alimentacao')) || cartAli,
pixcnpj: parseNum(val('sys-pixcnpj')) || pixcnpjTotal,
vales: parseNum(val('sys-vales')) || valesTotal,
receber: parseNum(val('sys-receber')) || receberTotal,
// Totais para colunas SQL
total_sangrias: sangriasTotal,
total_despesas: despesasTotal,
total_pixcnpj: pixcnpjTotal,
total_vales: valesTotal,
total_areceber: receberTotal,
total_cancelamentos: cancelTotal,
total_cartao_credito: cartCred,
total_cartao_debito: cartDeb,
total_cartao_alimentacao: cartAli,
total_cartao_pix: cartPix,
// Fechamento contado
fd: parseNum(val('f-fech-dinheiro')),
fc: parseNum(val('f-fech-cartoes')),
fr: parseNum(val('f-fech-receber')),
despesas: estado.despesas.map(r => ({ desc: r.desc || '', obs: r.obs || '', valor: r.valor || 0 })), 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 || '' })), 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 })), pixcnpj: estado.pixcnpj.map(r => ({ nome: r.nome || '', valor: r.valor || 0 })),
@@ -1636,6 +1669,10 @@ ${cancLines.map(l => `<div class="row"><span>${l.label}</span><span>${fmt(l.valo
<div class="row"><span>À Receber:</span><span>${fmt(frec)}</span></div> <div class="row"><span>À Receber:</span><span>${fmt(frec)}</span></div>
<div class="row total-row"><span>TOTAL:</span><span>${fmt(ftotal)}</span></div> <div class="row total-row"><span>TOTAL:</span><span>${fmt(ftotal)}</span></div>
<div class="section-title">CONTADORES</div>
<div class="row"><span>Clientes:</span><span>${data.clientes || 0}</span></div>
<div class="row"><span>Frango Assado:</span><span>${data.frango || 0}</span></div>
${data.observacoes ? `<div class="obs">${data.observacoes}</div>` : ''} ${data.observacoes ? `<div class="obs">${data.observacoes}</div>` : ''}
<div class="footer">Gerado em ${new Date().toLocaleString('pt-BR')}</div> <div class="footer">Gerado em ${new Date().toLocaleString('pt-BR')}</div>
@@ -1695,8 +1732,6 @@ function buildReportHTML(data) {
<div class="row"><span>💳 Débito:</span><span class="val">${fmt(cartDeb)}</span></div> <div class="row"><span>💳 Débito:</span><span class="val">${fmt(cartDeb)}</span></div>
<div class="row"><span>💳 Alimentação:</span><span class="val">${fmt(cartAli)}</span></div> <div class="row"><span>💳 Alimentação:</span><span class="val">${fmt(cartAli)}</span></div>
<div class="row"><span>❌ Cancelamentos:</span><span class="val">${fmt(cancelamentos)}</span></div> <div class="row"><span>❌ Cancelamentos:</span><span class="val">${fmt(cancelamentos)}</span></div>
<div class="row"><span>👥 Clientes:</span><span class="val">${data.clientes || 0}</span></div>
<div class="row"><span>🍗 Frango Assado:</span><span class="val">${data.frango || 0}</span></div>
<hr> <hr>
<div class="row"><span>📋 Fechamento (contado):</span><span class="val">${fmt(fechamento)}</span></div> <div class="row"><span>📋 Fechamento (contado):</span><span class="val">${fmt(fechamento)}</span></div>
<div class="row"><span>🖥️ Total Sistema:</span><span class="val">${fmt(sysTotal)}</span></div> <div class="row"><span>🖥️ Total Sistema:</span><span class="val">${fmt(sysTotal)}</span></div>
@@ -1704,6 +1739,9 @@ function buildReportHTML(data) {
<div class="row"><span>🎯 Saldo Esperado (contado):</span><span class="val">${fmt(saldoEsp)}</span></div> <div class="row"><span>🎯 Saldo Esperado (contado):</span><span class="val">${fmt(saldoEsp)}</span></div>
<div class="row"><span>📐 Diferença:</span><span class="val" style="color:${diffColor}">${diffStr}</span></div> <div class="row"><span>📐 Diferença:</span><span class="val" style="color:${diffColor}">${diffStr}</span></div>
<hr> <hr>
<div class="row"><span>👥 Clientes:</span><span class="val">${data.clientes || 0}</span></div>
<div class="row"><span>🍗 Frango Assado:</span><span class="val">${data.frango || 0}</span></div>
<hr>
<div style="text-align:center;font-size:10px;color:#888">ID: ${data.loja}_${data.data}_${data.operador}</div> <div style="text-align:center;font-size:10px;color:#888">ID: ${data.loja}_${data.data}_${data.operador}</div>
<div class="footer">Gerado em ${new Date().toLocaleString('pt-BR')}</div> <div class="footer">Gerado em ${new Date().toLocaleString('pt-BR')}</div>
</body></html>`; </body></html>`;
@@ -1807,10 +1845,10 @@ function buildReciboData() {
const cancelTotal = estado.cancelamentos.reduce((s,r) => s+(parseNum(r.valor||0)||0), 0); const cancelTotal = estado.cancelamentos.reduce((s,r) => s+(parseNum(r.valor||0)||0), 0);
const fechamentoCounted = parseNum(val('f-fech-dinheiro')) + parseNum(val('f-fech-cartoes')) + parseNum(val('f-fech-receber')); 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 saldoEsp = parseNum(val('f-saldo-esperado'));
// SYS total = crédito + débito + alimentação + voucher pix + pixcnpj + vales + receber (NÃO inclui troco) // Saldo de Caixa (Sistema) = troco + crédito + débito + alimentação + voucher pix + pixcnpj + vales + receber
const sysTotal = cartCred + cartDeb + cartAli + cartPix + pixCnpjTotal + valesTotal + receberTotal; const sysTotal = parseNum(val('sys-troco')) + cartCred + cartDeb + cartAli + cartPix + pixCnpjTotal + valesTotal + receberTotal;
// Diferença = fechamento - saldo_esperado - cancelamentos // Diferença = saldo de caixa (sistema) - saldo_esperado - cancelamentos
const diferenca = fechamentoCounted - saldoEsp - cancelTotal; const diferenca = sysTotal - saldoEsp - cancelTotal;
return { return {
uuid: estado.uuid, uuid: estado.uuid,
id_local: estado.id_local, id_local: estado.id_local,
@@ -1902,8 +1940,8 @@ function openConfirmModal() {
const pixcnpj = estado.pixcnpj.reduce((s,r) => s+(parseNum(r.valor||0)||0), 0); const pixcnpj = estado.pixcnpj.reduce((s,r) => s+(parseNum(r.valor||0)||0), 0);
const fechamento = parseNum(val('f-fech-dinheiro')) + parseNum(val('f-fech-cartoes')) + parseNum(val('f-fech-receber')); const fechamento = parseNum(val('f-fech-dinheiro')) + parseNum(val('f-fech-cartoes')) + parseNum(val('f-fech-receber'));
const saldoEsp = parseNum(val('f-saldo-esperado')); const saldoEsp = parseNum(val('f-saldo-esperado'));
const sysTotal = cartCred + cartDeb + cartAli + cartPix + vales + receber + pixcnpj; const sysTotal = parseNum(val('sys-troco')) + cartCred + cartDeb + cartAli + cartPix + vales + receber + pixcnpj;
const diferenca = fechamento - saldoEsp - cancelamentos; const diferenca = sysTotal - saldoEsp - cancelamentos;
const diffClass = diferenca === 0 ? '#2e7d32' : (diferenca > 0 ? '#e65100' : '#c0272d'); const diffClass = diferenca === 0 ? '#2e7d32' : (diferenca > 0 ? '#e65100' : '#c0272d');
document.getElementById('confirm-summary').innerHTML = document.getElementById('confirm-summary').innerHTML =
`<div style="margin-bottom:6px"><strong>📅 Data:</strong> ${estado.data} &nbsp; <strong>👤 Operador:</strong> ${operador} &nbsp; <strong>⏰ Turno:</strong> ${turno} &nbsp; <strong>🏪 Loja:</strong> ${loja}</div> `<div style="margin-bottom:6px"><strong>📅 Data:</strong> ${estado.data} &nbsp; <strong>👤 Operador:</strong> ${operador} &nbsp; <strong>⏰ Turno:</strong> ${turno} &nbsp; <strong>🏪 Loja:</strong> ${loja}</div>