Skip to content

Commit

Permalink
Merge pull request #40 from neicecilio/feature/comprovante-entrega
Browse files Browse the repository at this point in the history
feat:Evento de Comprovante de Entrega para NFe (NT 2021.001)
  • Loading branch information
adrbarros authored Sep 13, 2024
2 parents fe10948 + 82059a6 commit b8b9f1e
Show file tree
Hide file tree
Showing 10 changed files with 382 additions and 7 deletions.
8 changes: 6 additions & 2 deletions NFe.AppTeste/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,7 @@
</TabControl>
</StackPanel>
</GroupBox>
<TabControl Name="TabSuperior" Height="266" Margin="510,10,-0,0" VerticalAlignment="Top">
<TabControl Name="TabSuperior" Height="291" Margin="510,10,-0,0" VerticalAlignment="Top">
<TabItem Header="NF-e/NFC-e">
<Grid Background="White">
<Button x:Name="BtnStatusServico" Content="Status do Serviço" HorizontalAlignment="Left"
Expand Down Expand Up @@ -966,11 +966,15 @@
Margin="192,210,0,0" VerticalAlignment="Top" Width="177" Click="BtnInsucessoEntrega_Click" />
<Button x:Name="BtnCancInsucessoEntrega" Content="Canc. Insucesso Entrega NFe" HorizontalAlignment="Left"
Margin="375,210,0,0" VerticalAlignment="Top" Width="177" Click="BtnCancInsucessoEntrega_Click" />
<Button x:Name="BtnComprovanteEntrega" Content="Comprovante Entrega NFe" HorizontalAlignment="Left"
Margin="10,235,0,0" VerticalAlignment="Top" Width="177" Click="BtnComprovanteEntrega_Click" />
<Button x:Name="BtnCancComprovanteEntrega" Content="Canc. Comprovante Entrega NFe" HorizontalAlignment="Left"
Margin="192,235,0,0" VerticalAlignment="Top" Width="177" Click="BtnCancComprovanteEntrega_Click" />
</Grid>
</TabItem>

</TabControl>
<TabControl Name="TabInferior" Margin="509,281,0,0">
<TabControl Name="TabInferior" Margin="509,306,0,0">
<TabItem Header="Envio">
<Grid Background="#FFE5E5E5">
<Grid.ColumnDefinitions>
Expand Down
139 changes: 138 additions & 1 deletion NFe.AppTeste/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ private void BtnInsucessoEntrega_Click(object sender, RoutedEventArgs e)
}
}

private void BtnCancInsucessoEntrega_Click(object sender, RoutedEventArgs e)
private void BtnCancInsucessoEntrega_Click(object sender, RoutedEventArgs e)
{
const string titulo = "Cancelar Insucesso Entrega NFe";

Expand Down Expand Up @@ -435,6 +435,143 @@ private void BtnCancInsucessoEntrega_Click(object sender, RoutedEventArgs e)
}
}

private void BtnComprovanteEntrega_Click(object sender, RoutedEventArgs e)
{
const string titulo = "Comprovante Entrega NFe";

try
{
#region Comprovante 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 dhEntregaStr = Funcoes.InpuBox(this, titulo, "Data da entrega da NFe", DateTimeOffset.Now.ToString("dd/MM/yyyy"));
if (string.IsNullOrEmpty(dhEntregaStr)) throw new Exception("A Data deve ser informada!");

if (!DateTimeOffset.TryParse(dhEntregaStr, out DateTimeOffset dhEntrega))
throw new Exception("Data inválida!");

var nDoc = Funcoes.InpuBox(this, titulo, "Documento da Pessoa:", "1234");
if (string.IsNullOrEmpty(nDoc)) throw new Exception("Número do documento deve ser informado!");

var xNome = Funcoes.InpuBox(this, titulo, "Nome da Pessoa:", "José da Silva");
if (string.IsNullOrEmpty(xNome)) throw new Exception("Nome da Pessoa deve ser informado!");

var imagemExemploBase64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAADUlEQVR42gECAP3/AP8BAQEATamDVwAAAABJRU5ErkJggg==";
var concatenacao = chave + imagemExemploBase64;

var hashComprovante = 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
hashComprovante = Convert.ToBase64String(hashBytes).Trim();
}

DateTimeOffset? dhHashComprovante = null;
var dhHashComprovanteStr = Funcoes.InpuBox(this, titulo, "Data geração do Hash Tentativa na Entrega:", DateTimeOffset.Now.ToString("dd/MM/yyyy"));
if (!string.IsNullOrEmpty(dhHashComprovanteStr)) dhHashComprovante = Convert.ToDateTime(dhHashComprovanteStr);

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 retornoComprovante = servicoNFe.RecepcaoEventoComprovanteEntrega(Convert.ToInt32(idlote),
Convert.ToInt16(sequenciaEvento), cpfcnpj, chave, dhEntrega, nDoc, xNome, hashComprovante,
dhHashComprovante, latGps, longGps, DFe.Classes.Entidades.Estado.SP);

TrataRetorno(retornoComprovante);

#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 BtnCancComprovanteEntrega_Click(object sender, RoutedEventArgs e)
{
const string titulo = "Cancelar Comprovante Entrega NFe";

try
{
#region Cancelar Comprovante 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 retornoComprovante = servicoNFe.RecepcaoEventoCancComprovanteEntrega(Convert.ToInt32(idlote),
Convert.ToInt16(sequenciaEvento), cpfcnpj, chave, nProtEvento);

TrataRetorno(retornoComprovante);

#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
Expand Down
56 changes: 54 additions & 2 deletions NFe.Classes/Servicos/Evento/detEvento.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public bool ShouldSerializeItensAverbados()
}
#endregion

#region Cancelamento Insucesso NFe
#region Cancelamento Insucesso/Comprovante de Entrega NFe

/// <summary>
/// P22 - Informar o número do Protocolo de Autorização do
Expand All @@ -178,7 +178,7 @@ public bool ShouldSerializeItensAverbados()
public string nProtEvento { get; set; }

#endregion

#region Insucesso NFe
[XmlIgnore]
public DateTimeOffset? dhTentativaEntrega { get; set; }
Expand Down Expand Up @@ -262,5 +262,57 @@ public bool ShouldSerializelongGPS()

#endregion

#region Comprovante Entrega NFe

/// <summary>
/// P30 - Data e hora do final da entrega
/// </summary>
[XmlIgnore]
public DateTimeOffset? dhEntrega { get; set; }

/// <summary>
/// Proxy para dhEntrega no formato AAAA-MM-DDThh:mm:ssTZD (UTC - Universal Coordinated Time)
/// </summary>
[XmlElement(ElementName = "dhEntrega")]
public string ProxyDhEntrega
{
get { return dhEntrega.ParaDataHoraStringUtc(); }
set { dhEntrega = DateTimeOffset.Parse(value); }
}

/// <summary>
/// P31 - Número do documento de identificação da pessoa que assinou o Comprovante de Entrega da NF-e/>
/// </summary>
public string nDoc { get; set; }

/// <summary>
/// P32 - Nome da pessoa que assinou o Comprovante de Entrega da NF-e/>
/// </summary>
public string xNome { get; set; }

/// <summary>
/// P35 - Hash SHA-1, no formato Base64, resultante da concatenação de: Chave de Acesso da NF-e + Base64
/// da imagem capturada do Comprovante de Entrega da NFe (ex: imagem capturada da assinatura eletrônica, digital do recebedor, foto, etc).
/// </summary>
public string hashComprovante { get; set; }

/// <summary>
/// P36 - Data e hora da geração do hash da tentativa de entrega. Formato AAAA-MMDDThh:mm:ssTZD.
/// </summary>
[XmlIgnore]
public DateTimeOffset? dhHashComprovante { get; set; }

/// <summary>
/// Proxy para dhHashComprovante no formato AAAA-MM-DDThh:mm:ssTZD (UTC - Universal Coordinated Time)
/// </summary>
[XmlElement(ElementName = "dhHashComprovante")]
public string ProxyDhHashComprovante
{
get { return dhHashComprovante.ParaDataHoraStringUtc(); }
set { dhHashComprovante = DateTimeOffset.Parse(value); }
}

#endregion

}
}
24 changes: 24 additions & 0 deletions NFe.Classes/Servicos/Tipos/NFeServicosTipos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@ public enum ServicoNFe
/// </summary>
RecepcaoEventoCancInsucessoEntregaNFe,

/// <summary>
/// serviço destinado à recepção de mensagem do Evento Comprovante de Entrega da NFe
/// </summary>
RecepcaoEventoComprovanteEntregaNFe,

/// <summary>
/// serviço destinado à recepção de mensagem do Evento Cancelamento do Comprovante de Entrega da NFe
/// </summary>
RecepcaoEventoCancComprovanteEntregaNFe,

/// <summary>
/// serviço destinado à recepção de mensagem do Evento de Manifestação do destinatário da NF-e
/// </summary>
Expand Down Expand Up @@ -211,6 +221,20 @@ public enum NFeTipoEvento
[XmlEnum("110193")]
TeNfeCancInsucessoNaEntregadaNFe = 110193,

/// <summary>
/// 110130 - Comprovante de Entrega da NF-e
/// </summary>
[Description("Comprovante de Entrega da NF-e")]
[XmlEnum("110130")]
TeNfeComprovanteDeEntregadaNFe = 110130,

/// <summary>
/// 110131 - Cancelamento Comprovante de Entrega da NF-e
/// </summary>
[Description("Cancelamento Comprovante de Entrega da NF-e")]
[XmlEnum("110131")]
TeNfeCancComprovanteDeEntregadaNFe = 110131,

/// <summary>
/// 210200 – Confirmação da Operação
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions NFe.Integracao/NFeFacade.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ private void CarregarConfiguracoes()
ConfiguracaoServico.Instancia.VersaoNfeStatusServico = versaoNFe;
ConfiguracaoServico.Instancia.VersaoRecepcaoEventoCceCancelamento = versaoNFe;
ConfiguracaoServico.Instancia.VersaoRecepcaoEventoInsucessoEntrega = versaoNFe;
ConfiguracaoServico.Instancia.VersaoRecepcaoEventoComprovanteEntrega = versaoNFe;

#endregion

Expand Down
4 changes: 4 additions & 0 deletions NFe.Servicos/ServicoNfeFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,10 @@ public static INfeServico CriaWsdlOutros(ServicoNFe servico, ConfiguracaoServico
case ServicoNFe.RecepcaoEventoCancInsucessoEntregaNFe:
return new RecepcaoEvento4SVCAN(url, certificado, cfg.TimeOut);

case ServicoNFe.RecepcaoEventoComprovanteEntregaNFe:
case ServicoNFe.RecepcaoEventoCancComprovanteEntregaNFe:
return new RecepcaoEvento4AN(url, certificado, cfg.TimeOut);

case ServicoNFe.RecepcaoEventoManifestacaoDestinatario:
if (cfg.VersaoRecepcaoEventoManifestacaoDestinatario == VersaoServico.Versao400)
{
Expand Down
Loading

0 comments on commit b8b9f1e

Please sign in to comment.