diff --git a/NFe.AppTeste/MainWindow.xaml b/NFe.AppTeste/MainWindow.xaml
index 2589fda7..f84e452b 100644
--- a/NFe.AppTeste/MainWindow.xaml
+++ b/NFe.AppTeste/MainWindow.xaml
@@ -962,6 +962,10 @@
Margin="375,185,0,0" VerticalAlignment="Top" Width="177" Click="BtnConsultaRecibo_Click" />
+
+
diff --git a/NFe.AppTeste/MainWindow.xaml.cs b/NFe.AppTeste/MainWindow.xaml.cs
index 810ac910..8c06723b 100644
--- a/NFe.AppTeste/MainWindow.xaml.cs
+++ b/NFe.AppTeste/MainWindow.xaml.cs
@@ -75,6 +75,9 @@
using NFe.Utils.Excecoes;
using NFe.Utils.Tributacao.Federal;
using Image = System.Drawing.Image;
+using static System.Net.Mime.MediaTypeNames;
+using System.Text;
+using System.Security.Cryptography;
namespace NFe.AppTeste
{
@@ -289,6 +292,149 @@ private void BtnConsultaGtin_Click(object sender, RoutedEventArgs e)
}
}
+ private void BtnInsucessoEntrega_Click(object sender, RoutedEventArgs e)
+ {
+ const string titulo = "Insucesso Entrega NFe";
+
+ try
+ {
+ #region Insucesso Entrega NFe
+
+ var idlote = Funcoes.InpuBox(this, titulo, "Identificador de controle do Lote de envio:", "1");
+ if (string.IsNullOrEmpty(idlote)) throw new Exception("A Id do Lote deve ser informada!");
+
+ var sequenciaEvento = Funcoes.InpuBox(this, titulo, "Número sequencial do evento:", "1");
+ if (string.IsNullOrEmpty(sequenciaEvento))
+ throw new Exception("O número sequencial deve ser informado!");
+
+ var chave = Funcoes.InpuBox(this, titulo, "Chave da NFe:", "35240311656919000154550750000008281647961399");
+ if (string.IsNullOrEmpty(chave)) throw new Exception("A Chave deve ser informada!");
+ if (chave.Length != 44) throw new Exception("Chave deve conter 44 caracteres!");
+
+ var dhTentativaEntregaStr = Funcoes.InpuBox(this, titulo, "Data da tentativa da entrega da NFe", DateTimeOffset.Now.ToString("dd/MM/yyyy"));
+ if (string.IsNullOrEmpty(dhTentativaEntregaStr)) throw new Exception("A Data deve ser informada!");
+
+ if (!DateTimeOffset.TryParse(dhTentativaEntregaStr, out DateTimeOffset dhTentativaEntrega))
+ throw new Exception("Data inválida!");
+
+ var motivoInsucessoStr = Funcoes.InpuBox(this, titulo, "Motivo do Insucesso da entrega da NFe", "1");
+ if (!Enum.TryParse(motivoInsucessoStr, out NFe.Classes.Servicos.Evento.MotivoInsucesso motivoInsucesso)) throw new Exception("Motivo deve ser informada!");
+
+ string justificativa = null;
+
+ if (motivoInsucesso == Classes.Servicos.Evento.MotivoInsucesso.Outros)
+ justificativa = Funcoes.InpuBox(this, titulo, "Motivo");
+
+ var imagemExemploBase64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAADUlEQVR42gECAP3/AP8BAQEATamDVwAAAABJRU5ErkJggg==";
+ var concatenacao = chave + imagemExemploBase64;
+
+ var hashTentativaEntrega = string.Empty;
+ using (SHA1 sha1 = SHA1.Create())
+ {
+ byte[] inputBytes = Encoding.UTF8.GetBytes(concatenacao);
+ byte[] hashBytes = sha1.ComputeHash(inputBytes);
+ // O hash SHA-1 terá 20 bytes
+ hashTentativaEntrega = Convert.ToBase64String(hashBytes).Trim();
+ }
+
+ int? nTentativa = null;
+ var nTentativaStr = Funcoes.InpuBox(this, titulo, "Número tentativas de entrega:", "1");
+ if (!string.IsNullOrEmpty(nTentativaStr)) nTentativa = Convert.ToInt32(nTentativaStr);
+
+ DateTimeOffset? dhHashTentativaEntrega = null;
+ var dhHashTentativaEntregaStr = Funcoes.InpuBox(this, titulo, "Data geração do Hash Tentativa na Entrega:", DateTimeOffset.Now.ToString("dd/MM/yyyy"));
+ if (!string.IsNullOrEmpty(dhHashTentativaEntregaStr)) dhHashTentativaEntrega = Convert.ToDateTime(dhHashTentativaEntregaStr);
+
+ decimal? latGps = null;
+ var latGpsStr = Funcoes.InpuBox(this, titulo, "Latitude GPS:");
+ if (!string.IsNullOrEmpty(latGpsStr)) latGps = Convert.ToDecimal(latGpsStr);
+
+ decimal? longGps = null;
+ var longGpsStr = Funcoes.InpuBox(this, titulo, "Latitude GPS:");
+ if (!string.IsNullOrEmpty(longGpsStr)) longGps = Convert.ToDecimal(longGpsStr);
+
+
+ var servicoNFe = new ServicosNFe(_configuracoes.CfgServico);
+ var cpfcnpj = string.IsNullOrEmpty(_configuracoes.Emitente.CNPJ)
+ ? _configuracoes.Emitente.CPF
+ : _configuracoes.Emitente.CNPJ;
+
+ var retornoInsucesso = servicoNFe.RecepcaoEventoInsucessoEntrega(Convert.ToInt32(idlote),
+ Convert.ToInt16(sequenciaEvento), cpfcnpj, chave, dhTentativaEntrega, motivoInsucesso, hashTentativaEntrega, nTentativa,
+ dhHashTentativaEntrega, latGps, longGps, justificativa);
+
+ TrataRetorno(retornoInsucesso);
+
+ #endregion
+ }
+ catch (ComunicacaoException ex)
+ {
+ Funcoes.Mensagem(ex.Message, "Erro", MessageBoxButton.OK);
+ }
+ catch (ValidacaoSchemaException ex)
+ {
+ Funcoes.Mensagem(ex.Message, "Erro", MessageBoxButton.OK);
+ }
+ catch (Exception ex)
+ {
+ if (!string.IsNullOrEmpty(ex.Message))
+ Funcoes.Mensagem(ex.Message, "Erro", MessageBoxButton.OK);
+ }
+ }
+
+ private void BtnCancInsucessoEntrega_Click(object sender, RoutedEventArgs e)
+ {
+ const string titulo = "Cancelar Insucesso Entrega NFe";
+
+ try
+ {
+ #region Cancelar Insucesso Entrega NFe
+
+ var idlote = Funcoes.InpuBox(this, titulo, "Identificador de controle do Lote de envio:", "1");
+ if (string.IsNullOrEmpty(idlote)) throw new Exception("A Id do Lote deve ser informada!");
+
+ var sequenciaEvento = Funcoes.InpuBox(this, titulo, "Número sequencial do evento:", "1");
+ if (string.IsNullOrEmpty(sequenciaEvento))
+ throw new Exception("O número sequencial deve ser informado!");
+
+ var chave = Funcoes.InpuBox(this, titulo, "Chave da NFe:", "35240311656919000154550750000008281647961399");
+ if (string.IsNullOrEmpty(chave)) throw new Exception("A Chave deve ser informada!");
+ if (chave.Length != 44) throw new Exception("Chave deve conter 44 caracteres!");
+
+ var nProtEvento = Funcoes.InpuBox(this, titulo, "Nº Prot Evento:");
+
+ if (string.IsNullOrEmpty(nProtEvento))
+ throw new Exception("O nº Prot Evento deve ser informado!");
+
+
+
+ var servicoNFe = new ServicosNFe(_configuracoes.CfgServico);
+ var cpfcnpj = string.IsNullOrEmpty(_configuracoes.Emitente.CNPJ)
+ ? _configuracoes.Emitente.CPF
+ : _configuracoes.Emitente.CNPJ;
+
+ var retornoInsucesso = servicoNFe.RecepcaoEventoCancInsucessoEntrega(Convert.ToInt32(idlote),
+ Convert.ToInt16(sequenciaEvento), cpfcnpj, chave, nProtEvento);
+
+ TrataRetorno(retornoInsucesso);
+
+ #endregion
+ }
+ catch (ComunicacaoException ex)
+ {
+ Funcoes.Mensagem(ex.Message, "Erro", MessageBoxButton.OK);
+ }
+ catch (ValidacaoSchemaException ex)
+ {
+ Funcoes.Mensagem(ex.Message, "Erro", MessageBoxButton.OK);
+ }
+ catch (Exception ex)
+ {
+ if (!string.IsNullOrEmpty(ex.Message))
+ Funcoes.Mensagem(ex.Message, "Erro", MessageBoxButton.OK);
+ }
+ }
+
private void BtnConsultaXml_Click(object sender, RoutedEventArgs e)
{
try
diff --git a/NFe.AppTeste/NFe.AppTeste.csproj b/NFe.AppTeste/NFe.AppTeste.csproj
index 50ce9af1..4efbf95f 100644
--- a/NFe.AppTeste/NFe.AppTeste.csproj
+++ b/NFe.AppTeste/NFe.AppTeste.csproj
@@ -1000,6 +1000,20 @@
NFe.Utils
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Schema XML de validação do evento de Comprovante de Entrega da NF-e
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Versão do Aplicativo do Autor do Evento
+
+
+
+
+ Data e hora do final da tentativa entrega. Formato AAAA-MMDDThh:mm:ssTZD
+
+
+
+
+
+
+ Número da tentativa de entrega que não teve sucesso
+
+
+
+
+
+
+
+
+
+ Motivo do insucesso - 1 – Recebedor não encontrado
+ 2 – Recusa do recebedor
+ 3 – Endereço inexistente
+ 4 – Outros (exige informar justificativa)
+
+
+
+
+
+
+
+
+
+
+
+
+ Justificativa do motivo do insucesso. Informar apenas para tpMotivo=4
+
+
+
+
+
+
+
+
+
+
+ Latitude do ponto de entrega
+
+
+
+
+ Longitude do ponto de entrega
+
+
+
+
+ Hash (SHA1) no formato Base64 resultante da concatenação: Chave de acesso da NFe + Base64 da imagem capturada da entrega (Exemplo: imagem capturada da assinatura eletrônica, digital do recebedor, foto, etc)
+ O hashCSRT é o resultado das funções SHA-1 e base64 do token CSRT fornecido pelo fisco + chave de acesso do DF-e. (Implementação em futura NT)
+Observação: 28 caracteres são representados no schema como 20 bytes do tipo base64Binary
+
+
+
+
+
+
+
+
+
+ Data e hora da geração do hash da tentativa de entrega. Formato AAAA-MMDDThh:mm:ssTZD.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NFe.AppTeste/Schemas/e110193_v1.00.xsd b/NFe.AppTeste/Schemas/e110193_v1.00.xsd
new file mode 100644
index 00000000..86db7e82
--- /dev/null
+++ b/NFe.AppTeste/Schemas/e110193_v1.00.xsd
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+ Schema XML de validação do evento de Cancelamento do Comprovante de Entrega da NF-e
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Versão do Aplicativo do Autor do Evento
+
+
+
+
+ Número do Protocolo de Autorização do Evento da NF-e a que se refere este cancelamento.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NFe.AppTeste/Schemas/envEventoCancInsucessoNFe_v1.00.xsd b/NFe.AppTeste/Schemas/envEventoCancInsucessoNFe_v1.00.xsd
new file mode 100644
index 00000000..f2f3ee86
--- /dev/null
+++ b/NFe.AppTeste/Schemas/envEventoCancInsucessoNFe_v1.00.xsd
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+ Schema XML de validação do lote de envio do evento de Cancelamento de Insucesso na Entrega da NF-e
+
+
+
diff --git a/NFe.AppTeste/Schemas/envEventoInsucessoNFe_v1.00.xsd b/NFe.AppTeste/Schemas/envEventoInsucessoNFe_v1.00.xsd
new file mode 100644
index 00000000..65fb7c43
--- /dev/null
+++ b/NFe.AppTeste/Schemas/envEventoInsucessoNFe_v1.00.xsd
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+ Schema XML de validação do lote de envio do evento de Insucesso na Entrega da NF-e
+
+
+
diff --git a/NFe.AppTeste/Schemas/leiauteEventoCancInsucessoNFe_v1.00.xsd b/NFe.AppTeste/Schemas/leiauteEventoCancInsucessoNFe_v1.00.xsd
new file mode 100644
index 00000000..0bde4345
--- /dev/null
+++ b/NFe.AppTeste/Schemas/leiauteEventoCancInsucessoNFe_v1.00.xsd
@@ -0,0 +1,297 @@
+
+
+
+
+
+
+
+ Tipo Evento
+
+
+
+
+
+
+
+ Código do órgão de recepção do Evento. Utilizar a Tabela do IBGE extendida, utilizar 91 para identificar o Ambiente Nacional
+
+
+
+
+ Identificação do Ambiente:
+1 - Produção
+2 - Homologação
+
+
+
+
+ Identificação do autor do evento
+
+
+
+ CNPJ
+
+
+
+
+ CPF
+
+
+
+
+
+ Chave de Acesso da NF-e vinculada ao evento
+
+
+
+
+ Data de emissão no formato UTC. AAAA-MM-DDThh:mm:ssTZD
+
+
+
+
+ Tipo do Evento
+
+
+
+
+
+
+
+
+
+
+
+ Seqüencial do evento para o mesmo tipo de evento. Para maioria dos eventos será 1, nos casos em que possa existir mais de um evento, como é o caso da carta de correção, o autor do evento deve numerar de forma seqüencial.
+
+
+
+
+
+
+
+
+
+
+ Versão do Tipo do Evento
+
+
+
+
+
+
+
+
+
+
+
+
+ Identificador da TAG a ser assinada, a regra de formação do Id é:
+“ID” + tpEvento + chave da NF-e + nSeqEvento
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tipo Versão do Evento
+
+
+
+
+
+
+
+
+ Tipo retorno do Evento
+
+
+
+
+
+
+
+ Identificação do Ambiente:
+1 - Produção
+2 - Homologação
+
+
+
+
+ Versão do Aplicativo que recebeu o Evento
+
+
+
+
+ Código do órgão de recepção do Evento. Utilizar a Tabela do IBGE extendida, utilizar 91 para identificar o Ambiente Nacional
+
+
+
+
+ Código do status da registro do Evento
+
+
+
+
+ Descrição literal do status do registro do Evento
+
+
+
+
+ Chave de Acesso NF-e vinculada
+
+
+
+
+ Tipo do Evento vinculado
+
+
+
+
+
+
+
+
+
+
+ Descrição do Evento
+
+
+
+
+
+
+
+
+
+
+ Seqüencial do evento
+
+
+
+
+
+
+
+
+
+
+
+ Data e Hora de do recebimento do evento ou do registro do evento formato UTC AAAA-MM-DDThh:mm:ssTZD.
+
+
+
+
+
+
+
+
+
+
+ Número do protocolo de registro do evento
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tipo Lote de Envio
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tipo Versão do EnvEvento
+
+
+
+
+
+
+
+
+ Tipo Retorno de Lote de Envio
+
+
+
+
+
+
+
+
+
+
+
+
+ Identificação do Ambiente:
+1 - Produção
+2 - Homologação
+
+
+
+
+ Versão do Aplicativo que recebeu o Evento
+
+
+
+
+ Código do òrgao que registrou o Evento
+
+
+
+
+ Código do status da registro do Evento
+
+
+
+
+ Descrição literal do status do registro do Evento
+
+
+
+
+
+
+
+
+ Tipo procEvento
+
+
+
+
+
+
+
+
diff --git a/NFe.AppTeste/Schemas/leiauteEventoInsucessoNFe_v1.00.xsd b/NFe.AppTeste/Schemas/leiauteEventoInsucessoNFe_v1.00.xsd
new file mode 100644
index 00000000..9ab61fe4
--- /dev/null
+++ b/NFe.AppTeste/Schemas/leiauteEventoInsucessoNFe_v1.00.xsd
@@ -0,0 +1,297 @@
+
+
+
+
+
+
+
+ Tipo Evento
+
+
+
+
+
+
+
+ Código do órgão de recepção do Evento. Utilizar a Tabela do IBGE extendida, utilizar 91 para identificar o Ambiente Nacional
+
+
+
+
+ Identificação do Ambiente:
+1 - Produção
+2 - Homologação
+
+
+
+
+ Identificação do autor do evento
+
+
+
+ CNPJ
+
+
+
+
+ CPF
+
+
+
+
+
+ Chave de Acesso da NF-e vinculada ao evento
+
+
+
+
+ Data de emissão no formato UTC. AAAA-MM-DDThh:mm:ssTZD
+
+
+
+
+ Tipo do Evento
+
+
+
+
+
+
+
+
+
+
+
+ Seqüencial do evento para o mesmo tipo de evento. Para maioria dos eventos será 1, nos casos em que possa existir mais de um evento, como é o caso da carta de correção, o autor do evento deve numerar de forma seqüencial.
+
+
+
+
+
+
+
+
+
+
+ Versão do Tipo do Evento
+
+
+
+
+
+
+
+
+
+
+
+
+ Identificador da TAG a ser assinada, a regra de formação do Id é:
+“ID” + tpEvento + chave da NF-e + nSeqEvento
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tipo Versão do Evento
+
+
+
+
+
+
+
+
+ Tipo retorno do Evento
+
+
+
+
+
+
+
+ Identificação do Ambiente:
+1 - Produção
+2 - Homologação
+
+
+
+
+ Versão do Aplicativo que recebeu o Evento
+
+
+
+
+ Código do órgão de recepção do Evento. Utilizar a Tabela do IBGE extendida, utilizar 91 para identificar o Ambiente Nacional
+
+
+
+
+ Código do status da registro do Evento
+
+
+
+
+ Descrição literal do status do registro do Evento
+
+
+
+
+ Chave de Acesso NF-e vinculada
+
+
+
+
+ Tipo do Evento vinculado
+
+
+
+
+
+
+
+
+
+
+ Descrição do Evento
+
+
+
+
+
+
+
+
+
+
+ Seqüencial do evento
+
+
+
+
+
+
+
+
+
+
+
+ Data e Hora de do recebimento do evento ou do registro do evento formato UTC AAAA-MM-DDThh:mm:ssTZD.
+
+
+
+
+
+
+
+
+
+
+ Número do protocolo de registro do evento
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tipo Lote de Envio
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tipo Versão do EnvEvento
+
+
+
+
+
+
+
+
+ Tipo Retorno de Lote de Envio
+
+
+
+
+
+
+
+
+
+
+
+
+ Identificação do Ambiente:
+1 - Produção
+2 - Homologação
+
+
+
+
+ Versão do Aplicativo que recebeu o Evento
+
+
+
+
+ Código do òrgao que registrou o Evento
+
+
+
+
+ Código do status da registro do Evento
+
+
+
+
+ Descrição literal do status do registro do Evento
+
+
+
+
+
+
+
+
+ Tipo procEvento
+
+
+
+
+
+
+
+
diff --git a/NFe.AppTeste/Schemas/procEventoCancInsucessoNFe_v1.00.xsd b/NFe.AppTeste/Schemas/procEventoCancInsucessoNFe_v1.00.xsd
new file mode 100644
index 00000000..eb013ba0
--- /dev/null
+++ b/NFe.AppTeste/Schemas/procEventoCancInsucessoNFe_v1.00.xsd
@@ -0,0 +1,9 @@
+
+
+
+
+
+ Schema XML de validação do proc do evento de Cancelamento do Insucesso na Entrega da NFe
+
+
+
diff --git a/NFe.AppTeste/Schemas/procEventoInsucessoNFe_v1.00.xsd b/NFe.AppTeste/Schemas/procEventoInsucessoNFe_v1.00.xsd
new file mode 100644
index 00000000..b6834be2
--- /dev/null
+++ b/NFe.AppTeste/Schemas/procEventoInsucessoNFe_v1.00.xsd
@@ -0,0 +1,9 @@
+
+
+
+
+
+ Schema XML de validação do proc Insucesso na Entrega da NFe
+
+
+
diff --git a/NFe.AppTeste/Schemas/retEventoCancInsucessoNFe_v1.00.xsd b/NFe.AppTeste/Schemas/retEventoCancInsucessoNFe_v1.00.xsd
new file mode 100644
index 00000000..d832f623
--- /dev/null
+++ b/NFe.AppTeste/Schemas/retEventoCancInsucessoNFe_v1.00.xsd
@@ -0,0 +1,9 @@
+
+
+
+
+
+ Schema XML de Retorno da envio do evento de Insucesso na Entrega da NFe
+
+
+
diff --git a/NFe.AppTeste/Schemas/retEventoInsucessoNFe_v1.00.xsd b/NFe.AppTeste/Schemas/retEventoInsucessoNFe_v1.00.xsd
new file mode 100644
index 00000000..d832f623
--- /dev/null
+++ b/NFe.AppTeste/Schemas/retEventoInsucessoNFe_v1.00.xsd
@@ -0,0 +1,9 @@
+
+
+
+
+
+ Schema XML de Retorno da envio do evento de Insucesso na Entrega da NFe
+
+
+
diff --git a/NFe.AppTeste/Schemas/tiposBasico_v1.03.xsd b/NFe.AppTeste/Schemas/tiposBasico_v1.03.xsd
index b40445d8..780236b1 100644
--- a/NFe.AppTeste/Schemas/tiposBasico_v1.03.xsd
+++ b/NFe.AppTeste/Schemas/tiposBasico_v1.03.xsd
@@ -1,4 +1,5 @@
+
@@ -807,19 +808,10 @@ acrescentado:
-
-
- Tipo Decimal com até 15 dígitos, sendo 11 de corpo e até 4 decimais, aceitando valores negativos
-
-
-
-
-
-
-
+
@@ -858,7 +850,22 @@ acrescentado:
-
+
+
+
+
+ Coordenada geográfica Latitude
+
+
+
+
+
+
+
+ Coordenada geográfica Longitude
+
+
+
diff --git a/NFe.AppTeste/Schemas/xmldsig-core-schema_v1.01.xsd b/NFe.AppTeste/Schemas/xmldsig-core-schema_v1.01.xsd
index 65daee9a..76b74b38 100644
--- a/NFe.AppTeste/Schemas/xmldsig-core-schema_v1.01.xsd
+++ b/NFe.AppTeste/Schemas/xmldsig-core-schema_v1.01.xsd
@@ -95,4 +95,4 @@
-
\ No newline at end of file
+
diff --git a/NFe.Classes/Servicos/Evento/detEvento.cs b/NFe.Classes/Servicos/Evento/detEvento.cs
index d6e948bc..938e74a5 100644
--- a/NFe.Classes/Servicos/Evento/detEvento.cs
+++ b/NFe.Classes/Servicos/Evento/detEvento.cs
@@ -169,5 +169,98 @@ public bool ShouldSerializeItensAverbados()
}
#endregion
+ #region Cancelamento Insucesso NFe
+
+ ///
+ /// P22 - Informar o número do Protocolo de Autorização do
+ /// Evento da NF-e a que se refere este cancelamento.
+ ///
+ public string nProtEvento { get; set; }
+
+ #endregion
+
+ #region Insucesso NFe
+ [XmlIgnore]
+ public DateTimeOffset? dhTentativaEntrega { get; set; }
+
+ ///
+ /// Proxy para dhTentativaEntrega no formato AAAA-MM-DDThh:mm:ssTZD (UTC - Universal Coordinated Time)
+ ///
+ [XmlElement(ElementName = "dhTentativaEntrega")]
+ public string ProxyDhTentativaEntrega
+ {
+ get { return dhTentativaEntrega.ParaDataHoraStringUtc(); }
+ set { dhTentativaEntrega = DateTimeOffset.Parse(value); }
+ }
+
+ ///
+ /// P31 - Número da tentativa de entrega que não teve sucesso
+ ///
+ public int? nTentativa { get; set; }
+
+ ///
+ /// P32 - Motivo do insucesso
+ ///
+ public MotivoInsucesso? tpMotivo { get; set; }
+
+ ///
+ /// P33 - Justificativa do motivo do insucesso. Informar apenas para tpMotivo =
+ ///
+ public string xJustMotivo { get; set; }
+
+ ///
+ /// P33 - Latitude do ponto de entrega
+ ///
+ public decimal? latGPS { get; set; }
+
+ ///
+ /// P34 - Longitude do ponto de entrega
+ ///
+ public decimal? longGPS { get; set; }
+
+ ///
+ /// P35 - Hash SHA-1, no formato Base64, resultante da concatenação de: Chave de Acesso da NF-e + Base64
+ /// da imagem capturada na tentativa da entrega(ex: imagem capturada da assinatura eletrônica, digital do recebedor, foto, etc).
+ ///
+ public string hashTentativaEntrega { get; set; }
+
+ ///
+ /// Data e hora da geração do hash da tentativa de entrega. Formato AAAA-MMDDThh:mm:ssTZD.
+ ///
+ [XmlIgnore]
+ public DateTimeOffset? dhHashTentativaEntrega { get; set; }
+
+ ///
+ /// Proxy para dhHashTentativaEntrega no formato AAAA-MM-DDThh:mm:ssTZD (UTC - Universal Coordinated Time)
+ ///
+ [XmlElement(ElementName = "dhHashTentativaEntrega")]
+ public string ProxyDhHashTentativaEntrega
+ {
+ get { return dhHashTentativaEntrega.ParaDataHoraStringUtc(); }
+ set { dhHashTentativaEntrega = DateTimeOffset.Parse(value); }
+ }
+
+ public bool ShouldSerializenTentativa()
+ {
+ return nTentativa.HasValue;
+ }
+
+ public bool ShouldSerializetpMotivo()
+ {
+ return tpMotivo.HasValue;
+ }
+
+ public bool ShouldSerializelatGPS()
+ {
+ return latGPS.HasValue;
+ }
+
+ public bool ShouldSerializelongGPS()
+ {
+ return longGPS.HasValue;
+ }
+
+ #endregion
+
}
}
\ No newline at end of file
diff --git a/NFe.Classes/Servicos/Evento/detEventoTipos.cs b/NFe.Classes/Servicos/Evento/detEventoTipos.cs
index ba190a85..c2e3832d 100644
--- a/NFe.Classes/Servicos/Evento/detEventoTipos.cs
+++ b/NFe.Classes/Servicos/Evento/detEventoTipos.cs
@@ -89,4 +89,43 @@ public enum TipoAutor
[XmlEnum("9")]
taOutrosOrgaos = 9
}
+
+ ///
+ /// Motivo de Insucesso.
+ /// Nota:
+ /// 1 - Recebedor não encontrado;
+ /// 2 - Recusa do recebedor;
+ /// 3 - Endereço inexistente;
+ /// 4 - Outros (exige informar justificativa);
+ ///
+ public enum MotivoInsucesso
+ {
+ ///
+ /// 1 - Recebedor não encontrado
+ ///
+ [Description("Recebedor não encontrado")]
+ [XmlEnum("1")]
+ RecebedorNaoEncontrado = 1,
+
+ ///
+ /// 2 - Recusa do recebedor
+ ///
+ [Description("Recusa do recebedor")]
+ [XmlEnum("2")]
+ RecusaRecebedor = 2,
+
+ ///
+ /// 3 - Endereço inexistente
+ ///
+ [Description("Endereço inexistente")]
+ [XmlEnum("3")]
+ EnderecoInexistente = 3,
+
+ ///
+ /// 4 - Outros
+ ///
+ [Description("Outros")]
+ [XmlEnum("4")]
+ Outros = 4
+ }
}
\ No newline at end of file
diff --git a/NFe.Classes/Servicos/Tipos/NFeServicosTipos.cs b/NFe.Classes/Servicos/Tipos/NFeServicosTipos.cs
index a5ef781b..8b3dadc3 100644
--- a/NFe.Classes/Servicos/Tipos/NFeServicosTipos.cs
+++ b/NFe.Classes/Servicos/Tipos/NFeServicosTipos.cs
@@ -53,6 +53,16 @@ public enum ServicoNFe
/// serviço destinado à recepção de mensagem do Evento EPEC da NF-e
///
RecepcaoEventoEpec,
+
+ ///
+ /// serviço destinado à recepção de mensagem do Evento Insucesso na Entrega da NFe
+ ///
+ RecepcaoEventoInsucessoEntregaNFe,
+
+ ///
+ /// serviço destinado à recepção de mensagem do Evento Cancelamento Insucesso na Entrega da NFe
+ ///
+ RecepcaoEventoCancInsucessoEntregaNFe,
///
/// serviço destinado à recepção de mensagem do Evento de Manifestação do destinatário da NF-e
@@ -186,6 +196,20 @@ public enum NFeTipoEvento
[Description("Cancelamento por substituicao")]
[XmlEnum("110112")]
TeNfeCancelamentoSubstituicao = 110112,
+
+ ///
+ /// 110192 - Insucesso na Entrega da NF-e
+ ///
+ [Description("Insucesso na Entrega da NF-e")]
+ [XmlEnum("110192")]
+ TeNfeInsucessoNaEntregadaNFe = 110192,
+
+ ///
+ /// 110193 - Cancelamento Insucesso na Entrega da NF-e
+ ///
+ [Description("Cancelamento Insucesso na Entrega da NF-e")]
+ [XmlEnum("110193")]
+ TeNfeCancInsucessoNaEntregadaNFe = 110193,
///
/// 210200 – Confirmação da Operação
diff --git a/NFe.Integracao/NFeFacade.cs b/NFe.Integracao/NFeFacade.cs
index 03cea3b4..a8728efb 100644
--- a/NFe.Integracao/NFeFacade.cs
+++ b/NFe.Integracao/NFeFacade.cs
@@ -186,6 +186,7 @@ private void CarregarConfiguracoes()
ConfiguracaoServico.Instancia.VersaoNfeRetRecepcao = versaoNFe;
ConfiguracaoServico.Instancia.VersaoNfeStatusServico = versaoNFe;
ConfiguracaoServico.Instancia.VersaoRecepcaoEventoCceCancelamento = versaoNFe;
+ ConfiguracaoServico.Instancia.VersaoRecepcaoEventoInsucessoEntrega = versaoNFe;
#endregion
diff --git a/NFe.Servicos/ServicoNfeFactory.cs b/NFe.Servicos/ServicoNfeFactory.cs
index c2fe8397..b9e7eb1c 100644
--- a/NFe.Servicos/ServicoNfeFactory.cs
+++ b/NFe.Servicos/ServicoNfeFactory.cs
@@ -229,6 +229,10 @@ public static INfeServico CriaWsdlOutros(ServicoNFe servico, ConfiguracaoServico
return new RecepcaoEvento(url, certificado, cfg.TimeOut);
+ case ServicoNFe.RecepcaoEventoInsucessoEntregaNFe:
+ case ServicoNFe.RecepcaoEventoCancInsucessoEntregaNFe:
+ return new RecepcaoEvento4AN(url, certificado, cfg.TimeOut);
+
case ServicoNFe.RecepcaoEventoManifestacaoDestinatario:
if (cfg.VersaoRecepcaoEventoManifestacaoDestinatario == VersaoServico.Versao400)
{
diff --git a/NFe.Servicos/ServicosNFe.cs b/NFe.Servicos/ServicosNFe.cs
index 01b941b6..4aee927e 100644
--- a/NFe.Servicos/ServicosNFe.cs
+++ b/NFe.Servicos/ServicosNFe.cs
@@ -403,7 +403,9 @@ private RetornoRecepcaoEvento RecepcaoEvento(int idlote, List eventos, S
ServicoNFe.RecepcaoEventoCartaCorrecao,
ServicoNFe.RecepcaoEventoCancelmento,
ServicoNFe.RecepcaoEventoEpec,
- ServicoNFe.RecepcaoEventoManifestacaoDestinatario
+ ServicoNFe.RecepcaoEventoManifestacaoDestinatario,
+ ServicoNFe.RecepcaoEventoInsucessoEntregaNFe,
+ ServicoNFe.RecepcaoEventoCancInsucessoEntregaNFe
};
if (
!listaEventos.Contains(servicoEvento))
@@ -521,7 +523,7 @@ public RetornoRecepcaoEvento RecepcaoEventoCancelamento(int idlote, int sequenci
/// Envia eventos do tipo "Cancelamento" já assinado.
///
///
- ///
+ ///
///
public RetornoRecepcaoEvento RecepcaoEventoCancelamento(int idlote, List eventos)
{
@@ -638,7 +640,7 @@ public RetornoRecepcaoEvento RecepcaoEventoCartaCorrecao(int idlote, int sequenc
/// Envia eventos do tipo "Carta de correção" já assinado.
///
///
- ///
+ ///
///
public RetornoRecepcaoEvento RecepcaoEventoCartaCorrecao(int idlote, List eventos)
{
@@ -764,9 +766,7 @@ public RetornoRecepcaoEvento RecepcaoEventoEpec(int idlote, int sequenciaEvento,
/// Envia eventos do tipo "EPEC" já assinado
///
///
- ///
- ///
- ///
+ ///
/// Retorna um objeto da classe RetornoRecepcaoEvento com o retorno do serviço RecepcaoEvento
public RetornoRecepcaoEvento RecepcaoEventoEpec(int idlote, List eventos)
{
@@ -774,6 +774,128 @@ public RetornoRecepcaoEvento RecepcaoEventoEpec(int idlote, List eventos
return retorno;
}
+ ///
+ /// Recepção do Evento de Insucesso na Entrega
+ ///
+ /// Nº do lote
+ /// sequencia do evento
+ ///
+ ///
+ ///
+ /// preencher com Enum MotivoInsucesso
+ /// Hash SHA-1, no formato Base64, resultante da
+ /// concatenação de: Chave de Acesso da NF-e + Base64
+ /// da imagem capturada na tentativa da entrega(ex:
+ /// imagem capturada da assinatura eletrônica, digital do
+ /// recebedor, foto, etc).
+ ///
+ ///
+ /// Latitude do ponto de entrega (não obrigatório)
+ /// Longitude do ponto de entrega (não obrigatório)
+ /// Preencher apenas se o motivo for outros
+ ///
+ ///
+ ///
+ ///
+ public RetornoRecepcaoEvento RecepcaoEventoInsucessoEntrega(int idlote,
+ int sequenciaEvento, string cpfcnpj, string chaveNFe, DateTimeOffset dhTentativaEntrega, MotivoInsucesso motivo, string hashTentativaEntrega,
+ int? nTentativa = null, DateTimeOffset? dhHashTentativaEntrega = null, decimal? latGps = null, decimal? longGps = null,
+ string justificativa = null, Estado? ufAutor = null, string versaoAplicativo = null, DateTimeOffset? dhEvento = null)
+ {
+
+ var versaoServico =
+ ServicoNFe.RecepcaoEventoCancelmento.VersaoServicoParaString(
+ _cFgServico.VersaoRecepcaoEventoInsucessoEntrega);
+
+ var detEvento = new detEvento
+ {
+ versao = versaoServico,
+ descEvento = NFeTipoEvento.TeNfeInsucessoNaEntregadaNFe.Descricao(),
+ cOrgaoAutor = ufAutor ?? _cFgServico.cUF,
+ verAplic = versaoAplicativo ?? "1.0",
+ dhTentativaEntrega = dhTentativaEntrega,
+ nTentativa = nTentativa,
+ tpMotivo = motivo,
+ xJustMotivo = justificativa,
+ latGPS = latGps,
+ longGPS = longGps,
+ hashTentativaEntrega = hashTentativaEntrega,
+ dhHashTentativaEntrega = dhHashTentativaEntrega
+ };
+ var infEvento = new infEventoEnv
+ {
+ cOrgao = _cFgServico.cUF,
+ tpAmb = _cFgServico.tpAmb,
+ chNFe = chaveNFe,
+ dhEvento = dhEvento ?? DateTime.Now,
+ tpEvento = NFeTipoEvento.TeNfeInsucessoNaEntregadaNFe,
+ nSeqEvento = sequenciaEvento,
+ verEvento = versaoServico,
+ detEvento = detEvento
+ };
+ if (cpfcnpj.Length == 11)
+ infEvento.CPF = cpfcnpj;
+ else
+ infEvento.CNPJ = cpfcnpj;
+
+ var evento = new evento { versao = versaoServico, infEvento = infEvento };
+
+ var retorno = RecepcaoEvento(idlote, new List { evento }, ServicoNFe.RecepcaoEventoInsucessoEntregaNFe, _cFgServico.VersaoRecepcaoEventoInsucessoEntrega, true);
+ return retorno;
+ }
+
+ ///
+ /// Serviço para cancelamento insucesso na entrega
+ ///
+ /// Nº do lote
+ /// sequencia do evento
+ ///
+ ///
+ /// Protocolo do eveento de insucesso na entrega que deseja cancelar
+ ///
+ ///
+ ///
+ ///
+ public RetornoRecepcaoEvento RecepcaoEventoCancInsucessoEntrega(int idlote,
+ int sequenciaEvento, string cpfcnpj, string chaveNFe, string nProtEvento,
+ Estado? ufAutor = null, string versaoAplicativo = null, DateTimeOffset? dhEvento = null)
+ {
+
+ var versaoServico =
+ ServicoNFe.RecepcaoEventoCancelmento.VersaoServicoParaString(
+ _cFgServico.VersaoRecepcaoEventoInsucessoEntrega);
+
+ var detEvento = new detEvento
+ {
+ versao = versaoServico,
+ descEvento = NFeTipoEvento.TeNfeCancInsucessoNaEntregadaNFe.Descricao(),
+ cOrgaoAutor = ufAutor ?? _cFgServico.cUF,
+ verAplic = versaoAplicativo ?? "1.0",
+ nProtEvento = nProtEvento
+ };
+
+ var infEvento = new infEventoEnv
+ {
+ cOrgao = _cFgServico.cUF,
+ tpAmb = _cFgServico.tpAmb,
+ chNFe = chaveNFe,
+ dhEvento = dhEvento ?? DateTime.Now,
+ tpEvento = NFeTipoEvento.TeNfeCancInsucessoNaEntregadaNFe,
+ nSeqEvento = sequenciaEvento,
+ verEvento = versaoServico,
+ detEvento = detEvento
+ };
+ if (cpfcnpj.Length == 11)
+ infEvento.CPF = cpfcnpj;
+ else
+ infEvento.CNPJ = cpfcnpj;
+
+ var evento = new evento { versao = versaoServico, infEvento = infEvento };
+
+ var retorno = RecepcaoEvento(idlote, new List { evento }, ServicoNFe.RecepcaoEventoCancInsucessoEntregaNFe, _cFgServico.VersaoRecepcaoEventoInsucessoEntrega, true);
+ return retorno;
+ }
+
///
/// Consulta a situação cadastral, com base na UF/Documento
/// O documento pode ser: IE, CNPJ ou CPF
diff --git a/NFe.Utils/ConfiguracaoServico.cs b/NFe.Utils/ConfiguracaoServico.cs
index c41d20da..5cab4964 100644
--- a/NFe.Utils/ConfiguracaoServico.cs
+++ b/NFe.Utils/ConfiguracaoServico.cs
@@ -60,6 +60,7 @@ public sealed class ConfiguracaoServico : INotifyPropertyChanged
private bool _defineVersaoServicosAutomaticamente = true;
private bool _unZip = true;
private VersaoServico _versaoRecepcaoEventoCceCancelamento;
+ private VersaoServico _versaoRecepcaoEventoInsucessoEntrega;
private VersaoServico _versaoRecepcaoEventoEpec;
private VersaoServico _versaoRecepcaoEventoManifestacaoDestinatario;
private VersaoServico _versaoNfeRecepcao;
@@ -234,6 +235,7 @@ private void AtualizaVersoes()
if (enderecosMaisecentes.Any())
{
VersaoRecepcaoEventoCceCancelamento = obterVersao(ServicoNFe.RecepcaoEventoCancelmento);
+ VersaoRecepcaoEventoInsucessoEntrega = obterVersao(ServicoNFe.RecepcaoEventoInsucessoEntregaNFe);
VersaoRecepcaoEventoEpec = obterVersao(ServicoNFe.RecepcaoEventoEpec);
VersaoRecepcaoEventoManifestacaoDestinatario = obterVersao(ServicoNFe.RecepcaoEventoManifestacaoDestinatario);
VersaoNfeRecepcao = obterVersao(ServicoNFe.NfeRecepcao);
@@ -282,6 +284,21 @@ public VersaoServico VersaoRecepcaoEventoEpec
}
}
+
+ ///
+ /// Versão do serviço RecepcaoEvento para Carta de Correção e Cancelamento
+ ///
+ public VersaoServico VersaoRecepcaoEventoInsucessoEntrega
+ {
+ get { return _versaoRecepcaoEventoInsucessoEntrega; }
+ set
+ {
+ if (value == _versaoRecepcaoEventoInsucessoEntrega) return;
+ _versaoRecepcaoEventoInsucessoEntrega = value;
+ OnPropertyChanged();
+ }
+ }
+
///
/// Versão do serviço RecepcaoEvento para Manifestação do destinatário
///
diff --git a/NFe.Utils/Enderecos/Enderecador.cs b/NFe.Utils/Enderecos/Enderecador.cs
index 826337c4..453eb10c 100644
--- a/NFe.Utils/Enderecos/Enderecador.cs
+++ b/NFe.Utils/Enderecos/Enderecador.cs
@@ -1630,7 +1630,7 @@ private static List CarregarEnderecosServicos()
#endregion
- #region ConsultaGtin
+ #region ConsultaGtin e Insucesso na entrega
foreach (var estado in Enum.GetValues(typeof(Estado))
.Cast()
.ToList())
@@ -1639,8 +1639,13 @@ private static List CarregarEnderecosServicos()
{
foreach (var modelo in todosOsModelos)
{
+ //GTIN
addServico(new[] { ServicoNFe.ConsultaGtin }, versao1, TipoAmbiente.Producao, emissao, estado, modelo, "https://dfe-servico.svrs.rs.gov.br/ws/ccgConsGTIN/ccgConsGTIN.asmx");
addServico(new[] { ServicoNFe.ConsultaGtin }, versao1, TipoAmbiente.Homologacao, emissao, estado, modelo, "https://dfe-servico.svrs.rs.gov.br/ws/ccgConsGTIN/ccgConsGTIN.asmx");
+
+ //Insucesso Entrega NFe
+ addServico(new[] { ServicoNFe.RecepcaoEventoInsucessoEntregaNFe, ServicoNFe.RecepcaoEventoCancInsucessoEntregaNFe }, versao1, TipoAmbiente.Producao, emissao, estado, modelo, "https://www.nfe.fazenda.gov.br/NFeRecepcaoEvento4/NFeRecepcaoEvento4.asmx");
+ addServico(new[] { ServicoNFe.RecepcaoEventoInsucessoEntregaNFe, ServicoNFe.RecepcaoEventoCancInsucessoEntregaNFe }, versao1, TipoAmbiente.Homologacao, emissao, estado, modelo, "https://hom1.nfe.fazenda.gov.br/NFeRecepcaoEvento4/NFeRecepcaoEvento4.asmx");
}
}
}
@@ -1672,6 +1677,9 @@ public static void CarregarEnderecos()
case ServicoNFe.RecepcaoEventoCartaCorrecao:
case ServicoNFe.RecepcaoEventoCancelmento:
return cfgServico.VersaoRecepcaoEventoCceCancelamento;
+ case ServicoNFe.RecepcaoEventoInsucessoEntregaNFe:
+ case ServicoNFe.RecepcaoEventoCancInsucessoEntregaNFe:
+ return cfgServico.VersaoRecepcaoEventoInsucessoEntrega;
case ServicoNFe.RecepcaoEventoEpec:
return cfgServico.VersaoRecepcaoEventoEpec;
case ServicoNFe.RecepcaoEventoManifestacaoDestinatario:
diff --git a/NFe.Utils/Validacao/Validador.cs b/NFe.Utils/Validacao/Validador.cs
index 0c3e83da..f32170d2 100644
--- a/NFe.Utils/Validacao/Validador.cs
+++ b/NFe.Utils/Validacao/Validador.cs
@@ -62,6 +62,10 @@ internal static string ObterArquivoSchema(ServicoNFe servicoNFe, VersaoServico v
: "envEventoCancNFe_v1.00.xsd";
case ServicoNFe.RecepcaoEventoCartaCorrecao:
return "envCCe_v1.00.xsd";
+ case ServicoNFe.RecepcaoEventoInsucessoEntregaNFe:
+ return "envEventoInsucessoNFe_v1.00.xsd";
+ case ServicoNFe.RecepcaoEventoCancInsucessoEntregaNFe:
+ return "envEventoCancInsucessoNFe_v1.00.xsd";
case ServicoNFe.RecepcaoEventoEpec:
return "envEPEC_v1.00.xsd";
case ServicoNFe.RecepcaoEventoManifestacaoDestinatario:
@@ -154,13 +158,18 @@ public static string[] Valida(ServicoNFe servicoNFe, VersaoServico versaoServico
// Especifica o tratamento de evento para os erros de validacao
cfg.ValidationEventHandler += delegate (object sender, ValidationEventArgs args)
{
- string message = args.Message;
+ string message = args.Message.ToLower().RemoverAcentos();
- if (message.ToLower().Contains("tcorgaoibge") && message.ToLower().RemoverAcentos().Contains("ja foi declarado"))
- {
- //aqui talvez um aviso?
- }
- else
+ if (!(
+
+ //Está errado o schema. Pois o certo é ser 20 o length e não 28 como está no schema envIECTE_v4.00xsd
+ (message.Contains("hashtentativaentrega") && message.Contains("o comprimento atual nao e igual")) ||
+
+ //erro de orgaoibge que duplicou em alguns xsds porem a receita federal veio a arrumar posteriormente, mesmo assim alguns não atualizam os xsds
+ (message.Contains("tcorgaoibge") && message.Contains("ja foi declarado"))
+
+ //no futuro adicionar novos aqui...
+ ))
{
falhas.AppendLine($"[{args.Severity}] - {message} {args.Exception?.Message} " +
$"na linha {args.Exception.LineNumber} " +