Fix: align frontend commands with backend, fix data model mismatch
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

- Rename commands: salvar_local→salvar_fechamento, enviar_fechamento→sb_salvar_fechamento, etc.
- Fix typo: cartoes.credo→cartoes.credito
- storage: accept serde_json::Value instead of FechamentoEstado for flexibility
- Add Default derive on FechamentoEstado and SyncStatus
- Commands now return simplified JSON for frontend compatibility
This commit is contained in:
root
2026-06-21 02:16:13 +00:00
parent 3cb0f5a93b
commit 453f5ba4e3
2 changed files with 159 additions and 16 deletions
+153 -10
View File
@@ -33,7 +33,7 @@ impl serde::Serialize for StorageError {
// ── Tipos ──────────────────────────────────────────────────────────────────
#[derive(Debug, Serialize, Deserialize, Clone)]
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct FechamentoEstado {
pub id: Option<i64>,
pub uuid: String,
@@ -80,9 +80,10 @@ pub struct CartaoData {
pub voucher: Vec<TableRow>,
}
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq)]
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Default)]
#[serde(rename_all = "lowercase")]
pub enum SyncStatus {
#[default]
Local, // só local, não sincronizado
Syncing, // sync em progresso
Synced, // sincronizado com servidor
@@ -365,21 +366,126 @@ impl DbManager {
// ── Tauri Commands ─────────────────────────────────────────────────────────
// ── Tauri Commands ─────────────────────────────────────────────────────────
/// Salva fechamento com estrutura flexível ( campos simples do frontend JS )
#[tauri::command]
pub fn salvar_fechamento(
db: State<'_, DbManager>,
estado: FechamentoEstado,
estado: serde_json::Value,
) -> Result<SalvarResult, StorageError> {
db.salvar(&estado)
// Extrai campos simples do JSON flexível
let uuid = estado.get("uuid").and_then(|v| v.as_str()).unwrap_or("").to_string();
let loja = estado.get("loja").and_then(|v| v.as_str()).unwrap_or("").to_string();
let data = estado.get("data").and_then(|v| v.as_str()).unwrap_or("").to_string();
let operador = estado.get("operador").and_then(|v| v.as_str()).unwrap_or("").to_string();
let turno = estado.get("turno").and_then(|v| v.as_str()).unwrap_or("").to_string();
let saldo_troco = estado.get("saldo_troco").and_then(|v| v.as_f64()).unwrap_or(0.0);
let fechamento = estado.get("fechamento").and_then(|v| v.as_f64()).unwrap_or(0.0);
let saldo_esperado = saldo_troco + fechamento;
let diferenca = estado.get("diferenca").and_then(|v| v.as_f64()).unwrap_or(0.0);
// Constrói TableData a partir de despesas/receber arrays
let despesas: Vec<serde_json::Value> = estado.get("despesas")
.and_then(|v| v.as_array())
.map(|arr| arr.to_vec())
.unwrap_or_default();
let receber: Vec<serde_json::Value> = estado.get("receber")
.and_then(|v| v.as_array())
.map(|arr| arr.to_vec())
.unwrap_or_default();
let to_table_row = |v: &serde_json::Value| -> TableRow {
TableRow {
descricao: v.get("desc").and_then(|s| s.as_str()).map(String::from),
valor: v.get("valor").and_then(|n| n.as_f64()),
..Default::default()
}
};
let tabelas = TableData {
despesas: despesas.iter().map(to_table_row).collect(),
areceber: receber.iter().map(to_table_row).collect(),
..Default::default()
};
// Cartoes como scalars
let cartoes_json = estado.get("cartoes");
let cartoes = CartaoData {
credito: vec![TableRow { valor: cartoes_json.and_then(|c| c.get("credito")).and_then(|v| v.as_f64()), ..Default::default() }],
debito: vec![TableRow { valor: cartoes_json.and_then(|c| c.get("debito")).and_then(|v| v.as_f64()), ..Default::default() }],
alimentacao: vec![TableRow { valor: cartoes_json.and_then(|c| c.get("alimentacao")).and_then(|v| v.as_f64()), ..Default::default() }],
voucher: vec![TableRow { valor: cartoes_json.and_then(|c| c.get("voucher")).and_then(|v| v.as_f64()), ..Default::default() }],
};
let estado_rust = FechamentoEstado {
id: estado.get("id_local").and_then(|v| v.as_i64()),
uuid,
loja,
data,
operador,
turno,
saldo_troco,
fechamento,
saldo_esperado,
tabelas,
cartoes,
sync_status: SyncStatus::Local,
..Default::default()
};
db.salvar(&estado_rust)
}
/// Carrega rascunho e devolve estrutura simples para o frontend
#[tauri::command]
pub fn carregar_rascunho(
db: State<'_, DbManager>,
loja: String,
data: String,
) -> Result<Option<FechamentoEstado>, StorageError> {
db.carregar_rascunho(&loja, &data)
) -> Result<Option<serde_json::Value>, StorageError> {
match db.carregar_rascunho(&loja, &data)? {
Some(e) => {
// Simplifica para formato que o frontend espera
let total_sangrias: f64 = e.tabelas.sangrias.iter().filter_map(|r| r.valor).sum();
let total_despesas: f64 = e.tabelas.despesas.iter().filter_map(|r| r.valor).sum();
let total_receber: f64 = e.tabelas.areceber.iter().filter_map(|r| r.valor).sum();
let despesa_rows: Vec<_> = e.tabelas.despesas.iter().filter_map(|r| {
r.descricao.as_ref().map(|d| serde_json::json!({"desc": d, "valor": r.valor}))
}).collect();
let receber_rows: Vec<_> = e.tabelas.areceber.iter().filter_map(|r| {
r.descricao.as_ref().map(|d| serde_json::json!({"desc": d, "valor": r.valor}))
}).collect();
Ok(Some(serde_json::json!({
"id_local": e.id,
"uuid": e.uuid,
"loja": e.loja,
"data": e.data,
"operador": e.operador,
"turno": e.turno,
"saldo_troco": e.saldo_troco,
"fechamento": e.fechamento,
"saldo_esperado": e.saldo_esperado,
"diferenca": e.fechamento - e.saldo_esperado,
"despesas": despesa_rows,
"total_sangrias": total_sangrias,
"total_despesas": total_despesas,
"vales": 0.0,
"cartoes": {
"credito": e.cartoes.credito.iter().find_map(|r| r.valor).unwrap_or(0.0),
"debito": e.cartoes.debito.iter().find_map(|r| r.valor).unwrap_or(0.0),
"alimentacao": e.cartoes.alimentacao.iter().find_map(|r| r.valor).unwrap_or(0.0),
"voucher": e.cartoes.voucher.iter().find_map(|r| r.valor).unwrap_or(0.0),
"cancelamentos": 0.0,
},
"receber": receber_rows,
"observacoes": "",
"sync_status": "local",
})))
}
None => Ok(None),
}
}
#[tauri::command]
@@ -387,16 +493,53 @@ pub fn listar_fechamentos(
db: State<'_, DbManager>,
loja: String,
limite: Option<i64>,
) -> Result<Vec<FechamentoEstado>, StorageError> {
db.listar(&loja, limite.unwrap_or(50))
) -> Result<Vec<serde_json::Value>, StorageError> {
let rows = db.listar(&loja, limite.unwrap_or(50))?;
Ok(rows.into_iter().map(|e| serde_json::json!({
"id": e.id,
"uuid": e.uuid,
"data": e.data,
"operador": e.operador,
"turno": e.turno,
"saldo_esperado": e.saldo_esperado,
"sync_status": format!("{:?}", e.sync_status).to_lowercase(),
})).collect())
}
#[tauri::command]
pub fn buscar_fechamento_por_id(
db: State<'_, DbManager>,
id: i64,
) -> Result<Option<FechamentoEstado>, StorageError> {
db.buscar_por_id(id)
) -> Result<Option<serde_json::Value>, StorageError> {
match db.buscar_por_id(id)? {
Some(e) => Ok(Some(serde_json::json!({
"id_local": e.id,
"uuid": e.uuid,
"loja": e.loja,
"data": e.data,
"operador": e.operador,
"turno": e.turno,
"saldo_troco": e.saldo_troco,
"fechamento": e.fechamento,
"saldo_esperado": e.saldo_esperado,
"diferenca": e.fechamento - e.saldo_esperado,
"despesas": e.tabelas.despesas.iter().filter_map(|r| r.descricao.as_ref().map(|d| serde_json::json!({"desc": d, "valor": r.valor}))).collect::<Vec<_>>(),
"total_sangrias": e.tabelas.sangrias.iter().filter_map(|r| r.valor).sum::<f64>(),
"total_despesas": e.tabelas.despesas.iter().filter_map(|r| r.valor).sum::<f64>(),
"vales": 0.0,
"cartoes": {
"credito": e.cartoes.credito.iter().find_map(|r| r.valor).unwrap_or(0.0),
"debito": e.cartoes.debito.iter().find_map(|r| r.valor).unwrap_or(0.0),
"alimentacao": e.cartoes.alimentacao.iter().find_map(|r| r.valor).unwrap_or(0.0),
"voucher": e.cartoes.voucher.iter().find_map(|r| r.valor).unwrap_or(0.0),
"cancelamentos": 0.0,
},
"receber": e.tabelas.areceber.iter().filter_map(|r| r.descricao.as_ref().map(|d| serde_json::json!({"desc": d, "valor": r.valor}))).collect::<Vec<_>>(),
"observacoes": "",
"sync_status": format!("{:?}", e.sync_status).to_lowercase(),
}))),
None => Ok(None),
}
}
#[tauri::command]