fiscal_core/complement/
mod.rs1mod b2b;
12mod cancellation;
13mod event;
14mod helpers;
15mod inutilizacao;
16mod protocol;
17
18pub use b2b::attach_b2b;
19pub use cancellation::attach_cancellation;
20pub use event::attach_event_protocol;
21pub use inutilizacao::attach_inutilizacao;
22pub use protocol::attach_protocol;
23
24use crate::FiscalError;
25use helpers::contains_xml_tag;
26
27pub fn to_authorize(request_xml: &str, response_xml: &str) -> Result<String, FiscalError> {
49 if request_xml.is_empty() {
50 return Err(FiscalError::XmlParsing(
51 "Erro ao protocolar: o XML a protocolar está vazio.".into(),
52 ));
53 }
54 if response_xml.is_empty() {
55 return Err(FiscalError::XmlParsing(
56 "Erro ao protocolar: o retorno da SEFAZ está vazio.".into(),
57 ));
58 }
59
60 if contains_xml_tag(request_xml, "NFe") {
66 attach_protocol(request_xml, response_xml)
67 } else if contains_xml_tag(request_xml, "envEvento") {
68 attach_event_protocol(request_xml, response_xml)
69 } else if contains_xml_tag(request_xml, "inutNFe") {
70 attach_inutilizacao(request_xml, response_xml)
71 } else {
72 Err(FiscalError::XmlParsing(
73 "Tipo de documento não reconhecido para protocolação".into(),
74 ))
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[test]
83 fn to_authorize_empty_request_returns_error() {
84 let err = to_authorize("", "<retEnviNFe/>").unwrap_err();
85 assert!(matches!(err, FiscalError::XmlParsing(_)));
86 }
87
88 #[test]
89 fn to_authorize_empty_response_returns_error() {
90 let err = to_authorize("<NFe/>", "").unwrap_err();
91 assert!(matches!(err, FiscalError::XmlParsing(_)));
92 }
93
94 #[test]
95 fn to_authorize_unrecognized_document_returns_error() {
96 let err = to_authorize("<other>data</other>", "<response/>").unwrap_err();
97 let msg = format!("{err}");
98 assert!(
99 msg.contains("não reconhecido"),
100 "should mention unrecognized type: {msg}"
101 );
102 }
103
104 #[test]
107 fn to_authorize_dispatches_nfe() {
108 let request = concat!(
109 r#"<NFe><infNFe versao="4.00" Id="NFe35260112345678000199550010000000011123456780">"#,
110 r#"<DigestValue>abc</DigestValue>"#,
111 r#"</infNFe></NFe>"#
112 );
113 let response = concat!(
114 r#"<protNFe versao="4.00"><infProt>"#,
115 r#"<cStat>100</cStat><xMotivo>OK</xMotivo>"#,
116 r#"<digVal>abc</digVal>"#,
117 r#"<chNFe>35260112345678000199550010000000011123456780</chNFe>"#,
118 r#"</infProt></protNFe>"#
119 );
120 let result = to_authorize(request, response).unwrap();
121 assert!(result.contains("<nfeProc"));
122 }
123
124 #[test]
127 fn to_authorize_dispatches_env_evento() {
128 let request = concat!(
129 r#"<envEvento><idLote>1</idLote>"#,
130 r#"<evento versao="1.00"><infEvento>"#,
131 r#"<tpEvento>110110</tpEvento>"#,
132 r#"</infEvento></evento></envEvento>"#
133 );
134 let response = concat!(
135 r#"<retEnvEvento><idLote>1</idLote>"#,
136 r#"<retEvento versao="1.00"><infEvento>"#,
137 r#"<cStat>135</cStat><xMotivo>OK</xMotivo>"#,
138 r#"<tpEvento>110110</tpEvento>"#,
139 r#"</infEvento></retEvento></retEnvEvento>"#
140 );
141 let result = to_authorize(request, response).unwrap();
142 assert!(result.contains("<procEventoNFe"));
143 }
144
145 #[test]
148 fn to_authorize_dispatches_inut_nfe() {
149 let request = concat!(
150 r#"<inutNFe versao="4.00"><infInut>"#,
151 r#"<tpAmb>2</tpAmb><cUF>35</cUF><ano>26</ano>"#,
152 r#"<CNPJ>12345678000199</CNPJ><mod>55</mod><serie>1</serie>"#,
153 r#"<nNFIni>1</nNFIni><nNFFin>10</nNFFin>"#,
154 r#"</infInut></inutNFe>"#
155 );
156 let response = concat!(
157 r#"<retInutNFe versao="4.00"><infInut>"#,
158 r#"<cStat>102</cStat><xMotivo>Inutilizacao homologada</xMotivo>"#,
159 r#"<tpAmb>2</tpAmb><cUF>35</cUF><ano>26</ano>"#,
160 r#"<CNPJ>12345678000199</CNPJ><mod>55</mod><serie>1</serie>"#,
161 r#"<nNFIni>1</nNFIni><nNFFin>10</nNFFin>"#,
162 r#"</infInut></retInutNFe>"#
163 );
164 let result = to_authorize(request, response).unwrap();
165 assert!(result.contains("<ProcInutNFe"));
166 }
167}