Skip to content

Commit b8b9f1e

Browse files
authored
Merge pull request ZeusAutomacao#40 from neicecilio/feature/comprovante-entrega
feat:Evento de Comprovante de Entrega para NFe (NT 2021.001)
2 parents fe10948 + 82059a6 commit b8b9f1e

File tree

10 files changed

+382
-7
lines changed

10 files changed

+382
-7
lines changed

NFe.AppTeste/MainWindow.xaml

+6-2
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,7 @@
904904
</TabControl>
905905
</StackPanel>
906906
</GroupBox>
907-
<TabControl Name="TabSuperior" Height="266" Margin="510,10,-0,0" VerticalAlignment="Top">
907+
<TabControl Name="TabSuperior" Height="291" Margin="510,10,-0,0" VerticalAlignment="Top">
908908
<TabItem Header="NF-e/NFC-e">
909909
<Grid Background="White">
910910
<Button x:Name="BtnStatusServico" Content="Status do Serviço" HorizontalAlignment="Left"
@@ -966,11 +966,15 @@
966966
Margin="192,210,0,0" VerticalAlignment="Top" Width="177" Click="BtnInsucessoEntrega_Click" />
967967
<Button x:Name="BtnCancInsucessoEntrega" Content="Canc. Insucesso Entrega NFe" HorizontalAlignment="Left"
968968
Margin="375,210,0,0" VerticalAlignment="Top" Width="177" Click="BtnCancInsucessoEntrega_Click" />
969+
<Button x:Name="BtnComprovanteEntrega" Content="Comprovante Entrega NFe" HorizontalAlignment="Left"
970+
Margin="10,235,0,0" VerticalAlignment="Top" Width="177" Click="BtnComprovanteEntrega_Click" />
971+
<Button x:Name="BtnCancComprovanteEntrega" Content="Canc. Comprovante Entrega NFe" HorizontalAlignment="Left"
972+
Margin="192,235,0,0" VerticalAlignment="Top" Width="177" Click="BtnCancComprovanteEntrega_Click" />
969973
</Grid>
970974
</TabItem>
971975

972976
</TabControl>
973-
<TabControl Name="TabInferior" Margin="509,281,0,0">
977+
<TabControl Name="TabInferior" Margin="509,306,0,0">
974978
<TabItem Header="Envio">
975979
<Grid Background="#FFE5E5E5">
976980
<Grid.ColumnDefinitions>

NFe.AppTeste/MainWindow.xaml.cs

+138-1
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ private void BtnInsucessoEntrega_Click(object sender, RoutedEventArgs e)
382382
}
383383
}
384384

385-
private void BtnCancInsucessoEntrega_Click(object sender, RoutedEventArgs e)
385+
private void BtnCancInsucessoEntrega_Click(object sender, RoutedEventArgs e)
386386
{
387387
const string titulo = "Cancelar Insucesso Entrega NFe";
388388

@@ -435,6 +435,143 @@ private void BtnCancInsucessoEntrega_Click(object sender, RoutedEventArgs e)
435435
}
436436
}
437437

438+
private void BtnComprovanteEntrega_Click(object sender, RoutedEventArgs e)
439+
{
440+
const string titulo = "Comprovante Entrega NFe";
441+
442+
try
443+
{
444+
#region Comprovante Entrega NFe
445+
446+
var idlote = Funcoes.InpuBox(this, titulo, "Identificador de controle do Lote de envio:", "1");
447+
if (string.IsNullOrEmpty(idlote)) throw new Exception("A Id do Lote deve ser informada!");
448+
449+
var sequenciaEvento = Funcoes.InpuBox(this, titulo, "Número sequencial do evento:", "1");
450+
if (string.IsNullOrEmpty(sequenciaEvento))
451+
throw new Exception("O número sequencial deve ser informado!");
452+
453+
var chave = Funcoes.InpuBox(this, titulo, "Chave da NFe:", "35240311656919000154550750000008281647961399");
454+
if (string.IsNullOrEmpty(chave)) throw new Exception("A Chave deve ser informada!");
455+
if (chave.Length != 44) throw new Exception("Chave deve conter 44 caracteres!");
456+
457+
var dhEntregaStr = Funcoes.InpuBox(this, titulo, "Data da entrega da NFe", DateTimeOffset.Now.ToString("dd/MM/yyyy"));
458+
if (string.IsNullOrEmpty(dhEntregaStr)) throw new Exception("A Data deve ser informada!");
459+
460+
if (!DateTimeOffset.TryParse(dhEntregaStr, out DateTimeOffset dhEntrega))
461+
throw new Exception("Data inválida!");
462+
463+
var nDoc = Funcoes.InpuBox(this, titulo, "Documento da Pessoa:", "1234");
464+
if (string.IsNullOrEmpty(nDoc)) throw new Exception("Número do documento deve ser informado!");
465+
466+
var xNome = Funcoes.InpuBox(this, titulo, "Nome da Pessoa:", "José da Silva");
467+
if (string.IsNullOrEmpty(xNome)) throw new Exception("Nome da Pessoa deve ser informado!");
468+
469+
var imagemExemploBase64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAADUlEQVR42gECAP3/AP8BAQEATamDVwAAAABJRU5ErkJggg==";
470+
var concatenacao = chave + imagemExemploBase64;
471+
472+
var hashComprovante = string.Empty;
473+
using (SHA1 sha1 = SHA1.Create())
474+
{
475+
byte[] inputBytes = Encoding.UTF8.GetBytes(concatenacao);
476+
byte[] hashBytes = sha1.ComputeHash(inputBytes);
477+
// O hash SHA-1 terá 20 bytes
478+
hashComprovante = Convert.ToBase64String(hashBytes).Trim();
479+
}
480+
481+
DateTimeOffset? dhHashComprovante = null;
482+
var dhHashComprovanteStr = Funcoes.InpuBox(this, titulo, "Data geração do Hash Tentativa na Entrega:", DateTimeOffset.Now.ToString("dd/MM/yyyy"));
483+
if (!string.IsNullOrEmpty(dhHashComprovanteStr)) dhHashComprovante = Convert.ToDateTime(dhHashComprovanteStr);
484+
485+
decimal? latGps = null;
486+
var latGpsStr = Funcoes.InpuBox(this, titulo, "Latitude GPS:");
487+
if (!string.IsNullOrEmpty(latGpsStr)) latGps = Convert.ToDecimal(latGpsStr);
488+
489+
decimal? longGps = null;
490+
var longGpsStr = Funcoes.InpuBox(this, titulo, "Latitude GPS:");
491+
if (!string.IsNullOrEmpty(longGpsStr)) longGps = Convert.ToDecimal(longGpsStr);
492+
493+
494+
var servicoNFe = new ServicosNFe(_configuracoes.CfgServico);
495+
var cpfcnpj = string.IsNullOrEmpty(_configuracoes.Emitente.CNPJ)
496+
? _configuracoes.Emitente.CPF
497+
: _configuracoes.Emitente.CNPJ;
498+
499+
var retornoComprovante = servicoNFe.RecepcaoEventoComprovanteEntrega(Convert.ToInt32(idlote),
500+
Convert.ToInt16(sequenciaEvento), cpfcnpj, chave, dhEntrega, nDoc, xNome, hashComprovante,
501+
dhHashComprovante, latGps, longGps, DFe.Classes.Entidades.Estado.SP);
502+
503+
TrataRetorno(retornoComprovante);
504+
505+
#endregion
506+
}
507+
catch (ComunicacaoException ex)
508+
{
509+
Funcoes.Mensagem(ex.Message, "Erro", MessageBoxButton.OK);
510+
}
511+
catch (ValidacaoSchemaException ex)
512+
{
513+
Funcoes.Mensagem(ex.Message, "Erro", MessageBoxButton.OK);
514+
}
515+
catch (Exception ex)
516+
{
517+
if (!string.IsNullOrEmpty(ex.Message))
518+
Funcoes.Mensagem(ex.Message, "Erro", MessageBoxButton.OK);
519+
}
520+
}
521+
522+
private void BtnCancComprovanteEntrega_Click(object sender, RoutedEventArgs e)
523+
{
524+
const string titulo = "Cancelar Comprovante Entrega NFe";
525+
526+
try
527+
{
528+
#region Cancelar Comprovante Entrega NFe
529+
530+
var idlote = Funcoes.InpuBox(this, titulo, "Identificador de controle do Lote de envio:", "1");
531+
if (string.IsNullOrEmpty(idlote)) throw new Exception("A Id do Lote deve ser informada!");
532+
533+
var sequenciaEvento = Funcoes.InpuBox(this, titulo, "Número sequencial do evento:", "1");
534+
if (string.IsNullOrEmpty(sequenciaEvento))
535+
throw new Exception("O número sequencial deve ser informado!");
536+
537+
var chave = Funcoes.InpuBox(this, titulo, "Chave da NFe:", "35240311656919000154550750000008281647961399");
538+
if (string.IsNullOrEmpty(chave)) throw new Exception("A Chave deve ser informada!");
539+
if (chave.Length != 44) throw new Exception("Chave deve conter 44 caracteres!");
540+
541+
var nProtEvento = Funcoes.InpuBox(this, titulo, "Nº Prot Evento:");
542+
543+
if (string.IsNullOrEmpty(nProtEvento))
544+
throw new Exception("O nº Prot Evento deve ser informado!");
545+
546+
547+
548+
var servicoNFe = new ServicosNFe(_configuracoes.CfgServico);
549+
var cpfcnpj = string.IsNullOrEmpty(_configuracoes.Emitente.CNPJ)
550+
? _configuracoes.Emitente.CPF
551+
: _configuracoes.Emitente.CNPJ;
552+
553+
var retornoComprovante = servicoNFe.RecepcaoEventoCancComprovanteEntrega(Convert.ToInt32(idlote),
554+
Convert.ToInt16(sequenciaEvento), cpfcnpj, chave, nProtEvento);
555+
556+
TrataRetorno(retornoComprovante);
557+
558+
#endregion
559+
}
560+
catch (ComunicacaoException ex)
561+
{
562+
Funcoes.Mensagem(ex.Message, "Erro", MessageBoxButton.OK);
563+
}
564+
catch (ValidacaoSchemaException ex)
565+
{
566+
Funcoes.Mensagem(ex.Message, "Erro", MessageBoxButton.OK);
567+
}
568+
catch (Exception ex)
569+
{
570+
if (!string.IsNullOrEmpty(ex.Message))
571+
Funcoes.Mensagem(ex.Message, "Erro", MessageBoxButton.OK);
572+
}
573+
}
574+
438575
private void BtnConsultaXml_Click(object sender, RoutedEventArgs e)
439576
{
440577
try

NFe.Classes/Servicos/Evento/detEvento.cs

+54-2
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ public bool ShouldSerializeItensAverbados()
169169
}
170170
#endregion
171171

172-
#region Cancelamento Insucesso NFe
172+
#region Cancelamento Insucesso/Comprovante de Entrega NFe
173173

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

180180
#endregion
181-
181+
182182
#region Insucesso NFe
183183
[XmlIgnore]
184184
public DateTimeOffset? dhTentativaEntrega { get; set; }
@@ -262,5 +262,57 @@ public bool ShouldSerializelongGPS()
262262

263263
#endregion
264264

265+
#region Comprovante Entrega NFe
266+
267+
/// <summary>
268+
/// P30 - Data e hora do final da entrega
269+
/// </summary>
270+
[XmlIgnore]
271+
public DateTimeOffset? dhEntrega { get; set; }
272+
273+
/// <summary>
274+
/// Proxy para dhEntrega no formato AAAA-MM-DDThh:mm:ssTZD (UTC - Universal Coordinated Time)
275+
/// </summary>
276+
[XmlElement(ElementName = "dhEntrega")]
277+
public string ProxyDhEntrega
278+
{
279+
get { return dhEntrega.ParaDataHoraStringUtc(); }
280+
set { dhEntrega = DateTimeOffset.Parse(value); }
281+
}
282+
283+
/// <summary>
284+
/// P31 - Número do documento de identificação da pessoa que assinou o Comprovante de Entrega da NF-e/>
285+
/// </summary>
286+
public string nDoc { get; set; }
287+
288+
/// <summary>
289+
/// P32 - Nome da pessoa que assinou o Comprovante de Entrega da NF-e/>
290+
/// </summary>
291+
public string xNome { get; set; }
292+
293+
/// <summary>
294+
/// P35 - Hash SHA-1, no formato Base64, resultante da concatenação de: Chave de Acesso da NF-e + Base64
295+
/// da imagem capturada do Comprovante de Entrega da NFe (ex: imagem capturada da assinatura eletrônica, digital do recebedor, foto, etc).
296+
/// </summary>
297+
public string hashComprovante { get; set; }
298+
299+
/// <summary>
300+
/// P36 - Data e hora da geração do hash da tentativa de entrega. Formato AAAA-MMDDThh:mm:ssTZD.
301+
/// </summary>
302+
[XmlIgnore]
303+
public DateTimeOffset? dhHashComprovante { get; set; }
304+
305+
/// <summary>
306+
/// Proxy para dhHashComprovante no formato AAAA-MM-DDThh:mm:ssTZD (UTC - Universal Coordinated Time)
307+
/// </summary>
308+
[XmlElement(ElementName = "dhHashComprovante")]
309+
public string ProxyDhHashComprovante
310+
{
311+
get { return dhHashComprovante.ParaDataHoraStringUtc(); }
312+
set { dhHashComprovante = DateTimeOffset.Parse(value); }
313+
}
314+
315+
#endregion
316+
265317
}
266318
}

NFe.Classes/Servicos/Tipos/NFeServicosTipos.cs

+24
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,16 @@ public enum ServicoNFe
6464
/// </summary>
6565
RecepcaoEventoCancInsucessoEntregaNFe,
6666

67+
/// <summary>
68+
/// serviço destinado à recepção de mensagem do Evento Comprovante de Entrega da NFe
69+
/// </summary>
70+
RecepcaoEventoComprovanteEntregaNFe,
71+
72+
/// <summary>
73+
/// serviço destinado à recepção de mensagem do Evento Cancelamento do Comprovante de Entrega da NFe
74+
/// </summary>
75+
RecepcaoEventoCancComprovanteEntregaNFe,
76+
6777
/// <summary>
6878
/// serviço destinado à recepção de mensagem do Evento de Manifestação do destinatário da NF-e
6979
/// </summary>
@@ -211,6 +221,20 @@ public enum NFeTipoEvento
211221
[XmlEnum("110193")]
212222
TeNfeCancInsucessoNaEntregadaNFe = 110193,
213223

224+
/// <summary>
225+
/// 110130 - Comprovante de Entrega da NF-e
226+
/// </summary>
227+
[Description("Comprovante de Entrega da NF-e")]
228+
[XmlEnum("110130")]
229+
TeNfeComprovanteDeEntregadaNFe = 110130,
230+
231+
/// <summary>
232+
/// 110131 - Cancelamento Comprovante de Entrega da NF-e
233+
/// </summary>
234+
[Description("Cancelamento Comprovante de Entrega da NF-e")]
235+
[XmlEnum("110131")]
236+
TeNfeCancComprovanteDeEntregadaNFe = 110131,
237+
214238
/// <summary>
215239
/// 210200 – Confirmação da Operação
216240
/// </summary>

NFe.Integracao/NFeFacade.cs

+1
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ private void CarregarConfiguracoes()
187187
ConfiguracaoServico.Instancia.VersaoNfeStatusServico = versaoNFe;
188188
ConfiguracaoServico.Instancia.VersaoRecepcaoEventoCceCancelamento = versaoNFe;
189189
ConfiguracaoServico.Instancia.VersaoRecepcaoEventoInsucessoEntrega = versaoNFe;
190+
ConfiguracaoServico.Instancia.VersaoRecepcaoEventoComprovanteEntrega = versaoNFe;
190191

191192
#endregion
192193

NFe.Servicos/ServicoNfeFactory.cs

+4
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ public static INfeServico CriaWsdlOutros(ServicoNFe servico, ConfiguracaoServico
233233
case ServicoNFe.RecepcaoEventoCancInsucessoEntregaNFe:
234234
return new RecepcaoEvento4SVCAN(url, certificado, cfg.TimeOut);
235235

236+
case ServicoNFe.RecepcaoEventoComprovanteEntregaNFe:
237+
case ServicoNFe.RecepcaoEventoCancComprovanteEntregaNFe:
238+
return new RecepcaoEvento4AN(url, certificado, cfg.TimeOut);
239+
236240
case ServicoNFe.RecepcaoEventoManifestacaoDestinatario:
237241
if (cfg.VersaoRecepcaoEventoManifestacaoDestinatario == VersaoServico.Versao400)
238242
{

0 commit comments

Comments
 (0)