Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integracao Hercules em DFe.NET #1576

Merged
merged 12 commits into from
Feb 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading