Skip to content

Commit ca90ece

Browse files
Merge pull request #1576 from ZeusAutomacao/Integracao_Hercules
Integracao Hercules em DFe.NET
2 parents 516cf0d + df677ec commit ca90ece

File tree

9 files changed

+395
-19
lines changed

9 files changed

+395
-19
lines changed

DFe.Utils/ExtXmlSerializerFactory.cs

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using System.Xml.Serialization;
8+
9+
namespace DFe.Utils {
10+
11+
public abstract class XmlOrderFreeSerializerFactory {
12+
// Referência https://stackoverflow.com/a/33508815
13+
readonly static XmlAttributeOverrides overrides = new XmlAttributeOverrides();
14+
readonly static object locker = new object();
15+
readonly static Dictionary<Type, XmlSerializer> serializers = new Dictionary<Type, XmlSerializer>();
16+
static HashSet<string> overridesAdded = new HashSet<string>();
17+
18+
static void AddOverrideAttributes(Type type, XmlAttributeOverrides overrides) {
19+
20+
if (type == null || type == typeof(object) || type.IsPrimitive || type == typeof(string) || type == typeof(DateTime)) {
21+
return;
22+
}
23+
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) {
24+
AddOverrideAttributes(type.GetGenericArguments()[0], overrides);
25+
return;
26+
}
27+
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)) {
28+
AddOverrideAttributes(type.GetGenericArguments()[0], overrides);
29+
return;
30+
}
31+
32+
var mask = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public;
33+
foreach (var member in type.GetProperties(mask).Cast<MemberInfo>().Union(type.GetFields(mask))) {
34+
var otTag = $"{type.Name}_{member.Name}";
35+
if (overridesAdded.Contains(otTag)) {
36+
continue;
37+
}
38+
XmlAttributes overrideAttr = null;
39+
foreach (var attr in member.GetCustomAttributes<XmlElementAttribute>()) {
40+
overrideAttr = overrideAttr ?? new XmlAttributes();
41+
var overrideElt = new XmlElementAttribute(attr.ElementName, attr.Type) { DataType = attr.DataType, ElementName = attr.ElementName, Form = attr.Form, Namespace = attr.Namespace, Type = attr.Type };
42+
if(attr.IsNullable) {
43+
// Isso aqui deve ter uma logica personalizada no setter, colocar ali em cima causa erro
44+
overrideElt.IsNullable = true;
45+
}
46+
overrideAttr.XmlElements.Add(overrideElt);
47+
if(attr.Type != null) {
48+
AddOverrideAttributes(attr.Type, overrides);
49+
}
50+
}
51+
foreach (var attr in member.GetCustomAttributes<XmlArrayAttribute>()) {
52+
overrideAttr = overrideAttr ?? new XmlAttributes();
53+
overrideAttr.XmlArray = new XmlArrayAttribute { ElementName = attr.ElementName, Form = attr.Form, IsNullable = attr.IsNullable, Namespace = attr.Namespace };
54+
}
55+
foreach (var attr in member.GetCustomAttributes<XmlArrayItemAttribute>()) {
56+
overrideAttr = overrideAttr ?? new XmlAttributes();
57+
overrideAttr.XmlArrayItems.Add(attr);
58+
}
59+
foreach (var attr in member.GetCustomAttributes<XmlAnyElementAttribute>()) {
60+
overrideAttr = overrideAttr ?? new XmlAttributes();
61+
overrideAttr.XmlAnyElements.Add(new XmlAnyElementAttribute { Name = attr.Name, Namespace = attr.Namespace });
62+
}
63+
if (overrideAttr != null) {
64+
overridesAdded.Add(otTag);
65+
overrides.Add(type, member.Name, overrideAttr);
66+
}
67+
var mType = (member is PropertyInfo pi ? pi.PropertyType : member is FieldInfo fi ? fi.FieldType : null);
68+
AddOverrideAttributes(mType, overrides);
69+
}
70+
}
71+
72+
public static XmlSerializer GetSerializer(Type type) {
73+
if (type == null)
74+
throw new ArgumentNullException("type");
75+
lock (locker) {
76+
XmlSerializer serializer;
77+
if (!serializers.TryGetValue(type, out serializer)) {
78+
AddOverrideAttributes(type, overrides);
79+
serializers[type] = serializer = new XmlSerializer(type, overrides);
80+
}
81+
return serializer;
82+
}
83+
}
84+
85+
}
86+
87+
public static class TypeExtensions {
88+
public static IEnumerable<Type> BaseTypesAndSelf(this Type type) {
89+
while (type != null) {
90+
yield return type;
91+
type = type.BaseType;
92+
}
93+
}
94+
}
95+
}

DFe.Utils/FuncoesXml.cs

+20-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/********************************************************************************/
1+
/********************************************************************************/
22
/* Projeto: Biblioteca ZeusDFe */
33
/* Biblioteca C# para auxiliar no desenvolvimento das demais bibliotecas DFe */
44
/* */
@@ -77,14 +77,21 @@ public static string ClasseParaXmlString<T>(T objeto)
7777
/// </summary>
7878
/// <typeparam name="T"></typeparam>
7979
/// <param name="input"></param>
80+
/// <param name="ignorarOrdenacaoElementos">true caso o XML possa conter elementos fora de ordem</param>
8081
/// <returns></returns>
81-
public static T XmlStringParaClasse<T>(string input) where T : class
82+
public static T XmlStringParaClasse<T>(string input, bool ignorarOrdenacaoElementos = false) where T : class
8283
{
8384
var keyNomeClasseEmUso = typeof(T).FullName;
84-
var ser = BuscarNoCache(keyNomeClasseEmUso, typeof(T));
85+
86+
XmlSerializer serializador;
87+
if(ignorarOrdenacaoElementos) {
88+
serializador = XmlOrderFreeSerializerFactory.GetSerializer(typeof(T));
89+
} else {
90+
serializador = BuscarNoCache(keyNomeClasseEmUso, typeof(T));
91+
}
8592

8693
using (var sr = new StringReader(input))
87-
return (T)ser.Deserialize(sr);
94+
return (T)serializador.Deserialize(sr);
8895
}
8996

9097
/// <summary>
@@ -94,15 +101,22 @@ public static T XmlStringParaClasse<T>(string input) where T : class
94101
/// <typeparam name="T">Classe</typeparam>
95102
/// <param name="arquivo">Arquivo XML</param>
96103
/// <returns>Retorna a classe</returns>
97-
public static T ArquivoXmlParaClasse<T>(string arquivo) where T : class
104+
public static T ArquivoXmlParaClasse<T>(string arquivo, bool ignorarOrdenacaoElementos = false) where T : class
98105
{
99106
if (!File.Exists(arquivo))
100107
{
101108
throw new FileNotFoundException("Arquivo " + arquivo + " não encontrado!");
102109
}
103110

104111
var keyNomeClasseEmUso = typeof(T).FullName;
105-
var serializador = BuscarNoCache(keyNomeClasseEmUso, typeof(T));
112+
113+
XmlSerializer serializador;
114+
if (ignorarOrdenacaoElementos) {
115+
serializador = XmlOrderFreeSerializerFactory.GetSerializer(typeof(T));
116+
} else {
117+
serializador = BuscarNoCache(keyNomeClasseEmUso, typeof(T));
118+
}
119+
106120
var stream = new FileStream(arquivo, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
107121
try
108122
{

NFe.AppTeste/Schemas/leiauteNFe_v4.00.xsd

+84-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<!-- edited with XMLSpy v2008 (http://www.altova.com) by [email protected] (PROCERGS) -->
2+
<!-- edited with XMLSpy v2011 sp1 (http://www.altova.com) by End User (free.org) -->
33
<!-- PL_009 alterações de esquema decorrentes da - NT2016.002 v1.20 - 31/05/2017 13:14hs-->
44
<!-- PL_008g alterações de esquema decorrentes da - NT2015.002 - 15/07/2015 -->
55
<!-- PL_008h alterações de esquema decorrentes da - NT2015.003 - 17/09/2015 -->
@@ -17,6 +17,7 @@
1717
<!-- PL_009l_NT2023_002_v100 - Alteração de Schema para evitar caracteres inválidos -->
1818
<!-- PL_009m_NT2019_001_v155 - Inclusão de campos para Crédito Presumido e Redução da base de cálculo -->
1919
<!-- PL_009m_NT2023_004_v101 - Informações de Pagamentos e Outros -->
20+
<!-- PL_009p_NT2024_003_v101 - Produtos agropecuários -->
2021
<xs:schema xmlns="http://www.portalfiscal.inf.br/nfe" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:editix="http://www.portalfiscal.inf.br/nfe" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.portalfiscal.inf.br/nfe" elementFormDefault="qualified" attributeFormDefault="unqualified">
2122
<xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema_v1.01.xsd"/>
2223
<xs:include schemaLocation="tiposBasico_v4.00.xsd"/>
@@ -6285,6 +6286,88 @@ tipo de ato concessório:
62856286
</xs:sequence>
62866287
</xs:complexType>
62876288
</xs:element>
6289+
<xs:element name="agropecuario" minOccurs="0">
6290+
<xs:annotation>
6291+
<xs:documentation>Produtos Agropecurários Animais, Vegetais e Florestais</xs:documentation>
6292+
</xs:annotation>
6293+
<xs:complexType>
6294+
<xs:choice>
6295+
<xs:element name="defensivo">
6296+
<xs:annotation>
6297+
<xs:documentation>Defensivo Agrícola / Agrotóxico</xs:documentation>
6298+
</xs:annotation>
6299+
<xs:complexType>
6300+
<xs:sequence>
6301+
<xs:element name="nReceituario">
6302+
<xs:annotation>
6303+
<xs:documentation>Número do Receituário ou Receita do Defensivo / Agrotóxico</xs:documentation>
6304+
</xs:annotation>
6305+
<xs:simpleType>
6306+
<xs:restriction base="xs:string">
6307+
<xs:maxLength value="20"/>
6308+
<xs:minLength value="1"/>
6309+
</xs:restriction>
6310+
</xs:simpleType>
6311+
</xs:element>
6312+
<xs:element name="CPFRespTec" type="TCpf">
6313+
<xs:annotation>
6314+
<xs:documentation>CPF do Responsável Técnico pelo receituário</xs:documentation>
6315+
</xs:annotation>
6316+
</xs:element>
6317+
</xs:sequence>
6318+
</xs:complexType>
6319+
</xs:element>
6320+
<xs:element name="guiaTransito">
6321+
<xs:annotation>
6322+
<xs:documentation>Guias De Trânsito de produtos agropecurários animais, vegetais e de origem florestal.</xs:documentation>
6323+
</xs:annotation>
6324+
<xs:complexType>
6325+
<xs:sequence>
6326+
<xs:element name="tpGuia">
6327+
<xs:annotation>
6328+
<xs:documentation>Tipo da Guia: 1 - GTA; 2 - TTA; 3 - DTA; 4 - ATV; 5 - PTV; 6 - GTV; 7 - Guia Florestal (DOF, SisFlora - PA e MT, SIAM - MG)</xs:documentation>
6329+
</xs:annotation>
6330+
<xs:simpleType>
6331+
<xs:restriction base="xs:string">
6332+
<xs:whiteSpace value="preserve"/>
6333+
<xs:enumeration value="1"/>
6334+
<xs:enumeration value="2"/>
6335+
<xs:enumeration value="3"/>
6336+
<xs:enumeration value="4"/>
6337+
<xs:enumeration value="5"/>
6338+
<xs:enumeration value="6"/>
6339+
<xs:enumeration value="7"/>
6340+
</xs:restriction>
6341+
</xs:simpleType>
6342+
</xs:element>
6343+
<xs:element name="UFGuia" type="TUfEmi" minOccurs="0"/>
6344+
<xs:element name="serieGuia" minOccurs="0">
6345+
<xs:annotation>
6346+
<xs:documentation>Série da Guia</xs:documentation>
6347+
</xs:annotation>
6348+
<xs:simpleType>
6349+
<xs:restriction base="TString">
6350+
<xs:minLength value="1"/>
6351+
<xs:maxLength value="9"/>
6352+
</xs:restriction>
6353+
</xs:simpleType>
6354+
</xs:element>
6355+
<xs:element name="nGuia">
6356+
<xs:annotation>
6357+
<xs:documentation>Número da Guia</xs:documentation>
6358+
</xs:annotation>
6359+
<xs:simpleType>
6360+
<xs:restriction base="xs:string">
6361+
<xs:pattern value="[0-9]{1,9}"/>
6362+
</xs:restriction>
6363+
</xs:simpleType>
6364+
</xs:element>
6365+
</xs:sequence>
6366+
</xs:complexType>
6367+
</xs:element>
6368+
</xs:choice>
6369+
</xs:complexType>
6370+
</xs:element>
62886371
</xs:sequence>
62896372
<xs:attribute name="versao" type="TVerNFe" use="required">
62906373
<xs:annotation>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using System.ComponentModel;
2+
using System.Xml.Serialization;
3+
4+
namespace NFe.Classes.Informacoes.Agropecuario
5+
{
6+
/// <summary>
7+
/// Tipo da Guia
8+
/// <para>1 - GTA - Guia de Trânsito Animal</para>
9+
/// <para>2 - TTA - Termo de Trânsito Animal</para>
10+
/// <para>3 - DTA - Documento de Transferência Animal</para>
11+
/// <para>4 - ATV - Autorização de Trânsito Vegetal</para>
12+
/// <para>5 - PTV - Permissão de Trânsito Vegetal</para>
13+
/// <para>6 - GTV - Guia de Trânsito Vegetal</para>
14+
/// <para>7 - Guia Florestal (DOF, SisFlora - PA e MT ou SIAM - MG)</para>
15+
/// </summary>
16+
public enum TipoGuia
17+
{
18+
/// <summary>
19+
/// 1 - GTA - Guia de Trânsito Animal
20+
/// </summary>
21+
[Description("GTA - Guia de Trânsito Animal")]
22+
[XmlEnum("1")]
23+
GTA = 1,
24+
25+
/// <summary>
26+
/// 2 - TTA - Termo de Trânsito Animal
27+
/// </summary>
28+
[Description("TTA - Termo de Trânsito Animal")]
29+
[XmlEnum("2")]
30+
TTA = 2,
31+
32+
/// <summary>
33+
/// 3 - DTA - Documento de Transferência Animal
34+
/// </summary>
35+
[Description("DTA - Documento de Transferência Animal")]
36+
[XmlEnum("3")]
37+
DTA = 3,
38+
39+
/// <summary>
40+
/// 4 - ATV - Autorização de Trânsito Vegetal
41+
/// </summary>
42+
[Description("ATV - Autorização de Trânsito Vegetal")]
43+
[XmlEnum("4")]
44+
ATV = 4,
45+
46+
/// <summary>
47+
/// 5 - PTV - Permissão de Trânsito Vegetal
48+
/// </summary>
49+
[Description("PTV - Permissão de Trânsito Vegetal")]
50+
[XmlEnum("5")]
51+
PTV = 5,
52+
53+
/// <summary>
54+
/// 6 - GTV - Guia de Trânsito Vegetal
55+
/// </summary>
56+
[Description("GTV - Guia de Trânsito Vegetal")]
57+
[XmlEnum("6")]
58+
GTV = 6,
59+
60+
/// <summary>
61+
/// 7 - Guia Florestal (DOF, SisFlora - PA e MT ou SIAM - MG)
62+
/// </summary>
63+
[Description("Guia Florestal (DOF, SisFlora - PA e MT ou SIAM - MG)")]
64+
[XmlEnum("7")]
65+
GuiaFlorestal = 7,
66+
}
67+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
namespace NFe.Classes.Informacoes.Agropecuario
2+
{
3+
public class agropecuario
4+
{
5+
#if NET5_0_OR_GREATER//o uso de tipos de referência anuláveis não é permitido até o C# 8.0.
6+
7+
/// <summary>
8+
/// ZF02 - serieGuia
9+
/// </summary>
10+
public defensivo? defensivo { get; set; }
11+
12+
/// <summary>
13+
/// ZF04 - Guia de Trânsito
14+
/// </summary>
15+
public guiaTransito? guiaTransito { get; set; }
16+
17+
public bool ShouldSerializedefensivo()
18+
{
19+
return defensivo != null;
20+
}
21+
public bool ShouldSerializeguiaTransito()
22+
{
23+
return guiaTransito != null;
24+
}
25+
#else
26+
/// <summary>
27+
/// ZF02 - serieGuia
28+
/// </summary>
29+
public defensivo defensivo { get; set; }
30+
31+
/// <summary>
32+
/// ZF04 - Guia de Trânsito
33+
/// </summary>
34+
public guiaTransito guiaTransito { get; set; }
35+
#endif
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace NFe.Classes.Informacoes.Agropecuario
2+
{
3+
public class defensivo
4+
{
5+
/// <summary>
6+
/// ZF03 - Número da receita ou receituário do agrotóxico / defensivo agrícola
7+
/// </summary>
8+
public string nReceituario { get; set; }
9+
10+
/// <summary>
11+
/// ZP03a - CPF do Responsável Técnico, emitente do receituário
12+
/// </summary>
13+
public string CPFRespTec { get; set; }
14+
}
15+
}

0 commit comments

Comments
 (0)