use crate::nfe::autorizacao::det_process::entity::DetProcess;
use super::Total;
use anyhow::{Error, Result};
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename = "total")]
pub struct TotalProcess {
#[serde(rename = "ICMSTot")]
pub icms_tot: ICMSTot,
#[serde(rename = "IBSCBSTot", skip_serializing_if = "Option::is_none")]
pub ibs_cbs_tot: Option<IBSCBSTot>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct IBSCBSTot {
#[serde(rename = "vBCIBSCBS")]
pub v_bc_ibs_cbs: String,
#[serde(rename = "gIBS")]
pub g_ibs: GIBS,
#[serde(rename = "gCBS")]
pub g_cbs: GCBS,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct GIBS {
#[serde(rename = "gIBSUF")]
pub g_ibs_uf: GIBSUF,
#[serde(rename = "gIBSMun")]
pub g_ibs_mun: GIBSMun,
#[serde(rename = "vIBS")]
pub v_ibs: String,
#[serde(rename = "vCredPres")]
pub v_cred_pres: Option<Decimal>,
#[serde(rename = "vCredPresCondSus")]
pub v_cred_pres_cond_sus: Option<Decimal>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct GIBSUF {
#[serde(rename = "vDif")]
pub v_dif: Decimal,
#[serde(rename = "vDevTrib")]
pub v_dev_trib: Decimal,
#[serde(rename = "vIBSUF")]
pub v_ibs_uf: String,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct GIBSMun {
#[serde(rename = "vDif")]
pub v_dif: Decimal,
#[serde(rename = "vDevTrib")]
pub v_dev_trib: Decimal,
#[serde(rename = "vIBSMun")]
pub v_ibs_mun: String,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct GCBS {
#[serde(rename = "vDif")]
pub v_dif: Decimal,
#[serde(rename = "vDevTrib")]
pub v_dev_trib: Decimal,
#[serde(rename = "vCBS")]
pub v_cbs: String,
#[serde(rename = "vCredPres")]
pub v_cred_pres: Option<Decimal>,
#[serde(rename = "vCredPresCondSus")]
pub v_cred_pres_cond_sus: Option<Decimal>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ICMSTot {
#[serde(rename = "vBC")]
pub v_bc: String,
#[serde(rename = "vICMS")]
pub v_icms: String,
#[serde(rename = "vICMSDeson")]
pub v_icms_deson: String,
#[serde(rename = "vFCPUFDest")]
pub v_fcpuf_dest: String,
#[serde(rename = "vICMSUFDest")]
pub v_icms_uf_dest: String,
#[serde(rename = "vICMSUFRemet")]
pub v_icms_uf_remet: String,
#[serde(rename = "vFCP")]
pub v_fcp: String,
#[serde(rename = "vBCST")]
pub v_bc_st: String,
#[serde(rename = "vST")]
pub v_st: String,
#[serde(rename = "vFCPST")]
pub v_fcpst: String,
#[serde(rename = "vFCPSTRet")]
pub v_fcpst_ret: String,
#[serde(rename = "vProd")]
pub v_prod: String,
#[serde(rename = "vFrete")]
pub v_frete: String,
#[serde(rename = "vSeg")]
pub v_seg: String,
#[serde(rename = "vDesc")]
pub v_desc: String,
#[serde(rename = "vII")]
pub v_ii: String,
#[serde(rename = "vIPI")]
pub v_ipi: String,
#[serde(rename = "vIPIDevol")]
pub v_ipi_devol: String,
#[serde(rename = "vPIS")]
pub v_pis: String,
#[serde(rename = "vCOFINS")]
pub v_cofins: String,
#[serde(rename = "vOutro")]
pub v_outro: String,
#[serde(rename = "vNF")]
pub v_nf: String,
#[serde(rename = "vTotTrib")]
pub v_tot_trib: String,
}
pub fn total_process(
total: Total,
dets: Vec<DetProcess>,
_ambiente: u8,
_active_ibscbs: Option<String>,
) -> Result<TotalProcess, Error> {
let mut v_bc_ibs_cbs_total = 0.0;
let mut ibs_uf_total = 0.0;
let mut ibs_uf_dif_total = 0.0;
let mut ibs_uf_dev_trib_total = 0.0;
let mut ibs_mun_total = 0.0;
let mut ibs_mun_dif_total = 0.0;
let mut ibs_mun_dev_trib_total = 0.0;
let mut ibs_total = 0.0;
let mut cbs_total = 0.0;
let mut cbs_dif_total = 0.0;
let mut cbs_dev_trib_total = 0.0;
for det in &dets {
if let Some(ibs_cbs) = det.imposto.ibs_cbs.as_ref() {
let v_bc = ibs_cbs.g_ibscbs.v_bc.parse::<f64>().unwrap_or(0.0);
v_bc_ibs_cbs_total += v_bc;
let v_ibs_uf = ibs_cbs
.g_ibscbs
.g_ibs_uf
.v_ibs_uf
.parse::<f64>()
.unwrap_or(0.0);
ibs_uf_total += v_ibs_uf;
if let Some(ref g_dif) = ibs_cbs.g_ibscbs.g_ibs_uf.g_dif {
ibs_uf_dif_total += g_dif.v_dif.to_string().parse::<f64>().unwrap_or(0.0);
}
if let Some(ref g_dev) = ibs_cbs.g_ibscbs.g_ibs_uf.g_dev_trib {
ibs_uf_dev_trib_total += g_dev.v_dev_trib.to_string().parse::<f64>().unwrap_or(0.0);
}
let v_ibs_mun = ibs_cbs
.g_ibscbs
.g_ibs_mun
.v_ibs_mun
.parse::<f64>()
.unwrap_or(0.0);
ibs_mun_total += v_ibs_mun;
if let Some(ref g_dif) = ibs_cbs.g_ibscbs.g_ibs_mun.g_dif {
ibs_mun_dif_total += g_dif.v_dif.to_string().parse::<f64>().unwrap_or(0.0);
}
if let Some(ref g_dev) = ibs_cbs.g_ibscbs.g_ibs_mun.g_dev_trib {
ibs_mun_dev_trib_total +=
g_dev.v_dev_trib.to_string().parse::<f64>().unwrap_or(0.0);
}
let v_ibs = ibs_cbs.g_ibscbs.v_ibs.parse::<f64>().unwrap_or(0.0);
ibs_total += v_ibs;
let v_cbs = ibs_cbs.g_ibscbs.g_cbs.v_cbs.parse::<f64>().unwrap_or(0.0);
cbs_total += v_cbs;
if let Some(ref g_dif) = ibs_cbs.g_ibscbs.g_cbs.g_dif {
cbs_dif_total += g_dif.v_dif.to_string().parse::<f64>().unwrap_or(0.0);
}
if let Some(ref g_dev) = ibs_cbs.g_ibscbs.g_cbs.g_dev_trib {
cbs_dev_trib_total += g_dev.v_dev_trib.to_string().parse::<f64>().unwrap_or(0.0);
}
}
}
let send_ibs_cbs = Some(IBSCBSTot {
v_bc_ibs_cbs: format!("{:.2}", v_bc_ibs_cbs_total),
g_ibs: GIBS {
g_ibs_uf: GIBSUF {
v_dif: Decimal::from_str_exact(&format!("{:.2}", ibs_uf_dif_total))
.unwrap_or(Decimal::new(0, 2)),
v_dev_trib: Decimal::from_str_exact(&format!("{:.2}", ibs_uf_dev_trib_total))
.unwrap_or(Decimal::new(0, 2)),
v_ibs_uf: format!("{:.2}", ibs_uf_total),
},
g_ibs_mun: GIBSMun {
v_dif: Decimal::from_str_exact(&format!("{:.2}", ibs_mun_dif_total))
.unwrap_or(Decimal::new(0, 2)),
v_dev_trib: Decimal::from_str_exact(&format!("{:.2}", ibs_mun_dev_trib_total))
.unwrap_or(Decimal::new(0, 2)),
v_ibs_mun: format!("{:.2}", ibs_mun_total),
},
v_ibs: format!("{:.2}", ibs_total),
v_cred_pres: Some(Decimal::new(0, 2)),
v_cred_pres_cond_sus: Some(Decimal::new(0, 2)),
},
g_cbs: GCBS {
v_dif: Decimal::from_str_exact(&format!("{:.2}", cbs_dif_total))
.unwrap_or(Decimal::new(0, 2)),
v_dev_trib: Decimal::from_str_exact(&format!("{:.2}", cbs_dev_trib_total))
.unwrap_or(Decimal::new(0, 2)),
v_cbs: format!("{:.2}", cbs_total),
v_cred_pres: Some(Decimal::new(0, 2)),
v_cred_pres_cond_sus: Some(Decimal::new(0, 2)),
},
});
let send_icms_tot = ICMSTot {
v_bc: format!("{:.2}", total.v_bc),
v_icms: format!("{:.2}", total.v_icms),
v_icms_deson: format!("{:.2}", total.v_icms_deson),
v_fcpuf_dest: format!("{:.2}", total.v_fcpuf_dest),
v_icms_uf_dest: format!("{:.2}", total.v_icms_uf_dest),
v_icms_uf_remet: format!("{:.2}", total.v_icms_uf_remet),
v_fcp: format!("{:.2}", total.v_fcp),
v_bc_st: format!("{:.2}", total.v_bc_st),
v_st: format!("{:.2}", total.v_st),
v_fcpst: format!("{:.2}", total.v_fcpst),
v_fcpst_ret: format!("{:.2}", total.v_fcpst_ret),
v_prod: format!("{:.2}", total.v_prod),
v_frete: format!("{:.2}", total.v_frete),
v_seg: format!("{:.2}", total.v_seg),
v_desc: format!("{:.2}", total.v_desc),
v_ii: format!("{:.2}", total.v_ii),
v_ipi: format!("{:.2}", total.v_ipi),
v_ipi_devol: format!("{:.2}", total.v_ipi_devol),
v_pis: format!("{:.2}", total.v_pis),
v_cofins: format!("{:.2}", total.v_cofins),
v_outro: format!("{:.2}", total.v_outro),
v_nf: format!("{:.2}", total.v_nf),
v_tot_trib: format!("{:.2}", total.v_tot_trib),
};
return Ok(TotalProcess {
icms_tot: send_icms_tot,
ibs_cbs_tot: send_ibs_cbs,
});
}