1use super::Error;
7use serde::{Deserialize, Deserializer, Serialize, Serializer};
8use std::str::FromStr;
9
10#[derive(Debug, PartialEq, Clone)]
20pub struct Totalizacao {
21 pub valor_base_calculo: f32,
23 pub valor_icms: f32,
25 pub valor_icms_desonerado: f32,
27 pub valor_fcp: f32,
29 pub valor_base_calculo_st: f32,
31 pub valor_icms_st: f32,
33 pub valor_fcp_st: f32,
35 pub valor_fcp_st_retido: f32,
37 pub valor_produtos: f32,
39 pub valor_frete: f32,
41 pub valor_seguro: f32,
43 pub valor_desconto: f32,
45 pub valor_outros: f32,
47 pub valor_ipi: f32,
49 pub valor_ipi_devolvido: f32,
51 pub valor_ii: f32,
53 pub valor_pis: f32,
55 pub valor_cofins: f32,
57 pub valor_total: f32,
59 pub valor_aproximado_tributos: f32,
61
62 pub valor_fcp_uf_dest: f32,
65 pub valor_icms_uf_dest: f32,
67 pub valor_icms_uf_remet: f32,
69}
70
71impl FromStr for Totalizacao {
72 type Err = Error;
73
74 fn from_str(s: &str) -> Result<Self, Self::Err> {
75 quick_xml::de::from_str(s).map_err(|e| e.into())
76 }
77}
78
79impl ToString for Totalizacao {
80 fn to_string(&self) -> String {
81 quick_xml::se::to_string(self).expect("Falha ao serializar a totalização")
82 }
83}
84
85impl Default for Totalizacao {
86 fn default() -> Self {
87 Self {
88 valor_base_calculo: 0.0,
89 valor_icms: 0.0,
90 valor_icms_desonerado: 0.0,
91 valor_fcp: 0.0,
92 valor_base_calculo_st: 0.0,
93 valor_icms_st: 0.0,
94 valor_fcp_st: 0.0,
95 valor_fcp_st_retido: 0.0,
96 valor_produtos: 0.0,
97 valor_frete: 0.0,
98 valor_seguro: 0.0,
99 valor_desconto: 0.0,
100 valor_outros: 0.0,
101 valor_ipi: 0.0,
102 valor_ipi_devolvido: 0.0,
103 valor_ii: 0.0,
104 valor_pis: 0.0,
105 valor_cofins: 0.0,
106 valor_total: 0.0,
107 valor_aproximado_tributos: 0.0,
108 valor_fcp_uf_dest: 0.0,
109 valor_icms_uf_dest: 0.0,
110 valor_icms_uf_remet: 0.0,
111 }
112 }
113}
114
115impl Serialize for Totalizacao {
116 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
117 where
118 S: Serializer,
119 {
120 let icms = IcmsTot {
121 valor_base_calculo: self.valor_base_calculo,
122 valor_icms: self.valor_icms,
123 valor_icms_desonerado: self.valor_icms_desonerado,
124 valor_fcp: if self.valor_fcp > 0.0 {
125 Some(self.valor_fcp)
126 } else {
127 None
128 },
129 valor_base_calculo_st: self.valor_base_calculo_st,
130 valor_icms_st: self.valor_icms_st,
131 valor_fcp_st: if self.valor_fcp_st > 0.0 {
132 Some(self.valor_fcp_st)
133 } else {
134 None
135 },
136 valor_fcp_st_retido: if self.valor_fcp_st_retido > 0.0 {
137 Some(self.valor_fcp_st_retido)
138 } else {
139 None
140 },
141 valor_produtos: self.valor_produtos,
142 valor_frete: self.valor_frete,
143 valor_seguro: self.valor_seguro,
144 valor_desconto: self.valor_desconto,
145 valor_outros: self.valor_outros,
146 valor_ipi: self.valor_ipi,
147 valor_ipi_devolvido: if self.valor_ipi_devolvido > 0.0 {
148 Some(self.valor_ipi_devolvido)
149 } else {
150 None
151 },
152 valor_ii: self.valor_ii,
153 valor_pis: self.valor_pis,
154 valor_cofins: self.valor_cofins,
155 valor_total: self.valor_total,
156 valor_aproximado_tributos: self.valor_aproximado_tributos,
157 valor_fcp_uf_dest: if self.valor_fcp_uf_dest > 0.0 {
158 Some(self.valor_fcp_uf_dest)
159 } else {
160 None
161 },
162 valor_icms_uf_dest: if self.valor_icms_uf_dest > 0.0 {
163 Some(self.valor_icms_uf_dest)
164 } else {
165 None
166 },
167 valor_icms_uf_remet: if self.valor_icms_uf_remet > 0.0 {
168 Some(self.valor_icms_uf_remet)
169 } else {
170 None
171 },
172 };
173
174 let total = TotalContainer { icms };
175
176 total.serialize(serializer)
177 }
178}
179
180impl<'de> Deserialize<'de> for Totalizacao {
181 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
182 where
183 D: Deserializer<'de>,
184 {
185 let helper = TotalContainer::deserialize(deserializer)?;
186 Ok(Totalizacao {
187 valor_base_calculo: helper.icms.valor_base_calculo,
188 valor_icms: helper.icms.valor_icms,
189 valor_icms_desonerado: helper.icms.valor_icms_desonerado,
190 valor_fcp: helper.icms.valor_fcp.unwrap_or(0.0),
191 valor_base_calculo_st: helper.icms.valor_base_calculo_st,
192 valor_icms_st: helper.icms.valor_icms_st,
193 valor_fcp_st: helper.icms.valor_fcp_st.unwrap_or(0.0),
194 valor_fcp_st_retido: helper.icms.valor_fcp_st_retido.unwrap_or(0.0),
195 valor_produtos: helper.icms.valor_produtos,
196 valor_frete: helper.icms.valor_frete,
197 valor_seguro: helper.icms.valor_seguro,
198 valor_desconto: helper.icms.valor_desconto,
199 valor_outros: helper.icms.valor_outros,
200 valor_ipi: helper.icms.valor_ipi,
201 valor_ipi_devolvido: helper.icms.valor_ipi_devolvido.unwrap_or(0.0),
202 valor_ii: helper.icms.valor_ii,
203 valor_pis: helper.icms.valor_pis,
204 valor_cofins: helper.icms.valor_cofins,
205 valor_total: helper.icms.valor_total,
206 valor_aproximado_tributos: helper.icms.valor_aproximado_tributos,
207 valor_fcp_uf_dest: helper.icms.valor_fcp_uf_dest.unwrap_or(0.0),
208 valor_icms_uf_dest: helper.icms.valor_icms_uf_dest.unwrap_or(0.0),
209 valor_icms_uf_remet: helper.icms.valor_icms_uf_remet.unwrap_or(0.0),
210 })
211 }
212}
213
214#[derive(Deserialize, Serialize)]
215#[serde(rename = "total")]
216struct TotalContainer {
217 #[serde(rename = "ICMSTot")]
218 icms: IcmsTot,
219}
220
221#[derive(Deserialize, Serialize)]
222struct IcmsTot {
223 #[serde(rename = "$unflatten=vBC")]
224 valor_base_calculo: f32,
225
226 #[serde(rename = "$unflatten=vICMS")]
227 valor_icms: f32,
228
229 #[serde(rename = "$unflatten=vICMSDeson")]
230 #[serde(default)]
231 valor_icms_desonerado: f32,
232
233 #[serde(rename = "$unflatten=vFCP")]
234 #[serde(skip_serializing_if = "Option::is_none")]
235 valor_fcp: Option<f32>,
236
237 #[serde(rename = "$unflatten=vBCST")]
238 #[serde(default)]
239 valor_base_calculo_st: f32,
240
241 #[serde(rename = "$unflatten=vST")]
242 #[serde(default)]
243 valor_icms_st: f32,
244
245 #[serde(rename = "$unflatten=vFCPST")]
246 #[serde(skip_serializing_if = "Option::is_none")]
247 valor_fcp_st: Option<f32>,
248
249 #[serde(rename = "$unflatten=vFCPSTRet")]
250 #[serde(skip_serializing_if = "Option::is_none")]
251 valor_fcp_st_retido: Option<f32>,
252
253 #[serde(rename = "$unflatten=vProd")]
254 valor_produtos: f32,
255
256 #[serde(rename = "$unflatten=vFrete")]
257 valor_frete: f32,
258
259 #[serde(rename = "$unflatten=vSeg")]
260 valor_seguro: f32,
261
262 #[serde(rename = "$unflatten=vDesc")]
263 valor_desconto: f32,
264
265 #[serde(rename = "$unflatten=vOutro")]
266 valor_outros: f32,
267
268 #[serde(rename = "$unflatten=vII")]
269 #[serde(default)]
270 valor_ii: f32,
271
272 #[serde(rename = "$unflatten=vIPI")]
273 #[serde(default)]
274 valor_ipi: f32,
275
276 #[serde(rename = "$unflatten=vIPIDevol")]
277 #[serde(skip_serializing_if = "Option::is_none")]
278 valor_ipi_devolvido: Option<f32>,
279
280 #[serde(rename = "$unflatten=vPIS")]
281 valor_pis: f32,
282
283 #[serde(rename = "$unflatten=vCOFINS")]
284 valor_cofins: f32,
285
286 #[serde(rename = "$unflatten=vNF")]
287 valor_total: f32,
288
289 #[serde(rename = "$unflatten=vTotTrib")]
290 valor_aproximado_tributos: f32,
291
292 #[serde(rename = "$unflatten=vFCPUFDest")]
294 #[serde(skip_serializing_if = "Option::is_none")]
295 valor_fcp_uf_dest: Option<f32>,
296
297 #[serde(rename = "$unflatten=vICMSUFDest")]
298 #[serde(skip_serializing_if = "Option::is_none")]
299 valor_icms_uf_dest: Option<f32>,
300
301 #[serde(rename = "$unflatten=vICMSUFRemet")]
302 #[serde(skip_serializing_if = "Option::is_none")]
303 valor_icms_uf_remet: Option<f32>,
304}