Skip to content

Commit

Permalink
Merge pull request #1576 from ZeusAutomacao/Integracao_Hercules
Browse files Browse the repository at this point in the history
Integracao Hercules em DFe.NET
  • Loading branch information
MauricioSuporte authored Feb 27, 2025
2 parents 516cf0d + df677ec commit ca90ece
Show file tree
Hide file tree
Showing 9 changed files with 395 additions and 19 deletions.
95 changes: 95 additions & 0 deletions DFe.Utils/ExtXmlSerializerFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace DFe.Utils {

public abstract class XmlOrderFreeSerializerFactory {
// Referência https://stackoverflow.com/a/33508815
readonly static XmlAttributeOverrides overrides = new XmlAttributeOverrides();
readonly static object locker = new object();
readonly static Dictionary<Type, XmlSerializer> serializers = new Dictionary<Type, XmlSerializer>();
static HashSet<string> overridesAdded = new HashSet<string>();

static void AddOverrideAttributes(Type type, XmlAttributeOverrides overrides) {

if (type == null || type == typeof(object) || type.IsPrimitive || type == typeof(string) || type == typeof(DateTime)) {
return;
}
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) {
AddOverrideAttributes(type.GetGenericArguments()[0], overrides);
return;
}
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)) {
AddOverrideAttributes(type.GetGenericArguments()[0], overrides);
return;
}

var mask = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public;
foreach (var member in type.GetProperties(mask).Cast<MemberInfo>().Union(type.GetFields(mask))) {
var otTag = $"{type.Name}_{member.Name}";
if (overridesAdded.Contains(otTag)) {
continue;
}
XmlAttributes overrideAttr = null;
foreach (var attr in member.GetCustomAttributes<XmlElementAttribute>()) {
overrideAttr = overrideAttr ?? new XmlAttributes();
var overrideElt = new XmlElementAttribute(attr.ElementName, attr.Type) { DataType = attr.DataType, ElementName = attr.ElementName, Form = attr.Form, Namespace = attr.Namespace, Type = attr.Type };
if(attr.IsNullable) {
// Isso aqui deve ter uma logica personalizada no setter, colocar ali em cima causa erro
overrideElt.IsNullable = true;
}
overrideAttr.XmlElements.Add(overrideElt);
if(attr.Type != null) {
AddOverrideAttributes(attr.Type, overrides);
}
}
foreach (var attr in member.GetCustomAttributes<XmlArrayAttribute>()) {
overrideAttr = overrideAttr ?? new XmlAttributes();
overrideAttr.XmlArray = new XmlArrayAttribute { ElementName = attr.ElementName, Form = attr.Form, IsNullable = attr.IsNullable, Namespace = attr.Namespace };
}
foreach (var attr in member.GetCustomAttributes<XmlArrayItemAttribute>()) {
overrideAttr = overrideAttr ?? new XmlAttributes();
overrideAttr.XmlArrayItems.Add(attr);
}
foreach (var attr in member.GetCustomAttributes<XmlAnyElementAttribute>()) {
overrideAttr = overrideAttr ?? new XmlAttributes();
overrideAttr.XmlAnyElements.Add(new XmlAnyElementAttribute { Name = attr.Name, Namespace = attr.Namespace });
}
if (overrideAttr != null) {
overridesAdded.Add(otTag);
overrides.Add(type, member.Name, overrideAttr);
}
var mType = (member is PropertyInfo pi ? pi.PropertyType : member is FieldInfo fi ? fi.FieldType : null);
AddOverrideAttributes(mType, overrides);
}
}

public static XmlSerializer GetSerializer(Type type) {
if (type == null)
throw new ArgumentNullException("type");
lock (locker) {
XmlSerializer serializer;
if (!serializers.TryGetValue(type, out serializer)) {
AddOverrideAttributes(type, overrides);
serializers[type] = serializer = new XmlSerializer(type, overrides);
}
return serializer;
}
}

}

public static class TypeExtensions {
public static IEnumerable<Type> BaseTypesAndSelf(this Type type) {
while (type != null) {
yield return type;
type = type.BaseType;
}
}
}
}
26 changes: 20 additions & 6 deletions DFe.Utils/FuncoesXml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/********************************************************************************/
/********************************************************************************/
/* Projeto: Biblioteca ZeusDFe */
/* Biblioteca C# para auxiliar no desenvolvimento das demais bibliotecas DFe */
/* */
Expand Down Expand Up @@ -77,14 +77,21 @@ public static string ClasseParaXmlString<T>(T objeto)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="input"></param>
/// <param name="ignorarOrdenacaoElementos">true caso o XML possa conter elementos fora de ordem</param>
/// <returns></returns>
public static T XmlStringParaClasse<T>(string input) where T : class
public static T XmlStringParaClasse<T>(string input, bool ignorarOrdenacaoElementos = false) where T : class
{
var keyNomeClasseEmUso = typeof(T).FullName;
var ser = BuscarNoCache(keyNomeClasseEmUso, typeof(T));

XmlSerializer serializador;
if(ignorarOrdenacaoElementos) {
serializador = XmlOrderFreeSerializerFactory.GetSerializer(typeof(T));
} else {
serializador = BuscarNoCache(keyNomeClasseEmUso, typeof(T));
}

using (var sr = new StringReader(input))
return (T)ser.Deserialize(sr);
return (T)serializador.Deserialize(sr);
}

/// <summary>
Expand All @@ -94,15 +101,22 @@ public static T XmlStringParaClasse<T>(string input) where T : class
/// <typeparam name="T">Classe</typeparam>
/// <param name="arquivo">Arquivo XML</param>
/// <returns>Retorna a classe</returns>
public static T ArquivoXmlParaClasse<T>(string arquivo) where T : class
public static T ArquivoXmlParaClasse<T>(string arquivo, bool ignorarOrdenacaoElementos = false) where T : class
{
if (!File.Exists(arquivo))
{
throw new FileNotFoundException("Arquivo " + arquivo + " não encontrado!");
}

var keyNomeClasseEmUso = typeof(T).FullName;
var serializador = BuscarNoCache(keyNomeClasseEmUso, typeof(T));

XmlSerializer serializador;
if (ignorarOrdenacaoElementos) {
serializador = XmlOrderFreeSerializerFactory.GetSerializer(typeof(T));
} else {
serializador = BuscarNoCache(keyNomeClasseEmUso, typeof(T));
}

var stream = new FileStream(arquivo, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
try
{
Expand Down
85 changes: 84 additions & 1 deletion NFe.AppTeste/Schemas/leiauteNFe_v4.00.xsd
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- edited with XMLSpy v2008 (http://www.altova.com) by sas-software@procergs.rs.gov.br (PROCERGS) -->
<!-- edited with XMLSpy v2011 sp1 (http://www.altova.com) by End User (free.org) -->
<!-- PL_009 alterações de esquema decorrentes da - NT2016.002 v1.20 - 31/05/2017 13:14hs-->
<!-- PL_008g alterações de esquema decorrentes da - NT2015.002 - 15/07/2015 -->
<!-- PL_008h alterações de esquema decorrentes da - NT2015.003 - 17/09/2015 -->
Expand All @@ -17,6 +17,7 @@
<!-- PL_009l_NT2023_002_v100 - Alteração de Schema para evitar caracteres inválidos -->
<!-- PL_009m_NT2019_001_v155 - Inclusão de campos para Crédito Presumido e Redução da base de cálculo -->
<!-- PL_009m_NT2023_004_v101 - Informações de Pagamentos e Outros -->
<!-- PL_009p_NT2024_003_v101 - Produtos agropecuários -->
<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">
<xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema_v1.01.xsd"/>
<xs:include schemaLocation="tiposBasico_v4.00.xsd"/>
Expand Down Expand Up @@ -6285,6 +6286,88 @@ tipo de ato concessório:
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="agropecuario" minOccurs="0">
<xs:annotation>
<xs:documentation>Produtos Agropecurários Animais, Vegetais e Florestais</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:choice>
<xs:element name="defensivo">
<xs:annotation>
<xs:documentation>Defensivo Agrícola / Agrotóxico</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="nReceituario">
<xs:annotation>
<xs:documentation>Número do Receituário ou Receita do Defensivo / Agrotóxico</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="20"/>
<xs:minLength value="1"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="CPFRespTec" type="TCpf">
<xs:annotation>
<xs:documentation>CPF do Responsável Técnico pelo receituário</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="guiaTransito">
<xs:annotation>
<xs:documentation>Guias De Trânsito de produtos agropecurários animais, vegetais e de origem florestal.</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="tpGuia">
<xs:annotation>
<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>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:whiteSpace value="preserve"/>
<xs:enumeration value="1"/>
<xs:enumeration value="2"/>
<xs:enumeration value="3"/>
<xs:enumeration value="4"/>
<xs:enumeration value="5"/>
<xs:enumeration value="6"/>
<xs:enumeration value="7"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="UFGuia" type="TUfEmi" minOccurs="0"/>
<xs:element name="serieGuia" minOccurs="0">
<xs:annotation>
<xs:documentation>Série da Guia</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="TString">
<xs:minLength value="1"/>
<xs:maxLength value="9"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="nGuia">
<xs:annotation>
<xs:documentation>Número da Guia</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{1,9}"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="versao" type="TVerNFe" use="required">
<xs:annotation>
Expand Down
67 changes: 67 additions & 0 deletions NFe.Classes/Informacoes/Agropecuario/agroTipos.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using System.ComponentModel;
using System.Xml.Serialization;

namespace NFe.Classes.Informacoes.Agropecuario
{
/// <summary>
/// Tipo da Guia
/// <para>1 - GTA - Guia de Trânsito Animal</para>
/// <para>2 - TTA - Termo de Trânsito Animal</para>
/// <para>3 - DTA - Documento de Transferência Animal</para>
/// <para>4 - ATV - Autorização de Trânsito Vegetal</para>
/// <para>5 - PTV - Permissão de Trânsito Vegetal</para>
/// <para>6 - GTV - Guia de Trânsito Vegetal</para>
/// <para>7 - Guia Florestal (DOF, SisFlora - PA e MT ou SIAM - MG)</para>
/// </summary>
public enum TipoGuia
{
/// <summary>
/// 1 - GTA - Guia de Trânsito Animal
/// </summary>
[Description("GTA - Guia de Trânsito Animal")]
[XmlEnum("1")]
GTA = 1,

/// <summary>
/// 2 - TTA - Termo de Trânsito Animal
/// </summary>
[Description("TTA - Termo de Trânsito Animal")]
[XmlEnum("2")]
TTA = 2,

/// <summary>
/// 3 - DTA - Documento de Transferência Animal
/// </summary>
[Description("DTA - Documento de Transferência Animal")]
[XmlEnum("3")]
DTA = 3,

/// <summary>
/// 4 - ATV - Autorização de Trânsito Vegetal
/// </summary>
[Description("ATV - Autorização de Trânsito Vegetal")]
[XmlEnum("4")]
ATV = 4,

/// <summary>
/// 5 - PTV - Permissão de Trânsito Vegetal
/// </summary>
[Description("PTV - Permissão de Trânsito Vegetal")]
[XmlEnum("5")]
PTV = 5,

/// <summary>
/// 6 - GTV - Guia de Trânsito Vegetal
/// </summary>
[Description("GTV - Guia de Trânsito Vegetal")]
[XmlEnum("6")]
GTV = 6,

/// <summary>
/// 7 - Guia Florestal (DOF, SisFlora - PA e MT ou SIAM - MG)
/// </summary>
[Description("Guia Florestal (DOF, SisFlora - PA e MT ou SIAM - MG)")]
[XmlEnum("7")]
GuiaFlorestal = 7,
}
}
37 changes: 37 additions & 0 deletions NFe.Classes/Informacoes/Agropecuario/agropecuario.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
namespace NFe.Classes.Informacoes.Agropecuario
{
public class agropecuario
{
#if NET5_0_OR_GREATER//o uso de tipos de referência anuláveis não é permitido até o C# 8.0.

/// <summary>
/// ZF02 - serieGuia
/// </summary>
public defensivo? defensivo { get; set; }

Check warning on line 10 in NFe.Classes/Informacoes/Agropecuario/agropecuario.cs

View workflow job for this annotation

GitHub Actions / build (windows-2022)

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

Check warning on line 10 in NFe.Classes/Informacoes/Agropecuario/agropecuario.cs

View workflow job for this annotation

GitHub Actions / build (windows-2022)

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

/// <summary>
/// ZF04 - Guia de Trânsito
/// </summary>
public guiaTransito? guiaTransito { get; set; }

Check warning on line 15 in NFe.Classes/Informacoes/Agropecuario/agropecuario.cs

View workflow job for this annotation

GitHub Actions / build (windows-2022)

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

Check warning on line 15 in NFe.Classes/Informacoes/Agropecuario/agropecuario.cs

View workflow job for this annotation

GitHub Actions / build (windows-2022)

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

public bool ShouldSerializedefensivo()
{
return defensivo != null;
}
public bool ShouldSerializeguiaTransito()
{
return guiaTransito != null;
}
#else
/// <summary>
/// ZF02 - serieGuia
/// </summary>
public defensivo defensivo { get; set; }

/// <summary>
/// ZF04 - Guia de Trânsito
/// </summary>
public guiaTransito guiaTransito { get; set; }
#endif
}
}
15 changes: 15 additions & 0 deletions NFe.Classes/Informacoes/Agropecuario/defensivo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace NFe.Classes.Informacoes.Agropecuario
{
public class defensivo
{
/// <summary>
/// ZF03 - Número da receita ou receituário do agrotóxico / defensivo agrícola
/// </summary>
public string nReceituario { get; set; }

/// <summary>
/// ZP03a - CPF do Responsável Técnico, emitente do receituário
/// </summary>
public string CPFRespTec { get; set; }
}
}
Loading

0 comments on commit ca90ece

Please sign in to comment.