diff --git a/.github/workflows/DFe.NET_build.yml b/.github/workflows/DFe.NET_build.yml index b7ab764eb..ea9766c6d 100644 --- a/.github/workflows/DFe.NET_build.yml +++ b/.github/workflows/DFe.NET_build.yml @@ -64,7 +64,7 @@ jobs: dotnet build -p:Version=${{ steps.date.outputs.date }} ".\MDFe.Utils\MDFe.Utils.csproj" -c "Release" dotnet build -p:Version=${{ steps.date.outputs.date }} ".\MDFe.Wsdl\MDFe.Wsdl.csproj" -c "Release" - - name: Build/Restore MDFe + - name: Build/Restore CTe run: | dotnet build -p:Version=${{ steps.date.outputs.date }} ".\CTe.Classes\CTe.Classes.csproj" -c "Release" dotnet build -p:Version=${{ steps.date.outputs.date }} ".\CTe.Servicos\CTe.Servicos.csproj" -c "Release" @@ -150,4 +150,4 @@ jobs: DISCORD_MENSAGEM: ${{ needs.build.outputs.version }} uses: Ilshidur/action-discord@master with: - args: 'Lançado Zeus DFe.NET versão {{ DISCORD_MENSAGEM }} no Nuget! Acesse: https://www.nuget.org/profiles/ZeusAutomacao' \ No newline at end of file + args: 'Lançado Zeus DFe.NET versão {{ DISCORD_MENSAGEM }} no Nuget! Acesse: https://www.nuget.org/profiles/ZeusAutomacao' diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 33df31b40..c1ca367e2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -127,6 +127,8 @@ A mensagem do commit deve descrever claramente como o comportamento está mudand #### Pull requests +Os Pull Requests devem conter apenas alterações relacionadas a uma única funcionalidade ou correção. Isso auxilia na revisão e mantém o histórico do repositório organizado e facilita a compreensão das mudanças. + Após concluir as alterações na sua branch, abra um Pull Request (PR) da branch, em seu fork, onde realizou a implementação, para a branch `master` do repositório principal. Isso permitirá que seu código seja revisado e mesclado ao repositório principal. Para isso, siga as diretrizes abaixo: 1. Certifique-se de que sua branch está sincronizada com a branch principal (`master`). Caso necessário, faça um rebase ou merge antes de abrir o PR @@ -186,4 +188,4 @@ public string verAplic { get; set; } ## Licença -Ao contribuir para o projeto DFe.NET, você concorda que suas contribuições estarão sob a mesma [Licença do Projeto](LICENSE). \ No newline at end of file +Ao contribuir para o projeto DFe.NET, você concorda que suas contribuições estarão sob a mesma [Licença do Projeto](LICENSE). diff --git a/CTe.AppTeste.NetCore/Program.cs b/CTe.AppTeste.NetCore/Program.cs index 6ed940b80..e348f7241 100644 --- a/CTe.AppTeste.NetCore/Program.cs +++ b/CTe.AppTeste.NetCore/Program.cs @@ -111,6 +111,9 @@ private static async void Menu() case 10: await EventoDesacordoCTe(); break; + case 11: + await EventoCancelaDesacordoCTe(); + break; } if (Convert.ToInt32(option) > 0) @@ -370,6 +373,23 @@ private static async Task EventoDesacordoCTe() OnSucessoSync(new RetornoEEnvio(retorno)); } + private static async Task EventoCancelaDesacordoCTe() + { + var config = new ConfiguracaoDao().BuscarConfiguracao(); + //CarregarConfiguracoes(config); + var configuracaoServico = MontarConfiguracoes(config); + + var cnpj = RequisitarInput("CNPJ Tomador"); + var chave = RequisitarInput("Chave CTe"); + var sequenciaEvento = int.Parse(RequisitarInput("Sequencia Evento")); + var nProtEventoDesacordo = RequisitarInput("Número do Protocolo do Evento de Desacordo"); + + var servico = new EventoCancelamentoDesacordo(sequenciaEvento, chave, cnpj, nProtEventoDesacordo); + var retorno = await servico.CancelarDesacordoAsync(configuracaoServico); + + OnSucessoSync(new RetornoEEnvio(retorno)); + } + private static async Task CartaCorrecao() { var config = new ConfiguracaoDao().BuscarConfiguracao(); diff --git a/CTe.AppTeste/CTe.AppTeste.csproj b/CTe.AppTeste/CTe.AppTeste.csproj index e7087b778..a1c168627 100644 --- a/CTe.AppTeste/CTe.AppTeste.csproj +++ b/CTe.AppTeste/CTe.AppTeste.csproj @@ -302,6 +302,9 @@ Designer Always + + Designer + Designer Always @@ -326,6 +329,9 @@ Designer Always + + Designer + Designer Always @@ -382,6 +388,9 @@ Designer Always + + Designer + Designer Always @@ -590,6 +599,9 @@ Designer Always + + Designer + Designer Always @@ -690,6 +702,9 @@ Designer Always + + Designer + Designer Always diff --git a/CTe.AppTeste/CTeTesteModel.cs b/CTe.AppTeste/CTeTesteModel.cs index 0e5f2fef4..d5772b197 100644 --- a/CTe.AppTeste/CTeTesteModel.cs +++ b/CTe.AppTeste/CTeTesteModel.cs @@ -84,6 +84,7 @@ using infTribFed = CTe.Classes.Informacoes.Impostos.infTribFed; using OpenFileDialog = Microsoft.Win32.OpenFileDialog; using rodoOS = CTe.Classes.Informacoes.infCTeNormal.infModals.rodoOS; +using CTe.Classes.Informacoes.Impostos.IBSCBS; namespace CTe.AppTeste { @@ -602,6 +603,7 @@ private static void CarregarConfiguracoes(Configuracao config) var configuracaoCertificado = new ConfiguracaoCertificado { Arquivo = config.CertificadoDigital.CaminhoArquivo, + TipoCertificado = TipoCertificado.A1Repositorio, ManterDadosEmCache = config.CertificadoDigital.ManterEmCache, Serial = config.CertificadoDigital.NumeroDeSerie }; @@ -824,6 +826,22 @@ public void EventoDesacordoCTe() OnSucessoSync(new RetornoEEnvio(retorno)); } + public void EventoCancelaDesacordoCTe() + { + var config = new ConfiguracaoDao().BuscarConfiguracao(); + CarregarConfiguracoes(config); + + var cnpj = (InputBoxTuche("CNPJ Tomador")); + var chave = (InputBoxTuche("Chave CTe")); + var sequenciaEvento = int.Parse(InputBoxTuche("Sequencia Evento")); + var nProtEventoDesacordo = InputBoxTuche("Número do Protocolo do Evento de Desacordo"); + + var servico = new EventoCancelamentoDesacordo(sequenciaEvento, chave, cnpj, nProtEventoDesacordo); + var retorno = servico.CancelarDesacordo(); + + OnSucessoSync(new RetornoEEnvio(retorno)); + } + public void CartaCorrecao() { var config = new ConfiguracaoDao().BuscarConfiguracao(); @@ -1031,6 +1049,32 @@ public void CriarEnviarCTe2e3() icmsSimplesNacional.CST = CST.ICMS90; } + cteEletronico.infCte.imp.IBSCBS = new IBSCBS() + { + cClassTrib = "000001", + CST = CSTIBSCBS.cst000, + gIBSCBS = new gIBSCBS() + { + vBC = 0m, + vIBS = 0m, + gIBSUF = new gIBSUF() + { + pIBSUF = 0.1m, + vIBSUF = 0m, + }, + gIBSMun = new gIBSMun() + { + pIBSMun = 0, + vIBSMun = 0, + }, + gCBS = new gCBS() + { + pCBS = 0.09m, + vCBS = 0 + }, + } + }; + #endregion #region infCTeNorm @@ -1094,9 +1138,7 @@ public void CriarEnviarCTe2e3() cteEletronico.infCte.infCTeNorm.infModal.ContainerModal = rodoviario; #endregion - - - + var servicoRecepcao = new ServicoCTeRecepcao(); diff --git a/CTe.AppTeste/MainWindow.xaml b/CTe.AppTeste/MainWindow.xaml index f928d0d3c..d576a74b3 100644 --- a/CTe.AppTeste/MainWindow.xaml +++ b/CTe.AppTeste/MainWindow.xaml @@ -228,6 +228,7 @@ + @@ -243,8 +244,9 @@ + - + diff --git a/CTe.AppTeste/MainWindow.xaml.cs b/CTe.AppTeste/MainWindow.xaml.cs index 6f1511e49..0f847b006 100644 --- a/CTe.AppTeste/MainWindow.xaml.cs +++ b/CTe.AppTeste/MainWindow.xaml.cs @@ -120,6 +120,11 @@ private void EventoDesacordoCTe_Click(object sender, RoutedEventArgs e) _model.EventoDesacordoCTe(); } + private void EventoCancelaDesacordoCTe_Click(object sender, RoutedEventArgs e) + { + _model.EventoCancelaDesacordoCTe(); + } + private void CartaCorrecao_Click(object sender, RoutedEventArgs e) { _model.CartaCorrecao(); diff --git a/CTe.AppTeste/schemas/DFeTiposBasicos_v1.00.xsd b/CTe.AppTeste/schemas/DFeTiposBasicos_v1.00.xsd new file mode 100644 index 000000000..ea6eab8e8 --- /dev/null +++ b/CTe.AppTeste/schemas/DFeTiposBasicos_v1.00.xsd @@ -0,0 +1,1293 @@ + + + + + + Tipo string genérico + + + + + + + + + Código Situação Tributária do IBS/CBS + + + + + + + + + Código de Classificação Tributária do IBS e da CBS + + + + + + + + + Código de Classificação do Crédito Presumido do IBS e da CBS, conforme tabela cCredPres + + + + + + + + + Tipo Decimal com 15 dígitos, sendo 11 de corpo e 4 decimais + + + + + + + + + Tipo Decimal com 11 inteiros, podendo ter 4 decimais (utilizado em tags opcionais) + + + + + + + + + Tipo Decimal com 15 dígitos, sendo 13 de corpo e 2 decimais + + + + + + + + + Tipo Decimal com até 3 dígitos inteiros, podendo ter de 2 até 4 decimais + + + + + + + + + Tipo da Operação com Ente Governamental + + + + + + + + + + Tipo de Ente Governamental + + + + + + + + + + + + Tipo de classificação do Crédito Presumido IBS ZFM + + + + + + + + + + + + Tipo Indicador de Doação + + + + + + + + Grupo de informações da Tributação da NFCom + + + + + Código Situação Tributária do IBS/CBS + + + + + + Indica se a operação é de doação + + + + + + Informado conforme indicador no cClassTrib + + + + + + + Grupo de informações da Tributação da NF3e + + + + + Código Situação Tributária do IBS/CBS + + + + + + Indica se a operação é de doação + + + + + + Informado conforme indicador no cClassTrib + + + + + + + Grupo de informações da Tributação da NFAg + + + + + Código Situação Tributária do IBS/CBS + + + + + + + + Informado conforme indicador no cClassTrib + + + + + + + Grupo de informações da Tributação do CTe + + + + + Código Situação Tributária do IBS/CBS + + + + + + + + Informado conforme indicador no cClassTrib + + + + + + + Grupo de informações da Tributação do BPe + + + + + Código Situação Tributária do IBS/CBS + + + + + + + + Informado conforme indicador no cClassTrib + + + + + + + Grupo de informações da Tributação da NFCe + + + + + Código Situação Tributária do IBS/CBS + + + + + + Indica se a operação é de doação + + + + + + + + + + + Grupo de informações da Tributação da NFe + + + + + Código Situação Tributária do IBS/CBS + + + + + + Indica se a operação é de doação + + + + + + + Informar essa opção da Choice para Monofasia (CST 620) + + + + + Informar essa opção da Choice para o CST 800 + + + + + Informar essa opção da Choice para o CST 811 + + + + + + Informado conforme indicador no cClassTrib + + + + + + Crédito Presumido da Operação. Informado conforme indicador no cClassTrib. + + + + + Classificação de acordo com o art. 450, § 1º, da LC 214/25 para o cálculo do crédito presumido na ZFM. Informado conforme indicador no cClassTrib. + + + + + + + + Grupo de informações da Tributação da NFGas + + + + + Código Situação Tributária do IBS/CBS + + + + + + + + + Informar essa opção da Choice para Monofasia + + + + + + Informado conforme indicador no cClassTrib + + + + + + + Grupo de informações do Imposto Seletivo + + + + + Código Situação Tributária do Imposto Seletivo + + + + + + + Valor do BC + + + + + Alíquota do Imposto Seletivo (percentual) + + + + + Alíquota do Imposto Seletivo (por valor) + + + + + + Unidade de medida apropriada especificada em Lei Ordinaria para fins de apuração do Imposto Seletivo + + + + + + + + + + + Quantidade com abse no campo uTrib informado + + + + + + Valor do Imposto Seletivo calculado + + + + + + + + Grupo de informações de totais do Imposto Seletivo + + + + + Valor Total do Imposto Seletivo + + + + + + + Grupo de informações de totais da CBS/IBS + + + + + Total Base de Calculo + + + + + Totalização do IBS + + + + + + Totalização do IBS de competência da UF + + + + + + Total do Diferimento + + + + + Total de devoluções de tributos + + + + + Valor total do IBS Estadual + + + + + + + + Totalização do IBS de competência Municipal + + + + + + Total do Diferimento + + + + + Total de devoluções de tributos + + + + + Valor total do IBS Municipal + + + + + + + + Valor total do IBS + + + + + + + + Totalização da CBS + + + + + + Total do Diferimento + + + + + Total de devoluções de tributos + + + + + Valor total da CBS + + + + + + + + Totalização do estorno de crédito + + + + + + Valor total do IBS estornado + + + + + Valor total da CBS estornada + + + + + + + + + + Grupo de informações de totais da CBS/IBS com monofasia + + + + + Total Base de Calculo + + + + + Totalização do IBS + + + + + + Totalização do IBS de competência da UF + + + + + + Total do Diferimento + + + + + Total de devoluções de tributos + + + + + Valor total do IBS Estadual + + + + + + + + Totalização do IBS de competência Municipal + + + + + + Total do Diferimento + + + + + Total de devoluções de tributos + + + + + Valor total do IBS Municipal + + + + + + + + Valor total do IBS + + + + + Total do Crédito Presumido + + + + + Total do Crédito Presumido Condição Suspensiva + + + + + + + + Totalização da CBS + + + + + + Total do Diferimento + + + + + Total de devoluções de tributos + + + + + Valor total da CBS + + + + + Total do Crédito Presumido + + + + + Total do Crédito Presumido Condição Suspensiva + + + + + + + + Totais da Monofasia + Só deverá ser utilizado para DFe modelos 55 e 65 + + + + + + Valor total do IBS monofásico + + + + + Valor total da CBS monofásica + + + + + Valor total do IBS monofásico sujeito a retenção + + + + + Valor total da CBS monofásica sujeita a retenção + + + + + Valor do IBS monofásico retido anteriormente + + + + + Valor da CBS monofásica retida anteriormente + + + + + + + + Totalização do estorno de crédito + + + + + + Valor total do IBS estornado + + + + + Valor total da CBS estornada + + + + + + + + + + Tipo Monofasia + + + + Monofasia + + + + Grupo de informações da Tributação Monofásica padrão + + + + + + Quantidade tributada na monofasia + + + + + Alíquota ad rem do IBS + + + + + Alíquota ad rem da CBS + + + + + Valor do IBS monofásico + + + + + Valor da CBS monofásica + + + + + + + + Grupo de informações da Tributação Monofásica sujeita a retenção + + + + + + Quantidade tributada sujeita a retenção. + + + + + Alíquota ad rem do IBS sujeito a retenção + + + + + Valor do IBS monofásico sujeito a retenção + + + + + Alíquota ad rem da CBS sujeita a retenção + + + + + Valor da CBS monofásica sujeita a retenção + + + + + + + + Grupo de informações da Tributação Monofásica retida anteriormente + + + + + + Quantidade tributada retida anteriormente + + + + + Alíquota ad rem do IBS retido anteriormente + + + + + Valor do IBS retido anteriormente + + + + + Alíquota ad rem da CBS retida anteriormente + + + + + Valor da CBS retida anteriormente + + + + + + + + Grupo de informações do diferimento da Tributação Monofásica + + + + + + Percentual do diferimento do imposto monofásico + + + + + Valor do IBS monofásico diferido + + + + + Percentual do diferimento do imposto monofásico + + + + + Valor da CBS monofásica diferida + + + + + + + + Total de IBS monofásico do item + + + + + Total da CBS monofásica do item + + + + + + + Tipo CBS IBS Completo + + + + IBS / CBS + + + + Valor do BC + + + + + + Grupo de informações do IBS na UF + + + + + + Aliquota do IBS de competência das UF (em percentual) + + + + + Grupo de campos do Diferimento + + + + + Grupo de Informações da devolução de tributos + + + + + Grupo de campos da redução de aliquota + + + + + Valor do IBS de competência das UF + + + + + + + + Grupo de Informações do IBS no Município + + + + + + Aliquota do IBS Municipal (em percentual) + + + + + Grupo de campos do Diferimento + + + + + Grupo de Informações da devolução de tributos + + + + + Grupo de campos da redução de aliquota + + + + + Valor do IBS Municipal + + + + + + + + Valor do IBS + + + + + + Grupo de Tributação da CBS + + + + + + Aliquota da CBS (em percentual) + + + + + Grupo de campos do Diferimento + + + + + Grupo de Informações da devolução de tributos + + + + + Grupo de campos da redução de aliquota + + + + + Valor da CBS + + + + + + + + Grupo de informações da Tributação Regular. Informar como seria a tributação caso não cumprida a condição resolutória/suspensiva. Exemplo 1: Art. 442, §4. Operações com ZFM e ALC. Exemplo 2: Operações com suspensão do tributo. + + + + + Grupo de informações da composição do valor do IBS e da CBS em compras governamental + + + + + + + Tipo Redução Base de Cálculo + + + + + Percentual de redução de aliquota do cClassTrib + + + + + Aliquota Efetiva que será aplicada a Base de Calculo (em percentual) + + + + + + + Tipo Crédito Presumido + + + + + Percentual do Crédito Presumido + + + + + + Valor do Crédito Presumido + + + + + Valor do Crédito Presumido Condição Suspensiva, preencher apenas para cCredPres que possui indicação de Condição Suspensiva + + + + + + + + Tipo Diferimento + + + + + Percentual do diferimento + + + + + Valor do diferimento + + + + + + + Tipo Devolução Tributo + + + + + Valor do tributo devolvido. No fornecimento de energia elétrica, água, esgoto e +gás natural e em outras hipóteses definidas no regulamento + + + + + + + Tipo Tributação Regular + + + + + Código da Situação Tributária do IBS e CBS + Informar qual seria o CST caso não cumprida a condição resolutória/suspensiva + + + + + Informar qual seria o cClassTrib caso não cumprida a condição resolutória/suspensiva + + + + + Alíquota do IBS da UF + Informar como seria a Alíquota caso não cumprida a condição resolutória/suspensiva + + + + + Valor do IBS da UF + Informar como seria o valor do Tributo caso não cumprida a condição resolutória/suspensiva + + + + + Alíquota do IBS do Município + Informar como seria a Alíquota caso não cumprida a condição resolutória/suspensiva + + + + + Valor do IBS do Município + Informar como seria o valor do Tributo caso não cumprida a condição resolutória/suspensiva + + + + + Alíquota da CBS + Informar como seria a Alíquota caso não cumprida a condição resolutória/suspensiva + + + + + Valor da CBS + Informar como seria o valor do Tributo caso não cumprida a condição resolutória/suspensiva + + + + + + + Tipo Tributação Compra Governamental + + + + + + Valor que seria devido a UF, sem aplicação do Art. 473. da LC 214/2025 + + + + + + Valor que seria devido ao município, sem aplicação do Art. 473. da LC 214/2025 + + + + + + Valor que seria devido a CBS, sem aplicação do Art. 473. da LC 214/2025 + + + + + + + Tipo Compras Governamentais + Cada DFe que utilizar deverá utilizar esses tipo no grupo ide + + + + + Para administração pública direta e suas autarquias e fundações: +1=União +2=Estados +3=Distrito Federal +4=Municípios + + + + + Percentual de redução de aliquota em compra governamental + + + + + + + Tipo Compras Governamentais + Cada DFe que utilizar deverá utilizar esses tipo no grupo ide + + + + + Para administração pública direta e suas autarquias e fundações: +1=União +2=Estados +3=Distrito Federal +4=Municípios + + + + + Percentual de redução de aliquota em compra governamental + + + + + Tipo da operação com ente governamental: +1 - Fornecimento +2 - Recebimento do Pagamento + + + + + + + Tipo Transferência de Crédito + + + + + Valor do IBS a ser transferido + + + + + Valor da CBS a ser transferida + + + + + + + Tipo Estorno de Crédito + + + + + Valor do IBS a ser estornado + + + + + Valor da CBS a ser estornada + + + + + + + Ano e mês referência do período de apuração (AAAA-MM) + + + + + + + + Tipo Ajuste de Competência + + + + + Ano e mês referência do período de apuração (AAAA-MM) + + + + + Valor do IBS + + + + + Valor da CBS + + + + + + + Tipo Crédito Presumido da Operação + + + + + Valor da Base de Cálculo do Crédito Presumido da Operação + + + + + Código de Classificação do Crédito Presumido do IBS e da CBS + + + + + Grupo de Informações do Crédito Presumido referente ao IBS, quando aproveitado pelo emitente do documento. + + + + + Grupo de Informações do Crédito Presumido referente a CBS, quando aproveitado pelo emitente do documento. + + + + + + + Tipo Informações do crédito presumido de IBS para fornecimentos a partir da ZFM + + + + + Ano e mês referência do período de apuração (AAAA-MM) + + + + + Classificação de acordo com o art. 450, § 1º, da LC 214/25 para o cálculo do crédito presumido na ZFM + 0 - Sem crédito presumido; +1 - Bens de consumo final (55%); +2 - Bens de capital (75%); +3 - Bens intermediários (90,25%); +4 - Bens de informática e outros definidos em legislação (100%). +OBS: Percentuais definidos no art. 450, § 1º, da LC 214/25 para o cálculo do crédito presumido + + + + + + Valor do crédito presumido calculado sobre o saldo devedor apurado + + + + + \ No newline at end of file diff --git a/CTe.AppTeste/schemas/cteModalDutoviario_v4.00.xsd b/CTe.AppTeste/schemas/cteModalDutoviario_v4.00.xsd index bc9c8940a..bb75ffd76 100644 --- a/CTe.AppTeste/schemas/cteModalDutoviario_v4.00.xsd +++ b/CTe.AppTeste/schemas/cteModalDutoviario_v4.00.xsd @@ -24,6 +24,68 @@ Data de Fim da prestação do serviço + + + Classificação do Dutoviário + Informar: 1 - Gasoduto 2 - Mineroduto 3 - Oleoduto + + + + + + + + + + + + Tipo de contratação do serviço de transporte (apenas para gasoduto) + Informar: +0 - Ponta a ponto +1 - Capacidade de Entrada +2 - Capacidade de Saida + + + + + + + + + + + + Código do Ponto de Entrada + + + + + + + + + + + Código do Ponto de Saída + + + + + + + + + + + Número do Contrato de Capacidade + + + + + + + + diff --git a/CTe.AppTeste/schemas/cteSimp_v4.00.xsd b/CTe.AppTeste/schemas/cteSimp_v4.00.xsd new file mode 100644 index 000000000..a6b23e03f --- /dev/null +++ b/CTe.AppTeste/schemas/cteSimp_v4.00.xsd @@ -0,0 +1,10 @@ + + + + + + + Conhecimento de Transporte Eletrônico Simplificado + + + diff --git a/CTe.AppTeste/schemas/cteTiposBasico_v4.00.xsd b/CTe.AppTeste/schemas/cteTiposBasico_v4.00.xsd index 3cf5e8845..389b6391d 100644 --- a/CTe.AppTeste/schemas/cteTiposBasico_v4.00.xsd +++ b/CTe.AppTeste/schemas/cteTiposBasico_v4.00.xsd @@ -1,8 +1,9 @@ - + + Tipo Modal transporte GTVe @@ -120,17 +121,13 @@ Forma de emissão da GTV-e Preencher com: 1 - Normal; - 2- Contingencia offline -7 - Autorização pela SVC-RS; - 8 - Autorização pela SVC-SP +2- Contingencia offline - - @@ -882,7 +879,7 @@ REENTREGA; DEVOLUÇÃO; REFATURAMENTO; etc - + @@ -903,7 +900,7 @@ REENTREGA; DEVOLUÇÃO; REFATURAMENTO; etc - + @@ -1191,6 +1188,46 @@ REENTREGA; DEVOLUÇÃO; REFATURAMENTO; etc + + + Tipo Retorno do Pedido de Autorização de CT-e Simplificado (Modelo 57) + + + + + Identificação do Ambiente: +1 - Produção +2 - Homologação + + + + + Identificação da UF + + + + + Versão do Aplicativo que processou a CT-e + + + + + código do status do retorno da consulta. + + + + + Descrição literal do status do do retorno da consulta. + + + + + Reposta ao processamento do CT-e + + + + + Tipo Retorno do Pedido de Autorização de CT-e (Modelo 57) @@ -1213,10 +1250,15 @@ REENTREGA; DEVOLUÇÃO; REFATURAMENTO; etc Versão do Aplicativo que processou a CT-e - + código do status do retorno da consulta. + + + + + @@ -1303,13 +1345,1370 @@ REENTREGA; DEVOLUÇÃO; REFATURAMENTO; etc Descrição literal do status do do retorno da consulta. - + + + Reposta ao processamento do CT-e + + + + + + + + Tipo Conhecimento de Transporte Eletrônico (Modelo 57) - Modelo Simplificado + + + + + Informações do CT-e + + + + + + Identificação do CT-e + + + + + + Código da UF do emitente do CT-e. + Utilizar a Tabela do IBGE. + + + + + Código numérico que compõe a Chave de Acesso. + Número aleatório gerado pelo emitente para cada CT-e, com o objetivo de evitar acessos indevidos ao documento. + + + + + + + + + + + Código Fiscal de Operações e Prestações + + + + + Natureza da Operação + + + + + + + + + + + Modelo do documento fiscal + Utilizar o código 57 para identificação do CT-e, emitido em substituição aos modelos de conhecimentos em papel. + + + + + Série do CT-e + Preencher com "0" no caso de série única + + + + + + + + Número do CT-e + + + + + Data e hora de emissão do CT-e + Formato AAAA-MM-DDTHH:MM:DD TZD + + + + + + + + Formato de impressão do DACTE + Preencher com: 1 - Retrato; 2 - Paisagem. + + + + + + + + + + + + Forma de emissão do CT-e + Preencher com: +1 - Normal; +3 - Regime Especial NFF; +4 - EPEC pela SVC; +7 - Autorização pela SVC-RS; +8 - Autorização pela SVC-SP + + + + + + + + + + + + + + + Digito Verificador da chave de acesso do CT-e + Informar o dígito de controle da chave de acesso do CT-e, que deve ser calculado com a aplicação do algoritmo módulo 11 (base 2,9) da chave de acesso. + + + + + + + + + + + Tipo do Ambiente + Preencher com:1 - Produção; 2 - Homologação. + + + + + Tipo do CT-e Simplificado + Preencher com: +5 - CTe Simplificado +6 - Substituição CTe Simplificado + + + + + Identificador do processo de emissão do CT-e + Preencher com: + 0 - emissão de CT-e com aplicativo do contribuinte; + 3- emissão CT-e pelo contribuinte com aplicativo fornecido pelo SEBRAE. + + + + + Versão do processo de emissão + Informar a versão do aplicativo emissor de CT-e. + + + + + + + + + + + Código do Município de envio do CT-e (de onde o documento foi transmitido) + Utilizar a tabela do IBGE. Informar 9999999 para as operações com o exterior. + + + + + Nome do Município de envio do CT-e (de onde o documento foi transmitido) + Informar PAIS/Municipio para as operações com o exterior. + + + + + + + + + + + Sigla da UF de envio do CT-e (de onde o documento foi transmitido) + Informar 'EX' para operações com o exterior. + + + + + Modal + Preencher com: +01-Rodoviário +02-Aéreo +03-Aquaviário + + + + + Tipo do Serviço + Preencher com: +0 - Normal; +1 - Subcontratação; +2 - Redespacho; + + + + + + + + + + + + + UF do início da prestação + Informar 'EX' para operações com o exterior. + + + + + UF do término da prestação + Informar 'EX' para operações com o exterior. + + + + + Indicador se o Recebedor retira no Aeroporto, Filial, Porto ou Estação de Destino? + Preencher com: 0 - sim; 1 - não + + + + + + + + + + + + Detalhes do retira + + + + + + + + + + + Informar apenas +para tpEmis diferente de 1 + + + + Data e Hora da entrada em contingência + Informar a data e hora no formato AAAA-MM-DDTHH:MM:SS + + + + + Justificativa da entrada em contingência + + + + + + + + + + + + Grupo de Compras Governamentais + + + + + + + + Dados complementares do CT-e para fins operacionais ou comerciais + + + + + + Característica adicional do transporte + Texto livre: +REENTREGA; DEVOLUÇÃO; REFATURAMENTO; etc + + + + + + + + + + + Característica adicional do serviço + Texto livre: + ENTREGA EXPRESSA; LOGÍSTICA REVERSA; CONVENCIONAL; EMERGENCIAL; etc + + + + + + + + + + + Previsão do fluxo da carga + Preenchimento obrigatório para o modal aéreo. + + + + + + Sigla ou código interno da Filial/Porto/Estação/ Aeroporto de Origem + Observações para o modal aéreo: + - Preenchimento obrigatório para o modal aéreo. + - O código de três letras IATA do aeroporto de partida deverá ser incluído como primeira anotação. Quando não for possível, utilizar a sigla OACI. + + + + + + + + + + + + + + Sigla ou código interno da Filial/Porto/Estação/Aeroporto de Passagem + Observação para o modal aéreo: + - O código de três letras IATA, referente ao aeroporto de transferência, deverá ser incluído, quando for o caso. Quando não for possível, utilizar a sigla OACI. Qualquer solicitação de itinerário deverá ser incluída. + + + + + + + + + + + + + + Sigla ou código interno da Filial/Porto/Estação/Aeroporto de Destino + Observações para o modal aéreo: + - Preenchimento obrigatório para o modal aéreo. + - Deverá ser incluído o código de três letras IATA do aeroporto de destino. Quando não for possível, utilizar a sigla OACI. + + + + + + + + + + + Código da Rota de Entrega + + + + + + + + + + + + + + Observações Gerais + + + + + + + + + + + Campo de uso livre do contribuinte + Informar o nome do campo no atributo xCampo e o conteúdo do campo no XTexto + + + + + + Conteúdo do campo + + + + + + + + + + + + Identificação do campo + + + + + + + + + + + + + Campo de uso livre do contribuinte + Informar o nome do campo no atributo xCampo e o conteúdo do campo no XTexto + + + + + + Conteúdo do campo + + + + + + + + + + + + Identificação do campo + + + + + + + + + + + + + + + + Identificação do Emitente do CT-e + + + + + + + CNPJ do emitente + Informar zeros não significativos + + + + + CPF do emitente + Informar zeros não significativos. + +Usar com série específica 920-969 para emitente pessoa física com inscrição estadual + + + + + + Inscrição Estadual do Emitente + A IE do emitente somente ficará sem informação para o caso do Regime Especial da NFF (tpEmis=3) + + + + + + + + Inscrição Estadual do Substituto Tributário + + + + + + + + Razão social ou Nome do emitente + + + + + + + + + + + Nome fantasia + + + + + + + + + + + Endereço do emitente + + + + + Código do Regime Tributário + Informar: 1=Simples Nacional; +2=Simples Nacional, excesso sublimite de receita bruta; +3=Regime Normal. +4=Simples Nacional - Microempreendedor Individual – MEI. + + + + + + + + + Identificação do tomador do serviço no CT-e + + + + + + Tomador do Serviço + Preencher com: + +0-Remetente; +1-Expedidor; +2-Recebedor; +3-Destinatário +4-Terceiro + + + + + + + + + + + + + + + Indicador do papel do tomador na prestação do serviço: +1 – Contribuinte ICMS; +2 – Contribuinte isento de inscrição; +9 – Não Contribuinte + Aplica-se ao tomador que for indicado no toma + + + + + + + + + + + + + + Número do CNPJ + Em caso de empresa não estabelecida no Brasil, será informado o CNPJ com zeros. +Informar os zeros não significativos. + + + + + Número do CPF + Informar os zeros não significativos. + + + + + + Inscrição Estadual + Informar a IE do tomador ou ISENTO se tomador é contribuinte do ICMS isento de inscrição no cadastro de contribuintes do ICMS. Caso o tomador não seja contribuinte do ICMS não informar o conteúdo. + + + + + + + + Razão Social ou Nome + + + + + + + + + + + Inscrição na SUFRAMA + (Obrigatório nas operações com as áreas com benefícios de incentivos fiscais sob controle da SUFRAMA) + + + + + + + + + + + Telefone + + + + + Dados do endereço + + + + + Endereço de email + + + + + + + + Informações da Carga do CT-e + + + + + + Valor total da carga + + + + + Produto predominante + Informar a descrição do produto predominante + + + + + + + + + + + Outras características da carga + "FRIA", "GRANEL", "REFRIGERADA", "Medidas: 12X12X12" + + + + + + + + + + + Informações de quantidades da Carga do CT-e + Para o Aéreo é obrigatório o preenchimento desse campo da seguinte forma. +1 - Peso Bruto, sempre em quilogramas (obrigatório); +2 - Peso Cubado; sempre em quilogramas; +3 - Quantidade de volumes, sempre em unidades (obrigatório); +4 - Cubagem, sempre em metros cúbicos (obrigatório apenas quando for impossível preencher as dimensões da(s) embalagem(ens) na tag xDime do leiaute do Aéreo). + + + + + + Código da Unidade de Medida + Preencher com: +00-M3; +01-KG; +02-TON; +03-UNIDADE; +04-LITROS; +05-MMBTU + + + + + + + + + + + + + + + + Tipo da Medida + Informar com: +00-Cubagem da NF-e +01-Cubagem Aferida pelo Transportador +02-Peso Bruto da NF-e +03-Peso Bruto Aferido pelo Transportador +04-Peso Cubado +05-Peso Base do Cálculo do Frete +06-Peso para uso Operacional +07-Caixas +08-Paletes +09-Sacas +10-Containers +11-Rolos +12-Bombonas +13-Latas +14-Litragem +15-Milhão de BTU (British Thermal Units) +99-Outros + + + + + + + + + + + + + + + + + + + + + + + + + + + + Quantidade + + + + + + + + Valor da Carga para efeito de averbação + Normalmente igual ao valor declarado da mercadoria, diferente por exemplo, quando a mercadoria transportada é isenta de tributos nacionais para exportação, onde é preciso averbar um valor maior, pois no caso de indenização, o valor a ser pago será maior + + + + + + + + Detalhamento das entregas / prestações do CTe Simplificado + + + + + + + Código do Município de início da prestação + Utilizar a tabela do IBGE. Informar 9999999 para operações com o exterior. + + + + + Nome do Município do início da prestação + Informar 'EXTERIOR' para operações com o exterior. + + + + + + + + + + + + + Código do Município de término da prestação + Utilizar a tabela do IBGE. Informar 9999999 para operações com o exterior. + + + + + Nome do Município do término da prestação + Informar 'EXTERIOR' para operações com o exterior. + + + + + + + + + + + + Valorl da Prestação do Serviço + Pode conter zeros quando o CT-e for de complemento de ICMS + + + + + Valor a Receber + + + + + Componentes do Valor da Prestação + + + + + + Nome do componente + Exxemplos: FRETE PESO, FRETE VALOR, SEC/CAT, ADEME, AGENDAMENTO, etc + + + + + + + + + + + Valor do componente + + + + + + + + + Informações das NF-e + + + + + + Chave de acesso da NF-e + + + + + + + + + + PIN SUFRAMA + PIN atribuído pela SUFRAMA para a operação. + + + + + + + + + + + + + Data prevista de entrega + Formato AAAA-MM-DD + + + + + + Informações das Unidades de Carga (Containeres/ULD/Outros) + Dispositivo de carga utilizada (Unit Load Device - ULD) significa todo tipo de contêiner de carga, vagão, contêiner de avião, palete de aeronave com rede ou palete de aeronave com rede sobre um iglu. + + + + + Informações das Unidades de Transporte (Carreta/Reboque/Vagão) + Deve ser preenchido com as informações das unidades de transporte utilizadas. + + + + + + + + + Documentos anteriores + + + + + + Chave de acesso do CT-e + + + + + indica se a prestação é total ou parcial em relação as notas do documento anterior + Preencher com: + +1 - Total +2 - Parcial + + + + + + + + + + + + + + + Chave de acesso da NF-e + Informando o tpPrest com “2 – Parcial” deve-se informar as chaves de acesso das NF-e que acobertam a carga transportada. + + + + + + + + + + + + + Número identificador do item agrupador da prestação + + + + + + + + + + + + + Informações do modal + + + + + + XML do modal +Insira neste local o XML específico do modal (rodoviário, aéreo, ferroviário, aquaviário ou dutoviário). + O elemento do tipo -any- permite estender o documento XML com elementos não especificados pelo schema. + Insira neste local - any- o XML específico do modal (rodoviário, aéreo, ferroviário, aquaviário ou dutoviário). A especificação do schema XML para cada modal pode ser encontrada nos arquivos que acompanham este pacote de liberação: + Rodoviário - ver arquivo CTeModalRodoviario_v9.99 + Aéreo - ver arquivo CTeModalAereo_v9.99 + Aquaviário - arquivo CTeModalAquaviario_v9.99 + Ferroviário - arquivo CTeModalFerroviario_v9.99 + Dutoviário - arquivo CTeModalDutoviario_v9.99 + +Onde v9.99 é a a designação genérica para a versão do arquivo. Por exemplo, o arquivo para o schema do modal Rodoviário na versão 1.04 será denominado "CTeModalRodoviario_v1.04". + + + + + + Versão do leiaute específico para o Modal + + + + + + + + + + + + + Dados da cobrança do CT-e + + + + + + Dados da fatura + + + + + + Número da fatura + + + + + + + + + + + Valor original da fatura + + + + + Valor do desconto da fatura + + + + + Valor líquido da fatura + + + + + + + + Dados das duplicatas + + + + + + Número da duplicata + + + + + + + + + + + Data de vencimento da duplicata (AAAA-MM-DD) + + + + + Valor da duplicata + + + + + + + + + + + Informações do CT-e de substituição + + + + + + Chave de acesso do CT-e a ser substituído (original) + + + + + + + + + + Indicador de CT-e Alteração de Tomador + + + + + + + + + + + + + Informações relativas aos Impostos + + + + + + Informações relativas ao ICMS + + + + + + Valor Total dos Tributos + + + + + Informações adicionais de interesse do Fisco + Norma referenciada, informações complementares, etc + + + + + + + + + + + Informações do ICMS de partilha com a UF de término do serviço de transporte na operação interestadual + Grupo a ser informado nas prestações interestaduais para consumidor final, não contribuinte do ICMS + + + + + + Valor da BC do ICMS na UF de término da prestação do serviço de transporte + + + + + Percentual do ICMS relativo ao Fundo de Combate à pobreza (FCP) na UF de término da prestação do serviço de transporte + Alíquota adotada nas operações internas na UF do destinatário + + + + + Alíquota interna da UF de término da prestação do serviço de transporte + Alíquota adotada nas operações internas na UF do destinatário + + + + + Alíquota interestadual das UF envolvidas + Alíquota interestadual das UF envolvidas + + + + + + Valor do ICMS relativo ao Fundo de Combate á Pobreza (FCP) da UF de término da prestação + + + + + Valor do ICMS de partilha para a UF de término da prestação do serviço de transporte + + + + + Valor do ICMS de partilha para a UF de início da prestação do serviço de transporte + + + + + + + + Grupo de informações do IBS e CBS + + + + + + + + Valores Totais do CTe + + + + + + Valor Total da Prestação do Serviço + Pode conter zeros quando o CT-e for de complemento de ICMS + + + + + Valor total a Receber + + + + + Valor total do documento fiscal +(vTPrest + total do IBS + total da CBS) + + + + + + + + + Autorizados para download do XML do DF-e + Informar CNPJ ou CPF. Preencher os zeros não significativos. + + + + + + + CNPJ do autorizado + Informar zeros não significativos + + + + + CPF do autorizado + Informar zeros não significativos + + + + + + + + + Informações do Responsável Técnico pela emissão do DF-e + + + + + Grupo de informações do pedido de emissão da Nota Fiscal Fácil + + + + + + Solicitação do pedido de emissão da NFF. + Será preenchido com a totalidade de campos informados no aplicativo emissor serializado. + + + + + + + + + + + + + + Grupo de Informação do Provedor de Assinatura e Autorização + + + + + + CNPJ do Provedor de Assinatura e Autorização + + + + + Assinatura RSA do Emitente para DFe gerados por PAA + + + + + + Assinatura digital padrão RSA + Converter o atributo Id do DFe para array de bytes e assinar com a chave privada do RSA com algoritmo SHA1 gerando um valor no formato base64. + + + + + Chave Publica no padrão XML RSA Key + + + + + + + + + + + + Versão do leiaute + Ex: "4.00" + + + + + + + + Identificador da tag a ser assinada + Informar a chave de acesso do CT-e e precedida do literal "CTe" + + + + + + + + + + + + + + - Reposta ao processamento do CT-e + Informações suplementares do CT-e + + + + + Texto com o QR-Code impresso no DACTE + + + + + + + + + + + + + - @@ -1518,8 +2917,11 @@ REENTREGA; DEVOLUÇÃO; REFATURAMENTO; etc Tipo do Serviço Preencher com: -0 - Normal;1 - Subcontratação; -2 - Redespacho;3 - Redespacho Intermediário; 4 - Serviço Vinculado a Multimodal +0 - Normal; +1 - Subcontratação; +2 - Redespacho; +3 - Redespacho Intermediário; +4 - Serviço Vinculado a Multimodal @@ -1761,6 +3163,11 @@ para tpEmis diferente de 1 + + + Grupo de Compras Governamentais + + @@ -2628,6 +4035,18 @@ Usar com série específica 920-969 para emitente pessoa física com inscrição + + + Grupo de informações do IBS e CBS + + + + + Valor total do documento fiscal +(vTPrest + total do IBS + total da CBS) + + + @@ -3024,6 +4443,20 @@ Opcional para Redespacho Intermediario e Serviço vinculado a multimodal. + + + Informações das DCe + + + + + + Chave de acesso da DCe + + + + + @@ -3478,7 +4911,7 @@ Onde v9.99 é a a designação genérica para a versão do arquivo. Por exemplo, - + @@ -3536,7 +4969,7 @@ Onde v9.99 é a a designação genérica para a versão do arquivo. Por exemplo, - + @@ -3557,7 +4990,7 @@ Onde v9.99 é a a designação genérica para a versão do arquivo. Por exemplo, - + @@ -3703,7 +5136,6 @@ Onde v9.99 é a a designação genérica para a versão do arquivo. Por exemplo, Preencher com: 0 - CT-e Normal; 1 - CT-e Complementar; - 3 - CT-e de Substituição. @@ -3882,6 +5314,11 @@ para tpEmis diferente de 1 + + + Grupo de Compras Governamentais + + @@ -4307,6 +5744,18 @@ REENTREGA; DEVOLUÇÃO; REFATURAMENTO; etc + + + Grupo de informações do IBS e CBS + + + + + Valor total do documento fiscal +(vTPrest + total do IBS + total da CBS) + + + @@ -4732,7 +6181,7 @@ Somente para Transporte de Valores - + @@ -4753,7 +6202,7 @@ Somente para Transporte de Valores - + @@ -5371,6 +6820,29 @@ Somente para Transporte de Valores Valor do ICMS + + + Sequencia XML + + + + Valor do ICMS de desoneração + + + + + Código de Benefício Fiscal na UF + Código de Benefício Fiscal utilizado pela UF + + + + + + + + + + @@ -5397,6 +6869,29 @@ Somente para Transporte de Valores + + + Sequencia XML + + + + Valor do ICMS de desoneração + + + + + Código de Benefício Fiscal na UF + Código de Benefício Fiscal utilizado pela UF + + + + + + + + + + @@ -5442,6 +6937,29 @@ Somente para Transporte de Valores Preencher somente quando o transportador substituído, for optante pelo crédito outorgado previsto no Convênio 106/96 e corresponde ao percentual de 20% do valor do ICMS ST retido. + + + Sequencia XML + + + + Valor do ICMS de desoneração + + + + + Código de Benefício Fiscal na UF + Código de Benefício Fiscal utilizado pela UF + + + + + + + + + + @@ -5488,6 +7006,29 @@ Somente para Transporte de Valores Valor do Crédito Outorgado/Presumido + + + Sequencia XML + + + + Valor do ICMS de desoneração + + + + + Código de Benefício Fiscal na UF + Código de Benefício Fiscal utilizado pela UF + + + + + + + + + + @@ -5529,6 +7070,29 @@ Somente para Transporte de Valores Valor do ICMS devido outra UF + + + Sequencia XML + + + + Valor do ICMS de desoneração + + + + + Código de Benefício Fiscal na UF + Código de Benefício Fiscal utilizado pela UF + + + + + + + + + + @@ -5645,6 +7209,29 @@ Somente para Transporte de Valores Valor do ICMS + + + Sequencia XML + + + + Valor do ICMS de desoneração + + + + + Código de Benefício Fiscal na UF + Código de Benefício Fiscal utilizado pela UF + + + + + + + + + + @@ -5671,6 +7258,29 @@ Somente para Transporte de Valores + + + Sequencia XML + + + + Valor do ICMS de desoneração + + + + + Código de Benefício Fiscal na UF + Código de Benefício Fiscal utilizado pela UF + + + + + + + + + + @@ -5717,6 +7327,29 @@ Somente para Transporte de Valores Valor do Crédito Outorgado/Presumido + + + Sequencia XML + + + + Valor do ICMS de desoneração + + + + + Código de Benefício Fiscal na UF + Código de Benefício Fiscal utilizado pela UF + + + + + + + + + + @@ -5758,6 +7391,29 @@ Somente para Transporte de Valores Valor do ICMS devido outra UF + + + Sequencia XML + + + + Valor do ICMS de desoneração + + + + + Código de Benefício Fiscal na UF + Código de Benefício Fiscal utilizado pela UF + + + + + + + + + + @@ -6226,6 +7882,16 @@ Observação: 28 caracteres são representados no schema como 20 bytes do tipo b + + + Tipos Finalidade de CT-e Simplificado + + + + + + + Tipo Identificador de controle do envio do lote. Número seqüencial auto-incremental, de controle correspondente ao identificador único do lote enviado. A responsabilidade de gerar e controlar esse número é do próprio contribuinte. @@ -6298,6 +7964,17 @@ Observação: 28 caracteres são representados no schema como 20 bytes do tipo b + + + Tipo Modal transporte do CTe Simplificado + + + + + + + + Tipo RNTRC - Registro Nacional Transportadores Rodoviários de Carga @@ -6358,4 +8035,4 @@ Observação: 28 caracteres são representados no schema como 20 bytes do tipo b - + \ No newline at end of file diff --git a/CTe.AppTeste/schemas/evCancPrestDesacordo_v4.00.xsd b/CTe.AppTeste/schemas/evCancPrestDesacordo_v4.00.xsd new file mode 100644 index 000000000..a3404d254 --- /dev/null +++ b/CTe.AppTeste/schemas/evCancPrestDesacordo_v4.00.xsd @@ -0,0 +1,32 @@ + + + + + + + Schema XML de validação do evento Cancelamento Prestação do Serviço em Desacordo 610111 + + + + + + Descrição do Evento - “Cancelamento Prestação do Serviço em Desacordo” + + + + + + + + + + + + Protocolo do evento que será cancelado + Informar o número do protocolo de autorização do evento de prestação de serviço em desacordo que será cancelado + + + + + + diff --git a/CTe.AppTeste/schemas/eventoCTeTiposBasico_v4.00.xsd b/CTe.AppTeste/schemas/eventoCTeTiposBasico_v4.00.xsd index 71ce7421d..ae2e98b8b 100644 --- a/CTe.AppTeste/schemas/eventoCTeTiposBasico_v4.00.xsd +++ b/CTe.AppTeste/schemas/eventoCTeTiposBasico_v4.00.xsd @@ -107,7 +107,7 @@ Insira neste local o XML específico do tipo de evento (cancelamento, encerramen - + @@ -156,7 +156,7 @@ Insira neste local o XML específico do tipo de evento (cancelamento, encerramen - + diff --git a/CTe.AppTeste/schemas/procCTeSimp_v4.00.xsd b/CTe.AppTeste/schemas/procCTeSimp_v4.00.xsd new file mode 100644 index 000000000..ae7e19cb5 --- /dev/null +++ b/CTe.AppTeste/schemas/procCTeSimp_v4.00.xsd @@ -0,0 +1,37 @@ + + + + + + + CT-e Simplificado processado + + + + + + + + + + IP do transmissor do documento fiscal para o ambiente autorizador + + + + + Porta de origem utilizada na conexão (De 0 a 65535) + + + + + + + + + + Data e Hora da Conexão de Origem + + + + + diff --git a/CTe.AppTeste/schemas/retCTeSimp_v4.00.xsd b/CTe.AppTeste/schemas/retCTeSimp_v4.00.xsd new file mode 100644 index 000000000..8140961c8 --- /dev/null +++ b/CTe.AppTeste/schemas/retCTeSimp_v4.00.xsd @@ -0,0 +1,10 @@ + + + + + + + Schema XML de validação do retorno do recibo de envio do CT-e Simplificado (Modelo 57) + + + diff --git a/CTe.AppTeste/schemas/tiposGeralCTe_v4.00.xsd b/CTe.AppTeste/schemas/tiposGeralCTe_v4.00.xsd index 20f80af49..f3757bab2 100644 --- a/CTe.AppTeste/schemas/tiposGeralCTe_v4.00.xsd +++ b/CTe.AppTeste/schemas/tiposGeralCTe_v4.00.xsd @@ -121,7 +121,7 @@ - + @@ -130,7 +130,7 @@ - + @@ -142,22 +142,13 @@ - - - Tipo Número do CNPJ tamanho varíavel (3-14) - - - - - - Tipo Número do CNPJ Opcional - + @@ -509,7 +500,7 @@ - + diff --git a/CTe.Classes/CTeOutrosServicos/Informacoes/Impostos/impOs.cs b/CTe.Classes/CTeOutrosServicos/Informacoes/Impostos/impOs.cs index 64d234b4d..378cdb677 100644 --- a/CTe.Classes/CTeOutrosServicos/Informacoes/Impostos/impOs.cs +++ b/CTe.Classes/CTeOutrosServicos/Informacoes/Impostos/impOs.cs @@ -22,5 +22,23 @@ public decimal? vTotTrib public ICMSUFFim ICMSUFFim { get; set; } public infTribFed infTribFed { get; set; } + + public IBSCBS IBSCBS { get; set; } + + private decimal? _vTotDFe; + /// + /// O total geral do DFe deverá ser a soma do total da prestação + IBS + CBS + /// vTotDFe = vPrest / vTPrest + gIBSCBS / vIBS + gCBS / vCBS + /// + /// Exceção: Em 2026 não somar IBS e CBS + /// Observação: Implementação futura + /// + public decimal? vTotDFe + { + get { return _vTotDFe.Arredondar(2); } + set { _vTotDFe = value.Arredondar(2); } + } + + public bool vTotDFeSpecified { get { return vTotDFe.HasValue; } } } } \ No newline at end of file diff --git a/CTe.Classes/Informacoes/Identificacao/gCompraGov.cs b/CTe.Classes/Informacoes/Identificacao/gCompraGov.cs new file mode 100644 index 000000000..1c75654bb --- /dev/null +++ b/CTe.Classes/Informacoes/Identificacao/gCompraGov.cs @@ -0,0 +1,19 @@ +using CTe.Classes.Informacoes.Tipos; +using DFe.Classes; + +namespace CTe.Classes.Informacoes.Identificacao +{ + public class gCompraGov + { + private decimal _pRedutor; + + public TipoEnteGov tpEnteGov { get; set; } + + public decimal pRedutor + { + get => _pRedutor.Arredondar(4); + set => _pRedutor = value.Arredondar(4); + } + + } +} diff --git a/CTe.Classes/Informacoes/Identificacao/ide.cs b/CTe.Classes/Informacoes/Identificacao/ide.cs index 94bee15cf..52528c0cf 100644 --- a/CTe.Classes/Informacoes/Identificacao/ide.cs +++ b/CTe.Classes/Informacoes/Identificacao/ide.cs @@ -248,5 +248,8 @@ public string ProxydhCont } public string xJust { get; set; } + + public gCompraGov gCompraGov { get; set; } + } } diff --git a/CTe.Classes/Informacoes/Impostos/IBSCBS.cs b/CTe.Classes/Informacoes/Impostos/IBSCBS.cs index eac0359bf..662e47fe7 100644 --- a/CTe.Classes/Informacoes/Impostos/IBSCBS.cs +++ b/CTe.Classes/Informacoes/Impostos/IBSCBS.cs @@ -1,4 +1,4 @@ -/********************************************************************************/ +/********************************************************************************/ /* Projeto: Biblioteca ZeusNFe */ /* Biblioteca C# para emissão de Nota Fiscal Eletrônica - NFe e Nota Fiscal de */ /* Consumidor Eletrônica - NFC-e (http://www.nfe.fazenda.gov.br) */ @@ -31,29 +31,44 @@ /* Rua Comendador Francisco josé da Cunha, 111 - Itabaiana - SE - 49500-000 */ /********************************************************************************/ -using CTe.Classes.Informacoes.Impostos.InformacoesIbsCbs; -using CTe.Classes.Informacoes.Impostos.Tipos; +using CTe.Classes.Informacoes.Impostos.IBSCBS; +using CTe.Classes.Informacoes.Tipos; +using System.Xml.Serialization; -namespace CTe.Classes.Informacoes.Impostos +namespace CTe.Classes.Informacoes.Impostos.Tributacao { - /// - /// Grupo do IBS e CBS - /// public class IBSCBS { - /// - /// Código de Situação Tributária do IBS e CBS - /// - public CstIbsCbs CST { get; set; } + private string _cClassTrib; - /// - /// Código de Classificação Tributária do IBS e CBS - /// - public string cClassTrib { get; set; } + [XmlElement(Order = 1)] + public CSTIBSCBS CST { get; set; } + + [XmlElement(Order = 2)] + public string cClassTrib + { + get => _cClassTrib; + set => _cClassTrib = value; + } + + [XmlElement(Order = 3)] + public short? indDoacao { get; set; } + + [XmlElement(Order = 4)] + public gIBSCBS gIBSCBS { get; set; } + + //define se o campo indDoacao deve ser serializado + public bool ShouldSerializeindDoacao() + { + return indDoacao.HasValue; + } /// - /// Grupo de Informações do IBS e da CBS + /// Define o valor de cClassTrib a partir de um inteiro /// - public gIBSCBS gIBSCBS { get; set; } + public void SetcClassTrib(int intValue) + { + _cClassTrib = intValue.ToString("D6"); + } } } diff --git a/CTe.Classes/Informacoes/Impostos/IBSCBS/gCBS.cs b/CTe.Classes/Informacoes/Impostos/IBSCBS/gCBS.cs new file mode 100644 index 000000000..efcad234a --- /dev/null +++ b/CTe.Classes/Informacoes/Impostos/IBSCBS/gCBS.cs @@ -0,0 +1,34 @@ +using DFe.Classes; +using System.Xml.Serialization; + +namespace CTe.Classes.Informacoes.Impostos.IBSCBS +{ + public class gCBS + { + private decimal _pGBS; + private decimal _vGBS; + + [XmlElement(Order = 1)] + public decimal pCBS + { + get => _pGBS.Arredondar(4); + set => _pGBS = value.Arredondar(4); + } + + [XmlElement(Order = 2)] + public gDif gDif { get; set; } + + [XmlElement(Order = 3)] + public gDevTrib gDevTrib { get; set; } + + [XmlElement(Order = 4)] + public gRed gRed { get; set; } + + [XmlElement(Order = 5)] + public decimal vCBS + { + get => _vGBS.Arredondar(2); + set => _vGBS = value.Arredondar(2); + } + } +} diff --git a/CTe.Classes/Informacoes/Impostos/IBSCBS/gDevTrib.cs b/CTe.Classes/Informacoes/Impostos/IBSCBS/gDevTrib.cs new file mode 100644 index 000000000..4a185edc9 --- /dev/null +++ b/CTe.Classes/Informacoes/Impostos/IBSCBS/gDevTrib.cs @@ -0,0 +1,15 @@ +using DFe.Classes; + +namespace CTe.Classes.Informacoes.Impostos.IBSCBS +{ + public class gDevTrib + { + private decimal _vDevTrib { get; set; } + + public decimal vDevTrib + { + get => _vDevTrib.Arredondar(2); + set => _vDevTrib = value.Arredondar(2); + } + } +} diff --git a/CTe.Classes/Informacoes/Impostos/IBSCBS/gDif.cs b/CTe.Classes/Informacoes/Impostos/IBSCBS/gDif.cs new file mode 100644 index 000000000..c83dafdc0 --- /dev/null +++ b/CTe.Classes/Informacoes/Impostos/IBSCBS/gDif.cs @@ -0,0 +1,22 @@ +using DFe.Classes; + +namespace CTe.Classes.Informacoes.Impostos.IBSCBS +{ + public class gDif + { + private decimal _pDif; + private decimal _vDif; + + public decimal pDif + { + get => _pDif.Arredondar(4); + set => _pDif = value.Arredondar(4); + } + + public decimal vDif + { + get => _vDif.Arredondar(2); + set => _vDif = value.Arredondar(2); + } + } +} diff --git a/CTe.Classes/Informacoes/Impostos/IBSCBS/gEstornoCred.cs b/CTe.Classes/Informacoes/Impostos/IBSCBS/gEstornoCred.cs new file mode 100644 index 000000000..bf73ce1a5 --- /dev/null +++ b/CTe.Classes/Informacoes/Impostos/IBSCBS/gEstornoCred.cs @@ -0,0 +1,25 @@ +using DFe.Classes; +using System.Xml.Serialization; + +namespace CTe.Classes.Informacoes.Impostos.IBSCBS +{ + public class gEstornoCred + { + private decimal _vIBSEstCred; + private decimal _vCBSEstCred; + + [XmlElement(Order = 1)] + public decimal vIBSEstCred + { + get => _vIBSEstCred.Arredondar(2); + set => _vIBSEstCred = value.Arredondar(2); + } + + [XmlElement(Order = 2)] + public decimal vCBSEstCred + { + get => _vCBSEstCred.Arredondar(2); + set => _vCBSEstCred = value.Arredondar(2); + } + } +} diff --git a/CTe.Classes/Informacoes/Impostos/IBSCBS/gIBSCBS.cs b/CTe.Classes/Informacoes/Impostos/IBSCBS/gIBSCBS.cs new file mode 100644 index 000000000..9c1bf0136 --- /dev/null +++ b/CTe.Classes/Informacoes/Impostos/IBSCBS/gIBSCBS.cs @@ -0,0 +1,48 @@ +using DFe.Classes; +using System.Xml.Serialization; + +namespace CTe.Classes.Informacoes.Impostos.IBSCBS +{ + public class gIBSCBS + { + private decimal _vBc; + private decimal? _vIbs; + + [XmlElement(Order = 1)] + public decimal vBC + { + get => _vBc.Arredondar(2); + set => _vBc = value.Arredondar(2); + } + + [XmlElement(Order = 2)] + public gIBSUF gIBSUF { get; set; } + + [XmlElement(Order = 3)] + public gIBSMun gIBSMun { get; set; } + + [XmlElement(Order = 4)] + public decimal? vIBS + { + get => _vIbs.Arredondar(2); + set => _vIbs = value.Arredondar(2); + } + + [XmlElement(Order = 5)] + public gCBS gCBS { get; set; } + + [XmlElement(Order = 6)] + public gTribRegular gTribRegular { get; set; } + + [XmlElement(Order = 7)] + public gTribCompraGov gTribCompraGov { get; set; } + + [XmlElement(Order = 8)] + public gEstornoCred gEstornoCred { get; set; } + + public bool vIBSSpecified + { + get { return vIBS.HasValue; } + } + } +} diff --git a/CTe.Classes/Informacoes/Impostos/IBSCBS/gIBSMun.cs b/CTe.Classes/Informacoes/Impostos/IBSCBS/gIBSMun.cs new file mode 100644 index 000000000..afbdb5b3e --- /dev/null +++ b/CTe.Classes/Informacoes/Impostos/IBSCBS/gIBSMun.cs @@ -0,0 +1,34 @@ +using DFe.Classes; +using System.Xml.Serialization; + +namespace CTe.Classes.Informacoes.Impostos.IBSCBS +{ + public class gIBSMun + { + private decimal _pIbsMun; + private decimal _vIbsMun; + + [XmlElement(Order = 1)] + public decimal pIBSMun + { + get => _pIbsMun.Arredondar(4); + set => _pIbsMun = value.Arredondar(4); + } + + [XmlElement(Order = 2)] + public gDif gDif { get; set; } + + [XmlElement(Order = 3)] + public gDevTrib gDevTrib { get; set; } + + [XmlElement(Order = 4)] + public gRed gRed { get; set; } + + [XmlElement(Order = 5)] + public decimal vIBSMun + { + get => _vIbsMun.Arredondar(2); + set => _vIbsMun = value.Arredondar(2); + } + } +} diff --git a/CTe.Classes/Informacoes/Impostos/IBSCBS/gIBSUF.cs b/CTe.Classes/Informacoes/Impostos/IBSCBS/gIBSUF.cs new file mode 100644 index 000000000..e0a5600e2 --- /dev/null +++ b/CTe.Classes/Informacoes/Impostos/IBSCBS/gIBSUF.cs @@ -0,0 +1,35 @@ +using DFe.Classes; +using System.Xml.Serialization; + +namespace CTe.Classes.Informacoes.Impostos.IBSCBS +{ + public class gIBSUF + { + private decimal _pIbsUf; + private decimal _vIbsUf; + + [XmlElement(Order = 1)] + public decimal pIBSUF + { + get => _pIbsUf.Arredondar(4); + set => _pIbsUf = value.Arredondar(4); + } + + [XmlElement(Order = 2)] + public gDif gDif { get; set; } + + [XmlElement(Order = 3)] + public gDevTrib gDevTrib { get; set; } + + [XmlElement(Order = 4)] + public gRed gRed { get; set; } + + [XmlElement(Order = 5)] + public decimal vIBSUF + { + get => _vIbsUf.Arredondar(2); + set => _vIbsUf = value.Arredondar(2); + } + } + +} diff --git a/CTe.Classes/Informacoes/Impostos/IBSCBS/gRed.cs b/CTe.Classes/Informacoes/Impostos/IBSCBS/gRed.cs new file mode 100644 index 000000000..bed8183a1 --- /dev/null +++ b/CTe.Classes/Informacoes/Impostos/IBSCBS/gRed.cs @@ -0,0 +1,22 @@ +using DFe.Classes; + +namespace CTe.Classes.Informacoes.Impostos.IBSCBS +{ + public class gRed + { + private decimal _pRedAliq; + private decimal _pAliqEfet; + + public decimal pRedAliq + { + get => _pRedAliq.Arredondar(4); + set => _pRedAliq = value.Arredondar(4); + } + + public decimal pAliqEfet + { + get => _pAliqEfet.Arredondar(4); + set => _pAliqEfet = value.Arredondar(4); + } + } +} diff --git a/CTe.Classes/Informacoes/Impostos/IBSCBS/gTribCompraGov.cs b/CTe.Classes/Informacoes/Impostos/IBSCBS/gTribCompraGov.cs new file mode 100644 index 000000000..cf8ef7abf --- /dev/null +++ b/CTe.Classes/Informacoes/Impostos/IBSCBS/gTribCompraGov.cs @@ -0,0 +1,57 @@ +using DFe.Classes; +using System.Xml.Serialization; + +namespace CTe.Classes.Informacoes.Impostos.IBSCBS +{ + public class gTribCompraGov + { + private decimal _pAliqIbsUf; + private decimal _vTribIbsUf; + private decimal _pAliqIbsMun; + private decimal _vTribIbsMun; + private decimal _pAliqCbs; + private decimal _vTribCbs; + + [XmlElement(Order = 1)] + public decimal pAliqIBSUF + { + get => _pAliqIbsUf.Arredondar(4); + set => _pAliqIbsUf = value.Arredondar(4); + } + + [XmlElement(Order = 2)] + public decimal vTribIBSUF + { + get => _vTribIbsUf.Arredondar(2); + set => _vTribIbsUf = value.Arredondar(2); + } + + [XmlElement(Order = 3)] + public decimal pAliqIBSMun + { + get => _pAliqIbsMun.Arredondar(4); + set => _pAliqIbsMun = value.Arredondar(4); + } + + [XmlElement(Order = 4)] + public decimal vTribIBSMun + { + get => _vTribIbsMun.Arredondar(2); + set => _vTribIbsMun = value.Arredondar(2); + } + + [XmlElement(Order = 5)] + public decimal pAliqCBS + { + get => _pAliqCbs.Arredondar(4); + set => _pAliqCbs = value.Arredondar(4); + } + + [XmlElement(Order = 6)] + public decimal vTribCBS + { + get => _vTribCbs.Arredondar(2); + set => _vTribCbs = value.Arredondar(2); + } + } +} diff --git a/CTe.Classes/Informacoes/Impostos/IBSCBS/gTribRegular.cs b/CTe.Classes/Informacoes/Impostos/IBSCBS/gTribRegular.cs new file mode 100644 index 000000000..43600dfbd --- /dev/null +++ b/CTe.Classes/Informacoes/Impostos/IBSCBS/gTribRegular.cs @@ -0,0 +1,77 @@ +using CTe.Classes.Informacoes.Tipos; +using DFe.Classes; +using System.Xml.Serialization; + +namespace CTe.Classes.Informacoes.Impostos.IBSCBS +{ + public class gTribRegular + { + private string _cClassTribReg; + private decimal _pAliqEfetRegIbsUf; + private decimal _vTribRegIbsUf; + private decimal _pAliqEfetRegIbsMun; + private decimal _vTribRegIbsMun; + private decimal _pAliqEfetRegCbs; + private decimal _vTribRegCbs; + + [XmlElement(Order = 1)] + public CSTIBSCBS CSTReg { get; set; } + + [XmlElement(Order = 2)] + public string cClassTribReg + { + get => _cClassTribReg; + set => _cClassTribReg = value; + } + + [XmlElement(Order = 3)] + public decimal pAliqEfetRegIBSUF + { + get => _pAliqEfetRegIbsUf.Arredondar(4); + set => _pAliqEfetRegIbsUf = value.Arredondar(4); + } + + [XmlElement(Order = 4)] + public decimal vTribRegIBSUF + { + get => _vTribRegIbsUf.Arredondar(2); + set => _vTribRegIbsUf = value.Arredondar(2); + } + + [XmlElement(Order = 5)] + public decimal pAliqEfetRegIBSMun + { + get => _pAliqEfetRegIbsMun.Arredondar(4); + set => _pAliqEfetRegIbsMun = value.Arredondar(4); + } + + [XmlElement(Order = 6)] + public decimal vTribRegIBSMun + { + get => _vTribRegIbsMun.Arredondar(2); + set => _vTribRegIbsMun = value.Arredondar(2); + } + + [XmlElement(Order = 7)] + public decimal pAliqEfetRegCBS + { + get => _pAliqEfetRegCbs.Arredondar(4); + set => _pAliqEfetRegCbs = value.Arredondar(4); + } + + [XmlElement(Order = 8)] + public decimal vTribRegCBS + { + get => _vTribRegCbs.Arredondar(2); + set => _vTribRegCbs = value.Arredondar(2); + } + + /// + /// Define o valor de cClassTrib a partir de um inteiro + /// + public void SetcClassTrib(int intValue) + { + _cClassTribReg = intValue.ToString("D6"); + } + } +} diff --git a/CTe.Classes/Informacoes/Impostos/imp.cs b/CTe.Classes/Informacoes/Impostos/imp.cs index 2e2b248ae..4527a10c8 100644 --- a/CTe.Classes/Informacoes/Impostos/imp.cs +++ b/CTe.Classes/Informacoes/Impostos/imp.cs @@ -1,36 +1,37 @@ -/********************************************************************************/ +/********************************************************************************/ /* Projeto: Biblioteca ZeusNFe */ -/* Biblioteca C# para emissão de Nota Fiscal Eletrônica - NFe e Nota Fiscal de */ -/* Consumidor Eletrônica - NFC-e (http://www.nfe.fazenda.gov.br) */ +/* Biblioteca C# para emiss�o de Nota Fiscal Eletr�nica - NFe e Nota Fiscal de */ +/* Consumidor Eletr�nica - NFC-e (http://www.nfe.fazenda.gov.br) */ /* */ /* Direitos Autorais Reservados (c) 2014 Adenilton Batista da Silva */ /* Zeusdev Tecnologia LTDA ME */ /* */ -/* Você pode obter a última versão desse arquivo no GitHub */ +/* Voc� pode obter a �ltima vers�o desse arquivo no GitHub */ /* localizado em https://github.com/adeniltonbs/Zeus.Net.NFe.NFCe */ /* */ /* */ -/* Esta biblioteca é software livre; você pode redistribuí-la e/ou modificá-la */ -/* sob os termos da Licença Pública Geral Menor do GNU conforme publicada pela */ -/* Free Software Foundation; tanto a versão 2.1 da Licença, ou (a seu critério) */ -/* qualquer versão posterior. */ +/* Esta biblioteca � software livre; voc� pode redistribu�-la e/ou modific�-la */ +/* sob os termos da Licen�a P�blica Geral Menor do GNU conforme publicada pela */ +/* Free Software Foundation; tanto a vers�o 2.1 da Licen�a, ou (a seu crit�rio) */ +/* qualquer vers�o posterior. */ /* */ -/* Esta biblioteca é distribuída na expectativa de que seja útil, porém, SEM */ -/* NENHUMA GARANTIA; nem mesmo a garantia implícita de COMERCIABILIDADE OU */ -/* ADEQUAÇÃO A UMA FINALIDADE ESPECÍFICA. Consulte a Licença Pública Geral Menor*/ -/* do GNU para mais detalhes. (Arquivo LICENÇA.TXT ou LICENSE.TXT) */ +/* Esta biblioteca � distribu�da na expectativa de que seja �til, por�m, SEM */ +/* NENHUMA GARANTIA; nem mesmo a garantia impl�cita de COMERCIABILIDADE OU */ +/* ADEQUA��O A UMA FINALIDADE ESPEC�FICA. Consulte a Licen�a P�blica Geral Menor*/ +/* do GNU para mais detalhes. (Arquivo LICEN�A.TXT ou LICENSE.TXT) */ /* */ -/* Você deve ter recebido uma cópia da Licença Pública Geral Menor do GNU junto*/ -/* com esta biblioteca; se não, escreva para a Free Software Foundation, Inc., */ -/* no endereço 59 Temple Street, Suite 330, Boston, MA 02111-1307 USA. */ -/* Você também pode obter uma copia da licença em: */ +/* Voc� deve ter recebido uma c�pia da Licen�a P�blica Geral Menor do GNU junto*/ +/* com esta biblioteca; se n�o, escreva para a Free Software Foundation, Inc., */ +/* no endere�o 59 Temple Street, Suite 330, Boston, MA 02111-1307 USA. */ +/* Voc� tamb�m pode obter uma copia da licen�a em: */ /* http://www.opensource.org/licenses/lgpl-license.php */ /* */ /* Zeusdev Tecnologia LTDA ME - adenilton@zeusautomacao.com.br */ /* http://www.zeusautomacao.com.br/ */ -/* Rua Comendador Francisco josé da Cunha, 111 - Itabaiana - SE - 49500-000 */ +/* Rua Comendador Francisco jos� da Cunha, 111 - Itabaiana - SE - 49500-000 */ /********************************************************************************/ - +using CTe.Classes.Informacoes.Impostos.IBSCBS; +using CTe.Classes.Informacoes.Valores; using DFe.Classes; namespace CTe.Classes.Informacoes.Impostos @@ -40,17 +41,13 @@ public class imp public Tributacao.ICMS ICMS { get; set; } private decimal? _vTotTrib; - public decimal? vTotTrib { get { return _vTotTrib.Arredondar(2); } set { _vTotTrib = value.Arredondar(2); } } - public bool vTotTribSpecified - { - get { return vTotTrib.HasValue; } - } + public bool vTotTribSpecified { get { return vTotTrib.HasValue; } } public string infAdFisco { get; set; } @@ -58,12 +55,16 @@ public bool vTotTribSpecified public infTribFed infTribFed { get; set; } - public IBSCBS IBSCBS { get; set; } - private decimal? _vTotDFe; + public Tributacao.IBSCBS IBSCBS { get; set; } + private decimal? _vTotDFe; /// - /// Valor Total do DFe + /// O total geral do DFe dever� ser a soma do total da presta��o + IBS + CBS + /// vTotDFe = vPrest / vTPrest + gIBSCBS / vIBS + gCBS / vCBS + /// + /// Exce��o: Em 2026 n�o somar IBS e CBS + /// Observa��o: Implementa��o futura /// public decimal? vTotDFe { @@ -71,9 +72,6 @@ public decimal? vTotDFe set { _vTotDFe = value.Arredondar(2); } } - public bool vTotDFeSpecified - { - get { return vTotDFe.HasValue; } - } + public bool vTotDFeSpecified { get { return vTotDFe.HasValue; } } } } \ No newline at end of file diff --git a/CTe.Classes/Informacoes/Tipos/CSTIBSCBS.cs b/CTe.Classes/Informacoes/Tipos/CSTIBSCBS.cs new file mode 100644 index 000000000..36b3c62b5 --- /dev/null +++ b/CTe.Classes/Informacoes/Tipos/CSTIBSCBS.cs @@ -0,0 +1,80 @@ +using System.ComponentModel; +using System.Xml.Serialization; + +namespace CTe.Classes.Informacoes.Tipos +{ + public enum CSTIBSCBS + { + [Description("Tributação integral")] + [XmlEnum("000")] + cst000 = 000, + + [Description("Tributação com alíquotas uniformes")] + [XmlEnum("010")] + cst010 = 010, + + [Description("Tributação com alíquotas uniformes reduzidas")] + [XmlEnum("011")] + cst011 = 011, + + [Description("Alíquota reduzida")] + [XmlEnum("200")] + cst200 = 200, + + [Description("Alíquota fixa")] + [XmlEnum("220")] + cst220 = 220, + + [Description("Alíquota fixa rateada")] + [XmlEnum("221")] + cst221 = 221, + + [Description("Redução de Base de Cálculo")] + [XmlEnum("222")] + cst222 = 222, + + [Description("Isenção")] + [XmlEnum("400")] + cst400 = 400, + + [Description("Imunidade e não incidência")] + [XmlEnum("410")] + cst410 = 410, + + [Description("Diferimento")] + [XmlEnum("510")] + cst510 = 510, + + [Description("Diferimento com redução de alíquota")] + [XmlEnum("515")] + cst515 = 515, + + [Description("Suspensão")] + [XmlEnum("550")] + cst550 = 550, + + [Description("Tributação Monofásica")] + [XmlEnum("620")] + cst620 = 620, + + [Description("Transferência de crédito")] + [XmlEnum("800")] + cst800 = 800, + + [Description("Ajuste de IBS na ZFM")] + [XmlEnum("810")] + cst810 = 810, + + [Description("Ajustes")] + [XmlEnum("811")] + cst811 = 811, + + [Description("Tributação em declaração de regime específico")] + [XmlEnum("820")] + cst820 = 820, + + [Description("Exclusão da Base de Cálculo")] + [XmlEnum("830")] + cst830 = 830, + } +} diff --git a/CTe.Classes/Informacoes/Tipos/TipoEnteGov.cs b/CTe.Classes/Informacoes/Tipos/TipoEnteGov.cs new file mode 100644 index 000000000..e82732fee --- /dev/null +++ b/CTe.Classes/Informacoes/Tipos/TipoEnteGov.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Serialization; + +namespace CTe.Classes.Informacoes.Tipos +{ + public enum TipoEnteGov + { + [Description("União")] + [XmlEnum("1")] + Uniao = 1, + + [Description("Estado")] + [XmlEnum("2")] + Estado = 2, + + [Description("Distrito Federal")] + [XmlEnum("3")] + DistritoFederal = 3, + + [Description("Município")] + [XmlEnum("4")] + Municipio = 4 + } +} diff --git a/CTe.Classes/Informacoes/Tipos/tpEmis.cs b/CTe.Classes/Informacoes/Tipos/tpEmis.cs index 154f06900..32554c433 100644 --- a/CTe.Classes/Informacoes/Tipos/tpEmis.cs +++ b/CTe.Classes/Informacoes/Tipos/tpEmis.cs @@ -36,6 +36,7 @@ namespace CTe.Classes.Informacoes.Tipos /// /// Forma de emissão da CT-e /// 1 - Emissão normal (não em contingência) + /// 3 - Regime Especial NFF /// 4 - Contingência EPEC pela SVC /// 5 - Contingência FS-DA, com impressão do DANFE em formulário de segurança /// 7 - Contingência SVC-RS (SEFAZ Virtual de Contingência do RS) @@ -45,6 +46,8 @@ public enum tpEmis { [XmlEnum("1")] teNormal = 1, + [XmlEnum("3")] + teNFF = 3, [XmlEnum("4")] teEPEC = 4, [XmlEnum("5")] @@ -54,4 +57,4 @@ public enum tpEmis [XmlEnum("8")] teSVCSP = 8 } -} \ No newline at end of file +} diff --git a/CTe.Classes/Informacoes/autXML.cs b/CTe.Classes/Informacoes/autXML.cs index e49bd4c29..ed8e8b204 100644 --- a/CTe.Classes/Informacoes/autXML.cs +++ b/CTe.Classes/Informacoes/autXML.cs @@ -49,13 +49,12 @@ public string CNPJ get { return cnpj; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(cpf)) - cnpj = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(cpf)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + cnpj = value; } } @@ -67,13 +66,12 @@ public string CPF get { return cpf; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(cnpj)) - cpf = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(cnpj)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + cpf = value; } } } diff --git a/CTe.Classes/Servicos/DistribuicaoDFe/Schemas/procEventoCTe.cs b/CTe.Classes/Servicos/DistribuicaoDFe/Schemas/procEventoCTe.cs index 72e81ee2a..571ea6796 100644 --- a/CTe.Classes/Servicos/DistribuicaoDFe/Schemas/procEventoCTe.cs +++ b/CTe.Classes/Servicos/DistribuicaoDFe/Schemas/procEventoCTe.cs @@ -64,7 +64,5 @@ public class procEventoCTe /// [XmlElement(Namespace = "http://www.portalfiscal.inf.br/cte")] public retEventoCTe retEventoCTe { get; set; } - - } } diff --git a/CTe.Classes/Servicos/DistribuicaoDFe/Schemas/resCTe.cs b/CTe.Classes/Servicos/DistribuicaoDFe/Schemas/resCTe.cs new file mode 100644 index 000000000..638022f1a --- /dev/null +++ b/CTe.Classes/Servicos/DistribuicaoDFe/Schemas/resCTe.cs @@ -0,0 +1,123 @@ +using DFe.Utils; +using System; +using System.ComponentModel; +using System.Xml.Serialization; + +namespace CTe.Classes.Servicos.DistribuicaoDFe.Schemas +{ + /// + /// Resumo de CT-e retornado no docZip com schema resCTe_v1.03.xsd + /// Ref: NT 2015/002 - CTeDistribuicaoDFe + /// + [Serializable()] + [DesignerCategory("code")] + [XmlType(AnonymousType = true, Namespace = "http://www.portalfiscal.inf.br/cte")] + [XmlRoot(Namespace = "http://www.portalfiscal.inf.br/cte", IsNullable = false)] + public class resCTe + { + /// + /// Chave de acesso do CT-e (44 dígitos) + /// + [XmlElement("chCTe")] + public string chCTe { get; set; } + + /// + /// CNPJ do emitente (14 dígitos) + /// + [XmlElement("CNPJ")] + public string CNPJ { get; set; } + + /// + /// Razão social ou nome do emitente + /// + [XmlElement("xNome")] + public string xNome { get; set; } + + /// + /// Inscrição Estadual do emitente + /// + [XmlElement("IE")] + public string IE { get; set; } + + /// + /// Modal do CT-e + /// + /// 01=Rodoviário + /// 02=Aéreo + /// 03=Aquaviário + /// 04=Ferroviário + /// 05=Dutoviário + /// 06=Multimodal + /// + /// + [XmlElement("modal")] + public string modal { get; set; } + + /// + /// Data e hora de emissão do CT-e + /// + [XmlIgnore] + public DateTimeOffset dhEmi { get; set; } + + [XmlElement(ElementName = "dhEmi")] + public string ProxydhEmi + { + get { return dhEmi.ParaDataHoraStringUtc(); } + set { dhEmi = DateTimeOffset.Parse(value); } + } + + /// + /// Tipo do CT-e + /// + /// 0=CT-e Normal + /// 1=CT-e de Complemento de Valores + /// 2=CT-e de Anulação + /// 3=CT-e de Substituição + /// + /// + [XmlElement("tpCTe")] + public string tpCTe { get; set; } + + /// + /// Digest value da assinatura do CT-e + /// + [XmlElement("digVal")] + public string digVal { get; set; } + + /// + /// Data e hora do recebimento pelo Ambiente Nacional + /// + [XmlIgnore] + public DateTimeOffset dhRecbto { get; set; } + + [XmlElement(ElementName = "dhRecbto")] + public string ProxydhRecbto + { + get { return dhRecbto.ParaDataHoraStringUtc(); } + set { dhRecbto = DateTimeOffset.Parse(value); } + } + + /// + /// Número do protocolo de autorização + /// + [XmlElement("nProt")] + public string nProt { get; set; } + + /// + /// Valor a receber pelo transportador + /// + [XmlElement("vRec")] + public string vRec { get; set; } + + /// + /// Situação do CT-e + /// + /// 100=Autorizado o uso do CT-e + /// 101=Cancelamento de CT-e homologado + /// 110=Uso denegado + /// + /// + [XmlElement("cSitCTe")] + public string cSitCTe { get; set; } + } +} diff --git a/CTe.Classes/Servicos/DistribuicaoDFe/distDFeInt.cs b/CTe.Classes/Servicos/DistribuicaoDFe/distDFeInt.cs index b61e0d2cd..f40503365 100644 --- a/CTe.Classes/Servicos/DistribuicaoDFe/distDFeInt.cs +++ b/CTe.Classes/Servicos/DistribuicaoDFe/distDFeInt.cs @@ -71,13 +71,12 @@ public string CNPJ get { return _cNPJ; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(_cPF)) - _cNPJ = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(_cPF)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + _cNPJ = value; } } @@ -89,13 +88,12 @@ public string CPF get { return _cPF; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(_cNPJ)) - _cPF = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(_cNPJ)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + _cPF = value; } } @@ -107,8 +105,6 @@ public string CPF /// /// A09 - Grupo para consultar um DF-e a partir de um NSU específico /// - public consNSU consNSU { get; set; } - - + public consNSU consNSU { get; set; } } } diff --git a/CTe.Classes/Servicos/DistribuicaoDFe/loteDistDFeInt.cs b/CTe.Classes/Servicos/DistribuicaoDFe/loteDistDFeInt.cs index 5a12f9988..3e0dbf8ab 100644 --- a/CTe.Classes/Servicos/DistribuicaoDFe/loteDistDFeInt.cs +++ b/CTe.Classes/Servicos/DistribuicaoDFe/loteDistDFeInt.cs @@ -31,6 +31,7 @@ /* Rua Comendador Francisco josé da Cunha, 111 - Itabaiana - SE - 49500-000 */ /********************************************************************************/ +using CTe.Classes.Servicos.DistribuicaoDFe.Schemas; using System; using System.ComponentModel; using System.Xml.Serialization; @@ -69,5 +70,21 @@ public class loteDistDFeInt /// [XmlText(DataType = "base64Binary")] public byte[] XmlNfe { get; set; } + + #region Objetos possíveis para descompactar o conteúdo do campo XmlNfe, dependendo do valor do campo schema + [XmlIgnore] + public cteProc cteProc { get; set; } + + [XmlIgnore] + public resCTe resCTe { get; set; } + + [XmlIgnore] + public CTeOSDocumento.CTe.CTeOS.Retorno.cteOSProc cteOSProc { get; set; } + + [XmlIgnore] + public Classes.Servicos.DistribuicaoDFe.Schemas.procEventoCTe procEventoCTe { get; set; } + + //TO DO: Adicionar no futuro o procGTVe adicionando na versão 1.04 do schema de distribuição de DFe + #endregion } } diff --git a/CTe.Classes/Servicos/Evento/dest.cs b/CTe.Classes/Servicos/Evento/dest.cs index 9ac0e13ed..204a57316 100644 --- a/CTe.Classes/Servicos/Evento/dest.cs +++ b/CTe.Classes/Servicos/Evento/dest.cs @@ -60,13 +60,12 @@ public string CNPJ get { return _cnpj; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(CPF) & string.IsNullOrEmpty(idEstrangeiro)) - _cnpj = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(CPF) || !string.IsNullOrEmpty(idEstrangeiro)) throw new ArgumentException(ErroCpfCnpjIdEstrangeiroPreenchidos); - } + + _cnpj = value; } } @@ -78,13 +77,12 @@ public string CPF get { return _cpf; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(CNPJ) & string.IsNullOrEmpty(idEstrangeiro)) - _cpf = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(CNPJ) || !string.IsNullOrEmpty(idEstrangeiro)) throw new ArgumentException(ErroCpfCnpjIdEstrangeiroPreenchidos); - } + + _cpf = value; } } @@ -96,13 +94,12 @@ public string idEstrangeiro get { return _idEstrangeiro; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(CNPJ) & string.IsNullOrEmpty(CPF)) - _idEstrangeiro = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(CNPJ) || !string.IsNullOrEmpty(CPF)) throw new ArgumentException(ErroCpfCnpjIdEstrangeiroPreenchidos); - } + + _idEstrangeiro = value; } } diff --git a/CTe.Classes/Servicos/Evento/detEvento.cs b/CTe.Classes/Servicos/Evento/detEvento.cs index 17c3d2563..e840e81d3 100644 --- a/CTe.Classes/Servicos/Evento/detEvento.cs +++ b/CTe.Classes/Servicos/Evento/detEvento.cs @@ -44,6 +44,7 @@ public class detEvento [XmlElement("evCancCTe", typeof(evCancCTe), Namespace = "http://www.portalfiscal.inf.br/cte")] [XmlElement("evCCeCTe", typeof(evCCeCTe), Namespace = "http://www.portalfiscal.inf.br/cte")] [XmlElement("evPrestDesacordo", typeof(evPrestDesacordo), Namespace = "http://www.portalfiscal.inf.br/cte")] + [XmlElement("evCancPrestDesacordo", typeof(evCancPrestDesacordo), Namespace = "http://www.portalfiscal.inf.br/cte")] public EventoContainer EventoContainer { get; set; } } } \ No newline at end of file diff --git a/CTe.Classes/Servicos/Evento/evCancPrestDesacordo.cs b/CTe.Classes/Servicos/Evento/evCancPrestDesacordo.cs new file mode 100644 index 000000000..f50233dc4 --- /dev/null +++ b/CTe.Classes/Servicos/Evento/evCancPrestDesacordo.cs @@ -0,0 +1,18 @@ +using System.Xml.Serialization; + +namespace CTe.Classes.Servicos.Evento +{ + [XmlRoot(Namespace = "http://www.portalfiscal.inf.br/cte")] + public class evCancPrestDesacordo : EventoContainer + { + public evCancPrestDesacordo() + { + this.descEvento = "Cancelamento Prestação do Serviço em Desacordo"; + } + + public string descEvento { get; set; } + + public string nProtEvPrestDes { get; set; } + + } +} diff --git a/CTe.Dacte.OpenFast/CTe.Dacte.OpenFast.csproj b/CTe.Dacte.OpenFast/CTe.Dacte.OpenFast.csproj index a8094a73c..a0bb23341 100644 --- a/CTe.Dacte.OpenFast/CTe.Dacte.OpenFast.csproj +++ b/CTe.Dacte.OpenFast/CTe.Dacte.OpenFast.csproj @@ -5,11 +5,16 @@ - + + + + + + diff --git a/CTe.Servicos/ConsultaStatus/StatusServico.cs b/CTe.Servicos/ConsultaStatus/StatusServico.cs index 296f79b6b..d1c8063d2 100644 --- a/CTe.Servicos/ConsultaStatus/StatusServico.cs +++ b/CTe.Servicos/ConsultaStatus/StatusServico.cs @@ -61,6 +61,9 @@ public retConsStatServCte ConsultaStatus(ConfiguracaoServico configuracaoServico public retConsStatServCTe ConsultaStatusV4(ConfiguracaoServico configuracaoServico = null) { + if (configuracaoServico == null) + configuracaoServico = ConfiguracaoServico.Instancia; + var consStatServCte = ClassesFactory.CriaConsStatServCTe(configuracaoServico); if (configuracaoServico.IsValidaSchemas) diff --git a/CTe.Servicos/DistribuicaoDFe/ServicoCTeDistribuicaoDFe.cs b/CTe.Servicos/DistribuicaoDFe/ServicoCTeDistribuicaoDFe.cs index e068c9f3e..d4b7db967 100644 --- a/CTe.Servicos/DistribuicaoDFe/ServicoCTeDistribuicaoDFe.cs +++ b/CTe.Servicos/DistribuicaoDFe/ServicoCTeDistribuicaoDFe.cs @@ -98,27 +98,33 @@ public RetornoCteDistDFeInt CTeDistDFeInteresse(string ufAutor, string documento { for (int i = 0; i < retConsulta.loteDistDFeInt.Length; i++) { - string conteudo = Compressao.Unzip(retConsulta.loteDistDFeInt[i].XmlNfe).RemoverDeclaracaoXml(); + var loteAtual = retConsulta.loteDistDFeInt[i]; + string conteudo = Compressao.Unzip(loteAtual.XmlNfe).RemoverDeclaracaoXml(); string chCTe = string.Empty; if (conteudo.StartsWith("(conteudo); - chCTe = retConteudo.protCTe.infProt.chCTe; + var cteConteudo = FuncoesXml.XmlStringParaClasse(conteudo); + chCTe = cteConteudo.protCTe.infProt.chCTe; + loteAtual.cteProc = cteConteudo; } else if (conteudo.StartsWith("(conteudo); chCTe = procEventoNFeConteudo.eventoCTe.infEvento.chCTe; + loteAtual.procEventoCTe = procEventoNFeConteudo; } else if (conteudo.StartsWith("(conteudo); - chCTe = retConteudo.protCTe.infProt.chCTe; + var cteOSConteudo = FuncoesXml.XmlStringParaClasse(conteudo); + chCTe = cteOSConteudo.protCTe.infProt.chCTe; + loteAtual.cteOSProc = cteOSConteudo; } - else + else if (conteudo.StartsWith("(conteudo); + chCTe = resCTeConteudo.chCTe; + loteAtual.resCTe = resCTeConteudo; } string[] schema = retConsulta.loteDistDFeInt[i].schema.Split('_'); diff --git a/CTe.Servicos/Enderecos/Helpers/UrlHelper.cs b/CTe.Servicos/Enderecos/Helpers/UrlHelper.cs index 827cd2a1e..6c007186b 100644 --- a/CTe.Servicos/Enderecos/Helpers/UrlHelper.cs +++ b/CTe.Servicos/Enderecos/Helpers/UrlHelper.cs @@ -42,36 +42,51 @@ namespace CTe.Servicos.Enderecos.Helpers { public class UrlHelper { - public static UrlCTe ObterUrlServico(ConfiguracaoServico configuracaoServico = null) + /// + /// Obtem a url de Serviço. Por padrão pega as informações de ConfiguracaoServico, mas pode ser customizada individualmente. Motivo: em alguns casos a url de destino de um evento de CTe pode seguir as informações do xml e não da empresa emissora / com certificado ativo + /// + /// + /// + /// + /// + /// + /// + /// + public static UrlCTe ObterUrlServico(ConfiguracaoServico configuracaoServico = null, tpEmis? tipoEmissao = null , TipoAmbiente? tipoAmbiente = null, Estado? ufRecepcao = null, versao? versaoLayout = null) { var configServico = configuracaoServico ?? ConfiguracaoServico.Instancia; - switch (configServico.tpAmb) + var tipoEmissaoUtilizado = tipoEmissao ?? configServico.TipoEmissao; + var tipoAmbienteUtilizado = tipoAmbiente ?? configServico.tpAmb; + var ufUtilizada = ufRecepcao ?? configServico.cUF; + var versaoUtilizada = versaoLayout ?? configServico.VersaoLayout; + + switch (tipoAmbienteUtilizado) { case TipoAmbiente.Homologacao: - if (configServico.TipoEmissao == tpEmis.teSVCRS) + if (tipoEmissaoUtilizado == tpEmis.teSVCRS) { - return UrlHomologacaoSvrs(configServico); + return UrlHomologacaoSvrs(versaoUtilizada); } - if (configServico.TipoEmissao == tpEmis.teSVCSP) + if (tipoEmissaoUtilizado == tpEmis.teSVCSP) { - return UrlHomologacaoSvcsp(configServico); + return UrlHomologacaoSvcsp(versaoUtilizada); } - return UrlHomologacao(configServico); + return UrlHomologacao(ufUtilizada, versaoUtilizada); case TipoAmbiente.Producao: - if (configServico.TipoEmissao == tpEmis.teSVCRS) + if (tipoEmissaoUtilizado == tpEmis.teSVCRS) { - return UrlProducaoSvrs(configServico); + return UrlProducaoSvrs(versaoUtilizada); } - if (configServico.TipoEmissao == tpEmis.teSVCSP) + if (tipoEmissaoUtilizado == tpEmis.teSVCSP) { - return UrlProducaoSvcsp(configServico); + return UrlProducaoSvcsp(versaoUtilizada); } - return UrlProducao(configServico); + return UrlProducao(ufUtilizada, versaoUtilizada); } throw new InvalidOperationException("Tipo Ambiente inválido"); @@ -84,17 +99,17 @@ public static string ObterUrlQrCode(ConfiguracaoServico configuracaoServico = nu switch (configServico.tpAmb) { case TipoAmbiente.Homologacao: - return UrlHomologacao(configServico).QrCode; + return UrlHomologacao(configServico.cUF, configServico.VersaoLayout).QrCode; case TipoAmbiente.Producao: - return UrlProducao(configServico).QrCode; + return UrlProducao(configServico.cUF, configServico.VersaoLayout).QrCode; } throw new InvalidOperationException("Tipo Ambiente inválido"); } - private static UrlCTe UrlProducaoSvcsp(ConfiguracaoServico configuracaoServico) + private static UrlCTe UrlProducaoSvcsp(versao VersaoLayout) { - if (configuracaoServico.VersaoLayout == versao.ve400) + if (VersaoLayout == versao.ve400) { return new UrlCTe { @@ -119,9 +134,9 @@ private static UrlCTe UrlProducaoSvcsp(ConfiguracaoServico configuracaoServico) }; } - private static UrlCTe UrlHomologacaoSvcsp(ConfiguracaoServico configuracaoServico) + private static UrlCTe UrlHomologacaoSvcsp(versao VersaoLayout) { - if (configuracaoServico.VersaoLayout == versao.ve400) + if (VersaoLayout == versao.ve400) { return new UrlCTe { @@ -146,9 +161,9 @@ private static UrlCTe UrlHomologacaoSvcsp(ConfiguracaoServico configuracaoServic }; } - private static UrlCTe UrlHomologacaoSvrs(ConfiguracaoServico configuracaoServico) + private static UrlCTe UrlHomologacaoSvrs(versao VersaoLayout) { - if (configuracaoServico.VersaoLayout == versao.ve400) + if (VersaoLayout == versao.ve400) { return new UrlCTe { @@ -174,9 +189,9 @@ private static UrlCTe UrlHomologacaoSvrs(ConfiguracaoServico configuracaoServico }; } - private static UrlCTe UrlProducaoSvrs(ConfiguracaoServico configuracaoServico) + private static UrlCTe UrlProducaoSvrs(versao VersaoLayout) { - if (configuracaoServico.VersaoLayout == versao.ve400) + if (VersaoLayout == versao.ve400) { return new UrlCTe { @@ -202,12 +217,12 @@ private static UrlCTe UrlProducaoSvrs(ConfiguracaoServico configuracaoServico) }; } - private static UrlCTe UrlProducao(ConfiguracaoServico configuracaoServico) + private static UrlCTe UrlProducao(Estado UFRecepcao, versao VersaoLayout) { - switch (configuracaoServico.cUF) + switch (UFRecepcao) { case Estado.MT: - if (configuracaoServico.VersaoLayout == versao.ve400) + if (VersaoLayout == versao.ve400) { return new UrlCTe { @@ -233,7 +248,7 @@ private static UrlCTe UrlProducao(ConfiguracaoServico configuracaoServico) CTeDistribuicaoDFe = "https://www1.cte.fazenda.gov.br/CTeDistribuicaoDFe/CTeDistribuicaoDFe.asmx" }; case Estado.MS: - if (configuracaoServico.VersaoLayout == versao.ve400) + if (VersaoLayout == versao.ve400) { return new UrlCTe { @@ -259,7 +274,7 @@ private static UrlCTe UrlProducao(ConfiguracaoServico configuracaoServico) CTeDistribuicaoDFe = "https://www1.cte.fazenda.gov.br/CTeDistribuicaoDFe/CTeDistribuicaoDFe.asmx" }; case Estado.MG: - if (configuracaoServico.VersaoLayout == versao.ve400) + if (VersaoLayout == versao.ve400) { return new UrlCTe { @@ -285,7 +300,7 @@ private static UrlCTe UrlProducao(ConfiguracaoServico configuracaoServico) CTeDistribuicaoDFe = "https://www1.cte.fazenda.gov.br/CTeDistribuicaoDFe/CTeDistribuicaoDFe.asmx" }; case Estado.PR: - if (configuracaoServico.VersaoLayout == versao.ve400) + if (VersaoLayout == versao.ve400) { return new UrlCTe { @@ -311,7 +326,7 @@ private static UrlCTe UrlProducao(ConfiguracaoServico configuracaoServico) CTeDistribuicaoDFe = "https://www1.cte.fazenda.gov.br/CTeDistribuicaoDFe/CTeDistribuicaoDFe.asmx" }; case Estado.SP: - if (configuracaoServico.VersaoLayout == versao.ve400) + if (VersaoLayout == versao.ve400) { return new UrlCTe { @@ -359,7 +374,7 @@ private static UrlCTe UrlProducao(ConfiguracaoServico configuracaoServico) case Estado.SE: case Estado.TO: case Estado.RS: - if (configuracaoServico.VersaoLayout == versao.ve400) + if (VersaoLayout == versao.ve400) { return new UrlCTe { @@ -390,7 +405,7 @@ private static UrlCTe UrlProducao(ConfiguracaoServico configuracaoServico) case Estado.AP: case Estado.PE: case Estado.RR: - if (configuracaoServico.VersaoLayout == versao.ve400) + if (VersaoLayout == versao.ve400) { return new UrlCTe { @@ -422,12 +437,12 @@ private static UrlCTe UrlProducao(ConfiguracaoServico configuracaoServico) } - private static UrlCTe UrlHomologacao(ConfiguracaoServico configuracaoServico) + private static UrlCTe UrlHomologacao(Estado UFRecepcao, versao VersaoLayout) { - switch (configuracaoServico.cUF) + switch (UFRecepcao) { case Estado.MT: - if (configuracaoServico.VersaoLayout == versao.ve400) + if (VersaoLayout == versao.ve400) { return new UrlCTe { @@ -454,7 +469,7 @@ private static UrlCTe UrlHomologacao(ConfiguracaoServico configuracaoServico) CTeDistribuicaoDFe = @"https://hom1.cte.fazenda.gov.br/CTeDistribuicaoDFe/CTeDistribuicaoDFe.asmx" }; case Estado.MS: - if (configuracaoServico.VersaoLayout == versao.ve400) + if (VersaoLayout == versao.ve400) { return new UrlCTe { @@ -478,7 +493,7 @@ private static UrlCTe UrlHomologacao(ConfiguracaoServico configuracaoServico) CTeDistribuicaoDFe = @"https://hom1.cte.fazenda.gov.br/CTeDistribuicaoDFe/CTeDistribuicaoDFe.asmx" }; case Estado.MG: - if (configuracaoServico.VersaoLayout == versao.ve400) + if (VersaoLayout == versao.ve400) { return new UrlCTe { @@ -504,7 +519,7 @@ private static UrlCTe UrlHomologacao(ConfiguracaoServico configuracaoServico) CTeDistribuicaoDFe = @"https://hom1.cte.fazenda.gov.br/CTeDistribuicaoDFe/CTeDistribuicaoDFe.asmx" }; case Estado.PR: - if (configuracaoServico.VersaoLayout == versao.ve400) + if (VersaoLayout == versao.ve400) { return new UrlCTe { @@ -545,7 +560,7 @@ private static UrlCTe UrlHomologacao(ConfiguracaoServico configuracaoServico) CTeDistribuicaoDFe = @"https://hom1.cte.fazenda.gov.br/CTeDistribuicaoDFe/CTeDistribuicaoDFe.asmx" }; case Estado.SP: - if (configuracaoServico.VersaoLayout == versao.ve400) + if (VersaoLayout == versao.ve400) { return new UrlCTe { @@ -588,7 +603,7 @@ private static UrlCTe UrlHomologacao(ConfiguracaoServico configuracaoServico) case Estado.SC: case Estado.SE: case Estado.TO: - if (configuracaoServico.VersaoLayout == versao.ve400) + if (VersaoLayout == versao.ve400) { return new UrlCTe { @@ -619,7 +634,7 @@ private static UrlCTe UrlHomologacao(ConfiguracaoServico configuracaoServico) case Estado.AP: case Estado.PE: case Estado.RR: - if (configuracaoServico.VersaoLayout == versao.ve400) + if (VersaoLayout == versao.ve400) { return new UrlCTe { diff --git a/CTe.Servicos/Eventos/EventoCancelamentoDesacordo.cs b/CTe.Servicos/Eventos/EventoCancelamentoDesacordo.cs new file mode 100644 index 000000000..f4040a0d2 --- /dev/null +++ b/CTe.Servicos/Eventos/EventoCancelamentoDesacordo.cs @@ -0,0 +1,49 @@ +using CTe.Classes; +using CTe.Classes.Servicos.Evento; +using CTe.Classes.Servicos.Evento.Flags; +using CTe.Servicos.Factory; +using System.Threading.Tasks; + +namespace CTe.Servicos.Eventos +{ + public class EventoCancelamentoDesacordo + { + private readonly int _sequenciaEvento; + private readonly string _cnpj; + private readonly string _chave; + private readonly string _nProtEvPrestDes; + + public eventoCTe EventoEnviado { get; private set; } + public retEventoCTe RetornoSefaz { get; private set; } + + public EventoCancelamentoDesacordo(int sequenciaEvento, string chave, string cnpj, string nProtEvPrestDes) + { + _chave = chave; + _cnpj = cnpj; + _sequenciaEvento = sequenciaEvento; + _nProtEvPrestDes = nProtEvPrestDes; + } + + public retEventoCTe CancelarDesacordo(ConfiguracaoServico configuracaoServico = null, DFe.Classes.Entidades.Estado? orgaoEmissor = null) + { + var configServico = configuracaoServico ?? ConfiguracaoServico.Instancia; + var eventoCancelaDiscordar = ClassesFactory.CriaEvCancPrestDesacordo(_nProtEvPrestDes); + + EventoEnviado = FactoryEvento.CriaEvento(CTeTipoEvento.CancelamentoPrestacaodoServicoemDesacordo, _sequenciaEvento, _chave, _cnpj, eventoCancelaDiscordar, configServico, orgaoEmissor); + RetornoSefaz = new ServicoController().Executar(CTeTipoEvento.CancelamentoPrestacaodoServicoemDesacordo, _sequenciaEvento, _chave, _cnpj, eventoCancelaDiscordar, configServico, orgaoEmissor); + + return RetornoSefaz; + } + + public async Task CancelarDesacordoAsync(ConfiguracaoServico configuracaoServico = null, DFe.Classes.Entidades.Estado? orgaoEmissor = null) + { + var configServico = configuracaoServico ?? ConfiguracaoServico.Instancia; + var eventoCancelaDiscordar = ClassesFactory.CriaEvCancPrestDesacordo(_nProtEvPrestDes); + + EventoEnviado = FactoryEvento.CriaEvento(CTeTipoEvento.CancelamentoPrestacaodoServicoemDesacordo, _sequenciaEvento, _chave, _cnpj, eventoCancelaDiscordar, configServico, orgaoEmissor); + RetornoSefaz = await new ServicoController().ExecutarAsync(CTeTipoEvento.CancelamentoPrestacaodoServicoemDesacordo, _sequenciaEvento, _chave, _cnpj, eventoCancelaDiscordar, configServico, orgaoEmissor); + + return RetornoSefaz; + } + } +} diff --git a/CTe.Servicos/Eventos/EventoDesacordo.cs b/CTe.Servicos/Eventos/EventoDesacordo.cs index d2cef837a..a90db0d8d 100644 --- a/CTe.Servicos/Eventos/EventoDesacordo.cs +++ b/CTe.Servicos/Eventos/EventoDesacordo.cs @@ -59,23 +59,35 @@ public EventoDesacordo(int sequenciaEvento, string chave, string cnpj, string in _observacao = observacao; } - public retEventoCTe Discordar(ConfiguracaoServico configuracaoServico = null) + /// + /// Gera o evento de desacordo de CTe + /// + /// + /// Sempre considera a UF que gerou o xml. Então a empresa pode estar configurada para uma UF X e gerar o desacordo de um xml gerado na UF Y, sendo o evento, portanto, enviado para UF Y + /// + public retEventoCTe Discordar(ConfiguracaoServico configuracaoServico = null, DFe.Classes.Entidades.Estado? orgaoEmissor = null) { + var configServico = configuracaoServico ?? ConfiguracaoServico.Instancia; var eventoDiscordar = ClassesFactory.CriaEvPrestDesacordo(_indicadorDesacordo, _observacao); - EventoEnviado = FactoryEvento.CriaEvento(CTeTipoEvento.Desacordo, _sequenciaEvento, _chave, _cnpj, eventoDiscordar, configuracaoServico); - RetornoSefaz = new ServicoController().Executar(CTeTipoEvento.Desacordo, _sequenciaEvento, _chave, _cnpj, eventoDiscordar, configuracaoServico); - + EventoEnviado = FactoryEvento.CriaEvento(CTeTipoEvento.Desacordo, _sequenciaEvento, _chave, _cnpj, eventoDiscordar, configServico, orgaoEmissor); + RetornoSefaz = new ServicoController().Executar(CTeTipoEvento.Desacordo, _sequenciaEvento, _chave, _cnpj, eventoDiscordar, configServico, orgaoEmissor); return RetornoSefaz; } - public async Task DiscordarAsync(ConfiguracaoServico configuracaoServico = null) + /// + /// Gera o evento de desacordo de CTe de forma assíncrona + /// + /// + /// Sempre considera a UF que gerou o xml. Então a empresa pode estar configurada para uma UF X e gerar o desacordo de um xml gerado na UF Y, sendo o evento, portanto, enviado para UF Y + /// + public async Task DiscordarAsync(ConfiguracaoServico configuracaoServico = null, DFe.Classes.Entidades.Estado? orgaoEmissor = null) { + var configServico = configuracaoServico ?? ConfiguracaoServico.Instancia; var eventoDiscordar = ClassesFactory.CriaEvPrestDesacordo(_indicadorDesacordo, _observacao); - EventoEnviado = FactoryEvento.CriaEvento(CTeTipoEvento.Desacordo, _sequenciaEvento, _chave, _cnpj, eventoDiscordar, configuracaoServico); - RetornoSefaz = await new ServicoController().ExecutarAsync(CTeTipoEvento.Desacordo, _sequenciaEvento, _chave, _cnpj, eventoDiscordar, configuracaoServico); - + EventoEnviado = FactoryEvento.CriaEvento(CTeTipoEvento.Desacordo, _sequenciaEvento, _chave, _cnpj, eventoDiscordar, configServico, orgaoEmissor); + RetornoSefaz = await new ServicoController().ExecutarAsync(CTeTipoEvento.Desacordo, _sequenciaEvento, _chave, _cnpj, eventoDiscordar, configServico, orgaoEmissor); return RetornoSefaz; } } diff --git a/CTe.Servicos/Eventos/FactoryEvento.cs b/CTe.Servicos/Eventos/FactoryEvento.cs index f862794e2..465732105 100644 --- a/CTe.Servicos/Eventos/FactoryEvento.cs +++ b/CTe.Servicos/Eventos/FactoryEvento.cs @@ -51,7 +51,7 @@ public static eventoCTe CriaEvento(CTeEletronico cte, CTeTipoEvento cTeTipoEvent return CriaEvento(cTeTipoEvento, sequenciaEvento, cte.Chave(), cte.infCte.emit.CNPJ, container, configServico); } - public static eventoCTe CriaEvento(CTeTipoEvento cTeTipoEvento, int sequenciaEvento, string chave, string cnpj, EventoContainer container, ConfiguracaoServico configuracaoServico = null) + public static eventoCTe CriaEvento(CTeTipoEvento cTeTipoEvento, int sequenciaEvento, string chave, string cnpj, EventoContainer container, ConfiguracaoServico configuracaoServico = null, DFe.Classes.Entidades.Estado? cOrgao = null) { var configServico = configuracaoServico ?? ConfiguracaoServico.Instancia; @@ -72,7 +72,7 @@ public static eventoCTe CriaEvento(CTeTipoEvento cTeTipoEvento, int sequenciaEve { tpAmb = configServico.tpAmb, CNPJ = cnpj, - cOrgao = configServico.cUF, + cOrgao = cOrgao ?? configServico.cUF, chCTe = chave, dhEvento = DateTimeOffset.Now, nSeqEvento = sequenciaEvento, diff --git a/CTe.Servicos/Eventos/ServicoController.cs b/CTe.Servicos/Eventos/ServicoController.cs index 5e319f335..751b9e719 100644 --- a/CTe.Servicos/Eventos/ServicoController.cs +++ b/CTe.Servicos/Eventos/ServicoController.cs @@ -66,10 +66,10 @@ public async Task ExecutarAsync(CteEletronico cte, int sequenciaEv return await ExecutarAsync(cTeTipoEvento, sequenciaEvento, cte.Chave(), cte.infCte.emit.CNPJ, container, configServico); } - public retEventoCTe Executar(CTeTipoEvento cTeTipoEvento, int sequenciaEvento, string chave, string cnpj, EventoContainer container, ConfiguracaoServico configuracaoServico = null) + public retEventoCTe Executar(CTeTipoEvento cTeTipoEvento, int sequenciaEvento, string chave, string cnpj, EventoContainer container, ConfiguracaoServico configuracaoServico = null, DFe.Classes.Entidades.Estado? cOrgao = null) { var configServico = configuracaoServico ?? ConfiguracaoServico.Instancia; - var evento = FactoryEvento.CriaEvento(cTeTipoEvento, sequenciaEvento, chave, cnpj, container, configServico); + var evento = FactoryEvento.CriaEvento(cTeTipoEvento, sequenciaEvento, chave, cnpj, container, configServico, cOrgao); evento.Assina(configServico); if (configServico.IsValidaSchemas) @@ -81,13 +81,13 @@ public retEventoCTe Executar(CTeTipoEvento cTeTipoEvento, int sequenciaEvento, s if (evento.versao == versao.ve200 || evento.versao == versao.ve300) { - var webService = WsdlFactory.CriaWsdlCteEvento(configServico); + var webService = WsdlFactory.CriaWsdlCteEvento(configServico, ufUrl: cOrgao); retornoXml = webService.cteRecepcaoEvento(evento.CriaXmlRequestWs()); } if (evento.versao == versao.ve400) { - var webService = WsdlFactory.CriaWsdlCteEventoV4(configServico); + var webService = WsdlFactory.CriaWsdlCteEventoV4(configServico, ufUrl: cOrgao); retornoXml = webService.cteRecepcaoEvento(evento.CriaXmlRequestWs()); } @@ -97,15 +97,11 @@ public retEventoCTe Executar(CTeTipoEvento cTeTipoEvento, int sequenciaEvento, s return retorno; } - public async Task ExecutarAsync(CTeTipoEvento cTeTipoEvento, - int sequenciaEvento, - string chave, string - cnpj, EventoContainer container, - ConfiguracaoServico configuracaoServico = null) + public async Task ExecutarAsync(CTeTipoEvento cTeTipoEvento, int sequenciaEvento, string chave, string cnpj, EventoContainer container, ConfiguracaoServico configuracaoServico = null, DFe.Classes.Entidades.Estado? cOrgao = null) { var configServico = configuracaoServico ?? ConfiguracaoServico.Instancia; - var evento = FactoryEvento.CriaEvento(cTeTipoEvento, sequenciaEvento, chave, cnpj, container, configServico); + var evento = FactoryEvento.CriaEvento(cTeTipoEvento, sequenciaEvento, chave, cnpj, container, configServico, cOrgao); evento.Assina(configServico); if (configServico.IsValidaSchemas) @@ -117,16 +113,15 @@ public async Task ExecutarAsync(CTeTipoEvento cTeTipoEvento, if (evento.versao == versao.ve200 || evento.versao == versao.ve300) { - var webService = WsdlFactory.CriaWsdlCteEvento(configServico); + var webService = WsdlFactory.CriaWsdlCteEvento(configServico, ufUrl: cOrgao); retornoXml = await webService.cteRecepcaoEventoAsync(evento.CriaXmlRequestWs()); } if (evento.versao == versao.ve400) { - var webService = WsdlFactory.CriaWsdlCteEventoV4(configServico); + var webService = WsdlFactory.CriaWsdlCteEventoV4(configServico, ufUrl: cOrgao); retornoXml = await webService.cteRecepcaoEventoAsync(evento.CriaXmlRequestWs()); } - var retorno = retEventoCTe.LoadXml(retornoXml.OuterXml, evento); retorno.SalvarXmlEmDisco(configServico); diff --git a/CTe.Servicos/Factory/ClassesFactory.cs b/CTe.Servicos/Factory/ClassesFactory.cs index 03492279d..646c6428e 100644 --- a/CTe.Servicos/Factory/ClassesFactory.cs +++ b/CTe.Servicos/Factory/ClassesFactory.cs @@ -164,6 +164,22 @@ public static evPrestDesacordo CriaEvPrestDesacordo(string indicadorDesacordo, s return evPrestDesacordo; } + public static evCancPrestDesacordo CriaEvCancPrestDesacordo(string nProtEvPrestDes, ConfiguracaoServico configuracaoServico = null) + { + var configServico = configuracaoServico ?? ConfiguracaoServico.Instancia; + + var evPrestDesacordo = new evCancPrestDesacordo + { + nProtEvPrestDes = nProtEvPrestDes + }; + + if (configServico.cUF == Estado.MT)//sem acentuação issue #1386 + { + evPrestDesacordo.descEvento = "Cancelamento Prestacao do Servico em Desacordo"; + } + + return evPrestDesacordo; + } public static enviCTe CriaEnviCTe(int lote, List cteEletronicoList, ConfiguracaoServico configuracaoServico = null) { diff --git a/CTe.Servicos/Factory/WsdlFactory.cs b/CTe.Servicos/Factory/WsdlFactory.cs index fb633d0e2..cc0bd4591 100644 --- a/CTe.Servicos/Factory/WsdlFactory.cs +++ b/CTe.Servicos/Factory/WsdlFactory.cs @@ -47,6 +47,7 @@ using CTe.Wsdl.Evento.V4; using CTe.Wsdl.Recepcao.Sincrono; using System.Security.Cryptography.X509Certificates; +using DFe.Classes.Entidades; namespace CTe.Servicos.Factory { @@ -123,22 +124,22 @@ public static CteRecepcaoSincronoOSV4 CriaWsdlCteRecepcaoSincronoOSV4(Configurac return new CteRecepcaoSincronoOSV4(configuracaoWsdl); } - public static CteRecepcaoEvento CriaWsdlCteEvento(ConfiguracaoServico configuracaoServico = null, X509Certificate2 certificado = null) + public static CteRecepcaoEvento CriaWsdlCteEvento(ConfiguracaoServico configuracaoServico = null, X509Certificate2 certificado = null, Estado? ufUrl = null) { - var url = UrlHelper.ObterUrlServico(configuracaoServico).CteRecepcaoEvento; + var url = UrlHelper.ObterUrlServico(configuracaoServico, ufRecepcao: ufUrl).CteRecepcaoEvento; - var configuracaoWsdl = CriaConfiguracao(url, configuracaoServico, certificado); + var configuracaoWsdl = CriaConfiguracao(url, configuracaoServico, certificado, ufUrl); return new CteRecepcaoEvento(configuracaoWsdl); } - public static CteRecepcaoEventoV4 CriaWsdlCteEventoV4(ConfiguracaoServico configuracaoServico = null, X509Certificate2 certificado = null) + public static CteRecepcaoEventoV4 CriaWsdlCteEventoV4(ConfiguracaoServico configuracaoServico = null, X509Certificate2 certificado = null, Estado? ufUrl = null) { var configServico = configuracaoServico ?? ConfiguracaoServico.Instancia; - var url = UrlHelper.ObterUrlServico(configServico).CteRecepcaoEvento; + var url = UrlHelper.ObterUrlServico(configServico, ufRecepcao: ufUrl).CteRecepcaoEvento; - var configuracaoWsdl = CriaConfiguracao(url, configServico, certificado); + var configuracaoWsdl = CriaConfiguracao(url, configServico, certificado, ufUrl); return new CteRecepcaoEventoV4(configuracaoWsdl); } @@ -154,11 +155,11 @@ public static CTeDistDFeInteresse CriaWsdlCTeDistDFeInteresse(ConfiguracaoServic } - private static WsdlConfiguracao CriaConfiguracao(string url, ConfiguracaoServico configuracaoServico, X509Certificate2 certificado) + private static WsdlConfiguracao CriaConfiguracao(string url, ConfiguracaoServico configuracaoServico, X509Certificate2 certificado, Estado? ufUrl = null) { var configServico = configuracaoServico ?? ConfiguracaoServico.Instancia; - var codigoEstado = configServico.cUF.GetCodigoIbgeEmString(); + var codigoEstado = ufUrl.HasValue ? ufUrl.Value.GetCodigoIbgeEmString() : configServico.cUF.GetCodigoIbgeEmString(); var certificadoDigital = certificado ?? configServico.X509Certificate2; var versaoEmString = configServico.VersaoLayout.GetString(); var timeOut = configServico.TimeOut; diff --git a/CTe.Utils/Validacao/Validador.cs b/CTe.Utils/Validacao/Validador.cs index 1d4773996..667b2560d 100644 --- a/CTe.Utils/Validacao/Validador.cs +++ b/CTe.Utils/Validacao/Validador.cs @@ -55,9 +55,15 @@ public static void Valida(string xml, string schema, ConfiguracaoServico configu // Define o tipo de validação var cfg = new XmlReaderSettings { ValidationType = ValidationType.Schema }; + // Previne ataques XXE: nao permite resolver recursos externos + cfg.DtdProcessing = DtdProcessing.Prohibit; + cfg.XmlResolver = null; + // Carrega o arquivo de esquema - var schemas = new XmlSchemaSet(); - schemas.XmlResolver = new XmlUrlResolver(); + var schemas = new XmlSchemaSet + { + XmlResolver = new XmlUrlResolver() + }; cfg.Schemas = schemas; // Quando carregar o schema, especificar o namespace que ele valida diff --git a/DFe.Testes/DFe.Testes.csproj b/DFe.Testes/DFe.Testes.csproj index cc90271e4..a7deb0021 100644 --- a/DFe.Testes/DFe.Testes.csproj +++ b/DFe.Testes/DFe.Testes.csproj @@ -18,8 +18,10 @@ + + diff --git a/DFe.Testes/Gerais/ChaveFiscalTestes.cs b/DFe.Testes/Gerais/ChaveFiscalTestes.cs new file mode 100644 index 000000000..4d761043b --- /dev/null +++ b/DFe.Testes/Gerais/ChaveFiscalTestes.cs @@ -0,0 +1,261 @@ +using System; +using DFe.Classes.Entidades; +using DFe.Classes.Flags; +using DFe.Utils; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace DFe.Testes.Gerais +{ + /// + /// Testes da chave de acesso do DF-e cobrindo o fluxo antigo (CNPJ 100% numérico) + /// e o novo fluxo com CNPJ alfanumérico da NT Conjunta 2025.001 + /// + [TestClass] + public class ChaveFiscalTestes + { + //Chave real de NFC-e homologação (CNPJ numérico) usada como âncora de regressão do fluxo antigo + private const string ChaveNumericaReal = "23190811820016000167650010000000221100000227"; + + //Vetor ouro da NT: NFe de GO, emitida em 07/2025 pelo CNPJ alfanumérico de teste da Receita PC3D315K000193 + private const string ChaveAlfanumericaOuro = "522507PC3D315K000193550010000000011000000018"; + + #region Fluxo novo - CNPJ alfanumérico + + [TestMethod] + public void ObterChave_ComCnpjAlfanumerico_GeraAChaveDoVetorOuro() + { + // Arrange + var dataEmissao = new DateTimeOffset(2025, 7, 15, 10, 0, 0, TimeSpan.FromHours(-3)); + + // Act + var dados = ChaveFiscal.ObterChave(Estado.GO, dataEmissao, "PC3D315K000193", ModeloDocumento.NFe, 1, 1, 1, 1); + + // Assert + Assert.AreEqual(ChaveAlfanumericaOuro, dados.Chave); + Assert.AreEqual((byte)8, dados.DigitoVerificador); + } + + [TestMethod] + public void ObterChave_ComCnpjAlfanumerico_ChaveTemLayoutCorreto() + { + var dados = ChaveFiscal.ObterChave(Estado.GO, new DateTime(2025, 7, 15), "PC3D315K000193", ModeloDocumento.NFe, 1, 1, 1, 1); + + Assert.AreEqual(44, dados.Chave.Length); + Assert.AreEqual("52", dados.Chave.Substring(0, 2), "cUF"); + Assert.AreEqual("2507", dados.Chave.Substring(2, 4), "AAMM"); + Assert.AreEqual("PC3D315K000193", dados.Chave.Substring(6, 14), "CNPJ"); + Assert.AreEqual("55", dados.Chave.Substring(20, 2), "modelo"); + } + + [TestMethod] + public void ChaveValida_ComChaveAlfanumericaDoVetorOuro_RetornaVerdadeiro() + { + Assert.IsTrue(ChaveFiscal.ChaveValida(ChaveAlfanumericaOuro)); + } + + [TestMethod] + [DataRow("0")] + [DataRow("1")] + [DataRow("5")] + [DataRow("9")] + public void ChaveValida_ComChaveAlfanumericaComDvErrado_RetornaFalso(string dvErrado) + { + var chaveComDvErrado = ChaveAlfanumericaOuro.Substring(0, 43) + dvErrado; + + Assert.IsFalse(ChaveFiscal.ChaveValida(chaveComDvErrado)); + } + + [TestMethod] + public void ObterChave_ComVariosCnpjsAlfanumericos_DvIgualAoDaImplementacaoDeReferenciaDaNT() + { + // Arrange - bases alfanuméricas com DVs calculados pela regra oficial de CNPJ + var basesCnpj = new[] { "12ABC34501DE", "PC3D315K0001", "A1B2C3D4E5F6", "ZZZZZZZZZZZZ", "0000000000AB", "H9J8K7L6M5N4" }; + var ufs = new[] { Estado.GO, Estado.SP, Estado.CE, Estado.RS, Estado.AM, Estado.DF }; + var modelos = new[] { ModeloDocumento.NFe, ModeloDocumento.NFCe }; + + for (var i = 0; i < basesCnpj.Length; i++) + { + var cnpj = basesCnpj[i] + CnpjFiscal.ObterDigitosVerificadores(basesCnpj[i]); + + foreach (var modelo in modelos) + { + // Act + var dados = ChaveFiscal.ObterChave(ufs[i], new DateTime(2026, 7, 1), cnpj, modelo, i + 1, 1000 + i, 1, 77000 + i); + + // Assert + var dvReferencia = CalcularDvReferenciaNt(dados.Chave.Substring(0, 43)); + Assert.AreEqual(dvReferencia, (int)dados.DigitoVerificador, "CNPJ {0}, modelo {1}", cnpj, modelo); + Assert.IsTrue(ChaveFiscal.ChaveValida(dados.Chave), "ChaveValida deveria aceitar {0}", dados.Chave); + } + } + } + + [TestMethod] + public void ObterChave_ComCnpjAlfanumericoMinusculo_LancaArgumentException() + { + Assert.ThrowsException(() => + ChaveFiscal.ObterChave(Estado.GO, new DateTime(2025, 7, 15), "pc3d315k000193", ModeloDocumento.NFe, 1, 1, 1, 1)); + } + + [TestMethod] + [DataRow(':')] + [DataRow(';')] + [DataRow('<')] + [DataRow('=')] + [DataRow('>')] + [DataRow('?')] + [DataRow('@')] + public void ObterChave_ComCaractereEntreDigitosELetras_LancaArgumentException(char caractereInvalido) + { + //os caracteres ASCII 58 a 64 ficam entre '9' e 'A' e produziriam DV errado sem erro se aceitos + var cnpjInvalido = "PC3D315K0001" + caractereInvalido + "3"; + + Assert.ThrowsException(() => + ChaveFiscal.ObterChave(Estado.GO, new DateTime(2025, 7, 15), cnpjInvalido, ModeloDocumento.NFe, 1, 1, 1, 1)); + } + + [TestMethod] + public void ChaveValida_ComLetraMinusculaNaChave_LancaArgumentException() + { + var chaveComMinuscula = "522507pC3D315K000193550010000000011000000018"; + + Assert.ThrowsException(() => ChaveFiscal.ChaveValida(chaveComMinuscula)); + } + + #endregion + + #region Fluxo antigo - CNPJ numérico (regressão) + + [TestMethod] + public void ObterChave_ComCnpjNumerico_GeraChaveRealConhecida() + { + // Arrange - componentes da chave real de homologação (NFC-e do CE, 08/2019) + var dataEmissao = new DateTimeOffset(2019, 8, 10, 12, 0, 0, TimeSpan.FromHours(-3)); + + // Act + var dados = ChaveFiscal.ObterChave(Estado.CE, dataEmissao, "11820016000167", ModeloDocumento.NFCe, 1, 22, 1, 10000022); + + // Assert + Assert.AreEqual(ChaveNumericaReal, dados.Chave); + Assert.AreEqual((byte)7, dados.DigitoVerificador); + } + + [TestMethod] + public void ChaveValida_ComChaveNumericaRealConhecida_RetornaVerdadeiro() + { + Assert.IsTrue(ChaveFiscal.ChaveValida(ChaveNumericaReal)); + } + + [TestMethod] + public void ChaveValida_ComChaveNumericaComDvErrado_RetornaFalso() + { + var chaveComDvErrado = ChaveNumericaReal.Substring(0, 43) + "9"; + + Assert.IsFalse(ChaveFiscal.ChaveValida(chaveComDvErrado)); + } + + [TestMethod] + public void ObterChave_ComVariosCnpjsNumericos_DvIdenticoAoAlgoritmoLegado() + { + // Arrange - regressão: para chave 100% numérica o DV novo deve ser idêntico ao da implementação antiga + var cnpjs = new[] { "11222333000181", "00000000000191", "11444777000161", "99999999999999", "00000000000000", "12345678000195" }; + var ufs = new[] { Estado.SP, Estado.GO, Estado.CE, Estado.RS, Estado.MG, Estado.BA }; + + for (var i = 0; i < cnpjs.Length; i++) + { + foreach (var modelo in new[] { ModeloDocumento.NFe, ModeloDocumento.NFCe }) + { + // Act + var dados = ChaveFiscal.ObterChave(ufs[i], new DateTime(2024, 12, 31), cnpjs[i], modelo, 883 + i, 999999990 + i, 2, 10000000 - i); + + // Assert + var dvLegado = CalcularDvAlgoritmoLegado(dados.Chave.Substring(0, 43)); + Assert.AreEqual(dvLegado, dados.DigitoVerificador.ToString(), "CNPJ {0}, modelo {1}", cnpjs[i], modelo); + Assert.IsTrue(ChaveFiscal.ChaveValida(dados.Chave)); + } + } + } + + [TestMethod] + public void ObterChave_ComCpfDe11Posicoes_PreencheComZerosAEsquerda() + { + // Act + var dados = ChaveFiscal.ObterChave(Estado.SP, new DateTime(2026, 7, 1), "12345678901", ModeloDocumento.NFe, 1, 123, 1, 55555); + + // Assert + Assert.AreEqual(44, dados.Chave.Length); + Assert.AreEqual("00012345678901", dados.Chave.Substring(6, 14)); + Assert.IsTrue(ChaveFiscal.ChaveValida(dados.Chave)); + } + + #endregion + + #region Validação do documento do emitente + + [TestMethod] + [DataRow("PC3D315K0001", DisplayName = "12 posições - base de CNPJ truncada")] + [DataRow("1122233300018", DisplayName = "13 posições")] + [DataRow("112223330001811", DisplayName = "15 posições")] + [DataRow("1234567890", DisplayName = "10 posições")] + public void ObterChave_ComDocumentoDeComprimentoInvalido_LancaArgumentException(string documento) + { + //um CNPJ truncado não pode virar silenciosamente uma chave bem-formada porém errada + Assert.ThrowsException(() => + ChaveFiscal.ObterChave(Estado.GO, new DateTime(2026, 7, 1), documento, ModeloDocumento.NFe, 1, 1, 1, 1)); + } + + [TestMethod] + public void ObterChave_ComDocumentoVazio_LancaArgumentException() + { + Assert.ThrowsException(() => + ChaveFiscal.ObterChave(Estado.GO, new DateTime(2026, 7, 1), "", ModeloDocumento.NFe, 1, 1, 1, 1)); + } + + [TestMethod] + public void ObterChave_ComDocumentoNulo_LancaArgumentException() + { + Assert.ThrowsException(() => + ChaveFiscal.ObterChave(Estado.GO, new DateTime(2026, 7, 1), null, ModeloDocumento.NFe, 1, 1, 1, 1)); + } + + #endregion + + /// + /// Implementação de referência do Anexo II da NT Conjunta 2025.001, portada para C# + /// + private static int CalcularDvReferenciaNt(string chave43) + { + var soma = 0; + var peso = 2; + for (var i = chave43.Length - 1; i >= 0; i--) + { + soma += (chave43[i] - '0') * peso; + peso = peso == 9 ? 2 : peso + 1; + } + var dv = 11 - soma % 11; + return dv >= 10 ? 0 : dv; + } + + /// + /// Algoritmo do DV como era antes da correção (só funciona com dígitos), + /// usado para garantir que chaves numéricas não sofreram regressão + /// + private static string CalcularDvAlgoritmoLegado(string chave43) + { + var soma = 0; + var peso = 2; + for (var i = chave43.Length - 1; i != -1; i--) + { + var ch = Convert.ToInt32(chave43[i].ToString()); + soma += ch * peso; + if (peso < 9) + peso += 1; + else + peso = 2; + } + var mod = soma % 11; + var dv = mod == 0 || mod == 1 ? 0 : 11 - mod; + return dv.ToString(); + } + } +} diff --git a/DFe.Testes/Gerais/CnpjFiscalTestes.cs b/DFe.Testes/Gerais/CnpjFiscalTestes.cs new file mode 100644 index 000000000..a91b7240c --- /dev/null +++ b/DFe.Testes/Gerais/CnpjFiscalTestes.cs @@ -0,0 +1,128 @@ +using System; +using DFe.Utils; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace DFe.Testes.Gerais +{ + /// + /// Testes do cálculo de dígitos verificadores e validação de CNPJ, + /// cobrindo CNPJs numéricos (fluxo antigo) e alfanuméricos (NT Conjunta 2025.001) + /// + [TestClass] + public class CnpjFiscalTestes + { + #region ObterDigitosVerificadores - vetores ouro + + [TestMethod] + [DataRow("112223330001", "81", DisplayName = "Base numérica")] + [DataRow("12ABC34501DE", "35", DisplayName = "Exemplo da NT Conjunta 2025.001")] + [DataRow("PC3D315K0001", "93", DisplayName = "CNPJ de teste da Receita Federal")] + [DataRow("000000000000", "00", DisplayName = "Base zerada - o DV confere, o bloqueio é do Valido")] + public void ObterDigitosVerificadores_ComBaseDe12Posicoes_RetornaDvsEsperados(string baseCnpj, string dvsEsperados) + { + Assert.AreEqual(dvsEsperados, CnpjFiscal.ObterDigitosVerificadores(baseCnpj)); + } + + [TestMethod] + [DataRow("000000000001", "91", DisplayName = "Banco do Brasil")] + [DataRow("114447770001", "61", DisplayName = "CNPJ numérico clássico de testes")] + [DataRow("123456780001", "95", DisplayName = "CNPJ numérico sequencial")] + public void ObterDigitosVerificadores_ComBasesNumericasHistoricas_MantemComportamentoAntigo(string baseCnpj, string dvsEsperados) + { + Assert.AreEqual(dvsEsperados, CnpjFiscal.ObterDigitosVerificadores(baseCnpj)); + } + + #endregion + + #region ObterDigitosVerificadores - entradas inválidas + + [TestMethod] + [DataRow("pc3d315k0001", DisplayName = "Minúsculas")] + [DataRow("12ABC34501D", DisplayName = "11 posições")] + [DataRow("12ABC34501DEF", DisplayName = "13 posições")] + [DataRow("12ABC34501D@", DisplayName = "Caractere @ (ASCII 64)")] + [DataRow("12ABC34501D:", DisplayName = "Caractere : (ASCII 58)")] + [DataRow("12.ABC.345/01", DisplayName = "Com máscara")] + [DataRow("", DisplayName = "Vazia")] + public void ObterDigitosVerificadores_ComBaseInvalida_LancaArgumentException(string baseCnpj) + { + Assert.ThrowsException(() => CnpjFiscal.ObterDigitosVerificadores(baseCnpj)); + } + + [TestMethod] + public void ObterDigitosVerificadores_ComBaseNula_LancaArgumentNullException() + { + Assert.ThrowsException(() => CnpjFiscal.ObterDigitosVerificadores(null)); + } + + #endregion + + #region Valido - CNPJs aceitos + + [TestMethod] + [DataRow("11222333000181", DisplayName = "Numérico do vetor ouro")] + [DataRow("12ABC34501DE35", DisplayName = "Alfanumérico do exemplo da NT")] + [DataRow("PC3D315K000193", DisplayName = "Alfanumérico de teste da Receita")] + [DataRow("00000000000191", DisplayName = "Numérico clássico - Banco do Brasil")] + [DataRow("11444777000161", DisplayName = "Numérico clássico de testes")] + public void Valido_ComCnpjCorreto_RetornaVerdadeiro(string cnpj) + { + Assert.IsTrue(CnpjFiscal.Valido(cnpj)); + } + + #endregion + + #region Valido - CNPJs rejeitados + + [TestMethod] + public void Valido_ComCnpjZerado_RetornaFalso() + { + //o DV do CNPJ zerado confere, mas a NT veda o seu uso + Assert.IsFalse(CnpjFiscal.Valido("00000000000000")); + } + + [TestMethod] + [DataRow("11222333000182", DisplayName = "Numérico com DV errado")] + [DataRow("12ABC34501DE36", DisplayName = "Alfanumérico com segundo DV errado")] + [DataRow("12ABC34501DE45", DisplayName = "Alfanumérico com primeiro DV errado")] + [DataRow("PC3D315K000139", DisplayName = "Alfanumérico com DVs trocados")] + public void Valido_ComDvIncorreto_RetornaFalso(string cnpj) + { + Assert.IsFalse(CnpjFiscal.Valido(cnpj)); + } + + [TestMethod] + [DataRow("pc3d315k000193", DisplayName = "Minúsculas")] + [DataRow("PC3D315K00019", DisplayName = "13 posições")] + [DataRow("PC3D315K0001935", DisplayName = "15 posições")] + [DataRow("12ABC34501DEA5", DisplayName = "Letra na posição dos DVs")] + [DataRow("12ABC34501D:93", DisplayName = "Caractere : (ASCII 58)")] + [DataRow("12ABC34501D@93", DisplayName = "Caractere @ (ASCII 64)")] + [DataRow("11.222.333/0001-81", DisplayName = "Com máscara")] + [DataRow("", DisplayName = "Vazio")] + [DataRow(null, DisplayName = "Nulo")] + public void Valido_ComFormatoInvalido_RetornaFalso(string cnpj) + { + Assert.IsFalse(CnpjFiscal.Valido(cnpj)); + } + + #endregion + + #region Coerência entre ObterDigitosVerificadores e Valido + + [TestMethod] + public void Valido_ComDvsCalculadosPelaPropriaClasse_RetornaVerdadeiro() + { + var bases = new[] { "112223330001", "12ABC34501DE", "PC3D315K0001", "A1B2C3D4E5F6", "ZZZZZZZZZZZZ", "0000000000AB", "999999999999" }; + + foreach (var baseCnpj in bases) + { + var cnpj = baseCnpj + CnpjFiscal.ObterDigitosVerificadores(baseCnpj); + + Assert.IsTrue(CnpjFiscal.Valido(cnpj), "O CNPJ {0} deveria ser válido", cnpj); + } + } + + #endregion + } +} diff --git a/DFe.Testes/Gerais/Code128HibridoTestes.cs b/DFe.Testes/Gerais/Code128HibridoTestes.cs new file mode 100644 index 000000000..9696207ba --- /dev/null +++ b/DFe.Testes/Gerais/Code128HibridoTestes.cs @@ -0,0 +1,252 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NFe.Danfe.PdfClown.Tools; + +namespace DFe.Testes.Gerais +{ + /// + /// Testes do codificador CODE-128 híbrido (subconjuntos C e A) da seção 6 da NT Conjunta 2025.001, + /// usado no código de barras da chave de acesso do DANFE + /// + [TestClass] + public class Code128HibridoTestes + { + private const byte StartC = 105; + private const byte TrocaParaCodeA = 101; + private const byte TrocaParaCodeC = 99; + private const byte Stop = 106; + + #region Exemplos literais da NT Conjunta 2025.001 - seção 6 + + [TestMethod] + public void ObterSimbolos_ExemploLiteralDaNT_5225AB83() + { + // Arrange - sequência completa dada pela NT: start, dados, DV 30 e stop + var esperado = new byte[] { 105, 52, 25, 101, 33, 34, 99, 83, 30, 106 }; + + // Act + var simbolos = Code128Hibrido.ObterSimbolos("5225AB83"); + + // Assert + CollectionAssert.AreEqual(esperado, simbolos); + } + + [TestMethod] + public void ObterSimbolos_ExemploLiteralDaNT_123A() + { + // Arrange - "12" em Code C, troca para o Code A (101), '3' (19) e 'A' (33) no Code A + var dadosEsperados = new byte[] { 105, 12, 101, 19, 33 }; + + // Act + var simbolos = Code128Hibrido.ObterSimbolos("123A"); + + // Assert + CollectionAssert.AreEqual(dadosEsperados, simbolos.Take(5).ToArray()); + AssertDigitoVerificadorEStop(simbolos); + } + + #endregion + + #region Chave de acesso com CNPJ alfanumérico + + [TestMethod] + public void ObterSimbolos_ChaveDeAcessoAlfanumericaDoVetorOuro_CodificaConformeAsRegrasDaNT() + { + // Arrange + //6 dígitos iniciais em Code C (3 pares); letras e corridas curtas do CNPJ no Code A; + //corrida final de 30 dígitos de volta ao Code C (15 pares) + var dadosEsperados = new byte[] + { + 105, //Start C + 52, 25, 7, //"522507" + 101, //troca para Code A + 48, 35, //'P' 'C' + 19, //'3' (corrida de 1 dígito fica no Code A) + 36, //'D' + 19, 17, 21, //'3' '1' '5' (corrida de 3 dígitos fica no Code A) + 43, //'K' + 99, //volta ao Code C (corrida final par) + 0, 1, 93, 55, 0, 10, 0, 0, 0, 1, 10, 0, 0, 0, 18 + }; + + // Act + var simbolos = Code128Hibrido.ObterSimbolos("522507PC3D315K000193550010000000011000000018"); + + // Assert + CollectionAssert.AreEqual(dadosEsperados, simbolos.Take(dadosEsperados.Length).ToArray()); + AssertDigitoVerificadorEStop(simbolos); + } + + #endregion + + #region Regressão - conteúdo 100% numérico deve gerar exatamente o CODE-128 C puro + + [TestMethod] + public void ObterSimbolos_ComChavesNumericas_IdenticoAoCode128CPuroDaImplementacaoAntiga() + { + var chavesNumericas = new[] + { + "23190811820016000167650010000000221100000227", + "11222333000181112223330001811122233300018111", + "00000000000000000000000000000000000000000000", + "99999999999999999999999999999999999999999999", + "35150300822602000124550010009923461099234656" + }; + + foreach (var chave in chavesNumericas) + { + // Act + var simbolos = Code128Hibrido.ObterSimbolos(chave); + + // Assert + CollectionAssert.AreEqual(CodificarCode128CPuroLegado(chave), simbolos, "Divergência na chave {0}", chave); + } + } + + #endregion + + #region Regras de troca de subconjunto + + [TestMethod] + public void ObterSimbolos_ComLetraInicial_TrocaParaCodeAAposOStartC() + { + var simbolos = Code128Hibrido.ObterSimbolos("A"); + + CollectionAssert.AreEqual(new byte[] { StartC, TrocaParaCodeA, 33 }, simbolos.Take(3).ToArray()); + AssertDigitoVerificadorEStop(simbolos); + } + + [TestMethod] + public void ObterSimbolos_CorridaDe4DigitosEntreLetras_VoltaAoCodeC() + { + //"AB" no Code A, "1234" volta ao Code C (2 pares), "CD" troca novamente para o Code A + var simbolos = Code128Hibrido.ObterSimbolos("AB1234CD"); + + CollectionAssert.AreEqual(new byte[] { StartC, TrocaParaCodeA, 33, 34, TrocaParaCodeC, 12, 34, TrocaParaCodeA, 35, 36 }, simbolos.Take(10).ToArray()); + AssertDigitoVerificadorEStop(simbolos); + } + + [TestMethod] + public void ObterSimbolos_CorridaDe3DigitosEntreLetras_PermaneceNoCodeA() + { + //corrida curta (menos de 4 dígitos) não justifica a troca + var simbolos = Code128Hibrido.ObterSimbolos("AB123C"); + + CollectionAssert.AreEqual(new byte[] { StartC, TrocaParaCodeA, 33, 34, 17, 18, 19, 35 }, simbolos.Take(8).ToArray()); + AssertDigitoVerificadorEStop(simbolos); + } + + [TestMethod] + public void ObterSimbolos_CorridaImparDe5DigitosAntesDeLetra_UltimoDigitoFicaNoCodeA() + { + //"12345" antes de letra: pares "12" "34" no Code C e o dígito ímpar '5' fica no Code A + var simbolos = Code128Hibrido.ObterSimbolos("AB12345C"); + + CollectionAssert.AreEqual(new byte[] { StartC, TrocaParaCodeA, 33, 34, TrocaParaCodeC, 12, 34, TrocaParaCodeA, 21, 35 }, simbolos.Take(10).ToArray()); + AssertDigitoVerificadorEStop(simbolos); + } + + [TestMethod] + public void ObterSimbolos_CorridaFinalParDe2Digitos_VoltaAoCodeC() + { + //final com quantidade par de dígitos volta ao Code C, como no exemplo 5225AB83 da NT + var simbolos = Code128Hibrido.ObterSimbolos("AB12"); + + CollectionAssert.AreEqual(new byte[] { StartC, TrocaParaCodeA, 33, 34, TrocaParaCodeC, 12 }, simbolos.Take(6).ToArray()); + AssertDigitoVerificadorEStop(simbolos); + } + + [TestMethod] + public void ObterSimbolos_CorridaFinalImparDe3Digitos_PermaneceNoCodeA() + { + var simbolos = Code128Hibrido.ObterSimbolos("AB123"); + + CollectionAssert.AreEqual(new byte[] { StartC, TrocaParaCodeA, 33, 34, 17, 18, 19 }, simbolos.Take(7).ToArray()); + AssertDigitoVerificadorEStop(simbolos); + } + + [TestMethod] + public void ObterSimbolos_CorridaFinalImparDe5Digitos_PrimeiroDigitoNoCodeAEDemaisNoCodeC() + { + //corrida final ímpar de 4+ dígitos: um dígito fica no Code A para a parte restante ser par + var simbolos = Code128Hibrido.ObterSimbolos("AB12345"); + + CollectionAssert.AreEqual(new byte[] { StartC, TrocaParaCodeA, 33, 34, 17, TrocaParaCodeC, 23, 45 }, simbolos.Take(8).ToArray()); + AssertDigitoVerificadorEStop(simbolos); + } + + [TestMethod] + public void ObterSimbolos_NumericoImpar_ParesNoCodeCEUltimoDigitoNoCodeA() + { + var simbolos = Code128Hibrido.ObterSimbolos("123"); + + CollectionAssert.AreEqual(new byte[] { StartC, 12, TrocaParaCodeA, 19 }, simbolos.Take(4).ToArray()); + AssertDigitoVerificadorEStop(simbolos); + } + + #endregion + + #region Entradas inválidas + + [TestMethod] + [DataRow("")] + [DataRow(null)] + public void ObterSimbolos_ComCodigoVazioOuNulo_LancaArgumentException(string codigo) + { + Assert.ThrowsException(() => Code128Hibrido.ObterSimbolos(codigo)); + } + + [TestMethod] + [DataRow("12a4", DisplayName = "Letra minúscula")] + [DataRow("12-4", DisplayName = "Hífen")] + [DataRow("12 34", DisplayName = "Espaço")] + [DataRow("12@34", DisplayName = "Caractere @")] + public void ObterSimbolos_ComCaractereForaDeDigitosELetrasMaiusculas_LancaArgumentException(string codigo) + { + Assert.ThrowsException(() => Code128Hibrido.ObterSimbolos(codigo)); + } + + #endregion + + /// + /// Confere as duas últimas posições da sequência: o DV módulo 103 + /// (soma ponderada com o start valendo peso 1) e o símbolo de Stop (106) + /// + private static void AssertDigitoVerificadorEStop(byte[] simbolos) + { + Assert.AreEqual(Stop, simbolos[simbolos.Length - 1], "O último símbolo deve ser o Stop (106)"); + + var soma = (int)simbolos[0]; + for (var i = 1; i < simbolos.Length - 2; i++) + soma += i * simbolos[i]; + + Assert.AreEqual((byte)(soma % 103), simbolos[simbolos.Length - 2], "Dígito verificador módulo 103 incorreto"); + } + + /// + /// Comportamento da implementação antiga (Barcode128C do DANFE PdfClown): Start C, + /// dados aos pares, DV módulo 103 e Stop - referência de regressão para conteúdo numérico + /// + private static byte[] CodificarCode128CPuroLegado(string codigo) + { + var codeBytes = new List { 105 }; + + for (var i = 0; i < codigo.Length; i += 2) + codeBytes.Add(byte.Parse(codigo.Substring(i, 2))); + + var cd = 105; + for (var i = 1; i < codeBytes.Count; i++) + { + cd += i * codeBytes[i]; + cd %= 103; + } + + codeBytes.Add((byte)cd); + codeBytes.Add(106); + + return codeBytes.ToArray(); + } + } +} diff --git a/DFe.Testes/Gerais/DanfePdfClownChaveAlfanumericaTestes.cs b/DFe.Testes/Gerais/DanfePdfClownChaveAlfanumericaTestes.cs new file mode 100644 index 000000000..1599753fa --- /dev/null +++ b/DFe.Testes/Gerais/DanfePdfClownChaveAlfanumericaTestes.cs @@ -0,0 +1,76 @@ +using System; +using System.IO; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NFe.Danfe.PdfClown; +using NFe.Danfe.PdfClown.Modelo; + +namespace DFe.Testes.Gerais +{ + /// + /// Smoke test do DANFE PdfClown: o PDF deve ser gerado com o código de barras CODE-128 híbrido + /// tanto para chave 100% numérica (fluxo antigo) quanto para chave com CNPJ alfanumérico + /// + [TestClass] + public class DanfePdfClownChaveAlfanumericaTestes + { + private static DanfeViewModel CriarViewModelMinimo(string chaveAcesso) + { + var model = new DanfeViewModel + { + ChaveAcesso = chaveAcesso, + NfNumero = 1, + NfSerie = 1, + TipoNF = 1, + TipoAmbiente = 2, + DataHoraEmissao = new DateTime(2025, 7, 15), + NaturezaOperacao = "VENDA", + ProtocoloAutorizacao = "352250000000001 15/07/2025 10:00:00" + }; + + model.Emitente.RazaoSocial = "EMITENTE DE TESTE LTDA"; + model.Emitente.CnpjCpf = chaveAcesso.Substring(6, 14); + model.Emitente.EnderecoLogadrouro = "RUA DE TESTE"; + model.Emitente.EnderecoNumero = "1"; + model.Emitente.EnderecoBairro = "CENTRO"; + model.Emitente.Municipio = "GOIANIA"; + model.Emitente.EnderecoUf = "GO"; + model.Emitente.EnderecoCep = "74000000"; + + model.Destinatario.RazaoSocial = "DESTINATARIO DE TESTE"; + model.Destinatario.CnpjCpf = "11222333000181"; + model.Destinatario.EnderecoLogadrouro = "AVENIDA DE TESTE"; + model.Destinatario.EnderecoNumero = "2"; + model.Destinatario.EnderecoBairro = "CENTRO"; + model.Destinatario.Municipio = "GOIANIA"; + model.Destinatario.EnderecoUf = "GO"; + model.Destinatario.EnderecoCep = "74000001"; + + return model; + } + + [TestMethod] + [DataRow("522507PC3D315K000193550010000000011000000018", DisplayName = "Chave com CNPJ alfanumérico")] + [DataRow("23190811820016000167650010000000221100000227", DisplayName = "Chave numérica (regressão)")] + public void Gerar_DanfeComChave_ProduzPdf(string chaveAcesso) + { + // Arrange + var model = CriarViewModelMinimo(chaveAcesso); + + using (var danfe = new DanfeDoc(model)) + { + // Act + danfe.Gerar(); + + using (var ms = new MemoryStream()) + { + danfe.Salvar(ms); + + // Assert - PDF gerado, não vazio e com o cabeçalho %PDF + var bytes = ms.ToArray(); + Assert.IsTrue(bytes.Length > 1000, "O PDF gerado está vazio ou pequeno demais ({0} bytes)", bytes.Length); + Assert.AreEqual("%PDF", System.Text.Encoding.ASCII.GetString(bytes, 0, 4)); + } + } + } + } +} diff --git a/DFe.Testes/Gerais/FormatadorDanfeTestes.cs b/DFe.Testes/Gerais/FormatadorDanfeTestes.cs new file mode 100644 index 000000000..f98d60239 --- /dev/null +++ b/DFe.Testes/Gerais/FormatadorDanfeTestes.cs @@ -0,0 +1,77 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NFe.Danfe.PdfClown.Tools; + +namespace DFe.Testes.Gerais +{ + /// + /// Testes da formatação de CNPJ, CPF e chave de acesso do DANFE (PdfClown), + /// cobrindo documentos numéricos (fluxo antigo) e o CNPJ alfanumérico da NT Conjunta 2025.001 + /// + [TestClass] + public class FormatadorDanfeTestes + { + #region FormatarCnpj + + [TestMethod] + [DataRow("11222333000181", "11.222.333/0001-81", DisplayName = "CNPJ numérico")] + [DataRow("00000000000191", "00.000.000/0001-91", DisplayName = "CNPJ numérico com zeros")] + [DataRow("12ABC34501DE35", "12.ABC.345/01DE-35", DisplayName = "CNPJ alfanumérico da NT")] + [DataRow("PC3D315K000193", "PC.3D3.15K/0001-93", DisplayName = "CNPJ alfanumérico de teste da Receita")] + public void FormatarCnpj_ComCnpjSemMascara_AplicaAMascaraPosicional(string cnpj, string esperado) + { + Assert.AreEqual(esperado, Formatador.FormatarCnpj(cnpj)); + } + + [TestMethod] + [DataRow("11.222.333/0001-81", "11.222.333/0001-81", DisplayName = "Numérico já com máscara")] + [DataRow("12.ABC.345/01DE-35", "12.ABC.345/01DE-35", DisplayName = "Alfanumérico já com máscara")] + public void FormatarCnpj_ComCnpjJaFormatado_MantemAMascara(string cnpj, string esperado) + { + Assert.AreEqual(esperado, Formatador.FormatarCnpj(cnpj)); + } + + [TestMethod] + [DataRow("12abc34501de35", DisplayName = "Minúsculas não formatam")] + [DataRow("12ABC34501DEA5", DisplayName = "Letra nos DVs não formata")] + [DataRow("123", DisplayName = "Curto demais não formata")] + public void FormatarCnpj_ComConteudoForaDoPadrao_DevolveOTextoOriginal(string cnpj) + { + Assert.AreEqual(cnpj, Formatador.FormatarCnpj(cnpj)); + } + + #endregion + + #region FormatarCpfCnpj + + [TestMethod] + [DataRow("12345678901", "123.456.789-01", DisplayName = "CPF continua com máscara de CPF")] + [DataRow("11222333000181", "11.222.333/0001-81", DisplayName = "CNPJ numérico")] + [DataRow("12ABC34501DE35", "12.ABC.345/01DE-35", DisplayName = "CNPJ alfanumérico")] + public void FormatarCpfCnpj_EscolheAMascaraCorreta(string documento, string esperado) + { + Assert.AreEqual(esperado, Formatador.FormatarCpfCnpj(documento)); + } + + #endregion + + #region FormatarChaveAcesso + + [TestMethod] + public void FormatarChaveAcesso_ComChaveAlfanumerica_AgrupaDeQuatroEmQuatro() + { + var formatada = Formatador.FormatarChaveAcesso("522507PC3D315K000193550010000000011000000018"); + + Assert.AreEqual("5225 07PC 3D31 5K00 0193 5500 1000 0000 0110 0000 0018", formatada); + } + + [TestMethod] + public void FormatarChaveAcesso_ComChaveNumerica_AgrupaDeQuatroEmQuatro() + { + var formatada = Formatador.FormatarChaveAcesso("23190811820016000167650010000000221100000227"); + + Assert.AreEqual("2319 0811 8200 1600 0167 6500 1000 0000 2211 0000 0227", formatada); + } + + #endregion + } +} diff --git a/DFe.Testes/Gerais/ObterIdTestes.cs b/DFe.Testes/Gerais/ObterIdTestes.cs new file mode 100644 index 000000000..2733d6e47 --- /dev/null +++ b/DFe.Testes/Gerais/ObterIdTestes.cs @@ -0,0 +1,61 @@ +using DFe.Classes.Entidades; +using DFe.Classes.Flags; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NFe.Classes.Servicos.Tipos; +using NFe.Utils.Evento; +using NFe.Utils.Inutilizacao; + +namespace DFe.Testes.Gerais +{ + /// + /// Vetores ouro do Id assinável de evento (infEvento/@Id) e de inutilização (infInut/@Id). + /// + /// Esses Ids também são calculados internamente pelos métodos que assinam (ServicosNFe). Se o formato + /// divergir, o digest da assinatura não bate e o SEFAZ rejeita — por isso os valores esperados aqui são + /// literais do layout, e não o resultado do próprio método. + /// + /// + [TestClass] + public class ObterIdTestes + { + /// Chave de NF-e (modelo 55) com CNPJ alfanumérico, conforme NT Conjunta 2025.001 + private const string ChaveNFe = "522507PC3D315K000193550010000000011000000018"; + + /// Chave de NFC-e (modelo 65), 100% numérica + private const string ChaveNFCe = "23190811820016000167650010000000221100000227"; + + private const string CnpjNumerico = "11820016000167"; + private const string CnpjAlfanumerico = "PC3D315K000193"; + + [TestMethod] + [DataRow(NFeTipoEvento.TeNfeCancelamento, ChaveNFe, 1, "ID110111" + ChaveNFe + "01", + DisplayName = "Cancelamento, chave com CNPJ alfanumérico")] + [DataRow(NFeTipoEvento.TeNfeCartaCorrecao, ChaveNFe, 2, "ID110110" + ChaveNFe + "02", + DisplayName = "Carta de Correção, 2ª sequência")] + [DataRow(NFeTipoEvento.TeMdCienciaDaOperacao, ChaveNFCe, 1, "ID210210" + ChaveNFCe + "01", + DisplayName = "Ciência da Operação, chave numérica")] + [DataRow(NFeTipoEvento.TeMdCienciaDaOperacao, ChaveNFCe, 11, "ID210210" + ChaveNFCe + "11", + DisplayName = "Sequência com 2 dígitos não recebe zero à esquerda")] + public void ObterIdEvento_SegueOLayout(NFeTipoEvento tpEvento, string chNFe, int nSeqEvento, string esperado) + { + Assert.AreEqual(esperado, Extevento.ObterId(tpEvento, chNFe, nSeqEvento)); + } + + [TestMethod] + [DataRow(ModeloDocumento.NFe, CnpjNumerico, 1, 1, 10, + "ID3525" + CnpjNumerico + "55" + "001" + "000000001" + "000000010", + DisplayName = "NF-e, modelo 55")] + [DataRow(ModeloDocumento.NFCe, CnpjNumerico, 1, 1, 10, + "ID3525" + CnpjNumerico + "65" + "001" + "000000001" + "000000010", + DisplayName = "NFC-e, modelo 65")] + [DataRow(ModeloDocumento.NFe, CnpjAlfanumerico, 12, 5, 5, + "ID3525" + CnpjAlfanumerico + "55" + "012" + "000000005" + "000000005", + DisplayName = "CNPJ alfanumérico, faixa de um número só")] + public void ObterIdInutilizacao_SegueOLayout(ModeloDocumento modelo, string cnpj, int serie, + int numeroInicial, int numeroFinal, string esperado) + { + Assert.AreEqual(esperado, + ExtinutNFe.ObterId(Estado.SP, 25, cnpj, modelo, serie, numeroInicial, numeroFinal)); + } + } +} diff --git a/DFe.Testes/Impostos/ICMSGeral_Teste.cs b/DFe.Testes/Impostos/ICMSGeral_Teste.cs index ba8a06ba7..6ec8792d2 100644 --- a/DFe.Testes/Impostos/ICMSGeral_Teste.cs +++ b/DFe.Testes/Impostos/ICMSGeral_Teste.cs @@ -1,5 +1,7 @@ using System; using System.ComponentModel; +using System.IO; +using System.Xml.Serialization; using DFe.Testes.Impostos.DadosDeTeste; using Microsoft.VisualStudio.TestTools.UnitTesting; using NFe.Classes.Informacoes.Detalhe.Tributacao.Estadual; @@ -115,6 +117,102 @@ public void ObterICMSBasico_ICMS10_Teste(CRT crt, OrigemMercadoria origem, Deter Assert.AreEqual(Convert.ToDecimal(vFCPST), tagICMSGerada.vFCPST); } + [TestMethod] + public void ObterICMSBasico_ICMS90ComDiferimento_Teste() + { + var icmsGeral = new ICMSGeral() + { + orig = OrigemMercadoria.OmNacional, + CST = Csticms.Cst90, + modBC = DeterminacaoBaseIcms.DbiValorOperacao, + vBC = 1000, + pRedBC = 10, + cBenefRBC = "ABC12345", + pICMS = 18, + vICMSOp = 180, + pDif = 50, + vICMSDif = 90, + vICMS = 90, + vBCFCP = 1000, + pFCP = 2, + vFCP = 20, + pFCPDif = 50, + vFCPDif = 10, + vFCPEfet = 10 + }; + + var tagGerada = icmsGeral.ObterICMSBasico(CRT.RegimeNormal); + + Assert.IsInstanceOfType(tagGerada, typeof(ICMS90)); + var tagICMSGerada = tagGerada as ICMS90; + Assert.AreEqual(Csticms.Cst90, tagICMSGerada.CST); + Assert.AreEqual("ABC12345", tagICMSGerada.cBenefRBC); + Assert.AreEqual(180m, tagICMSGerada.vICMSOp); + Assert.AreEqual(50m, tagICMSGerada.pDif); + Assert.AreEqual(90m, tagICMSGerada.vICMSDif); + Assert.AreEqual(50m, tagICMSGerada.pFCPDif); + Assert.AreEqual(10m, tagICMSGerada.vFCPDif); + Assert.AreEqual(10m, tagICMSGerada.vFCPEfet); + + var xml = Serializar(tagICMSGerada, "ICMS90"); + StringAssert.Contains(xml, "ABC12345"); + StringAssert.Contains(xml, "180.00"); + StringAssert.Contains(xml, "50.0000"); + StringAssert.Contains(xml, "90.00"); + StringAssert.Contains(xml, "50.0000"); + StringAssert.Contains(xml, "10.00"); + StringAssert.Contains(xml, "10.00"); + } + + [TestMethod] + public void ObterICMSBasico_ICMSPartCst20ComDesoneracao_Teste() + { + var icmsGeral = new ICMSGeral() + { + orig = OrigemMercadoria.OmNacional, + CST = Csticms.CstPart20, + modBC = DeterminacaoBaseIcms.DbiValorOperacao, + vBC = 1000, + pRedBC = 10, + pICMS = 18, + vICMS = 90, + modBCST = DeterminacaoBaseIcmsSt.DbisValordaOperacao, + vBCST = 1000, + pICMSST = 18, + vICMSST = 180, + pBCOp = 100, + UFST = "SP", + vICMSDeson = 10, + motDesICMS = MotivoDesoneracaoIcms.MdiDeficienteCondutor, + indDeduzDeson = DeduzDesoneracaoNoProduto.Deduz + }; + + var tagGerada = icmsGeral.ObterICMSBasico(CRT.RegimeNormal); + + Assert.IsInstanceOfType(tagGerada, typeof(ICMSPart)); + var tagICMSGerada = tagGerada as ICMSPart; + Assert.AreEqual(Csticms.CstPart20, tagICMSGerada.CST); + Assert.AreEqual(10m, tagICMSGerada.vICMSDeson); + Assert.AreEqual(MotivoDesoneracaoIcms.MdiDeficienteCondutor, tagICMSGerada.motDesICMS); + Assert.AreEqual(DeduzDesoneracaoNoProduto.Deduz, tagICMSGerada.indDeduzDeson); + + var xml = Serializar(tagICMSGerada, "ICMSPart"); + StringAssert.Contains(xml, "20"); + StringAssert.Contains(xml, "10.00"); + StringAssert.Contains(xml, "10"); + StringAssert.Contains(xml, "1"); + } + + private static string Serializar(T objeto, string raiz) + { + var serializer = new XmlSerializer(typeof(T), new XmlRootAttribute(raiz)); + using (var writer = new StringWriter()) + { + serializer.Serialize(writer, objeto); + return writer.ToString(); + } + } + //TODO: Falta criar os métodos de testes dos demais CSTs do ICMS (CTR = Normal) #endregion diff --git a/DFe.Utils/Assinatura/AssinaturaDigital.cs b/DFe.Utils/Assinatura/AssinaturaDigital.cs index 097acf2fb..5102e3875 100644 --- a/DFe.Utils/Assinatura/AssinaturaDigital.cs +++ b/DFe.Utils/Assinatura/AssinaturaDigital.cs @@ -51,16 +51,16 @@ public static SignatureZeus Assina(T objeto, string id, X509Certificate2 cert if (id == null) throw new Exception("Não é possível assinar um objeto evento sem sua respectiva Id!"); - var documento = new XmlDocument {PreserveWhitespace = true}; + var documento = new XmlDocument { PreserveWhitespace = true }; documento.LoadXml(cfgServicoRemoverAcentos ? FuncoesXml.ClasseParaXmlString(objetoLocal).RemoverAcentos() : FuncoesXml.ClasseParaXmlString(objetoLocal)); - var docXml = new SignedXml(documento) {SigningKey = certificado.PrivateKey}; + var docXml = new SignedXml(documento) { SigningKey = certificado.GetRSAPrivateKey() }; docXml.SignedInfo.SignatureMethod = signatureMethod; - var reference = new Reference {Uri = "#" + id, DigestMethod = digestMethod}; + var reference = new Reference { Uri = "#" + id, DigestMethod = digestMethod }; // adicionando EnvelopedSignatureTransform a referencia var envelopedSigntature = new XmlDsigEnvelopedSignatureTransform(); diff --git a/DFe.Utils/Assinatura/CertificadoDigital.cs b/DFe.Utils/Assinatura/CertificadoDigital.cs index 987bfbec0..7f29bcbe0 100644 --- a/DFe.Utils/Assinatura/CertificadoDigital.cs +++ b/DFe.Utils/Assinatura/CertificadoDigital.cs @@ -32,7 +32,7 @@ /********************************************************************************/ using System; -using System.Collections.Generic; +using System.Collections.Concurrent; using System.IO; using System.Runtime.InteropServices; using System.Security.Cryptography; @@ -43,7 +43,7 @@ namespace DFe.Utils.Assinatura { public static class CertificadoDigital { - private static readonly Dictionary CacheCertificado = new Dictionary(); + private static readonly ConcurrentDictionary CacheCertificado = new ConcurrentDictionary(); #region Métodos privados @@ -52,9 +52,9 @@ public static class CertificadoDigital /// /// /// - public static X509Store ObterX509Store(OpenFlags openFlags) + public static X509Store ObterX509Store(OpenFlags openFlags, StoreLocation storeLocation = StoreLocation.CurrentUser) { - var store = new X509Store(StoreName.My, StoreLocation.CurrentUser); + X509Store store = new X509Store(StoreName.My, storeLocation); store.Open(openFlags); return store; } @@ -89,7 +89,7 @@ private static X509Certificate2 ObterDoArrayBytes(byte[] arrayBytes, string senh { try { - var certificado = new X509Certificate2(arrayBytes, senha, keyStorageFlag); + X509Certificate2 certificado = new X509Certificate2(arrayBytes, senha, keyStorageFlag); return certificado; } catch (Exception ex) @@ -102,12 +102,12 @@ private static X509Certificate2 ObterDoArrayBytes(byte[] arrayBytes, string senh /// Obtém um objeto pelo serial passado no parÂmetro /// /// - private static X509Certificate2 ObterDoRepositorio(string serial, OpenFlags opcoesDeAbertura) + private static X509Certificate2 ObterDoRepositorio(string serial, OpenFlags opcoesDeAbertura, StoreLocation storeLocation = StoreLocation.CurrentUser) { if (string.IsNullOrEmpty(serial)) throw new ArgumentException("O número de série do certificado digital não foi informado!"); X509Certificate2 certificado = null; - var store = ObterX509Store(opcoesDeAbertura); + var store = ObterX509Store(opcoesDeAbertura, storeLocation); try { foreach (var item in store.Certificates) @@ -133,9 +133,9 @@ private static X509Certificate2 ObterDoRepositorio(string serial, OpenFlags opco /// /// /// - private static X509Certificate2 ObterDoRepositorioPassandoPin(string serial, string senha = null) + private static X509Certificate2 ObterDoRepositorioPassandoPin(string serial, string senha = null, StoreLocation storeLocation = StoreLocation.CurrentUser) { - var certificado = ObterDoRepositorio(serial, OpenFlags.ReadOnly); + var certificado = ObterDoRepositorio(serial, OpenFlags.ReadOnly, storeLocation); if (string.IsNullOrEmpty(senha)) return certificado; certificado.DefinirPinParaChavePrivada(senha); return certificado; @@ -187,13 +187,13 @@ private static X509Certificate2 ObterDadosCertificado(ConfiguracaoCertificado co switch (configuracaoCertificado.TipoCertificado) { case TipoCertificado.A1Repositorio: - return ObterDoRepositorio(configuracaoCertificado.Serial, OpenFlags.MaxAllowed); + return ObterDoRepositorio(configuracaoCertificado.Serial, OpenFlags.MaxAllowed, configuracaoCertificado.StoreLocation); case TipoCertificado.A1ByteArray: return ObterDoArrayBytes(configuracaoCertificado.ArrayBytesArquivo, configuracaoCertificado.Senha, configuracaoCertificado.KeyStorageFlags); case TipoCertificado.A1Arquivo: return ObterDeArquivo(configuracaoCertificado.Arquivo, configuracaoCertificado.Senha, configuracaoCertificado.KeyStorageFlags); case TipoCertificado.A3: - return ObterDoRepositorioPassandoPin(configuracaoCertificado.Serial, configuracaoCertificado.Senha); + return ObterDoRepositorioPassandoPin(configuracaoCertificado.Serial, configuracaoCertificado.Senha, configuracaoCertificado.StoreLocation); default: throw new ArgumentOutOfRangeException(); } @@ -204,8 +204,8 @@ private static X509Certificate2 ObterDadosCertificado(ConfiguracaoCertificado co /// /// Obtém um objeto contendo o certificado digital /// Se for informado , - /// o certificado digital será obtido pelo método , - /// senão será obtido pelo método + /// o certificado digital será obtido pelo método , + /// senão será obtido pelo método /// Para liberar os recursos do certificado, após seu uso, invoque o método /// public static X509Certificate2 ObterCertificado(ConfiguracaoCertificado configuracaoCertificado) @@ -213,20 +213,20 @@ public static X509Certificate2 ObterCertificado(ConfiguracaoCertificado configur if (!configuracaoCertificado.ManterDadosEmCache) return ObterDadosCertificado(configuracaoCertificado); - if (!string.IsNullOrEmpty(configuracaoCertificado.CacheId) && CacheCertificado.ContainsKey(configuracaoCertificado.CacheId)) - return CacheCertificado[configuracaoCertificado.CacheId]; + if (!string.IsNullOrWhiteSpace(configuracaoCertificado.CacheId) && CacheCertificado.TryGetValue(configuracaoCertificado.CacheId, out var certificadoEmCache)) + return certificadoEmCache; var certificado = ObterDadosCertificado(configuracaoCertificado); - var keyCertificado = string.IsNullOrEmpty(configuracaoCertificado.CacheId) + var keyCertificado = string.IsNullOrWhiteSpace(configuracaoCertificado.CacheId) ? certificado.SerialNumber : configuracaoCertificado.CacheId; configuracaoCertificado.CacheId = keyCertificado; + + var certificadoDoCache = CacheCertificado.GetOrAdd(keyCertificado, certificado); - CacheCertificado.Add(keyCertificado, certificado); - - return CacheCertificado[keyCertificado]; + return certificadoDoCache; } public static void ClearCache() diff --git a/DFe.Utils/CertificadoDigitalUtils.cs b/DFe.Utils/CertificadoDigitalUtils.cs index 178f71ea8..9b9067c37 100644 --- a/DFe.Utils/CertificadoDigitalUtils.cs +++ b/DFe.Utils/CertificadoDigitalUtils.cs @@ -16,9 +16,9 @@ public class CertificadoDigitalUtils /// Exibe a lista de certificados instalados no PC e devolve o certificado selecionado /// /// - public static X509Certificate2 ListareObterDoRepositorio() + public static X509Certificate2 ListareObterDoRepositorio(StoreLocation storeLocation = StoreLocation.CurrentUser) { - var store = CertificadoDigital.ObterX509Store(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly); + var store = CertificadoDigital.ObterX509Store(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly, storeLocation); var collection = store.Certificates; var fcollection = collection.Find(X509FindType.FindByTimeValid, DateTime.Now, true); var scollection = X509Certificate2UI.SelectFromCollection(fcollection, "Certificados válidos:", "Selecione o certificado que deseja usar", diff --git a/DFe.Utils/ChaveFiscal.cs b/DFe.Utils/ChaveFiscal.cs index 779a366a0..75cfe3dc6 100644 --- a/DFe.Utils/ChaveFiscal.cs +++ b/DFe.Utils/ChaveFiscal.cs @@ -57,16 +57,24 @@ public class ChaveFiscal /// Retorna um objeto com os dados da chave de acesso public static DadosChaveFiscal ObterChave(Estado ufEmitente, DateTimeOffset dataEmissao, string cnpjEmitente, ModeloDocumento modelo, int serie, long numero, int tipoEmissao, int cNf) { - var chave = new StringBuilder(); + if (string.IsNullOrEmpty(cnpjEmitente)) + throw new ArgumentException("O CNPJ/CPF do emitente deve ser informado.", "cnpjEmitente"); - if (cnpjEmitente.Length < 14) - { - cnpjEmitente = cnpjEmitente.PadLeft(14, '0'); - } + // NT Conjunta 2025.001: o CNPJ pode ser alfanumérico ([A-Z0-9]{12}[0-9]{2}) e ocupa 14 posições na chave. + // Somente CPF (11 posições) é completado com zeros à esquerda; qualquer outro comprimento seria um + // documento truncado e geraria uma chave bem-formada porém errada. + var documentoEmitente = cnpjEmitente.Length == 11 ? cnpjEmitente.PadLeft(14, '0') : cnpjEmitente; + + if (documentoEmitente.Length != 14) + throw new ArgumentException( + string.Format("O documento do emitente deve ter 14 posições (CNPJ) ou 11 posições (CPF); o valor informado \"{0}\" tem {1}.", cnpjEmitente, cnpjEmitente.Length), + "cnpjEmitente"); + + var chave = new StringBuilder(); chave.Append(((int)ufEmitente).ToString("D2")) .Append(dataEmissao.ToString("yyMM")) - .Append(cnpjEmitente) + .Append(documentoEmitente) .Append(((int)modelo).ToString("D2")) .Append(serie.ToString("D3")) .Append(numero.ToString("D9")) @@ -95,8 +103,8 @@ private static string ObterDigitoVerificador(string chave) //percorrendo cada caractere da chave da direita para esquerda para fazer os cálculos com o peso for (var i = chave.Length - 1; i != -1; i--) { - var ch = Convert.ToInt32(chave[i].ToString()); - soma += ch*peso; + var valorCaractere = ObterValorDoCaractere(chave[i]); + soma += valorCaractere * peso; //sempre que for 9 voltamos o peso a 2 if (peso < 9) peso += 1; @@ -115,6 +123,23 @@ private static string ObterDigitoVerificador(string chave) return dv.ToString(); } + /// + /// Obtém o valor numérico de um caractere da chave para o cálculo do dígito verificador, + /// conforme a NT Conjunta 2025.001: valor = código ASCII - 48 ('0'-'9' => 0 a 9; 'A'-'Z' => 17 a 42) + /// + /// + /// + internal static int ObterValorDoCaractere(char caractere) + { + // A chave admite somente dígitos e letras maiúsculas; qualquer outro caractere + // (minúsculas, símbolos, ASCII 58-64) produziria um DV errado sem nenhum erro. + if ((caractere < '0' || caractere > '9') && (caractere < 'A' || caractere > 'Z')) + throw new ArgumentException( + string.Format("Caractere inválido na chave do DF-e: '{0}'. São aceitos somente dígitos (0-9) e letras maiúsculas (A-Z).", caractere)); + + return caractere - '0'; + } + /// /// Informa se a chave de um DF-e é válida /// diff --git a/DFe.Utils/CnpjFiscal.cs b/DFe.Utils/CnpjFiscal.cs new file mode 100644 index 000000000..27bbd6b5a --- /dev/null +++ b/DFe.Utils/CnpjFiscal.cs @@ -0,0 +1,73 @@ +using System; +using System.Linq; +using System.Text.RegularExpressions; + +namespace DFe.Utils +{ + /// + /// Classe com métodos para tratamento do CNPJ, incluindo o CNPJ alfanumérico da NT Conjunta 2025.001 + /// (12 posições [A-Z0-9] + 2 dígitos verificadores numéricos) + /// + public static class CnpjFiscal + { + private static readonly Regex FormatoCnpj = new Regex("^[A-Z0-9]{12}[0-9]{2}$", RegexOptions.Compiled); + private static readonly Regex FormatoBaseCnpj = new Regex("^[A-Z0-9]{12}$", RegexOptions.Compiled); + + /// + /// Calcula os dois dígitos verificadores para as 12 primeiras posições de um CNPJ, + /// conforme a NT Conjunta 2025.001: módulo 11 sobre o valor de cada caractere (código ASCII - 48), + /// com pesos de 2 a 9 aplicados da direita para a esquerda + /// + /// 12 primeiras posições do CNPJ ([A-Z0-9]{12}) + /// Os dois dígitos verificadores, ex.: "93" + public static string ObterDigitosVerificadores(string cnpjBase) + { + if (cnpjBase == null) + throw new ArgumentNullException("cnpjBase"); + + if (!FormatoBaseCnpj.IsMatch(cnpjBase)) + throw new ArgumentException( + string.Format("A base do CNPJ deve ter 12 posições contendo somente dígitos e letras maiúsculas; valor informado: \"{0}\".", cnpjBase), + "cnpjBase"); + + var dv1 = CalcularDigito(cnpjBase); + var dv2 = CalcularDigito(cnpjBase + dv1); + + return string.Concat(dv1, dv2); + } + + /// + /// Informa se um CNPJ de 14 posições é válido: formato [A-Z0-9]{12}[0-9]{2}, + /// dígitos verificadores corretos e diferente do CNPJ zerado (vedado pela NT Conjunta 2025.001) + /// + /// CNPJ com 14 posições, sem máscara + public static bool Valido(string cnpj) + { + if (string.IsNullOrEmpty(cnpj) || !FormatoCnpj.IsMatch(cnpj)) + return false; + + //CNPJ zerado tem dígitos verificadores que conferem, mas é vedado + if (cnpj.All(c => c == '0')) + return false; + + return cnpj.Substring(12, 2) == ObterDigitosVerificadores(cnpj.Substring(0, 12)); + } + + private static int CalcularDigito(string valor) + { + var soma = 0; + var peso = 2; + + //pesos de 2 a 9, aplicados da direita para a esquerda + for (var i = valor.Length - 1; i != -1; i--) + { + //NT Conjunta 2025.001: valor do caractere = código ASCII - 48 ('0'-'9' => 0 a 9; 'A'-'Z' => 17 a 42) + soma += (valor[i] - '0') * peso; + peso = peso == 9 ? 2 : peso + 1; + } + + var resto = soma % 11; + return resto < 2 ? 0 : 11 - resto; + } + } +} diff --git a/DFe.Utils/ConfiguracaoCertificado.cs b/DFe.Utils/ConfiguracaoCertificado.cs index 158e28bf5..28ad75948 100644 --- a/DFe.Utils/ConfiguracaoCertificado.cs +++ b/DFe.Utils/ConfiguracaoCertificado.cs @@ -61,9 +61,11 @@ public class ConfiguracaoCertificado private string _cacheId; private byte[] _arrayBytesArquivo; private X509KeyStorageFlags _keyStorageFlags; + private StoreLocation _storeLocation; public ConfiguracaoCertificado() { + StoreLocation = StoreLocation.CurrentUser; KeyStorageFlags = X509KeyStorageFlags.MachineKeySet; SignatureMethodSignedXml = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; DigestMethodReference = "http://www.w3.org/2000/09/xmldsig#sha1"; @@ -195,5 +197,19 @@ public X509KeyStorageFlags KeyStorageFlags _keyStorageFlags = value; } } + + /// + /// + /// + public StoreLocation StoreLocation + { + get { return _storeLocation; } + set + { + if (value == _storeLocation) + return; + _storeLocation = value; + } + } } } diff --git a/DFe.Utils/FuncoesXml.cs b/DFe.Utils/FuncoesXml.cs index da5964da1..839f1d882 100644 --- a/DFe.Utils/FuncoesXml.cs +++ b/DFe.Utils/FuncoesXml.cs @@ -117,6 +117,11 @@ public static T ArquivoXmlParaClasse(string arquivo, bool ignorarOrdenacaoEle serializador = BuscarNoCache(keyNomeClasseEmUso, typeof(T)); } + if(arquivo.Contains("../") || arquivo.Contains("..\\")) + { + throw new Exception("Caminho do arquivo não pode conter ../ ou ..\\"); + } + var stream = new FileStream(arquivo, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); try { diff --git a/DFe.Utils/Properties/AssemblyInfo.cs b/DFe.Utils/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..9d397211c --- /dev/null +++ b/DFe.Utils/Properties/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("NFe.Utils.Testes")] diff --git a/Dev.VersaoAssemblies/ProgramMain.cs b/Dev.VersaoAssemblies/ProgramMain.cs index 2aa1df619..bf24f0c8b 100644 --- a/Dev.VersaoAssemblies/ProgramMain.cs +++ b/Dev.VersaoAssemblies/ProgramMain.cs @@ -91,6 +91,11 @@ private static void FazerAlteracaoDasVersoes(string versaoString) private static void AlterarVersaoDoAssembly(string infoFile, string versaoString) { + if(infoFile.Contains("../") || infoFile.Contains("..\\")) + { + throw new Exception("Caminho do arquivo não pode conter ../ ou ..\\"); + } + var content = File.ReadAllText(infoFile); var regexVersion = new Regex("assembly: AssemblyVersion.+\\)", RegexOptions.IgnoreCase); diff --git a/MDFe.Damdfe.OpenFast/MDFe.Damdfe.OpenFast.csproj b/MDFe.Damdfe.OpenFast/MDFe.Damdfe.OpenFast.csproj index ee560f9ba..5cc9fd5ba 100644 --- a/MDFe.Damdfe.OpenFast/MDFe.Damdfe.OpenFast.csproj +++ b/MDFe.Damdfe.OpenFast/MDFe.Damdfe.OpenFast.csproj @@ -5,11 +5,16 @@ - + + + + + + diff --git a/MDFe.Servicos/EventosMDFe/Contratos/IServicoController.cs b/MDFe.Servicos/EventosMDFe/Contratos/IServicoController.cs index 161ea4685..4f523579b 100644 --- a/MDFe.Servicos/EventosMDFe/Contratos/IServicoController.cs +++ b/MDFe.Servicos/EventosMDFe/Contratos/IServicoController.cs @@ -42,5 +42,7 @@ namespace MDFe.Servicos.EventosMDFe.Contratos public interface IServicoController { MDFeRetEventoMDFe Executar(MDFeEletronico mdfe, byte sequenciaEvento, MDFeEventoContainer eventoContainer, MDFeTipoEvento tipoEvento, MDFeConfiguracao cfgMdfe = null); + + MDFeRetEventoMDFe Executar(MDFeComandoEvento comando, MDFeEventoContainer eventoContainer, MDFeTipoEvento tipoEvento, MDFeConfiguracao cfgMdfe = null); } } \ No newline at end of file diff --git a/MDFe.Servicos/EventosMDFe/EventoCancelar.cs b/MDFe.Servicos/EventosMDFe/EventoCancelar.cs index 4a9f55e5c..b74350df5 100644 --- a/MDFe.Servicos/EventosMDFe/EventoCancelar.cs +++ b/MDFe.Servicos/EventosMDFe/EventoCancelar.cs @@ -51,5 +51,12 @@ public MDFeRetEventoMDFe MDFeEventoCancelar(MDFeEletronico mdfe, byte sequenciaE return retorno; } + + public MDFeRetEventoMDFe MDFeEventoCancelar(MDFeComandoCancelamento comando, MDFeConfiguracao cfgMdfe = null) + { + var config = cfgMdfe ?? MDFeConfiguracao.Instancia; + var evento = ClassesFactory.CriaEvCancMDFe(comando.Protocolo, comando.Justificativa); + return new ServicoController().Executar(comando, evento, MDFeTipoEvento.Cancelamento, config); + } } } \ No newline at end of file diff --git a/MDFe.Servicos/EventosMDFe/EventoEncerramento.cs b/MDFe.Servicos/EventosMDFe/EventoEncerramento.cs index e7de8b41c..1ae049cba 100644 --- a/MDFe.Servicos/EventosMDFe/EventoEncerramento.cs +++ b/MDFe.Servicos/EventosMDFe/EventoEncerramento.cs @@ -63,5 +63,12 @@ public MDFeRetEventoMDFe MDFeEventoEncerramento(MDFeEletronico mdfe, Estado esta return retorno; } + + public MDFeRetEventoMDFe MDFeEventoEncerramento(MDFeComandoEncerramento comando, MDFeConfiguracao cfgMdfe = null) + { + var config = cfgMdfe ?? MDFeConfiguracao.Instancia; + var evento = ClassesFactory.CriaEvEncMDFe(comando.EstadoEncerramento, comando.CodigoMunicipioEncerramento, comando.Protocolo); + return new ServicoController().Executar(comando, evento, MDFeTipoEvento.Encerramento, config); + } } } \ No newline at end of file diff --git a/MDFe.Servicos/EventosMDFe/EventoInclusaoCondutor.cs b/MDFe.Servicos/EventosMDFe/EventoInclusaoCondutor.cs index 32d640724..c3798ff2a 100644 --- a/MDFe.Servicos/EventosMDFe/EventoInclusaoCondutor.cs +++ b/MDFe.Servicos/EventosMDFe/EventoInclusaoCondutor.cs @@ -46,10 +46,14 @@ public MDFeRetEventoMDFe MDFeEventoIncluirCondutor(MDFeEletronico mdfe, byte seq var config = cfgMdfe ?? MDFeConfiguracao.Instancia; var incluirCodutor = ClassesFactory.CriaEvIncCondutorMDFe(nome, cpf); + return new ServicoController().Executar(mdfe, sequenciaEvento, incluirCodutor, MDFeTipoEvento.InclusaoDeCondutor, config); + } - var retorno = new ServicoController().Executar(mdfe, sequenciaEvento, incluirCodutor, MDFeTipoEvento.InclusaoDeCondutor, config); - - return retorno; + public MDFeRetEventoMDFe MDFeEventoIncluirCondutor(MDFeComandoInclusaoCondutor comando, MDFeConfiguracao cfgMdfe = null) + { + var config = cfgMdfe ?? MDFeConfiguracao.Instancia; + var evento = ClassesFactory.CriaEvIncCondutorMDFe(comando.Nome, comando.CpfCondutor); + return new ServicoController().Executar(comando, evento, MDFeTipoEvento.InclusaoDeCondutor, config); } } } \ No newline at end of file diff --git a/MDFe.Servicos/EventosMDFe/EventoInclusaoDFe.cs b/MDFe.Servicos/EventosMDFe/EventoInclusaoDFe.cs index 9dd35c33c..953f86882 100644 --- a/MDFe.Servicos/EventosMDFe/EventoInclusaoDFe.cs +++ b/MDFe.Servicos/EventosMDFe/EventoInclusaoDFe.cs @@ -49,8 +49,14 @@ public MDFeRetEventoMDFe MDFeEventoIncluirDFe(MDFeEletronico mdfe, byte sequenci var config = cfgMdfe ?? MDFeConfiguracao.Instancia; var inclusao = ClassesFactory.CriaEvIncDFeMDFe(protocolo, codigoMunicipioCarregamento, nomeMunicipioCarregamento, informacoesDocumentos); - return new ServicoController().Executar(mdfe, sequenciaEvento, inclusao, MDFeTipoEvento.InclusaoDFe, config); } + + public MDFeRetEventoMDFe MDFeEventoIncluirDFe(MDFeComandoInclusaoDFe comando, MDFeConfiguracao cfgMdfe = null) + { + var config = cfgMdfe ?? MDFeConfiguracao.Instancia; + var evento = ClassesFactory.CriaEvIncDFeMDFe(comando.Protocolo, comando.CodigoMunicipioCarregamento, comando.NomeMunicipioCarregamento, comando.InformacoesDocumentos); + return new ServicoController().Executar(comando, evento, MDFeTipoEvento.InclusaoDFe, config); + } } } \ No newline at end of file diff --git a/MDFe.Servicos/EventosMDFe/EventoPagamentoOperacao.cs b/MDFe.Servicos/EventosMDFe/EventoPagamentoOperacao.cs index 26e27ef71..21ba82430 100644 --- a/MDFe.Servicos/EventosMDFe/EventoPagamentoOperacao.cs +++ b/MDFe.Servicos/EventosMDFe/EventoPagamentoOperacao.cs @@ -47,15 +47,18 @@ public MDFeRetEventoMDFe MDFeEventoPagamentoOperacao(Classes.Informacoes.MDFe md { var config = cfgMdfe ?? MDFeConfiguracao.Instancia; - var eventoPagamento = ClassesFactory.CriaEvPagtoOperMDFe( - protocolo, - infViagens, - infPagamentos - ); + var eventoPagamento = ClassesFactory.CriaEvPagtoOperMDFe(protocolo, infViagens, infPagamentos); var retorno = new ServicoController().Executar(mdfe, sequencia, eventoPagamento, MDFeTipoEvento.PagamentoOperacaoMDFe, config); return retorno; } + + public MDFeRetEventoMDFe MDFeEventoPagamentoOperacao(MDFeComandoPagamentoOperacao comando, MDFeConfiguracao cfgMdfe = null) + { + var config = cfgMdfe ?? MDFeConfiguracao.Instancia; + var evento = ClassesFactory.CriaEvPagtoOperMDFe(comando.Protocolo, comando.InfViagens, comando.Pagamentos); + return new ServicoController().Executar(comando, evento, MDFeTipoEvento.PagamentoOperacaoMDFe, config); + } } } \ No newline at end of file diff --git a/MDFe.Servicos/EventosMDFe/FactoryEvento.cs b/MDFe.Servicos/EventosMDFe/FactoryEvento.cs index f566c4bf0..416ae76a4 100644 --- a/MDFe.Servicos/EventosMDFe/FactoryEvento.cs +++ b/MDFe.Servicos/EventosMDFe/FactoryEvento.cs @@ -78,5 +78,40 @@ public static MDFeEventoMDFe CriaEvento(MDFeEletronico MDFe, MDFeTipoEvento tipo return eventoMDFe; } + + public static MDFeEventoMDFe CriaEvento(MDFeComandoEvento comando, MDFeTipoEvento tipoEvento, MDFeEventoContainer evento, MDFeConfiguracao cfgMdfe = null) + { + var config = cfgMdfe ?? MDFeConfiguracao.Instancia; + var eventoMDFe = new MDFeEventoMDFe + { + Versao = config.VersaoWebService.VersaoLayout, + InfEvento = new MDFeInfEvento(config.VersaoWebService.VersaoLayout) + { + Id = "ID" + (long)tipoEvento + comando.Chave + comando.SequenciaEvento.ToString("D2"), + TpAmb = config.VersaoWebService.TipoAmbiente, + COrgao = comando.UfEmitente, + ChMDFe = comando.Chave, + DetEvento = new MDFeDetEvento + { + VersaoServico = config.VersaoWebService.VersaoLayout, + EventoContainer = evento + }, + DhEvento = DateTime.Now, + NSeqEvento = comando.SequenciaEvento, + TpEvento = tipoEvento + } + }; + + eventoMDFe.InfEvento.CNPJ = comando.CnpjEmitente; + + if (!string.IsNullOrEmpty(comando.CpfEmitente)) + { + eventoMDFe.InfEvento.CPF = comando.CpfEmitente; + } + + eventoMDFe.Assinar(config); + + return eventoMDFe; + } } } \ No newline at end of file diff --git a/MDFe.Servicos/EventosMDFe/MDFeComandoCancelamento.cs b/MDFe.Servicos/EventosMDFe/MDFeComandoCancelamento.cs new file mode 100644 index 000000000..f93c59411 --- /dev/null +++ b/MDFe.Servicos/EventosMDFe/MDFeComandoCancelamento.cs @@ -0,0 +1,11 @@ +namespace MDFe.Servicos.EventosMDFe +{ + /// + /// Dados para emitir o evento de cancelamento de MDFe. + /// + public class MDFeComandoCancelamento : MDFeComandoEvento + { + public string Protocolo { get; set; } + public string Justificativa { get; set; } + } +} \ No newline at end of file diff --git a/MDFe.Servicos/EventosMDFe/MDFeComandoEncerramento.cs b/MDFe.Servicos/EventosMDFe/MDFeComandoEncerramento.cs new file mode 100644 index 000000000..91c165bb9 --- /dev/null +++ b/MDFe.Servicos/EventosMDFe/MDFeComandoEncerramento.cs @@ -0,0 +1,14 @@ +using DFe.Classes.Entidades; + +namespace MDFe.Servicos.EventosMDFe +{ + /// + /// Dados para emitir o evento de encerramento de MDFe. + /// + public class MDFeComandoEncerramento : MDFeComandoEvento + { + public string Protocolo { get; set; } + public Estado EstadoEncerramento { get; set; } + public long CodigoMunicipioEncerramento { get; set; } + } +} \ No newline at end of file diff --git a/MDFe.Servicos/EventosMDFe/MDFeComandoEvento.cs b/MDFe.Servicos/EventosMDFe/MDFeComandoEvento.cs new file mode 100644 index 000000000..5c3d60faa --- /dev/null +++ b/MDFe.Servicos/EventosMDFe/MDFeComandoEvento.cs @@ -0,0 +1,18 @@ +using DFe.Classes.Entidades; + +namespace MDFe.Servicos.EventosMDFe +{ + /// + /// Base abstrata com os dados mínimos necessários + /// para emitir um evento de MDFe sem depender + /// do objeto "" completo. + /// + public abstract class MDFeComandoEvento + { + public string Chave { get; set; } + public Estado UfEmitente { get; set; } + public string CnpjEmitente { get; set; } + public string CpfEmitente { get; set; } + public byte SequenciaEvento { get; set; } + } +} \ No newline at end of file diff --git a/MDFe.Servicos/EventosMDFe/MDFeComandoInclusaoCondutor.cs b/MDFe.Servicos/EventosMDFe/MDFeComandoInclusaoCondutor.cs new file mode 100644 index 000000000..80dd508f1 --- /dev/null +++ b/MDFe.Servicos/EventosMDFe/MDFeComandoInclusaoCondutor.cs @@ -0,0 +1,11 @@ +namespace MDFe.Servicos.EventosMDFe +{ + /// + /// Dados para emitir o evento de inclusão de condutor no MDFe. + /// + public class MDFeComandoInclusaoCondutor : MDFeComandoEvento + { + public string Nome { get; set; } + public string CpfCondutor { get; set; } + } +} \ No newline at end of file diff --git a/MDFe.Servicos/EventosMDFe/MDFeComandoInclusaoDFe.cs b/MDFe.Servicos/EventosMDFe/MDFeComandoInclusaoDFe.cs new file mode 100644 index 000000000..aa4dcda39 --- /dev/null +++ b/MDFe.Servicos/EventosMDFe/MDFeComandoInclusaoDFe.cs @@ -0,0 +1,16 @@ +using MDFe.Classes.Informacoes.Evento.CorpoEvento; +using System.Collections.Generic; + +namespace MDFe.Servicos.EventosMDFe +{ + /// + /// Dados para emitir o evento de inclusão de DF-e no MDFe. + /// + public class MDFeComandoInclusaoDFe : MDFeComandoEvento + { + public string Protocolo { get; set; } + public string CodigoMunicipioCarregamento { get; set; } + public string NomeMunicipioCarregamento { get; set; } + public List InformacoesDocumentos { get; set; } + } +} \ No newline at end of file diff --git a/MDFe.Servicos/EventosMDFe/MDFeComandoPagamentoOperacao.cs b/MDFe.Servicos/EventosMDFe/MDFeComandoPagamentoOperacao.cs new file mode 100644 index 000000000..5e3615fd1 --- /dev/null +++ b/MDFe.Servicos/EventosMDFe/MDFeComandoPagamentoOperacao.cs @@ -0,0 +1,15 @@ +using MDFe.Classes.Informacoes; +using System.Collections.Generic; + +namespace MDFe.Servicos.EventosMDFe +{ + /// + /// Dados para emitir o evento de pagamento de operação de transporte. + /// + public class MDFeComandoPagamentoOperacao : MDFeComandoEvento + { + public string Protocolo { get; set; } + public MDFeInfViagens InfViagens { get; set; } + public List Pagamentos { get; set; } + } +} \ No newline at end of file diff --git a/MDFe.Servicos/EventosMDFe/ServicoController.cs b/MDFe.Servicos/EventosMDFe/ServicoController.cs index 72bf4a0c7..5a32c60f0 100644 --- a/MDFe.Servicos/EventosMDFe/ServicoController.cs +++ b/MDFe.Servicos/EventosMDFe/ServicoController.cs @@ -67,5 +67,22 @@ public MDFeRetEventoMDFe Executar(MDFeEletronico mdfe, byte sequenciaEvento, MDF return retorno; } + + public MDFeRetEventoMDFe Executar(MDFeComandoEvento comando, MDFeEventoContainer eventoContainer, MDFeTipoEvento tipoEvento, MDFeConfiguracao cfgMdfe = null) + { + var config = cfgMdfe ?? MDFeConfiguracao.Instancia; + var evento = FactoryEvento.CriaEvento(comando, tipoEvento, eventoContainer, config); + + evento.ValidarSchema(config); + evento.SalvarXmlEmDisco(comando.Chave, config); + + var webService = WsdlFactory.CriaWsdlMDFeRecepcaoEvento(config); + var retornoXml = webService.mdfeRecepcaoEvento(evento.CriaXmlRequestWs()); + + var retorno = MDFeRetEventoMDFe.LoadXml(retornoXml.OuterXml, evento); + retorno.SalvarXmlEmDisco(comando.Chave, config); + + return retorno; + } } } \ No newline at end of file diff --git a/MDFe.Servicos/EventosMDFe/ServicoMDFeEvento.cs b/MDFe.Servicos/EventosMDFe/ServicoMDFeEvento.cs index 653dae482..78b9a3fa1 100644 --- a/MDFe.Servicos/EventosMDFe/ServicoMDFeEvento.cs +++ b/MDFe.Servicos/EventosMDFe/ServicoMDFeEvento.cs @@ -54,6 +54,11 @@ public MDFeRetEventoMDFe MDFeEventoIncluirCondutor( return eventoIncluirCondutor.MDFeEventoIncluirCondutor(mdfe, sequenciaEvento, nome, cpf, config); } + public MDFeRetEventoMDFe MDFeEventoIncluirCondutor(MDFeComandoInclusaoCondutor cmd, MDFeConfiguracao cfgMdfe = null) + { + return new EventoInclusaoCondutor().MDFeEventoIncluirCondutor(cmd, cfgMdfe); + } + public MDFeRetEventoMDFe MDFeEventoIncluirDFe( MDFeEletronica mdfe, byte sequenciaEvento, string protocolo, string codigoMunicipioCarregamento, string nomeMunicipioCarregamento, List informacoesDocumentos, @@ -66,6 +71,11 @@ public MDFeRetEventoMDFe MDFeEventoIncluirDFe( return eventoIncluirDFe.MDFeEventoIncluirDFe(mdfe, sequenciaEvento, protocolo, codigoMunicipioCarregamento, nomeMunicipioCarregamento, informacoesDocumentos, config); } + public MDFeRetEventoMDFe MDFeEventoIncluirDFe(MDFeComandoInclusaoDFe cmd, MDFeConfiguracao cfgMdfe = null) + { + return new EventoInclusaoDFe().MDFeEventoIncluirDFe(cmd, cfgMdfe); + } + public MDFeRetEventoMDFe MDFeEventoEncerramentoMDFeEventoEncerramento(MDFeEletronica mdfe, byte sequenciaEvento, string protocolo, MDFeConfiguracao cfgMdfe = null) { var config = cfgMdfe ?? MDFeConfiguracao.Instancia; @@ -85,6 +95,11 @@ public MDFeRetEventoMDFe MDFeEventoEncerramentoMDFeEventoEncerramento(MDFeEletro return eventoEncerramento.MDFeEventoEncerramento(mdfe, estadoEncerramento, codigoMunicipioEncerramento, sequenciaEvento, protocolo, config); } + public MDFeRetEventoMDFe MDFeEventoEncerramentoMDFeEventoEncerramento(MDFeComandoEncerramento cmd, MDFeConfiguracao cfgMdfe = null) + { + return new EventoEncerramento().MDFeEventoEncerramento(cmd, cfgMdfe); + } + public MDFeRetEventoMDFe MDFeEventoCancelar(MDFeEletronica mdfe, byte sequenciaEvento, string protocolo, string justificativa, MDFeConfiguracao cfgMdfe = null) { @@ -95,6 +110,11 @@ public MDFeRetEventoMDFe MDFeEventoCancelar(MDFeEletronica mdfe, byte sequenciaE return eventoCancelamento.MDFeEventoCancelar(mdfe, sequenciaEvento, protocolo, justificativa, config); } + public MDFeRetEventoMDFe MDFeEventoCancelar(MDFeComandoCancelamento cmd, MDFeConfiguracao cfgMdfe = null) + { + return new EventoCancelar().MDFeEventoCancelar(cmd, cfgMdfe); + } + public MDFeRetEventoMDFe MDFeEventoPagamentoOperacaoTransporte(MDFeEletronica mdfe, byte sequenciaEvneto, string protocolo, MDFeInfViagens infViagens, List infPagamentos, MDFeConfiguracao cfgMdfe = null) { @@ -105,5 +125,10 @@ public MDFeRetEventoMDFe MDFeEventoPagamentoOperacaoTransporte(MDFeEletronica md return eventoPagamentoOperacao.MDFeEventoPagamentoOperacao(mdfe, sequenciaEvneto, protocolo, infViagens, infPagamentos, config); } + + public MDFeRetEventoMDFe MDFeEventoPagamentoOperacaoTransporte(MDFeComandoPagamentoOperacao cmd, MDFeConfiguracao cfgMdfe = null) + { + return new EventoPagamentoOperacao().MDFeEventoPagamentoOperacao(cmd, cfgMdfe); + } } } \ No newline at end of file diff --git a/MDFe.Utils/Validacao/Validador.cs b/MDFe.Utils/Validacao/Validador.cs index 07b0d4961..fa566f4b4 100644 --- a/MDFe.Utils/Validacao/Validador.cs +++ b/MDFe.Utils/Validacao/Validador.cs @@ -54,6 +54,10 @@ public static void Valida(string xml, string schema, MDFeConfiguracao cfgMdfe = // Define o tipo de validação var cfg = new XmlReaderSettings { ValidationType = ValidationType.Schema }; + // Previne ataques XXE: nao permite resolver recursos externos + cfg.DtdProcessing = DtdProcessing.Prohibit; + cfg.XmlResolver = null; + // Carrega o arquivo de esquema var schemas = new XmlSchemaSet(); schemas.XmlResolver = new XmlUrlResolver(); diff --git a/NFe.AppTeste/MainWindow.xaml.cs b/NFe.AppTeste/MainWindow.xaml.cs index ecf695959..38b287f21 100644 --- a/NFe.AppTeste/MainWindow.xaml.cs +++ b/NFe.AppTeste/MainWindow.xaml.cs @@ -1870,7 +1870,8 @@ protected virtual dest GetDestinatario(VersaoServico versao, ModeloDocumento mod { var dest = new dest(versao) { - CNPJ = "99999999000191", + CNPJ = "0ZEN3MS8000127", + //CNPJ = "99999999000191", //CPF = "99999999999", }; dest.xNome = "NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL"; //Obrigatório para NFe e opcional para NFCe @@ -2106,11 +2107,11 @@ protected virtual det GetDetalhe(int i, CRT crt, ModeloDocumento modelo) { qTrib = 1, uTrib = "PC", - pISEspec = 0, + adRemIS = 0, pIS = 0, vIS = 0, cClassTribIS = "000001", - CSTIS = CSTIS.Is000, + CSTIS = "000", vBCIS = 0, } : null, @@ -2593,18 +2594,15 @@ private void BtnAdminCsc_Click(object sender, RoutedEventArgs e) var raizCnpj = Funcoes.InpuBox( this, "Administração do CSC", - "Raiz do CNPJ do contribuinte que está efetuando a consulta (oito primeiros dígitos do CNPJ):" + "Raiz do CNPJ do contribuinte que está efetuando a consulta (oito primeiras posições do CNPJ):" ); if (string.IsNullOrEmpty(raizCnpj)) throw new Exception("A Raiz do CNPJ do contribuinte deve ser informada!"); - long l; - var longo = long.TryParse(raizCnpj, out l); - if (!longo) + //NT Conjunta 2025.001: o CNPJ pode ser alfanumérico nas 12 primeiras posições + if (!System.Text.RegularExpressions.Regex.IsMatch(raizCnpj, "^[0-9A-Z]{8}$")) throw new Exception( - "A Raiz do CNPJ do contribuinte deve conter apenas números!" + "A Raiz do CNPJ do contribuinte deve conter 8 caracteres, apenas números e letras maiúsculas!" ); - if (raizCnpj.Length != 8) - throw new Exception("A Raiz do CNPJ do contribuinte deve conter 8 caracteres!"); var idCsc = ""; var codigoCsc = ""; diff --git a/NFe.AppTeste/NFe.AppTeste.csproj b/NFe.AppTeste/NFe.AppTeste.csproj index af1c6380c..373bce9ee 100644 --- a/NFe.AppTeste/NFe.AppTeste.csproj +++ b/NFe.AppTeste/NFe.AppTeste.csproj @@ -119,10 +119,6 @@ Settings.Designer.cs - - Designer - Always - Designer Always @@ -139,10 +135,6 @@ Designer Always - - Designer - Always - Designer Always @@ -163,18 +155,10 @@ Designer Always - - Designer - Always - Designer Always - - Designer - Always - Designer Always @@ -357,10 +341,6 @@ Designer Always - - Designer - Always - Designer Always @@ -485,10 +465,6 @@ Designer Always - - Designer - Always - Designer Always @@ -509,10 +485,6 @@ Designer Always - - Designer - Always - Designer Always @@ -537,10 +509,6 @@ Designer Always - - Designer - Always - Designer Always @@ -553,10 +521,6 @@ Designer Always - - Designer - Always - Designer Always @@ -781,10 +745,6 @@ Designer Always - - Designer - Always - Designer Always @@ -797,18 +757,10 @@ Designer Always - - Designer - Always - Designer Always - - Designer - Always - Designer Always @@ -857,10 +809,6 @@ Designer Always - - Designer - Always - Designer Always diff --git a/NFe.AppTeste/Schemas/DFeTiposBasicos_v1.00.xsd b/NFe.AppTeste/Schemas/DFeTiposBasicos_v1.00.xsd index a5051dd02..d204e4061 100644 --- a/NFe.AppTeste/Schemas/DFeTiposBasicos_v1.00.xsd +++ b/NFe.AppTeste/Schemas/DFeTiposBasicos_v1.00.xsd @@ -1,6 +1,16 @@ + + + Tipo Chave de Documento Fiscal Eletrônico + + + + + + + Tipo string genérico @@ -55,6 +65,24 @@ + + + Tipo CNPJ Base + + + + + + + + + Tipo CNPJ + + + + + + Tipo Decimal com 15 dígitos, sendo 13 de corpo e 2 decimais @@ -81,6 +109,23 @@ + + + + + + + Tipo de Receita Bruta do SN + + + + + + + + + + @@ -93,6 +138,8 @@ + + @@ -115,6 +162,14 @@ + + + Ano e mês referência do período de apuração (AAAA-MM) + + + + + Grupo de informações da Tributação da NFCom @@ -163,6 +218,26 @@ + + + Grupo de informações da Tributação da NFGas + + + + + Código Situação Tributária do IBS/CBS + + + + + + + + Informado conforme indicador no cClassTrib + + + + Grupo de informações da Tributação da NFAg @@ -240,7 +315,7 @@ - + @@ -262,7 +337,7 @@ - + Informar essa opção da Choice para Monofasia (CST 620) @@ -298,33 +373,6 @@ - - - Grupo de informações da Tributação da NFGas - - - - - Código Situação Tributária do IBS/CBS - - - - - - - - - Informar essa opção da Choice para Monofasia - - - - - - Informado conforme indicador no cClassTrib - - - - Grupo de informações do Imposto Seletivo @@ -347,7 +395,7 @@ Alíquota do Imposto Seletivo (percentual) - + Alíquota do Imposto Seletivo (por valor) @@ -949,6 +997,152 @@ Grupo de campos da redução de aliquota + + + Grupo de operações em áreas incentivadas (ALC/ZFM) - CBS (alíquota zero) + Grupo de informações para identificação de operações em áreas incentivadas (ALC/ZFM) com alíquota zero da CBS, conforme arts. 451 e 466 da LC 214/2025, quando fornecedor e destinatário estiverem nessas áreas, distinguindo a existência de processo aprovado na Suframa. + + + + + Valor da CBS + + + + + + + + Grupo de informações da Tributação Regular. Informar como seria a tributação caso não cumprida a condição resolutória/suspensiva. Exemplo 1: Art. 442, §4. Operações com ZFM e ALC. Exemplo 2: Operações com suspensão do tributo. + + + + + Grupo de informações da composição do valor do IBS e da CBS em compras governamental + + + + + + + Tipo CBS IBS Completo NFe + + + + IBS / CBS + + + + Valor do BC + + + + + + Grupo de informações do IBS na UF + + + + + + Aliquota do IBS de competência das UF (em percentual) + + + + + Grupo de campos do Diferimento + + + + + Grupo de Informações da devolução de tributos + + + + + Grupo de campos da redução de aliquota + + + + + Valor do IBS de competência das UF + + + + + + + + Grupo de Informações do IBS no Município + + + + + + Aliquota do IBS Municipal (em percentual) + + + + + Grupo de campos do Diferimento + + + + + Grupo de Informações da devolução de tributos + + + + + Grupo de campos da redução de aliquota + + + + + Valor do IBS Municipal + + + + + + + + Valor do IBS + + + + + + Grupo de Tributação da CBS + + + + + + Aliquota da CBS (em percentual) + + + + + Grupo de campos do Diferimento + + + + + Grupo de Informações da devolução de tributos + + + + + Grupo de campos da redução de aliquota + + + + + Grupo de operações em áreas incentivadas (ALC/ZFM) - CBS (alíquota zero) + Grupo de informações para identificação de operações em áreas incentivadas (ALC/ZFM) com alíquota zero da CBS, conforme arts. 451 e 466 da LC 214/2025, quando fornecedor e destinatário estiverem nessas áreas, distinguindo a existência de processo aprovado na Suframa. + + Valor da CBS @@ -1032,10 +1226,14 @@ Tipo Devolução Tributo + + + Percentual de devolução do tributo, conforme LC 214/25 art. 118. + + - Valor do tributo devolvido. No fornecimento de energia elétrica, água, esgoto e -gás natural e em outras hipóteses definidas no regulamento + Valor do tributo devolvido ("cashback" de desconto na própria Nota Fiscal / Fatura) @@ -1131,7 +1329,9 @@ gás natural e em outras hipóteses definidas no regulamento 1=União 2=Estados 3=Distrito Federal -4=Municípios +4=Municípios +5=Consórcio Público +6=Comitê Gestor do IBS @@ -1139,6 +1339,29 @@ gás natural e em outras hipóteses definidas no regulamento Percentual de redução de aliquota em compra governamental + + + Tipo da operação com ente governamental: +1 – Fornecimento com pagamento posterior; + +2 - Recebimento do pagamento com fornecimento já realizado; + +3 – Fornecimento com pagamento já realizado; + +4 – Recebimento do pagamento com fornecimento posterior; + + + + + Chave de acesso do documento fiscal anterior. + +Deverá ser informado para tpOperGov 2 e 3 e vedado para os tipos 1 e 4. + +No caso do tpOperGov 2 aceitará apenas uma chave referenciada, no tipo 3 poderá aceitar múltiplas chaves + +Obs: a chave de acesso deverá ser de um emitente com o mesmo CNPJ base + + @@ -1153,19 +1376,49 @@ gás natural e em outras hipóteses definidas no regulamento 1=União 2=Estados 3=Distrito Federal -4=Municípios +4=Municípios +5=Consórcio Público +6=Comitê Gestor do IBS - Percentual de redução de aliquota em compra governamental + Percentual de redução de alíquota em compra governamental Tipo da operação com ente governamental: -1 - Fornecimento -2 - Recebimento do Pagamento +1 – Fornecimento com pagamento posterior; +2 - Recebimento do pagamento com fornecimento já realizado; +3 – Fornecimento com pagamento já realizado; +4 – Recebimento do pagamento com fornecimento posterior; + + + + + Chave de acesso do documento fiscal anterior. + +Deverá ser informado para tpOperGov 2 e 3 e vedado para os tipos 1 e 4. + +No caso do tpOperGov 2 aceitará apenas uma chave referenciada, no tipo 3 poderá aceitar múltiplas chaves + +Obs: a chave de acesso deverá ser de um emitente com o mesmo CNPJ base + + + + + + + Tipo Pagamento que ocorre em DFe emitdo anteriormente + Informado para abater as parcelas de antecipação de pagamento, conforme art. 10 §4 + + + + + Chave de acesso do documento fiscal de antecipação de pagamento + +Obs: esse DFe deverá ter o indAntecipacaoPgto marcado no grupo ide @@ -1187,6 +1440,68 @@ gás natural e em outras hipóteses definidas no regulamento + + + Tipo Operações em areas incentivadas com CBS Zero + + + + + Percentual efetivo sem a redução + Alíquota efetiva de referência da CBS aplicável à operação fora de áreas ou regimes incentivados. + + + + + Valor efetivo sem a redução + Valor da CBS calculado para a operação fora de áreas ou regimes incentivado + + + + + + + Tipo Operações em áreas incentivadas (ALC/ZFM) - CBS (alíquota zero) + + + + + Tipo de aplicação da alíquota zero da CBS. + + + + + + + + + + + + Número do processo na Suframa para o item +comercializado. + + + + + + + + + + + Percentual efetivo sem a redução + Alíquota efetiva de referência da CBS aplicável à operação fora de áreas ou regimes incentivados. + + + + + Valor efetivo sem a redução + Valor da CBS calculado para a operação fora de áreas ou regimes incentivado + + + + Tipo Estorno de Crédito @@ -1204,14 +1519,6 @@ gás natural e em outras hipóteses definidas no regulamento - - - Ano e mês referência do período de apuração (AAAA-MM) - - - - - Tipo Ajuste de Competência diff --git a/NFe.AppTeste/Schemas/LeiauteCadastroEmissorDFe_v1.01.xsd b/NFe.AppTeste/Schemas/LeiauteCadastroEmissorDFe_v1.01.xsd deleted file mode 100644 index 5852d55df..000000000 --- a/NFe.AppTeste/Schemas/LeiauteCadastroEmissorDFe_v1.01.xsd +++ /dev/null @@ -1,234 +0,0 @@ - - - - - - - Tipo Comunica atualização de cadastro de emissores de DF-e - - - - - Dados Comunica atualização de cadastro de emissores de DF-e - - - - - - sigla da UF solicitante - - - - - - Inclusão de novo Emissor - - - - - Exclui emissor inserido indevidamente - - - - - - Sigla da UF onde o emissor está autorizado a emitir DF-e - - - - - CNPJ do emissor a ser excluído - - - - - - - - - - - - - - - - - Tipo Retorno da atualização de cadastro de emissores de DF-e - - - - - Dados do retorno do processamento daa Comunicção de atualização de cadastro de emissores de DF-e - - - - - - sigla da UF onde o emissor está autorizado a emitir DF-e - - - - - CNPJ do emissor - - - - - operação solicitada: -0 - inclusão; -1 - exclusão. - - - - - - - - - - - Resultado da operação solicitada -0 - operação realizada com sucesso; -1 - Rejeição -mensagem inválida (erro de -Schema); -21- Rejeição - certificado digital não atende o -padrão estabelecido pelo projeto; -22 - Rejeição - certificado digital utilizado na -assinatura revogado; -23 - Rejeição - certificado digital utilizado na -assinatura expirado; -24 - Rejeição - certificado digital utilizado não -pertence a UF solicitante; -25 - Rejeição - assinatura digital inválida; -31 - Rejeição -CNPJ emissor inválido; -32 - Rejeição-CNPJ matriz inválido; -41 - Inclusão não atendida - Já existe um -emissor com o CNPJ informado; -42 - exclusão não atendida - não existe -emissor com CNPJ informado; - - - - - - - - - - - - - - - - - - - - - - - - - - - Tipo Cadastro de emissores de DF-e - - - - - Dados do cadastro de emissores de DF-e - - - - - - Data de publicação da Cadastro - - - - - - - - - - - - - - Tipo Emissor - - - - - sigla da UF onde o emissor está autorizado a emitir DF-e - - - - - CNPJ do Emissor - - - - - CNPJ do Estabelecimento matriz - - - - - IE do emissor - - - - - Documento Fiscal eletrônico autorizado - - - - - - Modelo do documento fiscal autorizado: -55 - NF-e; -99 - uso exclusivo do Fisco para inclusão de -qualquer órgão público no cadastro de -emissores de DFe com objetivo de permitir o -acesso ao WS - CadConsultaCadastro de -Consulta Cadastro de Contribuintes do ICMS -de qualquer unidade federada. - - - - - - - - - - - Situação do emissor: -0 - em homologação -1 - em produção - - - - - - - - - - - - - - - - Tipo Versão do Leiaute 1.01 - - - - - - diff --git a/NFe.AppTeste/Schemas/atuCadEmiDFe_v1.01.xsd b/NFe.AppTeste/Schemas/atuCadEmiDFe_v1.01.xsd deleted file mode 100644 index 833dc31bd..000000000 --- a/NFe.AppTeste/Schemas/atuCadEmiDFe_v1.01.xsd +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - Atualização de Emissor de DF-e - - - diff --git a/NFe.AppTeste/Schemas/cadEmiDFe_v1.01.xsd b/NFe.AppTeste/Schemas/cadEmiDFe_v1.01.xsd deleted file mode 100644 index b7d37f73e..000000000 --- a/NFe.AppTeste/Schemas/cadEmiDFe_v1.01.xsd +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - Cadastro de Emissores de DF-e - - - diff --git a/NFe.AppTeste/Schemas/consDPEC_v1.01.xsd b/NFe.AppTeste/Schemas/consDPEC_v1.01.xsd deleted file mode 100644 index 28459c746..000000000 --- a/NFe.AppTeste/Schemas/consDPEC_v1.01.xsd +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - Schema XML de validação do Pedido de Consulta de Declaração Prévia de Emissão em Contingência - - - diff --git a/NFe.AppTeste/Schemas/consNFeDest_v1.01.xsd b/NFe.AppTeste/Schemas/consNFeDest_v1.01.xsd deleted file mode 100644 index 9782130da..000000000 --- a/NFe.AppTeste/Schemas/consNFeDest_v1.01.xsd +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - Schema de validação XML dp Pedido de Consulta de NF-e - - - diff --git a/NFe.AppTeste/Schemas/e790700_v1.00.xsd b/NFe.AppTeste/Schemas/e790700_v1.00.xsd index a99c7b1a7..7a11e4d3b 100644 --- a/NFe.AppTeste/Schemas/e790700_v1.00.xsd +++ b/NFe.AppTeste/Schemas/e790700_v1.00.xsd @@ -42,17 +42,17 @@ - + Data do Embarque no formato AAAA-MM-DDThh:mm:ssTZD - + Data da averbação no formato AAAA-MM-DDThh:mm:ssTZD - + Número Identificador da Declaração Única do Comércio Exterior associada @@ -63,7 +63,7 @@ - + Número do item da NF-e averbada @@ -74,7 +74,7 @@ - + Informação do número do item na Declaração de Exportação associada a averbação. @@ -102,12 +102,32 @@ - - - + + + + + + Grupo de informações do enquadramento do item + + + + + + Código do enquadramento + + + + + + + + + + + @@ -123,3 +143,6 @@ + + + diff --git a/NFe.AppTeste/Schemas/envDPEC_v1.01.xsd b/NFe.AppTeste/Schemas/envDPEC_v1.01.xsd deleted file mode 100644 index a44527277..000000000 --- a/NFe.AppTeste/Schemas/envDPEC_v1.01.xsd +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - Schema XML de validação do Envio da Declaração previa de Emissão em Contingência - - - diff --git a/NFe.AppTeste/Schemas/leiauteAverb_v1.00.xsd b/NFe.AppTeste/Schemas/leiauteAverb_v1.00.xsd index cefca72cf..cc6372a75 100644 --- a/NFe.AppTeste/Schemas/leiauteAverb_v1.00.xsd +++ b/NFe.AppTeste/Schemas/leiauteAverb_v1.00.xsd @@ -10,14 +10,14 @@ - + Código do órgão de recepção do Evento. Para o evento de averbação de exportação será utilizado o valor 91 para o Ambiente Nacional. - + @@ -120,17 +120,17 @@ - + Data do Embarque no formato AAAA-MM-DDThh:mm:ssTZD - + Data da averbação no formato AAAA-MM-DDThh:mm:ssTZD - + Número Identificador da Declaração Única do Comércio Exterior associada @@ -141,7 +141,7 @@ - + Número do item da NF-e averbada @@ -152,7 +152,7 @@ - + Informação do número do item na Declaração de Exportação associada a averbação. @@ -180,12 +180,32 @@ - - - + + + + + + Grupo de informações do enquadramento do item + + + + + + Código do enquadramento + + + + + + + + + + + @@ -442,41 +462,7 @@ - - - Tipo Código de orgão (UF da tabela do IBGE) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + diff --git a/NFe.AppTeste/Schemas/leiauteConsNFeDest_v1.01.xsd b/NFe.AppTeste/Schemas/leiauteConsNFeDest_v1.01.xsd deleted file mode 100644 index 1699410bd..000000000 --- a/NFe.AppTeste/Schemas/leiauteConsNFeDest_v1.01.xsd +++ /dev/null @@ -1,483 +0,0 @@ - - - - - - - Tipo número sequencial único do AN - - - - - - - - Tipo Pedido de Consulta de Nota Fiscal Eletrônica - - - - - Identificação do Ambiente: -1 - Produção -2 - Homologação - - - - - Serviço Solicitado - - - - - - - - - - - CNPJ do destinatário da NF-e - - - - - Indicador de NF-e consultada: -0 – Todas as NF-e; -1 – Somente as NF-e ainda não confirmadas. -2 – Somente as NF-e ainda não confirmadas (inclusive Ciência). - - - - - - - - - - - - - - Indicador do Emissor da NF-e: -0 – Todos os Emitentes; -1 – Somente as NF-e emitidas por emissores que não tenham a mesma raiz do CNPJ (para excluir as notas fiscais de transferência entre filiais). - - - - - - - - - - - - Último NSU recebido. Caso seja informado com zero, a consulta deve ser realizada no universo das notas fiscais tenham sido recepcionadas nos últimos 30 dias. - - - - - - - - - - - - - - Tipo Retorno do pedido de Consulta de Nota Fiscal Eletrônica - - - - - Identificação do Ambiente: -1 - Produção -2 - Homologação - - - - - Versão do Aplicativo que processou a NF-e - - - - - Código do status da mensagem enviada. - - - - - Descrição literal do status do serviço solicitado. - - - - - Data e hora da resposta à solicitação, no formato AAAA-MM-DDTHH:MM:SS - - - - - Indicador de continuidade. Indica que o ambiente consultado POSSUI ainda documentos não pesquisados. 0 = NÃO possui documentos. 1 = Possui documentos. - - - - - - - - - - - - último NSU pesquisado, deve ser informado pelo WS, sempre que realizar alguma pesquisa para que o solicitante possa atualizar o último NSU pesquisado. - - - - - - - - - - - Resumo de NF-e ou CC-e - - - - - - Informações resumo da NF-e localizadas - - - - - - Chaves de acesso da NF-e consultada - - - - - - CNPJ do Remetente da NF-e - - - - - CPF do Remetente da NF-e - - - - - - Razão Social ou Nome do Remetente - - - - - - - - - - - IE do Remetente. Valores válidos: vazio (não contribuinte do ICMS), ISENTO (contribuinte do ICMS ISENTO de Inscrição no Cadastro de Contribuintes) ou IE (Contribuinte do ICMS) - - - - - Data de Emissão da NF-e - - - - - Tipo do Documento Fiscal (0 - entrada; 1 - saída) - - - - - - - - - - - - Valor Total da NF-e - - - - - Digest Value da NF-e na base de dados da SEFAZ - - - - - - - - - - - Data e hora de processamento de autorização, no formato AAAA-MM-DDTHH:MM:SS. - - - - - Situação da NF-e -1-Uso autorizado no momento da consulta; -2-Uso denegado; -3-NF-e cancelada; - - - - - - - - - - - - - Situação Confirmação do Destinatário: -0 – sem manifestacao; -1 – confirmada; -2 – desconhecida; -3 – recusada -4 - ciência. - - - - - - - - - - - - - - - - - - - Informações resumo da NF-e canceladas localizadas - - - - - - Chaves de acesso da NF-e consultada - - - - - - CNPJ do Remetente da NF-e - - - - - CPF do Remetente da NF-e - - - - - - Razão Social ou Nome do Remetente - - - - - - - - - - - IE do Remetente. Valores válidos: vazio (não contribuinte do ICMS), ISENTO (contribuinte do ICMS ISENTO de Inscrição no Cadastro de Contribuintes) ou IE (Contribuinte do ICMS) - - - - - Data de Emissão da NF-e - - - - - Tipo do Documento Fiscal (0 - entrada; 1 - saída) - - - - - - - - - - - - Valor Total da NF-e - - - - - Digest Value da NF-e na base de dados da SEFAZ - - - - - - - - - - - Data e hora de processamento de autorização, no formato AAAA-MM-DDTHH:MM:SS. - - - - - Situação da NF-e -3-NF-e cancelada; - - - - - - - - - - - Situação Confirmação do Destinatário: -0 – sem manifestacao; -1 – confirmada; -2 – desconhecida; -3 – recusada -4 - ciência. - - - - - - - - - - - - - - - - - - - Informações da carta de correção da NF-e localizadas - - - - - - Chave de Acesso da NF-e vinculada ao evento - - - - - Data e Hora do Evento, formato UTC (AAAA-MM-DDThh:mm:ssTZD, onde TZD = +hh:mm ou -hh:mm) - - - - - - - - - - - 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. - - - - - - - - - - - Descrição do Evento - “Carta de Correção” - - - - - - - - - - - - Correção a ser considerada - - - - - - - - - - - - - Tipo do Documento Fiscal (0 - entrada; 1 - saída) - - - - - - - - - - - - Data e hora de processamento de autorização, no formato AAAA-MM-DDTHH:MM:SS. - - - - - - - - - - - - - - - Tipo Versão da consultaNFeDest - - - - - - - diff --git a/NFe.AppTeste/Schemas/leiauteConsSitNFe_v4.00.xsd b/NFe.AppTeste/Schemas/leiauteConsSitNFe_v4.00.xsd index 5330c83d0..a43c7e033 100644 --- a/NFe.AppTeste/Schemas/leiauteConsSitNFe_v4.00.xsd +++ b/NFe.AppTeste/Schemas/leiauteConsSitNFe_v4.00.xsd @@ -315,7 +315,7 @@ - + diff --git a/NFe.AppTeste/Schemas/leiauteConsultaCadastro_v1.01.xsd b/NFe.AppTeste/Schemas/leiauteConsultaCadastro_v1.01.xsd deleted file mode 100644 index e6b8c7820..000000000 --- a/NFe.AppTeste/Schemas/leiauteConsultaCadastro_v1.01.xsd +++ /dev/null @@ -1,355 +0,0 @@ - - - - - - Tipo Pedido de Consulta de cadastro de contribuintes - - - - - Dados do Pedido de Consulta de cadastro de contribuintes - - - - - - Serviço Solicitado - - - - - sigla da UF consultada, utilizar SU para SUFRAMA - - - - - argumento de pesquisa - - - - Inscrição Estadual do contribuinte - - - - - CNPJ do contribuinte - - - - - CPF do contribuinte - - - - - - - - - - - - Tipo Retorno Pedido de Consulta de cadastro de contribuintes - - - - - Dados do Resultado doDados do Pedido de Consulta de cadastro de contribuintes - - - - - - Versão do Aplicativo que processou o pedido de consulta de cadastro - - - - - Código do status da mensagem enviada. - - - - - Descrição literal do status do serviço solicitado. - - - - - sigla da UF consultada, utilizar SU para SUFRAMA - - - - - argumento de pesquisa - - - - Inscrição Estadual do contribuinte - - - - - CNPJ do contribuinte - - - - - CPF do contribuinte - - - - - - Data da Consulta - - - - - código da UF de atendimento - - - - - Informações cadastrais do contribuinte consultado - - - - - - Número da Inscrição Estadual do contribuinte - - - - - - Número do CNPJ do contribuinte - - - - - Número do CPF do contribuinte - - - - - - Sigla da UF de localização do contribuinte. Em algumas situações, a UF de localização pode ser diferente da UF consultada. Ex. IE de Substituto Tributário. - - - - - Situação cadastral do contribuinte: -0 - não habilitado -1 - habilitado - - - - - - - - - - - Razão Social ou nome do contribuinte - - - - - - - - - - - Razão Social ou nome do contribuinte - - - - - - - - - - - Regime de Apuração do ICMS - - - - - - - - - - - CNAE Fiscal do contribuinte - - - - - - - - - - Data de início de atividades do contribuinte - - - - - Data da última modificação da situação cadastral do contribuinte. - - - - - Data de ocorrência da baixa do contribuinte. - - - - - Inscrição Estadual Única - - - - - Inscrição Estadual atual - - - - - Endereço - - - - - - - - - - - - - - Tipo Dados do Endereço - - - - - Logradouro - - - - - - - - - - - Número - - - - - - - - - - - Complemento - - - - - - - - - - - Bairro - - - - - - - - - - - Código do município (utilizar a tabela do IBGE), informar 9999999 para operações com o exterior. - - - - - Nome do município - - - - - - - - - - - CEP - - - - - - - - - - - - Tipo Sigla da UF consultada - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Tipo Versão do Leiaute da Consulta Cadastro - - - - - - diff --git a/NFe.AppTeste/Schemas/leiauteDPEC_v1.01.xsd b/NFe.AppTeste/Schemas/leiauteDPEC_v1.01.xsd deleted file mode 100644 index 1cca199df..000000000 --- a/NFe.AppTeste/Schemas/leiauteDPEC_v1.01.xsd +++ /dev/null @@ -1,464 +0,0 @@ - - - - - - Tipo Declaração Prévia de Emissão em Contingência - DPEC - - - - - Informações da Declaração Prévia de Emissão em Contingência - - - - - - Identificação do Declarante, deve ser informado com os dados do emissor das NF-e emitidas em contingência eletrônica - - - - - - Código da UF do emitente do Documento Fiscal. Utilizar a Tabela do IBGE. - - - - - Identificação do Ambiente: -1 - Produção -2 - Homologação - - - - - versão do aplicativo utilizado no processo de -emissãodo DPEC - - - - - - - - - - - Número do CNPJ do emitente - - - - - Inscrição Estadual do emitente - - - - - - - - Resumo das NF-e emitidas no Sistema de Contingência Eletrônica (até 50 NF-e com tpEmiss = "4") - - - - - - Chave de Acesso da NF-e emitida em contingência eletrônica - - - - - Identificação do Destinatário - - - - CNPJ do destinatário - - - - - CPF do destintário - - - - - - Sigla da UF de destinto da mercadoria - - - - - Valor Total da NF-e - - - - - Valor Total do ICMS da operação própria - - - - - Valor Total do ICMS retido por Subsituição Tributária - - - - - - - - - - - - - - - - - - - - - - Tipo Retorno da Declaração Prévia de Emissão em Contignência - DPEC - - - - - - - - Identificação do Ambiente: -1 - Produção -2 - Homologação - - - - - Versão do Aplicativo que recebeu o DPEC - - - - - Código do status da recepção do DPEC - - - - - Descrição literal do status da recepção do DPEC - - - - - - - Data e Hora de registro da DPEC - - - - - Número do registro do DPEC - - - - - Declaração Prévia de Emissão em Contingência - - - - - - - Chave de Acesso da primeira NF-e que causou o erro, se aplicável - - - - - - - - - - - - - - - - - - - - - Tipo Consulta Declaração prévia de Emissão em Contingência - DPEC - - - - - Identificação do Ambiente: -1 - Produção -2 - Homologação - - - - - Versão do Aplicativo que solicitou a Consulta - - - - - - Chave de Acesso da NF-e - - - - - Número de registro do DPEC - - - - - - - - - Tipo Retorno da Consulta da Declaração Prévia de Emissão em Contignência - DPEC - - - - - Identificação do Ambiente: -1 - Produção -2 - Homologação - - - - - Versão do Aplicativo que recebeu o DPEC - - - - - Código do status da recepção do DPEC - - - - - Descrição literal do status da recepção do DPEC - - - - - DPEC localizado - - - - - - - - Tipo Ambiente - - - - - - - - - - Tipo Chave da Nota Fiscal Eletrônica - - - - - - - - - Tipo Número do CNPJ - - - - - - - - - Tipo Número do CNPJ Opcional - - - - - - - - - Tipo Código da UF da tabela do IBGE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Tipo Código do Município da tabela do IBGE - - - - - - - - - Tipo Número do CPF - - - - - - - - - Tipo Decimal com 15 dígitos, sendo 13 de corpo e 2 decimais - - - - - - - - - Tipo Inscrição Estadual do Emissor - - - - - - - - Tipo Motivo - - - - - - - - - Tipo Número do Protocolo de Status - - - - - - - - - Tipo Número do Recibo do envio de lote de NF-e - - - - - - - - - Tipo Código da Mensagem enviada - - - - - - - - - Tipo string genérico - - - - - - - - - Tipo Sigla da UF - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Tipo Versão do Aplicativo - - - - - - - - - Tipo Versão do DPEC - - - - - - - diff --git a/NFe.AppTeste/Schemas/leiauteEvento_v1.00.xsd b/NFe.AppTeste/Schemas/leiauteEvento_v1.00.xsd index bb5ec2b02..1f23ffac0 100644 --- a/NFe.AppTeste/Schemas/leiauteEvento_v1.00.xsd +++ b/NFe.AppTeste/Schemas/leiauteEvento_v1.00.xsd @@ -1,4 +1,4 @@ - + @@ -91,6 +91,40 @@ + + + Grupo de Informação do Provedor de Assinatura e Autorização + + + + + + CNPJ do Provedor de Assinatura e Autorização + + + + + Assinatura RSA do Emitente para DFe gerados por PAA + + + + + + Assinatura digital padrão RSA + Converter o atributo Id do DFe para array de bytes e assinar com a chave privada do RSA com algoritmo SHA1 gerando um valor no formato base64. + + + + + Chave Publica no padrão XML RSA Key + + + + + + + + @@ -99,7 +133,7 @@ - + @@ -332,48 +366,4 @@ - - - diff --git a/NFe.AppTeste/Schemas/leiauteInutNFe_v4.00.xsd b/NFe.AppTeste/Schemas/leiauteInutNFe_v4.00.xsd index 819597c1a..886e05d0f 100644 --- a/NFe.AppTeste/Schemas/leiauteInutNFe_v4.00.xsd +++ b/NFe.AppTeste/Schemas/leiauteInutNFe_v4.00.xsd @@ -76,7 +76,7 @@ - + diff --git a/NFe.AppTeste/Schemas/leiauteNFe_v4.00.xsd b/NFe.AppTeste/Schemas/leiauteNFe_v4.00.xsd index 7d6fb69ef..9e86de93b 100644 --- a/NFe.AppTeste/Schemas/leiauteNFe_v4.00.xsd +++ b/NFe.AppTeste/Schemas/leiauteNFe_v4.00.xsd @@ -1,23 +1,5 @@ - - - - - - - - - - - - - - - - - - @@ -73,10 +55,7 @@ - Série do Documento Fiscal -série normal 0-889 -Avulsa Fisco 890-899 -SCAN 900-999 + Série do Documento Fiscal @@ -132,13 +111,19 @@ SCAN 900-999 Informar o município de ocorrência do fato gerador do fato gerador do IBS / CBS. -Campo preenchido somente quando “indPres = 5 (Operação presencial, fora do estabelecimento) ”, e não tiver endereço do destinatário (Grupo: E05) ou local de entrega (Grupo: G01). +Campo preenchido somente quando "indPres = 5 (Operação presencial, fora do estabelecimento)", e não estiver preenchido o endereço do destinatário (grupo: E05) nem o local de entrega (grupo: G01). - Formato de impressão do DANFE (0-sem DANFE;1-DANFe Retrato; 2-DANFe Paisagem;3-DANFe Simplificado; - 4-DANFe NFC-e;5-DANFe NFC-e em mensagem eletrônica) + Formato de impressão do DANFE: +0 - Sem DANFE; +1 - DANFE Retrato; +2 - DANFE Paisagem; +3 - DANFE Simplificado; +4 - DANFE NFC-e; +5 - DANFE NFC-e em mensagem eletrônica; +6 - DANFE Simplificado Tipo 2 (nas condições do Ajuste SINIEF 13/26). @@ -149,20 +134,21 @@ Campo preenchido somente quando “indPres = 5 (Operação presencial, fora do e + - Forma de emissão da NF-e + Forma de emissão da NF-e: 1 - Normal; -2 - Contingência FS -3 - Regime Especial NFF (NT 2021.002) -4 - Contingência DPEC -5 - Contingência FSDA -6 - Contingência SVC - AN -7 - Contingência SVC - RS -9 - Contingência off-line NFC-e +2 - Contingência FS; +3 - Regime Especial NFF (NT 2021.002); +4 - Contingência DPEC; +5 - Contingência FSDA; +6 - Contingência SVC - AN; +7 - Contingência SVC - RS; +9 - Contingência off-line da NFC-e e da NF-e com DANFE Simplificado Tipo 2. @@ -231,8 +217,14 @@ Campo preenchido somente quando “indPres = 5 (Operação presencial, fora do e - Indicador de presença do comprador no estabelecimento comercial no momento da oepração - (0-Não se aplica (ex.: Nota Fiscal complementar ou de ajuste;1-Operação presencial;2-Não presencial, internet;3-Não presencial, teleatendimento;4-NFC-e entrega em domicílio;5-Operação presencial, fora do estabelecimento;9-Não presencial, outros) + Indicador de presença do comprador no estabelecimento comercial no momento da oepração: +0 - Não se aplica (ex.: Nota Fiscal complementar ou de ajuste); +1 - Operação presencial; +2 - Operação não presencial, internet; +3 - Operação não presencial, teleatendimento; +4 - Operação não presencial com NFC-e e NFe com DANFE Simplificado Tipo 2 (com entrega); +5 - Operação presencial, fora do estabelecimento; +9 - Operação não presencial, outros. @@ -261,6 +253,17 @@ Campo preenchido somente quando “indPres = 5 (Operação presencial, fora do e + + + Código indicador do local da operação de fornecimento + + + + + + + + Processo de emissão utilizado com a seguinte codificação: @@ -268,7 +271,8 @@ Campo preenchido somente quando “indPres = 5 (Operação presencial, fora do e 1 - emissão de NF-e avulsa pelo Fisco; 2 - emissão de NF-e avulsa, pelo contribuinte com seu certificado digital, através do site do Fisco; -3- emissão de NF-e pelo contribuinte com aplicativo fornecido pelo Fisco. +3 - emissão de NF-e pelo contribuinte com aplicativo fornecido pelo Fisco; +4 - emissão de NF-e por Provedor de Assinatura e Autorização - PAA. @@ -501,7 +505,7 @@ Preencher com "2B", quando se tratar de Cupom Fiscal emitido por máqu - + Chave de acesso da NF-e de antecipação de pagamento @@ -613,6 +617,17 @@ Este campo será obrigatoriamente preenchido com: + + + Inscrição do emitente na Suframa + + + + + + + + @@ -2555,13 +2570,15 @@ ambiente. - Motivo da desoneração do ICMS:3-Uso na agropecuária;9-Outros;12-Fomento agropecuário + Motivo da desoneração do ICMS:3-Uso na agropecuária;9-Outros; 10=Deficiente Condutor (Convênio ICMS 38/12); 11=Deficiente Não Condutor (Convênio ICMS 38/12); 12-Fomento agropecuário + + @@ -3395,11 +3412,39 @@ Informar o motivo da desoneração: Percentual de redução da BC + + + Código de Benefício Fiscal na UF aplicado ao item quando houver RBC. + + + + + + + + Alíquota do ICMS + + + + Valor do ICMS da Operação + + + + + Percentual do diferemento + + + + + Valor do ICMS da diferido + + + Valor do ICMS @@ -3422,6 +3467,23 @@ Informar o motivo da desoneração: + + + + Percentual do diferimento do ICMS relativo ao Fundo de Combate à Pobreza (FCP). + + + + + Valor do ICMS relativo ao Fundo de Combate à Pobreza (FCP) diferido. + + + + + Valor efetivo do ICMS relativo ao Fundo de Combate à Pobreza (FCP). + + + @@ -3569,12 +3631,14 @@ Operação interestadual para consumidor final com partilha do ICMS devido na o Tributação pelo ICMS 10 - Tributada e com cobrança do ICMS por substituição tributária; +20 – Redução de base de cálculo 90 – Outros. + @@ -3693,6 +3757,43 @@ Operação interestadual para consumidor final com partilha do ICMS devido na o Sigla da UF para qual é devido o ICMS ST da operação. + + + Grupo desoneração + + + + Valor do ICMS de desoneração + + + + + Motivo da desoneração do ICMS:9-Outros;10=Deficiente Condutor (Convênio ICMS 38/12) 11=Deficiente Não Condutor (Convênio ICMS 38/12) + + + + + + + + + + + + + Indica se o valor do ICMS desonerado (vICMSDeson) deduz do valor do item (vProd): +0=Valor do ICMS desonerado (vICMSDeson) não deduz do valor do item (vProd) / total da NF-e; +1=Valor do ICMS desonerado (vICMSDeson) deduz do valor do item (vProd) / total da NF-e. + + + + + + + + + + @@ -6481,6 +6582,40 @@ tipo de ato concessório: + + + Grupo de Informação do Provedor de Assinatura e Autorização + + + + + + CNPJ do Provedor de Assinatura e Autorização + + + + + Assinatura RSA do Emitente para DFe gerados por PAA + + + + + + Assinatura digital padrão RSA + Converter o atributo Id do DFe para array de bytes e assinar com a chave privada do RSA com algoritmo SHA1 gerando um valor no formato base64. + + + + + Chave Publica no padrão XML RSA Key + + + + + + + + @@ -6493,7 +6628,7 @@ tipo de ato concessório: - + @@ -6519,15 +6654,15 @@ tipo de ato concessório: - + - + - + - + - + @@ -6601,7 +6736,7 @@ tipo de ato concessório: Descrição literal do status do serviço solicitado. - + Código da Mensagem. @@ -6620,7 +6755,7 @@ tipo de ato concessório: - + @@ -7356,7 +7491,7 @@ alterado para tamanho variavel 1-4. (NT2011/004) 04=Multa e juros; 05=Transferência de crédito na sucessão; 06=Pagamento antecipado; - 07=Perda em estoque; + 07=Perda em estoque (Perecimento, Perda, Furto, Roubo); 08=Desenquadramento do SN; @@ -7379,6 +7514,7 @@ alterado para tamanho variavel 1-4. (NT2011/004) 03=Retorno por recusa na entrega ou por não localização do destinatário na tentativa de entrega; 04=Redução de valores; 05=Transferência de crédito na sucessão; + 06=Retorno por recusa parcial na entrega; @@ -7388,6 +7524,7 @@ alterado para tamanho variavel 1-4. (NT2011/004) + @@ -7400,6 +7537,7 @@ alterado para tamanho variavel 1-4. (NT2011/004) + @@ -7576,4 +7714,4 @@ alterado para tamanho variavel 1-4. (NT2011/004) - \ No newline at end of file + diff --git a/NFe.AppTeste/Schemas/nfe_v4.00.xsd b/NFe.AppTeste/Schemas/nfe_v4.00.xsd index 7a2ffb25f..5b2eb0810 100644 --- a/NFe.AppTeste/Schemas/nfe_v4.00.xsd +++ b/NFe.AppTeste/Schemas/nfe_v4.00.xsd @@ -1,5 +1,5 @@ - + @@ -7,4 +7,4 @@ Nota Fiscal Eletrônica - + \ No newline at end of file diff --git a/NFe.AppTeste/Schemas/retAtuCadEmiDFe_v1.01.xsd b/NFe.AppTeste/Schemas/retAtuCadEmiDFe_v1.01.xsd deleted file mode 100644 index acf9676c7..000000000 --- a/NFe.AppTeste/Schemas/retAtuCadEmiDFe_v1.01.xsd +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - Retorno da Atualização de Emissor de NF-e - - - diff --git a/NFe.AppTeste/Schemas/retConsDPEC_v1.01.xsd b/NFe.AppTeste/Schemas/retConsDPEC_v1.01.xsd deleted file mode 100644 index 7c7819275..000000000 --- a/NFe.AppTeste/Schemas/retConsDPEC_v1.01.xsd +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - Schema XML de validação do Pedido de Consulta de Declaração Prévia de Emissão em Contingência - - - diff --git a/NFe.AppTeste/Schemas/retDPEC_v1.01.xsd b/NFe.AppTeste/Schemas/retDPEC_v1.01.xsd deleted file mode 100644 index 2d60a6965..000000000 --- a/NFe.AppTeste/Schemas/retDPEC_v1.01.xsd +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - Schema XML de validação do Retorno do processamento da Declaração Prévia de Emissão em Contingência - DPEC - - - diff --git a/NFe.AppTeste/Schemas/retconsNFeDest_v1.01.xsd b/NFe.AppTeste/Schemas/retconsNFeDest_v1.01.xsd deleted file mode 100644 index 9dea650c9..000000000 --- a/NFe.AppTeste/Schemas/retconsNFeDest_v1.01.xsd +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - Schema XML de validação do retorno de resumo das NF-e encontradas - - - diff --git a/NFe.AppTeste/Schemas/tiposBasico_v1.03.xsd b/NFe.AppTeste/Schemas/tiposBasico_v1.03.xsd index 1f9c9904b..592056fcc 100644 --- a/NFe.AppTeste/Schemas/tiposBasico_v1.03.xsd +++ b/NFe.AppTeste/Schemas/tiposBasico_v1.03.xsd @@ -1,13 +1,4 @@ - - - - - - - - - @@ -68,7 +59,7 @@ - + @@ -95,7 +86,8 @@ - + + @@ -104,16 +96,16 @@ - + - Tipo Número do CNPJ tmanho varíavel (3-14) + Tipo Número do CNPJ - + @@ -123,7 +115,7 @@ - + @@ -903,4 +895,13 @@ acrescentado: + + + Tipo que representa uma chave publica padrão RSA + + + + + + diff --git a/NFe.AppTeste/Schemas/tiposBasico_v4.00.xsd b/NFe.AppTeste/Schemas/tiposBasico_v4.00.xsd index 0ddf6ef7a..5fe029e97 100644 --- a/NFe.AppTeste/Schemas/tiposBasico_v4.00.xsd +++ b/NFe.AppTeste/Schemas/tiposBasico_v4.00.xsd @@ -1,4 +1,5 @@ + @@ -52,7 +53,7 @@ - + @@ -92,17 +93,17 @@ - + - Tipo Número do CNPJ tmanho varíavel (3-14) + Tipo Número do CNPJ - + @@ -112,7 +113,7 @@ - + @@ -595,4 +596,13 @@ - + + + Tipo que representa uma chave publica padrão RSA + + + + + + + \ No newline at end of file diff --git a/NFe.Classes/Informacoes/Destinatario/dest.cs b/NFe.Classes/Informacoes/Destinatario/dest.cs index 3cb1a1f73..8c9cd5fec 100644 --- a/NFe.Classes/Informacoes/Destinatario/dest.cs +++ b/NFe.Classes/Informacoes/Destinatario/dest.cs @@ -30,18 +30,19 @@ /* http://www.zeusautomacao.com.br/ */ /* Rua Comendador Francisco josé da Cunha, 111 - Itabaiana - SE - 49500-000 */ /********************************************************************************/ + +using DFe.Classes.Flags; using System; using System.Xml.Serialization; -using DFe.Classes.Flags; -using NFe.Classes.Servicos.Tipos; namespace NFe.Classes.Informacoes.Destinatario { public class dest { - private const string ErroCpfCnpjPreenchidos = "Somente preencher um dos campos: CNPJ ou CPF, para um objeto do tipo dest!"; + private const string ErroCpfCnpjIdEstrangeiroPreenchidos = "Somente preencher um dos campos: CNPJ, CPF ou idEstrangeiro, para um objeto do tipo dest!"; private string cnpj; private string cpf; + private string _idEstrangeiro; private readonly VersaoServico _versao; /// @@ -66,13 +67,12 @@ public string CNPJ get { return cnpj; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(cpf)) - cnpj = value; - else - { - throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(cpf) || !string.IsNullOrEmpty(idEstrangeiro)) + throw new ArgumentException(ErroCpfCnpjIdEstrangeiroPreenchidos); + + cnpj = value; } } @@ -84,20 +84,31 @@ public string CPF get { return cpf; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(cnpj)) - cpf = value; - else - { - throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(cnpj) || !string.IsNullOrEmpty(idEstrangeiro)) + throw new ArgumentException(ErroCpfCnpjIdEstrangeiroPreenchidos); + + cpf = value; } } /// /// E03a - Identificador do destinatário, em caso de comprador estrangeiro /// - public string idEstrangeiro { get; set; } + public string idEstrangeiro + { + get { return _idEstrangeiro; } + set + { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(CNPJ) || !string.IsNullOrEmpty(CPF)) + throw new ArgumentException(ErroCpfCnpjIdEstrangeiroPreenchidos); + + _idEstrangeiro = value; + } + } /// /// E04 - Razão Social ou nome do destinatário diff --git a/NFe.Classes/Informacoes/Detalhe/Tributacao/Estadual/ICMS90.cs b/NFe.Classes/Informacoes/Detalhe/Tributacao/Estadual/ICMS90.cs index a3bd586c8..b721dabdd 100644 --- a/NFe.Classes/Informacoes/Detalhe/Tributacao/Estadual/ICMS90.cs +++ b/NFe.Classes/Informacoes/Detalhe/Tributacao/Estadual/ICMS90.cs @@ -40,6 +40,9 @@ public class ICMS90 : ICMSBasico private decimal? _vBc; private decimal? _pRedBc; private decimal? _pIcms; + private decimal? _vIcmsOp; + private decimal? _pDif; + private decimal? _vIcmsDif; private decimal? _vIcms; private decimal? _pMvast; private decimal? _pRedBcst; @@ -50,6 +53,9 @@ public class ICMS90 : ICMSBasico private decimal? _vBcfcp; private decimal? _pFcp; private decimal? _vFcp; + private decimal? _pFCPDif; + private decimal? _vFCPDif; + private decimal? _vFCPEfet; private decimal? _vBcfcpst; private decimal? _pFcpst; private decimal? _vFcpst; @@ -94,19 +100,55 @@ public decimal? pRedBC } /// - /// N16 - Alíquota do imposto + /// N14a - Código de Benefício Fiscal na UF aplicado ao item quando houver RBC. /// [XmlElement(Order = 6)] + public string cBenefRBC { get; set; } + + /// + /// N16 - Alíquota do imposto + /// + [XmlElement(Order = 7)] public decimal? pICMS { get { return _pIcms.Arredondar(4); } set { _pIcms = value.Arredondar(4); } } + /// + /// N16b - Valor do ICMS da Operação + /// + [XmlElement(Order = 8)] + public decimal? vICMSOp + { + get { return _vIcmsOp.Arredondar(2); } + set { _vIcmsOp = value.Arredondar(2); } + } + + /// + /// N16c - Percentual do diferimento + /// + [XmlElement(Order = 9)] + public decimal? pDif + { + get { return _pDif.Arredondar(4); } + set { _pDif = value.Arredondar(4); } + } + + /// + /// N16d - Valor do ICMS diferido + /// + [XmlElement(Order = 10)] + public decimal? vICMSDif + { + get { return _vIcmsDif.Arredondar(2); } + set { _vIcmsDif = value.Arredondar(2); } + } + /// /// N17 - Valor do ICMS /// - [XmlElement(Order = 7)] + [XmlElement(Order = 11)] public decimal? vICMS { get { return _vIcms.Arredondar(2); } @@ -117,7 +159,7 @@ public decimal? vICMS /// N17a - Valor da Base de Cálculo do FCP /// Versão 4.00 /// - [XmlElement(Order = 8)] + [XmlElement(Order = 12)] public decimal? vBCFCP { get { return _vBcfcp.Arredondar(2); } @@ -133,7 +175,7 @@ public bool vBCFCPSpecified /// N17b - Percentual do Fundo de Combate à Pobreza (FCP) /// Versão 4.00 /// - [XmlElement(Order = 9)] + [XmlElement(Order = 13)] public decimal? pFCP { get { return _pFcp.Arredondar(4); } @@ -149,7 +191,7 @@ public bool pFCPSpecified /// N17c - Valor do Fundo de Combate à Pobreza (FCP) /// Versão 4.00 /// - [XmlElement(Order = 10)] + [XmlElement(Order = 14)] public decimal? vFCP { get { return _vFcp.Arredondar(2); } @@ -161,16 +203,49 @@ public bool vFCPSpecified get { return vFCP.HasValue; } } + /// + /// N17d - Percentual do diferimento do ICMS relativo ao Fundo de Combate à Pobreza (FCP) + /// Versão 4.00 + /// + [XmlElement(Order = 15)] + public decimal? pFCPDif + { + get { return _pFCPDif.Arredondar(4); } + set { _pFCPDif = value.Arredondar(4); } + } + + /// + /// N17e - Valor do ICMS relativo ao Fundo de Combate à Pobreza (FCP) diferido + /// Versão 4.00 + /// + [XmlElement(Order = 16)] + public decimal? vFCPDif + { + get { return _vFCPDif.Arredondar(2); } + set { _vFCPDif = value.Arredondar(2); } + } + + /// + /// N17f - Valor efetivo do ICMS relativo ao Fundo de Combate à Pobreza (FCP) + /// Versão 4.00 + /// + [XmlElement(Order = 17)] + public decimal? vFCPEfet + { + get { return _vFCPEfet.Arredondar(2); } + set { _vFCPEfet = value.Arredondar(2); } + } + /// /// N18 - Modalidade de determinação da BC do ICMS ST /// - [XmlElement(Order = 11)] + [XmlElement(Order = 18)] public DeterminacaoBaseIcmsSt? modBCST { get; set; } /// /// N19 - Percentual da margem de valor Adicionado do ICMS ST /// - [XmlElement(Order = 12)] + [XmlElement(Order = 19)] public decimal? pMVAST { get { return _pMvast.Arredondar(4); } @@ -180,7 +255,7 @@ public decimal? pMVAST /// /// N20 - Percentual da Redução de BC do ICMS ST /// - [XmlElement(Order = 13)] + [XmlElement(Order = 20)] public decimal? pRedBCST { get { return _pRedBcst.Arredondar(4); } @@ -190,7 +265,7 @@ public decimal? pRedBCST /// /// N21 - Valor da BC do ICMS ST /// - [XmlElement(Order = 14)] + [XmlElement(Order = 21)] public decimal? vBCST { get { return _vBcst.Arredondar(2); } @@ -200,7 +275,7 @@ public decimal? vBCST /// /// N22 - Alíquota do imposto do ICMS ST /// - [XmlElement(Order = 15)] + [XmlElement(Order = 22)] public decimal? pICMSST { get { return _pIcmsst.Arredondar(4); } @@ -210,7 +285,7 @@ public decimal? pICMSST /// /// N23 - Valor do ICMS ST /// - [XmlElement(Order = 16)] + [XmlElement(Order = 23)] public decimal? vICMSST { get { return _vIcmsst.Arredondar(2); } @@ -221,7 +296,7 @@ public decimal? vICMSST /// N23a - Valor da Base de Cálculo do FCP retido por Substituição Tributária /// Versão 4.00 /// - [XmlElement(Order = 17)] + [XmlElement(Order = 24)] public decimal? vBCFCPST { get { return _vBcfcpst.Arredondar(2); } @@ -237,7 +312,7 @@ public bool vBCFCPSTSpecified /// N23b - Percentual do FCP retido por Substituição Tributária /// Versão 4.00 /// - [XmlElement(Order = 18)] + [XmlElement(Order = 25)] public decimal? pFCPST { get { return _pFcpst.Arredondar(4); } @@ -253,7 +328,7 @@ public bool pFCPSTSpecified /// N23d - Valor do FCP retido por Substituição Tributária /// Versão 4.00 /// - [XmlElement(Order = 19)] + [XmlElement(Order = 26)] public decimal? vFCPST { get { return _vFcpst.Arredondar(2); } @@ -268,7 +343,7 @@ public bool vFCPSTSpecified /// /// N27a - Valor do ICMS desonerado /// - [XmlElement(Order = 20)] + [XmlElement(Order = 27)] public decimal? vICMSDeson { get { return _vIcmsDeson.Arredondar(2); } @@ -278,21 +353,21 @@ public decimal? vICMSDeson /// /// N28 - Motivo da desoneração do ICMS /// - [XmlElement(Order = 21)] + [XmlElement(Order = 28)] public MotivoDesoneracaoIcms? motDesICMS { get; set; } /// /// N28b - Indica se o valor do ICMS desonerado (vICMSDeson) deduz /// do valor do item (vProd). (NT 2023.004) /// - [XmlElement(Order = 22)] + [XmlElement(Order = 29)] public DeduzDesoneracaoNoProduto? indDeduzDeson { get; set; } /// /// N33a - Valor do ICMS- ST desonerado /// Versão 4.00 /// - [XmlElement(Order = 23)] + [XmlElement(Order = 30)] public decimal? vICMSSTDeson { get { return _vICMSSTDeson.Arredondar(2); } @@ -308,7 +383,7 @@ public bool ShouldSerializevICMSSTDeson() /// N33b - Motivo da desoneração do ICMS- ST /// Versão 4.00 /// - [XmlElement(Order = 24)] + [XmlElement(Order = 31)] public MotivoDesoneracaoIcmsSt? motDesICMSST { get; set; } public bool ShouldSerializemotDesICMSST() @@ -336,11 +411,41 @@ public bool ShouldSerializepICMS() return pICMS.HasValue; } + public bool ShouldSerializevICMSOp() + { + return vICMSOp.HasValue; + } + + public bool ShouldSerializepDif() + { + return pDif.HasValue; + } + + public bool ShouldSerializevICMSDif() + { + return vICMSDif.HasValue; + } + public bool ShouldSerializevICMS() { return vICMS.HasValue; } + public bool ShouldSerializepFCPDif() + { + return pFCPDif.HasValue; + } + + public bool ShouldSerializevFCPDif() + { + return vFCPDif.HasValue; + } + + public bool ShouldSerializevFCPEfet() + { + return vFCPEfet.HasValue; + } + public bool ShouldSerializemodBCST() { return modBCST.HasValue; @@ -386,4 +491,4 @@ public bool ShouldSerializeindDeduzDeson() return indDeduzDeson.HasValue; } } -} \ No newline at end of file +} diff --git a/NFe.Classes/Informacoes/Detalhe/Tributacao/Estadual/ICMSPart.cs b/NFe.Classes/Informacoes/Detalhe/Tributacao/Estadual/ICMSPart.cs index 754e6a20d..39c73c8be 100644 --- a/NFe.Classes/Informacoes/Detalhe/Tributacao/Estadual/ICMSPart.cs +++ b/NFe.Classes/Informacoes/Detalhe/Tributacao/Estadual/ICMSPart.cs @@ -50,6 +50,7 @@ public class ICMSPart : ICMSBasico private decimal? _pFCPST; private decimal? _vFCPST; private decimal _pBcOp; + private decimal? _vIcmsDeson; /// /// N11 - Origem da Mercadoria @@ -211,6 +212,29 @@ public decimal pBCOp [XmlElement(Order = 18)] public string UFST { get; set; } + /// + /// N28a - Valor do ICMS desonerado + /// + [XmlElement(Order = 19)] + public decimal? vICMSDeson + { + get { return _vIcmsDeson.Arredondar(2); } + set { _vIcmsDeson = value.Arredondar(2); } + } + + /// + /// N28 - Motivo da desoneração do ICMS + /// + [XmlElement(Order = 20)] + public MotivoDesoneracaoIcms? motDesICMS { get; set; } + + /// + /// N28b - Indica se o valor do ICMS desonerado (vICMSDeson) deduz + /// do valor do item (vProd). (NT 2023.004) + /// + [XmlElement(Order = 21)] + public DeduzDesoneracaoNoProduto? indDeduzDeson { get; set; } + public bool ShouldSerializepRedBC() { return pRedBC.HasValue; @@ -241,5 +265,20 @@ public bool ShouldSerializevFCPST() return vFCPST.HasValue; } + public bool ShouldSerializevICMSDeson() + { + return vICMSDeson.HasValue; + } + + public bool ShouldSerializemotDesICMS() + { + return motDesICMS.HasValue; + } + + public bool ShouldSerializeindDeduzDeson() + { + return indDeduzDeson.HasValue; + } + } -} \ No newline at end of file +} diff --git a/NFe.Classes/Informacoes/Detalhe/Tributacao/Estadual/Tipos/ICMSTipos.cs b/NFe.Classes/Informacoes/Detalhe/Tributacao/Estadual/Tipos/ICMSTipos.cs index afc2b80bc..9b01c2c7d 100644 --- a/NFe.Classes/Informacoes/Detalhe/Tributacao/Estadual/Tipos/ICMSTipos.cs +++ b/NFe.Classes/Informacoes/Detalhe/Tributacao/Estadual/Tipos/ICMSTipos.cs @@ -180,6 +180,13 @@ public enum Csticms [XmlEnum("20")] Cst20, + /// + /// 20 - Com redução de base de cálculo + /// + [Description("Com redução de base de cálculo")] + [XmlEnum("20")] + CstPart20, + /// /// 30 - Isenta ou não tributada e com cobrança do ICMS por substituição tributária /// diff --git a/NFe.Classes/Informacoes/Detalhe/Tributacao/Federal/IS.cs b/NFe.Classes/Informacoes/Detalhe/Tributacao/Federal/IS.cs index 3a649a812..06ad15da1 100644 --- a/NFe.Classes/Informacoes/Detalhe/Tributacao/Federal/IS.cs +++ b/NFe.Classes/Informacoes/Detalhe/Tributacao/Federal/IS.cs @@ -48,7 +48,7 @@ public class IS /// UB02 - Código de Situação Tributária do Imposto Seletivo /// [XmlElement(Order = 1)] - public CSTIS CSTIS { get; set; } + public string CSTIS { get; set; } /// /// UB03 - Código de Classificação Tributária do Imposto Seletivo @@ -80,7 +80,7 @@ public decimal pIS /// UB07 - Alíquota específica por unidade de medida apropriada (em percentual) /// [XmlElement(Order = 5)] - public decimal? pISEspec + public decimal? adRemIS { get => _pIsEspec.Arredondar(4); set => _pIsEspec = value.Arredondar(4); @@ -112,6 +112,6 @@ public decimal vIS set => _vIs = value.Arredondar(2); } - public bool ShouldSerializepISEspec() => pISEspec.HasValue; + public bool ShouldSerializeadRemIS() => adRemIS.HasValue; } } \ No newline at end of file diff --git a/NFe.Classes/Informacoes/Detalhe/Tributacao/Federal/Tipos/IPITipos.cs b/NFe.Classes/Informacoes/Detalhe/Tributacao/Federal/Tipos/IPITipos.cs index b6d87d258..c318df8bb 100644 --- a/NFe.Classes/Informacoes/Detalhe/Tributacao/Federal/Tipos/IPITipos.cs +++ b/NFe.Classes/Informacoes/Detalhe/Tributacao/Federal/Tipos/IPITipos.cs @@ -58,97 +58,97 @@ public enum CSTIPI /// [Description("Entrada com recuperação de crédito")] [XmlEnum("00")] - ipi00, - - /// - /// 49 - Outras entradas - /// - [Description("Outras entradas")] - [XmlEnum("49")] - ipi49, - - /// - /// 50 - Saída tributada - /// - [Description("Saída tributada")] - [XmlEnum("50")] - ipi50, - - /// - /// 99 - Outras saídas - /// - [Description("Outras saídas")] - [XmlEnum("99")] - ipi99, + ipi00 = 0, /// /// 01 - Entrada tributada com alíquota zero /// [Description("Entrada tributada com alíquota zero")] [XmlEnum("01")] - ipi01, + ipi01 = 1, /// /// 02 - Entrada isenta /// [Description("Entrada isenta")] [XmlEnum("02")] - ipi02, + ipi02 = 2, /// /// 03 - Entrada não-tributada /// [Description("Entrada não-tributada")] [XmlEnum("03")] - ipi03, + ipi03 = 3, /// /// 04 - Entrada imune /// [Description("Entrada imune")] [XmlEnum("04")] - ipi04, + ipi04 = 4, /// /// 05 - Entrada com suspensão /// [Description("Entrada com suspensão")] [XmlEnum("05")] - ipi05, + ipi05 = 5, + + /// + /// 49 - Outras entradas + /// + [Description("Outras entradas")] + [XmlEnum("49")] + ipi49 = 49, + + /// + /// 50 - Saída tributada + /// + [Description("Saída tributada")] + [XmlEnum("50")] + ipi50 = 50, /// /// 51 - Saída tributada com alíquota zero /// [Description("Saída tributada com alíquota zero")] [XmlEnum("51")] - ipi51, + ipi51 = 51, /// /// 52 - Saída isenta /// [Description("Saída isenta")] [XmlEnum("52")] - ipi52, + ipi52 = 52, /// /// 53 - Saída não-tributada /// [Description("Saída não-tributada")] [XmlEnum("53")] - ipi53, + ipi53 = 53, /// /// 54 - Saída imune /// [Description("Saída imune")] [XmlEnum("54")] - ipi54, + ipi54 = 54, /// /// 55 - Saída com suspensão /// [Description("Saída com suspensão")] [XmlEnum("55")] - ipi55 + ipi55 = 55, + + /// + /// 99 - Outras saídas + /// + [Description("Outras saídas")] + [XmlEnum("99")] + ipi99 = 99 } } \ No newline at end of file diff --git a/NFe.Classes/Informacoes/Detalhe/Tributacao/Federal/Tipos/ISTipos.cs b/NFe.Classes/Informacoes/Detalhe/Tributacao/Federal/Tipos/ISTipos.cs index f60a280d2..7c55e04f0 100644 --- a/NFe.Classes/Informacoes/Detalhe/Tributacao/Federal/Tipos/ISTipos.cs +++ b/NFe.Classes/Informacoes/Detalhe/Tributacao/Federal/Tipos/ISTipos.cs @@ -39,6 +39,7 @@ namespace NFe.Classes.Informacoes.Detalhe.Tributacao.Federal.Tipos /// /// CST para o Imposto Seletivo (IS) /// Tabela ainda não publicada oficialmente pela SEFAZ. Fonte: NT 2025.002-RTC + /// Enum sem utilização até a publicação da tabela oficial. /// public enum CSTIS { diff --git a/NFe.Classes/Informacoes/Emitente/emit.cs b/NFe.Classes/Informacoes/Emitente/emit.cs index 2b94d7ac0..fdd7b8abf 100644 --- a/NFe.Classes/Informacoes/Emitente/emit.cs +++ b/NFe.Classes/Informacoes/Emitente/emit.cs @@ -50,14 +50,12 @@ public string CNPJ get { return _cnpj; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(_cpf)) - _cnpj = Regex.Match(value, @"\d+").Value; - - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(_cpf)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + _cnpj = Regex.Match(value, @"[0-9A-Z]+").Value; } } @@ -69,13 +67,12 @@ public string CPF get { return _cpf; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(_cnpj)) - _cpf = Regex.Match(value, @"\d+").Value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(_cnpj)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + _cpf = Regex.Match(value, @"\d+").Value; } } diff --git a/NFe.Classes/Informacoes/Identificacao/Tipos/ideTipos.cs b/NFe.Classes/Informacoes/Identificacao/Tipos/ideTipos.cs index 065164a7e..73d2160d6 100644 --- a/NFe.Classes/Informacoes/Identificacao/Tipos/ideTipos.cs +++ b/NFe.Classes/Informacoes/Identificacao/Tipos/ideTipos.cs @@ -148,6 +148,7 @@ public enum DestinoOperacao /// 3 - DANFe Simplificado; /// 4 - DANFe NFC-e; /// 5 - DANFe NFC-e em mensagem eletrônica + /// 6 - DANFe Simplificado Tipo 2 /// public enum TipoImpressao { @@ -191,7 +192,14 @@ public enum TipoImpressao /// [Description("DANFe NFC-e em mensagem eletrônica")] [XmlEnum("5")] - tiMsgEletronica = 5 + tiMsgEletronica = 5, + + /// + /// 6 - DANFe Simplificado Tipo 2 + /// + [Description("DANFe Simplificado Tipo 2")] + [XmlEnum("6")] + tiSimplificadoTp2 = 6 } /// @@ -591,7 +599,8 @@ public enum TpNotaDebito /// 02 - Apropriação de crédito presumido de IBS sobre o saldo devedor na ZFM (art. 450, § 1º, LC 214/25) /// 03 - Retorno por recusa na entrega ou por não localização do destinatário na tentativa de entrega /// 04 - Redução de valores - /// 05 - Transferência de crédito na sucessão; + /// 05 - Transferência de crédito na sucessão + /// 06 - Retorno por recusa parcial na entrega /// public enum TpNotaCredito { @@ -611,9 +620,13 @@ public enum TpNotaCredito [XmlEnum("04")] ReducaoDeValores, - [Description("Transferência de crédito na sucessão;")] + [Description("Transferência de crédito na sucessão")] [XmlEnum("05")] - TfCreditoSucessao + TfCreditoSucessao, + + [Description("Retorno por recusa parcial na entrega")] + [XmlEnum("06")] + RetornoPorRecusaParcialNaEntrega } /// diff --git a/NFe.Classes/Informacoes/Pagamento/pagTipos.cs b/NFe.Classes/Informacoes/Pagamento/pagTipos.cs index 430c798b8..c45cf4d88 100644 --- a/NFe.Classes/Informacoes/Pagamento/pagTipos.cs +++ b/NFe.Classes/Informacoes/Pagamento/pagTipos.cs @@ -52,11 +52,13 @@ namespace NFe.Classes.Informacoes.Pagamento /// 15 - Boleto Bancário (versão 4.00) /// 16 - Depósito Bancário (versão 4.00) /// 17 - Pagamento Instantâneo (PIX) dinâmico (versão 4.00) - /// 18 - Transferência bancária, Carteira Digital (versão 4.00) + /// 18 - TED (Transferência Eletrônica Disponível) (versão 4.00) /// 19 - Programa de fidelidade, Cashback, Crédito Virtual (versão 4.00) /// 20 - Pagamento Instantâneo (PIX) estático /// 21 - Crédito em loja /// 22 - Pagamento eletrônico não informado - falha de hardware do sistema emissor + /// 23 - Pagamento Instantâneo (PIX) automático + /// 24 - TEF – 'Book Transfer' /// 90 - Sem pagamento (versão 4.00) /// 91 - Pagamento posterior (versão 4.00) /// 99 - Outros @@ -155,10 +157,10 @@ public enum FormaPagamento [XmlEnum("17")] fpPagamentoInstantaneoPIXDinamico = 17, /// - /// 18 - Transferência bancária, Carteira Digital + /// 18 - TED (Transferência Eletrônica Disponível) /// - [Description("Transferência bancária, Carteira Digital")] - [XmlEnum("18")] fpTransferenciabancaria = 18, + [Description("TED (Transferência Eletrônica Disponível)")] + [XmlEnum("18")] fpTed = 18, /// /// 19 - Programa de fidelidade, Cashback, Crédito Virtual @@ -184,6 +186,18 @@ public enum FormaPagamento [Description("Pagamento eletrônico não informado")] [XmlEnum("22")] fpPagamentoEletronicoNaoInformado = 22, + /// + /// 23 - Pagamento Instantâneo (PIX) automático + /// + [Description("Pagamento Instantâneo (PIX) automático")] + [XmlEnum("23")] fpPagamentoInstantaneoPixAutomatico = 23, + + /// + /// 24 - TEF – 'Book Transfer' + /// + [Description("TEF – 'Book Transfer'")] + [XmlEnum("24")] fpPagamentoTefBookTransfer = 24, + /// /// 90 - Sem pagamento /// diff --git a/NFe.Classes/Informacoes/Transporte/transporta.cs b/NFe.Classes/Informacoes/Transporte/transporta.cs index 288fddaec..fdca1caa0 100644 --- a/NFe.Classes/Informacoes/Transporte/transporta.cs +++ b/NFe.Classes/Informacoes/Transporte/transporta.cs @@ -48,13 +48,12 @@ public string CNPJ get { return cnpj; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(cpf)) - cnpj = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(cpf)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + cnpj = value; } } @@ -66,13 +65,12 @@ public string CPF get { return cpf; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(cnpj)) - cpf = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(cnpj)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + cpf = value; } } diff --git a/NFe.Classes/Informacoes/autXML.cs b/NFe.Classes/Informacoes/autXML.cs index 026bfc4d2..335d01b0d 100644 --- a/NFe.Classes/Informacoes/autXML.cs +++ b/NFe.Classes/Informacoes/autXML.cs @@ -48,13 +48,12 @@ public string CNPJ get { return cnpj; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(cpf)) - cnpj = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(cpf)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + cnpj = value; } } @@ -66,13 +65,12 @@ public string CPF get { return cpf; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(cnpj)) - cpf = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(cnpj)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + cpf = value; } } } diff --git a/NFe.Classes/Informacoes/entrega.cs b/NFe.Classes/Informacoes/entrega.cs index fbe1f8e07..83852d663 100644 --- a/NFe.Classes/Informacoes/entrega.cs +++ b/NFe.Classes/Informacoes/entrega.cs @@ -49,13 +49,12 @@ public string CNPJ get { return cnpj; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(cpf)) - cnpj = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(cpf)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + cnpj = value; } } @@ -67,13 +66,12 @@ public string CPF get { return cpf; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(cnpj)) - cpf = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(cnpj)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + cpf = value; } } diff --git a/NFe.Classes/Informacoes/retirada.cs b/NFe.Classes/Informacoes/retirada.cs index 72d3b0138..f90977335 100644 --- a/NFe.Classes/Informacoes/retirada.cs +++ b/NFe.Classes/Informacoes/retirada.cs @@ -49,13 +49,12 @@ public string CNPJ get { return cnpj; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(cpf)) - cnpj = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(cpf)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + cnpj = value; } } @@ -67,13 +66,12 @@ public string CPF get { return cpf; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(cnpj)) - cpf = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(cnpj)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + cpf = value; } } diff --git a/NFe.Classes/Servicos/ConsultaCadastro/infConsEnv.cs b/NFe.Classes/Servicos/ConsultaCadastro/infConsEnv.cs index fddac9e5e..6cf172235 100644 --- a/NFe.Classes/Servicos/ConsultaCadastro/infConsEnv.cs +++ b/NFe.Classes/Servicos/ConsultaCadastro/infConsEnv.cs @@ -65,13 +65,12 @@ public string IE get { return _ie; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(CNPJ) & string.IsNullOrEmpty(CPF)) - _ie = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(CNPJ) || !string.IsNullOrEmpty(CPF)) throw new ArgumentException(ErroCpfCnpjIePreenchidos); - } + + _ie = value; } } @@ -84,13 +83,12 @@ public string CNPJ get { return _cnpj; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(CPF) & string.IsNullOrEmpty(IE)) - _cnpj = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(CPF) || !string.IsNullOrEmpty(IE)) throw new ArgumentException(ErroCpfCnpjIePreenchidos); - } + + _cnpj = value; } } @@ -103,13 +101,12 @@ public string CPF get { return _cpf; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(CNPJ) & string.IsNullOrEmpty(IE)) - _cpf = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(CNPJ) || !string.IsNullOrEmpty(IE)) throw new ArgumentException(ErroCpfCnpjIePreenchidos); - } + + _cpf = value; } } } diff --git a/NFe.Classes/Servicos/DistribuicaoDFe/Schemas/detEvento.cs b/NFe.Classes/Servicos/DistribuicaoDFe/Schemas/detEvento.cs index fabfd01a9..a75338e72 100644 --- a/NFe.Classes/Servicos/DistribuicaoDFe/Schemas/detEvento.cs +++ b/NFe.Classes/Servicos/DistribuicaoDFe/Schemas/detEvento.cs @@ -35,8 +35,6 @@ using DFe.Utils; using NFe.Classes.Informacoes.Identificacao.Tipos; using NFe.Classes.Servicos.Evento; -using Shared.NFe.Classes.Servicos.Evento; - using System; using System.Collections.Generic; using System.Xml.Serialization; diff --git a/NFe.Classes/Servicos/DistribuicaoDFe/Schemas/infProt.cs b/NFe.Classes/Servicos/DistribuicaoDFe/Schemas/infProt.cs index ef9b9c3e7..303273be5 100644 --- a/NFe.Classes/Servicos/DistribuicaoDFe/Schemas/infProt.cs +++ b/NFe.Classes/Servicos/DistribuicaoDFe/Schemas/infProt.cs @@ -49,7 +49,6 @@ public class infProt public string verAplic { get; set; } - [XmlElement(DataType = "integer")] public string chNFe { get; set; } [XmlIgnore] diff --git a/NFe.Classes/Servicos/DistribuicaoDFe/Schemas/resEvento.cs b/NFe.Classes/Servicos/DistribuicaoDFe/Schemas/resEvento.cs index 72e83ef09..0cb7b1e40 100644 --- a/NFe.Classes/Servicos/DistribuicaoDFe/Schemas/resEvento.cs +++ b/NFe.Classes/Servicos/DistribuicaoDFe/Schemas/resEvento.cs @@ -59,7 +59,7 @@ public class resEvento /// /// D04 - CNPJ do Emitente /// - public ulong CNPJ { get; set; } + public string CNPJ { get; set; } /// /// D05 - CPF do Emitente @@ -69,7 +69,6 @@ public class resEvento /// /// D06 - Chave de acesso da NF-e /// - [XmlElement(DataType = "integer")] public string chNFe { get; set; } /// diff --git a/NFe.Classes/Servicos/DistribuicaoDFe/Schemas/resNFe.cs b/NFe.Classes/Servicos/DistribuicaoDFe/Schemas/resNFe.cs index 3c610803a..c682287ab 100644 --- a/NFe.Classes/Servicos/DistribuicaoDFe/Schemas/resNFe.cs +++ b/NFe.Classes/Servicos/DistribuicaoDFe/Schemas/resNFe.cs @@ -53,7 +53,6 @@ public class resNFe /// /// C03 - Chave de acesso da NF-e /// - [XmlElement(DataType = "integer")] public string chNFe { get; set; } /// diff --git a/NFe.Classes/Servicos/DistribuicaoDFe/distDFeInt.cs b/NFe.Classes/Servicos/DistribuicaoDFe/distDFeInt.cs index 8015a9795..5ad92bd01 100644 --- a/NFe.Classes/Servicos/DistribuicaoDFe/distDFeInt.cs +++ b/NFe.Classes/Servicos/DistribuicaoDFe/distDFeInt.cs @@ -71,13 +71,12 @@ public string CNPJ get { return _cNPJ; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(_cPF)) - _cNPJ = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(_cPF)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + _cNPJ = value; } } @@ -89,13 +88,12 @@ public string CPF get { return _cPF; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(_cNPJ)) - _cPF = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(_cNPJ)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + _cPF = value; } } diff --git a/NFe.Classes/Servicos/Evento/dest.cs b/NFe.Classes/Servicos/Evento/dest.cs index 725018543..7e6c820ae 100644 --- a/NFe.Classes/Servicos/Evento/dest.cs +++ b/NFe.Classes/Servicos/Evento/dest.cs @@ -58,13 +58,12 @@ public string CNPJ get { return _cnpj; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(CPF) & string.IsNullOrEmpty(idEstrangeiro)) - _cnpj = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(CPF) || !string.IsNullOrEmpty(idEstrangeiro)) throw new ArgumentException(ErroCpfCnpjIdEstrangeiroPreenchidos); - } + + _cnpj = value; } } @@ -76,13 +75,12 @@ public string CPF get { return _cpf; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(CNPJ) & string.IsNullOrEmpty(idEstrangeiro)) - _cpf = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(CNPJ) || !string.IsNullOrEmpty(idEstrangeiro)) throw new ArgumentException(ErroCpfCnpjIdEstrangeiroPreenchidos); - } + + _cpf = value; } } @@ -95,12 +93,10 @@ public string idEstrangeiro set { if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(CNPJ) & string.IsNullOrEmpty(CPF)) - _idEstrangeiro = value; - else - { + if (!string.IsNullOrEmpty(CNPJ) || !string.IsNullOrEmpty(CPF)) throw new ArgumentException(ErroCpfCnpjIdEstrangeiroPreenchidos); - } + + _idEstrangeiro = value; } } diff --git a/NFe.Classes/Servicos/Evento/detEvento.cs b/NFe.Classes/Servicos/Evento/detEvento.cs index 178615119..99fc664da 100644 --- a/NFe.Classes/Servicos/Evento/detEvento.cs +++ b/NFe.Classes/Servicos/Evento/detEvento.cs @@ -44,7 +44,6 @@ using NFe.Classes.Servicos.Evento.Informacoes.ItemConsumo; using NFe.Classes.Servicos.Evento.Informacoes.ItemNaoFornecido; using NFe.Classes.Servicos.Evento.Informacoes.Perecimento; -using Shared.NFe.Classes.Servicos.Evento; namespace NFe.Classes.Servicos.Evento { diff --git a/NFe.Classes/Servicos/Evento/enquad.cs b/NFe.Classes/Servicos/Evento/enquad.cs new file mode 100644 index 000000000..26c264e86 --- /dev/null +++ b/NFe.Classes/Servicos/Evento/enquad.cs @@ -0,0 +1,46 @@ +/********************************************************************************/ +/* Projeto: Biblioteca ZeusNFe */ +/* Biblioteca C# para emissão de Nota Fiscal Eletrônica - NFe e Nota Fiscal de */ +/* Consumidor Eletrônica - NFC-e (http://www.nfe.fazenda.gov.br) */ +/* */ +/* Direitos Autorais Reservados (c) 2014 Adenilton Batista da Silva */ +/* Zeusdev Tecnologia LTDA ME */ +/* */ +/* Você pode obter a última versão desse arquivo no GitHub */ +/* localizado em https://github.com/adeniltonbs/Zeus.Net.NFe.NFCe */ +/* */ +/* */ +/* Esta biblioteca é software livre; você pode redistribuí-la e/ou modificá-la */ +/* sob os termos da Licença Pública Geral Menor do GNU conforme publicada pela */ +/* Free Software Foundation; tanto a versão 2.1 da Licença, ou (a seu critério) */ +/* qualquer versão posterior. */ +/* */ +/* Esta biblioteca é distribuída na expectativa de que seja útil, porém, SEM */ +/* NENHUMA GARANTIA; nem mesmo a garantia implícita de COMERCIABILIDADE OU */ +/* ADEQUAÇÃO A UMA FINALIDADE ESPECÍFICA. Consulte a Licença Pública Geral Menor*/ +/* do GNU para mais detalhes. (Arquivo LICENÇA.TXT ou LICENSE.TXT) */ +/* */ +/* Você deve ter recebido uma cópia da Licença Pública Geral Menor do GNU junto*/ +/* com esta biblioteca; se não, escreva para a Free Software Foundation, Inc., */ +/* no endereço 59 Temple Street, Suite 330, Boston, MA 02111-1307 USA. */ +/* Você também pode obter uma copia da licença em: */ +/* http://www.opensource.org/licenses/lgpl-license.php */ +/* */ +/* Zeusdev Tecnologia LTDA ME - adenilton@zeusautomacao.com.br */ +/* http://www.zeusautomacao.com.br/ */ +/* Rua Comendador Francisco josé da Cunha, 111 - Itabaiana - SE - 49500-000 */ +/********************************************************************************/ + +using System.Xml.Serialization; + +namespace NFe.Classes.Servicos.Evento +{ + public class enquad + { + /// + /// P30 - Código do enquadramento + /// + [XmlElement(ElementName = "cEnq")] + public string cEnq { get; set; } + } +} \ No newline at end of file diff --git a/NFe.Classes/Servicos/Evento/infEventoEnv.cs b/NFe.Classes/Servicos/Evento/infEventoEnv.cs index 1c4592c3f..9c0b79ac1 100644 --- a/NFe.Classes/Servicos/Evento/infEventoEnv.cs +++ b/NFe.Classes/Servicos/Evento/infEventoEnv.cs @@ -69,13 +69,12 @@ public string CNPJ get { return cnpj; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(cpf)) - cnpj = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(cpf)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + cnpj = value; } } @@ -87,13 +86,12 @@ public string CPF get { return cpf; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(cnpj)) - cpf = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(cnpj)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + cpf = value; } } diff --git a/NFe.Classes/Servicos/Evento/infEventoRet.cs b/NFe.Classes/Servicos/Evento/infEventoRet.cs index 85b927e61..f33ee61f9 100644 --- a/NFe.Classes/Servicos/Evento/infEventoRet.cs +++ b/NFe.Classes/Servicos/Evento/infEventoRet.cs @@ -110,13 +110,12 @@ public string CNPJDest get { return cnpj; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(cpf)) - cnpj = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(cpf)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + cnpj = value; } } @@ -128,13 +127,12 @@ public string CPFDest get { return cpf; } set { - if (string.IsNullOrEmpty(value)) return; - if (string.IsNullOrEmpty(cnpj)) - cpf = value; - else - { + if (string.IsNullOrEmpty(value)) + return; + if (!string.IsNullOrEmpty(cnpj)) throw new ArgumentException(ErroCpfCnpjPreenchidos); - } + + cpf = value; } } diff --git a/NFe.Classes/Servicos/Evento/itensAverbados.cs b/NFe.Classes/Servicos/Evento/itensAverbados.cs index 8af3be283..5739f502a 100644 --- a/NFe.Classes/Servicos/Evento/itensAverbados.cs +++ b/NFe.Classes/Servicos/Evento/itensAverbados.cs @@ -1,8 +1,41 @@ -using DFe.Utils; +/********************************************************************************/ +/* Projeto: Biblioteca ZeusNFe */ +/* Biblioteca C# para emissão de Nota Fiscal Eletrônica - NFe e Nota Fiscal de */ +/* Consumidor Eletrônica - NFC-e (http://www.nfe.fazenda.gov.br) */ +/* */ +/* Direitos Autorais Reservados (c) 2014 Adenilton Batista da Silva */ +/* Zeusdev Tecnologia LTDA ME */ +/* */ +/* Você pode obter a última versão desse arquivo no GitHub */ +/* localizado em https://github.com/adeniltonbs/Zeus.Net.NFe.NFCe */ +/* */ +/* */ +/* Esta biblioteca é software livre; você pode redistribuí-la e/ou modificá-la */ +/* sob os termos da Licença Pública Geral Menor do GNU conforme publicada pela */ +/* Free Software Foundation; tanto a versão 2.1 da Licença, ou (a seu critério) */ +/* qualquer versão posterior. */ +/* */ +/* Esta biblioteca é distribuída na expectativa de que seja útil, porém, SEM */ +/* NENHUMA GARANTIA; nem mesmo a garantia implícita de COMERCIABILIDADE OU */ +/* ADEQUAÇÃO A UMA FINALIDADE ESPECÍFICA. Consulte a Licença Pública Geral Menor*/ +/* do GNU para mais detalhes. (Arquivo LICENÇA.TXT ou LICENSE.TXT) */ +/* */ +/* Você deve ter recebido uma cópia da Licença Pública Geral Menor do GNU junto*/ +/* com esta biblioteca; se não, escreva para a Free Software Foundation, Inc., */ +/* no endereço 59 Temple Street, Suite 330, Boston, MA 02111-1307 USA. */ +/* Você também pode obter uma copia da licença em: */ +/* http://www.opensource.org/licenses/lgpl-license.php */ +/* */ +/* Zeusdev Tecnologia LTDA ME - adenilton@zeusautomacao.com.br */ +/* http://www.zeusautomacao.com.br/ */ +/* Rua Comendador Francisco josé da Cunha, 111 - Itabaiana - SE - 49500-000 */ +/********************************************************************************/ + using System; using System.Xml.Serialization; +using DFe.Utils; -namespace Shared.NFe.Classes.Servicos.Evento +namespace NFe.Classes.Servicos.Evento { public sealed class itensAverbados { @@ -64,5 +97,11 @@ public string ProxyDhAverbacao /// [XmlElement(ElementName = "motAlteracao")] public int MotAlteracao { get; set; } + + /// + /// P29 - Grupo de informações do enquadramento do item + /// + [XmlElement(ElementName = "enquad")] + public enquad Enquad { get; set; } } } diff --git a/NFe.Danfe.App.Teste.Html/NFe.Danfe.App.Teste.Html.csproj b/NFe.Danfe.App.Teste.Html/NFe.Danfe.App.Teste.Html.csproj index 11ba5f138..e2d7fa06c 100644 --- a/NFe.Danfe.App.Teste.Html/NFe.Danfe.App.Teste.Html.csproj +++ b/NFe.Danfe.App.Teste.Html/NFe.Danfe.App.Teste.Html.csproj @@ -8,7 +8,7 @@ - + diff --git a/NFe.Danfe.AppTeste.Fast/MainWindow.xaml b/NFe.Danfe.AppTeste.Fast/MainWindow.xaml index cbd75fdf1..36f02701b 100644 --- a/NFe.Danfe.AppTeste.Fast/MainWindow.xaml +++ b/NFe.Danfe.AppTeste.Fast/MainWindow.xaml @@ -217,6 +217,8 @@ VerticalAlignment="Top" Width="120" Click="BtnNfceDanfe_Click" Margin="5,10,5,0" /> public bool PreferirEmitenteNomeFantasia { get; set; } = true; + /// + /// Exibe o e-mail do destinatário (tag dest/email) no quadro "Informações Complementares". + /// Desligado por padrão: não altera o impresso de quem já usa a biblioteca. + /// + public bool ExibirEmailDestinatario { get; set; } = false; + + /// + /// Exibe as informações adicionais de interesse do Fisco (tag infAdFisco) no quadro + /// "Informações Complementares", prefixadas por "Inf. fisco". Desligado por padrão: não + /// altera o impresso de quem já usa a biblioteca. + /// + public bool ExibirInformacoesAdicionaisFisco { get; set; } = false; + #endregion #region Contingencia @@ -319,17 +333,17 @@ public virtual string TextoAdicional() if (!string.IsNullOrEmpty(InformacoesComplementares)) sb.Append(InformacoesComplementares).Replace(";", "\r\n"); - /*if (!string.IsNullOrEmpty(Destinatario.Email)) + if (ExibirEmailDestinatario && Destinatario != null && !string.IsNullOrEmpty(Destinatario.Email)) { // Adiciona um espaço após a virgula caso necessário, isso facilita a quebra de linha. var destEmail = Regex.Replace(Destinatario.Email, @"(?<=\S)([,;])(?=\S)", "$1 ").Trim(new char[] { ' ', ',', ';' }); sb.AppendChaveValor("Email do Destinatário", destEmail); } - if (!string.IsNullOrEmpty(InformacoesAdicionaisFisco)) + if (ExibirInformacoesAdicionaisFisco && !string.IsNullOrEmpty(InformacoesAdicionaisFisco)) sb.AppendChaveValor("Inf. fisco", InformacoesAdicionaisFisco); - if (!string.IsNullOrEmpty(Pedido) && !Utils.StringContemChaveValor(InformacoesComplementares, "Pedido", Pedido)) + /*if (!string.IsNullOrEmpty(Pedido) && !Utils.StringContemChaveValor(InformacoesComplementares, "Pedido", Pedido)) sb.AppendChaveValor("Pedido", Pedido); if (!string.IsNullOrEmpty(Contrato) && !Utils.StringContemChaveValor(InformacoesComplementares, "Contrato", Contrato)) diff --git a/NFe.Danfe.PdfClown/Modelo/TransportadoraViewModel.cs b/NFe.Danfe.PdfClown/Modelo/TransportadoraViewModel.cs index cc6353bfb..a024441f0 100644 --- a/NFe.Danfe.PdfClown/Modelo/TransportadoraViewModel.cs +++ b/NFe.Danfe.PdfClown/Modelo/TransportadoraViewModel.cs @@ -72,6 +72,12 @@ public class TransportadoraViewModel : EmpresaViewModel /// public Double? PesoBruto { get; set; } + /// + /// Modalidade do frete como o campo "FRETE POR CONTA" do quadro + /// "TRANSPORTADOR / VOLUMES TRANSPORTADOS" do DANFE deve exibi-la: o código seguido do + /// nome da modalidade (ver ). A modalidade 9 + /// ("Sem Transporte") não é impressa. + /// public string ModalidadeFreteString { get @@ -82,8 +88,6 @@ public string ModalidadeFreteString { result = $"{ModalidadeFrete}-{ModalidadesFrete[ModalidadeFrete]}"; if (ModalidadeFrete == 9) result = string.Empty; - if (ModalidadeFrete == 0) result = "0 - CIF"; - if (ModalidadeFrete == 1) result = "1 - FOB"; } else { diff --git a/NFe.Danfe.PdfClown/NFe.Danfe.PdfClown.csproj b/NFe.Danfe.PdfClown/NFe.Danfe.PdfClown.csproj index e17a439a3..e91ef4be4 100644 --- a/NFe.Danfe.PdfClown/NFe.Danfe.PdfClown.csproj +++ b/NFe.Danfe.PdfClown/NFe.Danfe.PdfClown.csproj @@ -1,4 +1,4 @@ - + netstandard2.0;net6.0 diff --git a/NFe.Danfe.PdfClown/Tools/Code128Hibrido.cs b/NFe.Danfe.PdfClown/Tools/Code128Hibrido.cs new file mode 100644 index 000000000..e48f23d6f --- /dev/null +++ b/NFe.Danfe.PdfClown/Tools/Code128Hibrido.cs @@ -0,0 +1,149 @@ +using System.Text.RegularExpressions; + +namespace NFe.Danfe.PdfClown.Tools +{ + /// + /// Codificador CODE-128 híbrido (subconjuntos C e A) conforme a seção 6 da NT Conjunta 2025.001, + /// para o código de barras da chave de acesso com CNPJ alfanumérico. + /// Regras: inicia com Start C (105); alterna para o Code A (código 101) nos caracteres não numéricos; + /// retorna ao Code C (código 99) em corridas de 4 ou mais dígitos ou em corrida final com quantidade + /// par de dígitos; dígito ímpar remanescente antes de uma letra fica no Code A. + /// Conteúdo 100% numérico produz exatamente a sequência do CODE-128 C puro. + /// + public static class Code128Hibrido + { + private const byte StartC = 105; + private const byte TrocaParaCodeA = 101; + private const byte TrocaParaCodeC = 99; + private const byte Stop = 106; + + /// + /// Obtém a sequência completa de símbolos CODE-128 (Start C, dados com as trocas de subconjunto, + /// dígito verificador módulo 103 e Stop) para um conteúdo composto por dígitos e letras maiúsculas. + /// + /// Conteúdo a codificar ([0-9A-Z]+), ex.: chave de acesso de 44 posições + /// Símbolos CODE-128, um valor (0-106) por posição + public static byte[] ObterSimbolos(string codigo) + { + if (string.IsNullOrEmpty(codigo)) + throw new ArgumentException("O código não pode ser vazio.", nameof(codigo)); + + if (!Regex.IsMatch(codigo, "^[0-9A-Z]+$")) + throw new ArgumentException("O código deve conter somente dígitos (0-9) e letras maiúsculas (A-Z).", nameof(codigo)); + + var simbolos = new List { StartC }; + var emCodeC = true; + var i = 0; + + while (i < codigo.Length) + { + var corrida = TamanhoCorridaDeDigitos(codigo, i); + + if (corrida == 0) + { + //caractere não numérico: garante o Code A e codifica a letra + if (emCodeC) + { + simbolos.Add(TrocaParaCodeA); + emCodeC = false; + } + + simbolos.Add(ValorCodeA(codigo[i])); + i++; + continue; + } + + var corridaFinal = i + corrida == codigo.Length; + + if (emCodeC) + { + //em Code C codifica os dígitos aos pares; o dígito ímpar remanescente fica no Code A + for (var p = 0; p < corrida / 2; p++) + { + simbolos.Add(ValorCodeC(codigo, i)); + i += 2; + } + + if (corrida % 2 == 1) + { + simbolos.Add(TrocaParaCodeA); + emCodeC = false; + simbolos.Add(ValorCodeA(codigo[i])); + i++; + } + } + else if (corrida >= 4 || (corridaFinal && corrida % 2 == 0)) + { + //retorna ao Code C para a parte com quantidade par de dígitos + if (corrida % 2 == 1 && corridaFinal) + { + //corrida final ímpar de 4+ dígitos: o primeiro dígito fica no Code A para a parte restante ser par + simbolos.Add(ValorCodeA(codigo[i])); + i++; + corrida--; + } + + simbolos.Add(TrocaParaCodeC); + emCodeC = true; + + for (var p = 0; p < corrida / 2; p++) + { + simbolos.Add(ValorCodeC(codigo, i)); + i += 2; + } + + //corrida ímpar antes de letra: o dígito remanescente é codificado no Code A na próxima iteração + } + else + { + //corrida curta (1 a 3 dígitos) que não justifica a troca: codifica os dígitos no próprio Code A + for (var d = 0; d < corrida; d++) + { + simbolos.Add(ValorCodeA(codigo[i])); + i++; + } + } + } + + simbolos.Add(ObterDigitoVerificador(simbolos)); + simbolos.Add(Stop); + + return simbolos.ToArray(); + } + + /// + /// Dígito verificador módulo 103: soma ponderada dos símbolos, com o start valendo peso 1 + /// e cada símbolo de dados o peso da sua posição + /// + private static byte ObterDigitoVerificador(List simbolos) + { + var soma = (int)simbolos[0]; + + for (var i = 1; i < simbolos.Count; i++) + soma += i * simbolos[i]; + + return (byte)(soma % 103); + } + + private static int TamanhoCorridaDeDigitos(string codigo, int inicio) + { + var fim = inicio; + + while (fim < codigo.Length && codigo[fim] >= '0' && codigo[fim] <= '9') + fim++; + + return fim - inicio; + } + + private static byte ValorCodeC(string codigo, int posicao) + { + return (byte)((codigo[posicao] - '0') * 10 + (codigo[posicao + 1] - '0')); + } + + private static byte ValorCodeA(char caractere) + { + //no Code A os caracteres ASCII 32-95 valem ASCII - 32 ('0'-'9' => 16-25; 'A'-'Z' => 33-58) + return (byte)(caractere - 32); + } + } +} diff --git a/NFe.Danfe.PdfClown/Tools/Formatador.cs b/NFe.Danfe.PdfClown/Tools/Formatador.cs index 20b01c532..3202d715e 100644 --- a/NFe.Danfe.PdfClown/Tools/Formatador.cs +++ b/NFe.Danfe.PdfClown/Tools/Formatador.cs @@ -22,7 +22,7 @@ static Formatador() public const string FormatoNumeroNF = @"000\.000\.000"; public const string CEP = @"^(\d{5})\-?(\d{3})$"; - public const string CNPJ = @"^(\d{2})\.?(\d{3})\.?(\d{3})\/?(\d{4})\-?(\d{2})$"; + public const string CNPJ = @"^([0-9A-Z]{2})\.?([0-9A-Z]{3})\.?([0-9A-Z]{3})\/?([0-9A-Z]{4})\-?([0-9]{2})$"; public const string CPF = @"^(\d{3})\.?(\d{3})\.?(\d{3})\-?(\d{2})$"; public const string Telefone = @"^\(?(\d{2})\)?\s*(\d{4,5})\s*\-?\s*(\d{4})$"; diff --git a/NFe.Danfe.QuestPdf.Testes/ImpressaoNfce/DanfeNfceDocumentTesteUnitario.cs b/NFe.Danfe.QuestPdf.Testes/ImpressaoNfce/DanfeNfceDocumentTesteUnitario.cs new file mode 100644 index 000000000..8e1a372bc --- /dev/null +++ b/NFe.Danfe.QuestPdf.Testes/ImpressaoNfce/DanfeNfceDocumentTesteUnitario.cs @@ -0,0 +1,137 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NFe.Danfe.QuestPdf.ImpressaoNfce; +using QuestPDF.Fluent; +using QuestPDF.Infrastructure; + +namespace NFe.Danfe.QuestPdf.Testes.ImpressaoNfce; + +[TestClass] +public class DanfeNfceDocumentTesteUnitario +{ + [ClassInitialize] + public static void ConfigurarQuestPdf(TestContext _) + { + QuestPDF.Settings.License = LicenseType.Community; + } + + [DataTestMethod] + [DataRow(TamanhoImpressao.Impressao80)] + [DataRow(TamanhoImpressao.Impressao72)] + [DataRow(TamanhoImpressao.Impressao50)] + public void DadaNfceComAjustesNoItemQuandoGerarDanfeEntaoDeveGerarPdf(TamanhoImpressao tamanhoImpressao) + { + var documento = new DanfeNfceDocument(XmlNfce, null) + { + ImprimeDescontoItem = true, + ImprimeAcrescimoItem = true, + ImprimeInformacaoAdicionalItem = true + }; + + documento.TamanhoImpressao(tamanhoImpressao); + + var pdf = documento.GeneratePdf(); + + Assert.IsNotNull(pdf); + Assert.IsTrue(pdf.Length > 0); + } + + private const string XmlNfce = @" + + + + 42 + 00000001 + VENDA + 65 + 1 + 1 + 2026-08-14T12:00:00-03:00 + 1 + 1 + 4209102 + 4 + 1 + 0 + 2 + 1 + 1 + 1 + 0 + Teste + + + 00000000000100 + EMPRESA DE TESTE + EMPRESA DE TESTE + + RUA DE TESTE + 100 + CENTRO + 4209102 + CIDADE DE TESTE + SC + 00000000 + 1058 + BRASIL + + 000000000 + 1 + + + + 1 + SEM GTIN + PRODUTO DE TESTE + 00000000 + 5102 + UN + 1.0000 + 21.0000000000 + 21.00 + SEM GTIN + UN + 1.0000 + 21.0000000000 + 3.00 + 2.00 + 1 + + AZUL/M: 1 + + + + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 21.00 + 0.00 + 0.00 + 3.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 2.00 + 20.00 + 0.00 + + + + + 01 + 20.00 + + + + + https://example.com/qrcode + https://example.com/consulta + +"; +} diff --git a/NFe.Danfe.QuestPdf.Testes/NFe.Danfe.QuestPdf.Testes.csproj b/NFe.Danfe.QuestPdf.Testes/NFe.Danfe.QuestPdf.Testes.csproj new file mode 100644 index 000000000..7fa71f536 --- /dev/null +++ b/NFe.Danfe.QuestPdf.Testes/NFe.Danfe.QuestPdf.Testes.csproj @@ -0,0 +1,24 @@ + + + + net8.0 + enable + enable + false + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/NFe.Danfe.QuestPdf/ImpressaoNfce/DanfeNfceDocument.cs b/NFe.Danfe.QuestPdf/ImpressaoNfce/DanfeNfceDocument.cs index adde1b3a6..b55242d16 100644 --- a/NFe.Danfe.QuestPdf/ImpressaoNfce/DanfeNfceDocument.cs +++ b/NFe.Danfe.QuestPdf/ImpressaoNfce/DanfeNfceDocument.cs @@ -23,6 +23,21 @@ public class DanfeNfceDocument : IDocument private float _tamanhoImpressao = 300f; private float _tamanhoFontePadrao; + /// + /// Define se o desconto e o valor líquido do item devem ser exibidos no DANFE NFC-e. + /// + public bool ImprimeDescontoItem { get; set; } + + /// + /// Define se o acréscimo e o valor líquido do item devem ser exibidos no DANFE NFC-e. + /// + public bool ImprimeAcrescimoItem { get; set; } + + /// + /// Define se as informações adicionais do item devem ser exibidas no DANFE NFC-e. + /// + public bool ImprimeInformacaoAdicionalItem { get; set; } + public DanfeNfceDocument(string xml, byte[]? logo) { _logo = logo; @@ -178,6 +193,11 @@ IContainer CellStyle(IContainer container) foreach (var det in _nfe.infNFe.det) { + var valorDescontoItem = det.prod.vDesc.GetValueOrDefault(); + var valorAcrescimoItem = det.prod.vOutro.GetValueOrDefault(); + var imprimeDescontoItem = ImprimeDescontoItem && valorDescontoItem > 0; + var imprimeAcrescimoItem = ImprimeAcrescimoItem && valorAcrescimoItem > 0; + t.Cell().Text(det.nItem.ToString("D3")).FontSize(_tamanhoFontePadrao - 0.5f); t.Cell().ColumnSpan(11).Text(det.prod.xProd).FontSize(_tamanhoFontePadrao - 0.5f); t.Cell().RowSpan(1); @@ -186,6 +206,44 @@ IContainer CellStyle(IContainer container) t.Cell().ColumnSpan(4).AlignRight().Text(det.prod.vUnCom.ToString("N2")).FontSize(_tamanhoFontePadrao - 0.5f); t.Cell().ColumnSpan(1).AlignCenter(); t.Cell().ColumnSpan(3).AlignRight().Text(det.prod.vProd.ToString("N2")).FontSize(_tamanhoFontePadrao - 0.5f); + + if (imprimeDescontoItem || imprimeAcrescimoItem) + { + var valorLiquidoItem = det.prod.vProd + valorAcrescimoItem - valorDescontoItem; + + t.Cell().ColumnSpan(12).Row(row => + { + if (imprimeDescontoItem) + { + row.RelativeItem().PaddingRight(2).Row(ajuste => + { + ajuste.AutoItem().Text("Desc.").FontSize(_tamanhoFontePadrao - 1); + ajuste.AutoItem().PaddingLeft(2).Text($"R$ -{valorDescontoItem:N2}").FontSize(_tamanhoFontePadrao - 1); + }); + } + + if (imprimeAcrescimoItem) + { + row.RelativeItem().PaddingLeft(2).Row(ajuste => + { + ajuste.AutoItem().Text("Acrésc.").FontSize(_tamanhoFontePadrao - 1); + ajuste.AutoItem().PaddingLeft(2).Text($"R$ +{valorAcrescimoItem:N2}").FontSize(_tamanhoFontePadrao - 1); + }); + } + + row.AutoItem().PaddingLeft(2).Row(liquido => + { + liquido.AutoItem().Text("Líq.").SemiBold().FontSize(_tamanhoFontePadrao - 1); + liquido.AutoItem().PaddingLeft(2).Text($"R$ {valorLiquidoItem:N2}").SemiBold().FontSize(_tamanhoFontePadrao - 1); + }); + }); + } + + if (ImprimeInformacaoAdicionalItem && !string.IsNullOrWhiteSpace(det.infAdProd)) + { + t.Cell().ColumnSpan(12).Text(det.infAdProd).FontSize(_tamanhoFontePadrao - 1); + } + t.Cell().ColumnSpan(12).RowSpan(1).Element(CellStyle); } @@ -278,7 +336,7 @@ private void Rodape(IContainer container) r.RelativeItem().AlignRight().Column(c => { - c.Item().Text($"R$ {_nfe.infNFe.total.ICMSTot.vTotTrib:N2}").FontSize(_tamanhoFontePadrao); + c.Item().Text($"R$ {_nfe.infNFe.total.ICMSTot.vTotTrib ?? 0:N2}").FontSize(_tamanhoFontePadrao); }); }); @@ -627,4 +685,4 @@ private string ObtemDescricao(FormaPagamento? formaPagamento) else throw new ArgumentException("Forma pagamento inválida"); } -} \ No newline at end of file +} diff --git a/NFe.Danfe.QuestPdf/NFe.Danfe.QuestPdf.csproj b/NFe.Danfe.QuestPdf/NFe.Danfe.QuestPdf.csproj index 358752be6..a45de129d 100644 --- a/NFe.Danfe.QuestPdf/NFe.Danfe.QuestPdf.csproj +++ b/NFe.Danfe.QuestPdf/NFe.Danfe.QuestPdf.csproj @@ -28,7 +28,7 @@ - + diff --git a/NFe.Integracao/Program.cs b/NFe.Integracao/Program.cs index 6df36e7af..c91d31b26 100644 --- a/NFe.Integracao/Program.cs +++ b/NFe.Integracao/Program.cs @@ -529,6 +529,12 @@ private static void EnviarNFe(string dadosDoEnvio) try { + if(strPathArquivoXml.Contains("../") || strPathArquivoXml.Contains("..\\")) + { + Console.WriteLine("Caminho do arquivo não pode conter ../ ou ..\\"); + return; + } + File.ReadAllText(strPathArquivoXml); } catch (UnauthorizedAccessException ex) diff --git a/NFe.Servicos/ServicosNFe.cs b/NFe.Servicos/ServicosNFe.cs index 3d40f54b3..13f0be433 100644 --- a/NFe.Servicos/ServicosNFe.cs +++ b/NFe.Servicos/ServicosNFe.cs @@ -855,6 +855,23 @@ public RetornoRecepcaoEvento RecepcaoEventoManifestacaoDestinatario(int idlote, return retorno; } + /// + /// Envia eventos do tipo "Manifestação do destinatário" já assinado. + /// + /// + /// + /// + /// false (padrão) para transmitir os eventos exatamente como vieram, já assinados; true para a biblioteca + /// calcular o Id e assinar cada evento com o certificado desta instância de ServicosNFe, sobrescrevendo o Id + /// que já estiver preenchido. + /// + /// + public RetornoRecepcaoEvento RecepcaoEventoManifestacaoDestinatario(int idlote, List eventos, bool assinar = false) + { + var retorno = RecepcaoEvento(idlote, eventos, ServicoNFe.RecepcaoEventoManifestacaoDestinatario, _cFgServico.VersaoRecepcaoEventoManifestacaoDestinatario, assinar); + return retorno; + } + /// /// Envia um evento do tipo "EPEC" /// @@ -996,6 +1013,23 @@ public RetornoRecepcaoEvento RecepcaoEventoInsucessoEntrega(int idlote, return retorno; } + /// + /// Envia eventos do tipo "Insucesso na Entrega da NF-e" já assinado. + /// + /// + /// + /// + /// false (padrão) para transmitir os eventos exatamente como vieram, já assinados; true para a biblioteca + /// calcular o Id e assinar cada evento com o certificado desta instância de ServicosNFe, sobrescrevendo o Id + /// que já estiver preenchido. + /// + /// + public RetornoRecepcaoEvento RecepcaoEventoInsucessoEntrega(int idlote, List eventos, bool assinar = false) + { + var retorno = RecepcaoEvento(idlote, eventos, ServicoNFe.RecepcaoEventoInsucessoEntregaNFe, _cFgServico.VersaoRecepcaoEventoInsucessoEntrega, assinar); + return retorno; + } + /// /// Serviço para cancelamento insucesso na entrega /// @@ -1048,6 +1082,23 @@ public RetornoRecepcaoEvento RecepcaoEventoCancInsucessoEntrega(int idlote, return retorno; } + /// + /// Envia eventos do tipo "Cancelamento do Insucesso na Entrega da NF-e" já assinado. + /// + /// + /// + /// + /// false (padrão) para transmitir os eventos exatamente como vieram, já assinados; true para a biblioteca + /// calcular o Id e assinar cada evento com o certificado desta instância de ServicosNFe, sobrescrevendo o Id + /// que já estiver preenchido. + /// + /// + public RetornoRecepcaoEvento RecepcaoEventoCancInsucessoEntrega(int idlote, List eventos, bool assinar = false) + { + var retorno = RecepcaoEvento(idlote, eventos, ServicoNFe.RecepcaoEventoCancInsucessoEntregaNFe, _cFgServico.VersaoRecepcaoEventoInsucessoEntrega, assinar); + return retorno; + } + /// /// Recepção do Evento de Comprovante de Entrega /// @@ -1117,6 +1168,23 @@ public RetornoRecepcaoEvento RecepcaoEventoComprovanteEntrega(int idlote, return retorno; } + /// + /// Envia eventos do tipo "Comprovante de Entrega da NF-e" já assinado. + /// + /// + /// + /// + /// false (padrão) para transmitir os eventos exatamente como vieram, já assinados; true para a biblioteca + /// calcular o Id e assinar cada evento com o certificado desta instância de ServicosNFe, sobrescrevendo o Id + /// que já estiver preenchido. + /// + /// + public RetornoRecepcaoEvento RecepcaoEventoComprovanteEntrega(int idlote, List eventos, bool assinar = false) + { + var retorno = RecepcaoEvento(idlote, eventos, ServicoNFe.RecepcaoEventoComprovanteEntregaNFe, _cFgServico.VersaoRecepcaoEventoComprovanteEntrega, assinar); + return retorno; + } + /// /// Serviço para cancelamento comprovante de entrega /// @@ -1170,6 +1238,23 @@ public RetornoRecepcaoEvento RecepcaoEventoCancComprovanteEntrega(int idlote, return retorno; } + /// + /// Envia eventos do tipo "Cancelamento do Comprovante de Entrega da NF-e" já assinado. + /// + /// + /// + /// + /// false (padrão) para transmitir os eventos exatamente como vieram, já assinados; true para a biblioteca + /// calcular o Id e assinar cada evento com o certificado desta instância de ServicosNFe, sobrescrevendo o Id + /// que já estiver preenchido. + /// + /// + public RetornoRecepcaoEvento RecepcaoEventoCancComprovanteEntrega(int idlote, List eventos, bool assinar = false) + { + var retorno = RecepcaoEvento(idlote, eventos, ServicoNFe.RecepcaoEventoCancComprovanteEntregaNFe, _cFgServico.VersaoRecepcaoEventoComprovanteEntrega, assinar); + return retorno; + } + /// /// Recepção do Evento de Conciliação Financeira @@ -1221,6 +1306,23 @@ public RetornoRecepcaoEvento RecepcaoEventoConciliacaoFinanceira(int idlote, return retorno; } + /// + /// Envia eventos do tipo "Conciliação Financeira da NF-e" já assinado. + /// + /// + /// + /// + /// false (padrão) para transmitir os eventos exatamente como vieram, já assinados; true para a biblioteca + /// calcular o Id e assinar cada evento com o certificado desta instância de ServicosNFe, sobrescrevendo o Id + /// que já estiver preenchido. + /// + /// + public RetornoRecepcaoEvento RecepcaoEventoConciliacaoFinanceira(int idlote, List eventos, bool assinar = false) + { + var retorno = RecepcaoEvento(idlote, eventos, ServicoNFe.RecepcaoEventoConciliacaoFinanceiraNFe, _cFgServico.VersaoRecepcaoEventoConciliacaoFinanceira, assinar); + return retorno; + } + /// /// Serviço para cancelamento Conciliação Financeira /// @@ -1348,6 +1450,23 @@ public RetornoRecepcaoEvento RecepcaoEventoSolicitacaoDeApropriacaoDeCreditoPres return retornoRecepcaoEvento; } + /// + /// Envia eventos do tipo "Cancelamento da Conciliação Financeira da NF-e" já assinado. + /// + /// + /// + /// + /// false (padrão) para transmitir os eventos exatamente como vieram, já assinados; true para a biblioteca + /// calcular o Id e assinar cada evento com o certificado desta instância de ServicosNFe, sobrescrevendo o Id + /// que já estiver preenchido. + /// + /// + public RetornoRecepcaoEvento RecepcaoEventoCancConciliacaoFinanceira(int idlote, List eventos, bool assinar = false) + { + var retorno = RecepcaoEvento(idlote, eventos, ServicoNFe.RecepcaoEventoCancConciliacaoFinanceiraNFe, _cFgServico.VersaoRecepcaoEventoConciliacaoFinanceira, assinar); + return retorno; + } + /// /// Serviço para evento destinação de item para consumo pessoal /// @@ -2106,7 +2225,7 @@ public RetornoNfeConsultaCadastro NfeConsultaCadastro(string uf, ConsultaCadastr } var retornoXmlString = retorno.OuterXml; - var retConsulta = new retConsCad().CarregarDeXmlString(retornoXmlString); + var retConsulta = ExtretConsCad.CarregarDeXmlString(retornoXmlString); SalvarArquivoXml(DateTime.Now.ParaDataHoraString() + "-cad.xml", retornoXmlString); diff --git a/NFe.Utils.Testes/ChaveFiscalTesteUnitario.cs b/NFe.Utils.Testes/ChaveFiscalTesteUnitario.cs new file mode 100644 index 000000000..7d17f9955 --- /dev/null +++ b/NFe.Utils.Testes/ChaveFiscalTesteUnitario.cs @@ -0,0 +1,43 @@ +using System; +using DFe.Utils; +using DFe.Classes.Entidades; +using DFe.Classes.Flags; +using NFe.Utils.Testes.Dados; +using Xunit; + +namespace NFe.Utils.Testes; + +public class ChaveFiscalTesteUnitario +{ + [Theory(DisplayName = "Dado cnpj alfanumérico, quando obter chave fiscal, então não deve lançar exceção.")] + [InlineData("T6J3XFX0IVDD47")] + [InlineData("W2MNK0KZ000190")] + public void DadoCnpjAlfanumericoQuandoObterChaveFiscalEntaoNaoDeveLancarExcecao(string cnpj) + { + // Arrange + var estado = Estado.SE; + var data = DateTime.Now; + var modelo = ModeloDocumento.NFe; + var serie = 100; + var numero = 12345; + var tipoEmissao = 1; + var cNf = 12345678; + + // Act + var excecaoCapturada = Record.Exception(() => ChaveFiscal.ObterChave(estado, data, cnpj, modelo, serie, numero, tipoEmissao, cNf)); + + // Assert + Assert.Null(excecaoCapturada); + } + + [Theory(DisplayName = "Dado caractere, quando obter valor do caractere, então deve retornar o valor esperado.")] + [MemberData(nameof(ChaveFiscalDadosDeTeste.ObterCaracteresEValores), MemberType = typeof(ChaveFiscalDadosDeTeste))] + public void DadoCaractereQuandoObterValorEntaoDeveRetornarValorEsperado(char caractere, int valorEsperado) + { + // Act + var valorObtido = ChaveFiscal.ObterValorDoCaractere(caractere); + + // Assert + Assert.Equal(valorEsperado, valorObtido); + } +} diff --git a/NFe.Utils.Testes/Dados/ChaveFiscalDadosDeTeste.cs b/NFe.Utils.Testes/Dados/ChaveFiscalDadosDeTeste.cs new file mode 100644 index 000000000..7bf54ebe1 --- /dev/null +++ b/NFe.Utils.Testes/Dados/ChaveFiscalDadosDeTeste.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; + +namespace NFe.Utils.Testes.Dados; + +public static class ChaveFiscalDadosDeTeste +{ + public static IEnumerable ObterCaracteresEValores() + { + yield return new object[] { '0', 0 }; + yield return new object[] { '1', 1 }; + yield return new object[] { '2', 2 }; + yield return new object[] { '3', 3 }; + yield return new object[] { '4', 4 }; + yield return new object[] { '5', 5 }; + yield return new object[] { '6', 6 }; + yield return new object[] { '7', 7 }; + yield return new object[] { '8', 8 }; + yield return new object[] { '9', 9 }; + + yield return new object[] { 'A', 17 }; + yield return new object[] { 'B', 18 }; + yield return new object[] { 'C', 19 }; + yield return new object[] { 'D', 20 }; + yield return new object[] { 'E', 21 }; + yield return new object[] { 'F', 22 }; + yield return new object[] { 'G', 23 }; + yield return new object[] { 'H', 24 }; + yield return new object[] { 'I', 25 }; + yield return new object[] { 'J', 26 }; + yield return new object[] { 'K', 27 }; + yield return new object[] { 'L', 28 }; + yield return new object[] { 'M', 29 }; + yield return new object[] { 'N', 30 }; + yield return new object[] { 'O', 31 }; + yield return new object[] { 'P', 32 }; + yield return new object[] { 'Q', 33 }; + yield return new object[] { 'R', 34 }; + yield return new object[] { 'S', 35 }; + yield return new object[] { 'T', 36 }; + yield return new object[] { 'U', 37 }; + yield return new object[] { 'V', 38 }; + yield return new object[] { 'W', 39 }; + yield return new object[] { 'X', 40 }; + yield return new object[] { 'Y', 41 }; + yield return new object[] { 'Z', 42 }; + } +} diff --git a/NFe.Utils.Testes/ExtinfNFeSuplChaveAlfanumericaTestes.cs b/NFe.Utils.Testes/ExtinfNFeSuplChaveAlfanumericaTestes.cs new file mode 100644 index 000000000..f4b3fda9e --- /dev/null +++ b/NFe.Utils.Testes/ExtinfNFeSuplChaveAlfanumericaTestes.cs @@ -0,0 +1,82 @@ +using System; +using DFe.Classes.Entidades; +using DFe.Classes.Flags; +using NFe.Classes; +using NFe.Classes.Informacoes; +using NFe.Classes.Informacoes.Identificacao; +using NFe.Classes.Informacoes.Identificacao.Tipos; +using NFe.Classes.Informacoes.Total; +using NFe.Utils.InformacoesSuplementares; +using Xunit; + +namespace NFe.Utils.Testes +{ + /// + /// Testes do QR-Code da NFC-e com chave de acesso contendo CNPJ alfanumérico (NT Conjunta 2025.001) + /// + public class ExtinfNFeSuplChaveAlfanumericaTestes + { + //NFC-e de GO com o CNPJ alfanumérico de teste da Receita (PC3D315K000193); DV da chave = 0 + private const string ChaveAlfanumerica = "522507PC3D315K000193650010000000011000000010"; + + private static Classes.NFe CriarNfce(string chave) + { + return new Classes.NFe + { + infNFe = new infNFe + { + Id = "NFe" + chave, + versao = "4.00", + ide = new ide + { + tpAmb = TipoAmbiente.Homologacao, + cUF = Estado.GO, + tpEmis = TipoEmissao.teNormal, + dhEmi = new DateTimeOffset(2025, 7, 15, 10, 0, 0, TimeSpan.FromHours(-3)) + }, + total = new total + { + ICMSTot = new ICMSTot { vNF = 10.50m } + } + } + }; + } + + [Fact] + public void ObterUrlQrCode2_ComChaveAlfanumerica_MontaAUrlComAChaveSemConversaoNumerica() + { + // Arrange + var nfce = CriarNfce(ChaveAlfanumerica); + + // Act + var url = new infNFeSupl().ObterUrlQrCode(nfce, VersaoQrCode.QrCodeVersao2, "000001", "CSC-DE-TESTE"); + + // Assert + Assert.Contains(ChaveAlfanumerica, url); + + //formato dos parâmetros: chave|versão do QR-Code|ambiente|idCsc|hash SHA-1 + var parametros = url.Substring(url.IndexOf("p=", StringComparison.Ordinal) + 2).Split('|'); + Assert.Equal(5, parametros.Length); + Assert.Equal(ChaveAlfanumerica, parametros[0]); + Assert.Equal("2", parametros[1]); + Assert.Equal("2", parametros[2]); + Assert.Equal("1", parametros[3]); + Assert.Equal(40, parametros[4].Trim().Length); + } + + [Fact] + public void ObterUrlQrCode2_ComChaveNumerica_MantemComportamentoAntigo() + { + // Arrange + var nfce = CriarNfce("23190811820016000167650010000000221100000227"); + + // Act + var url = new infNFeSupl().ObterUrlQrCode(nfce, VersaoQrCode.QrCodeVersao2, "000001", "CSC-DE-TESTE"); + + // Assert + var parametros = url.Substring(url.IndexOf("p=", StringComparison.Ordinal) + 2).Split('|'); + Assert.Equal("23190811820016000167650010000000221100000227", parametros[0]); + Assert.Equal(40, parametros[4].Trim().Length); + } + } +} diff --git a/NFe.Utils.Testes/NFe.Utils.Testes.csproj b/NFe.Utils.Testes/NFe.Utils.Testes.csproj index c84a94097..d0365598d 100644 --- a/NFe.Utils.Testes/NFe.Utils.Testes.csproj +++ b/NFe.Utils.Testes/NFe.Utils.Testes.csproj @@ -19,6 +19,7 @@ + diff --git a/NFe.Utils/Assinatura/Assinador.cs b/NFe.Utils/Assinatura/Assinador.cs index a2fdf8f61..8ffcc5a52 100644 --- a/NFe.Utils/Assinatura/Assinador.cs +++ b/NFe.Utils/Assinatura/Assinador.cs @@ -97,7 +97,7 @@ public static Signature ObterAssinatura(T objeto, string id, X509Certificate2 documento.LoadXml(xml); - var docXml = new SignedXml(documento) { SigningKey = certificadoDigital.PrivateKey }; + var docXml = new SignedXml(documento) { SigningKey = certificadoDigital.GetRSAPrivateKey() }; docXml.SignedInfo.SignatureMethod = signatureMethod; diff --git a/NFe.Utils/ConsultaCadastro/ExtretConsCad.cs b/NFe.Utils/ConsultaCadastro/ExtretConsCad.cs index b9f5b3097..605808aaa 100644 --- a/NFe.Utils/ConsultaCadastro/ExtretConsCad.cs +++ b/NFe.Utils/ConsultaCadastro/ExtretConsCad.cs @@ -31,6 +31,7 @@ /* Rua Comendador Francisco josé da Cunha, 111 - Itabaiana - SE - 49500-000 */ /********************************************************************************/ +using System.Xml; using DFe.Utils; using NFe.Classes.Servicos.ConsultaCadastro; @@ -39,14 +40,18 @@ namespace NFe.Utils.ConsultaCadastro public static class ExtretConsCad { /// - /// Coverte uma string XML no formato NFe para um objeto retConsCad + /// Converte uma string XML no formato NFe para um objeto retConsCad /// - /// /// /// Retorna um objeto do tipo retConsCad - public static retConsCad CarregarDeXmlString(this retConsCad retConsCad, string xmlString) + public static retConsCad CarregarDeXmlString(string xmlString) { - return FuncoesXml.XmlStringParaClasse(xmlString); + var documento = new XmlDocument(); + documento.LoadXml(xmlString); + var node = documento.GetElementsByTagName("retConsCad")[0]; + var xmlParaDeserializar = node?.OuterXml ?? xmlString; + + return FuncoesXml.XmlStringParaClasse(xmlParaDeserializar); } /// diff --git a/NFe.Utils/Conversao.cs b/NFe.Utils/Conversao.cs index 5adaad42b..4222a7f66 100644 --- a/NFe.Utils/Conversao.cs +++ b/NFe.Utils/Conversao.cs @@ -200,6 +200,7 @@ public static string CsticmsParaString(this Csticms csticms) case Csticms.CstPart10: return "10"; case Csticms.Cst20: + case Csticms.CstPart20: return "20"; case Csticms.Cst15: return "15"; diff --git a/NFe.Utils/Enderecos/Enderecador.cs b/NFe.Utils/Enderecos/Enderecador.cs index dd269030d..1868705a9 100644 --- a/NFe.Utils/Enderecos/Enderecador.cs +++ b/NFe.Utils/Enderecos/Enderecador.cs @@ -850,13 +850,15 @@ private static List CarregarEnderecosServicos() addServico(new[] { ServicoNFe.NFeAutorizacao }, versao3, hom, emissao, Estado.PE, nfe, "https://nfehomolog.sefaz.pe.gov.br/nfe-service/services/NfeAutorizacao?wsdl"); addServico(new[] { ServicoNFe.NFeRetAutorizacao }, versao3, hom, emissao, Estado.PE, nfe, "https://nfehomolog.sefaz.pe.gov.br/nfe-service/services/NfeRetAutorizacao?wsdl"); - addServico(new[] { ServicoNFe.NfeInutilizacao }, versao4, hom, emissao, Estado.PE, nfe, "https://nfehomolog.sefaz.pe.gov.br/nfe-service/services/NFeInutilizacao4?wsdl"); - addServico(new[] { ServicoNFe.NfeConsultaProtocolo }, versao4, hom, emissao, Estado.PE, nfe, "https://nfehomolog.sefaz.pe.gov.br/nfe-service/services/NFeConsultaProtocolo4?wsdl"); - addServico(new[] { ServicoNFe.NfeStatusServico }, versao4, hom, emissao, Estado.PE, nfe, "https://nfehomolog.sefaz.pe.gov.br/nfe-service/services/NFeStatusServico4?wsdl"); - addServico(new[] { ServicoNFe.NfeConsultaCadastro }, versao4, hom, emissao, Estado.PE, nfe, "https://nfehomolog.sefaz.pe.gov.br/nfe-service/services/CadConsultaCadastro4?wsdl"); - addServico(eventoCceCanc, versao4, hom, emissao, Estado.PE, nfe, "https://nfehomolog.sefaz.pe.gov.br/nfe-service/services/NFeRecepcaoEvento4?wsdl"); - addServico(new[] { ServicoNFe.NFeAutorizacao }, versao4, hom, emissao, Estado.PE, nfe, "https://nfehomolog.sefaz.pe.gov.br/nfe-service/services/NFeAutorizacao4?wsdl"); - addServico(new[] { ServicoNFe.NFeRetAutorizacao }, versao4, hom, emissao, Estado.PE, nfe, "https://nfehomolog.sefaz.pe.gov.br/nfe-service/services/NFeRetAutorizacao4?wsdl"); + // PE Homologação NFe v4.00 - URLs corrigidas (removido ?wsdl que causava 404) + // Padrão: URLs de produção de PE não usam ?wsdl, homologação também não deveria + addServico(new[] { ServicoNFe.NfeInutilizacao }, versao4, hom, emissao, Estado.PE, nfe, "https://nfehomolog.sefaz.pe.gov.br/nfe-service/services/NFeInutilizacao4"); + addServico(new[] { ServicoNFe.NfeConsultaProtocolo }, versao4, hom, emissao, Estado.PE, nfe, "https://nfehomolog.sefaz.pe.gov.br/nfe-service/services/NFeConsultaProtocolo4"); + addServico(new[] { ServicoNFe.NfeStatusServico }, versao4, hom, emissao, Estado.PE, nfe, "https://nfehomolog.sefaz.pe.gov.br/nfe-service/services/NFeStatusServico4"); + addServico(new[] { ServicoNFe.NfeConsultaCadastro }, versao4, hom, emissao, Estado.PE, nfe, "https://nfehomolog.sefaz.pe.gov.br/nfe-service/services/CadConsultaCadastro4"); + addServico(eventoCceCanc, versao4, hom, emissao, Estado.PE, nfe, "https://nfehomolog.sefaz.pe.gov.br/nfe-service/services/NFeRecepcaoEvento4"); + addServico(new[] { ServicoNFe.NFeAutorizacao }, versao4, hom, emissao, Estado.PE, nfe, "https://nfehomolog.sefaz.pe.gov.br/nfe-service/services/NFeAutorizacao4"); + addServico(new[] { ServicoNFe.NFeRetAutorizacao }, versao4, hom, emissao, Estado.PE, nfe, "https://nfehomolog.sefaz.pe.gov.br/nfe-service/services/NFeRetAutorizacao4"); } diff --git a/NFe.Utils/Evento/Extevento.cs b/NFe.Utils/Evento/Extevento.cs index 95ad2764d..b5fa718ec 100644 --- a/NFe.Utils/Evento/Extevento.cs +++ b/NFe.Utils/Evento/Extevento.cs @@ -34,6 +34,7 @@ using System.Security.Cryptography.X509Certificates; using DFe.Utils; using NFe.Classes.Servicos.Evento; +using NFe.Classes.Servicos.Tipos; using NFe.Utils.Assinatura; namespace NFe.Utils.Evento @@ -50,6 +51,23 @@ public static string ObterXmlString(this evento pedEvento) return FuncoesXml.ClasseParaXmlString(pedEvento); } + /// + /// Obtém o Id de um evento (infEvento/@Id): literal "ID" + tpEvento + chNFe + nSeqEvento com 2 dígitos + /// + /// Uso opcional, para quando o evento for montado fora da biblioteca — por exemplo, para assinar com o + /// certificado numa máquina cliente e depois transmitir com a sobrecarga que recebe o evento já + /// assinado. Os métodos que assinam internamente continuam calculando o Id sozinhos. + /// + /// + /// Código do evento + /// Chave de acesso da NF-e vinculada ao evento + /// Sequencial do evento para o mesmo tipo de evento + /// Retorna o conteúdo do atributo infEvento/@Id + public static string ObterId(NFeTipoEvento tpEvento, string chNFe, int nSeqEvento) + { + return "ID" + ((int)tpEvento) + chNFe + nSeqEvento.ToString().PadLeft(2, '0'); + } + /// /// Assina um objeto evento /// diff --git a/NFe.Utils/InformacoesSuplementares/ExtinfNFeSupl.cs b/NFe.Utils/InformacoesSuplementares/ExtinfNFeSupl.cs index 2599c50b7..28d21870e 100644 --- a/NFe.Utils/InformacoesSuplementares/ExtinfNFeSupl.cs +++ b/NFe.Utils/InformacoesSuplementares/ExtinfNFeSupl.cs @@ -264,7 +264,7 @@ private static List CarregarUrls() {Estado.PR, versao3E4, "http://www.fazenda.pr.gov.br"}, {Estado.PI, versao3E4, "http://webas.sefaz.pi.gov.br/nfceweb-homologacao/consultarNFCe.jsf"}, {Estado.RJ, versao3E4, "http://nfce.fazenda.rj.gov.br/consulta"}, - {Estado.RN, versao3E4, "http://nfce.set.rn.gov.br/consultarNFCe.aspx"}, + {Estado.RN, versao3E4, "http://hom.nfce.set.rn.gov.br/consultarNFCe.aspx"}, {Estado.RS, versao3E4, "https://www.sefaz.rs.gov.br/NFCE/NFCE-COM.aspx"}, {Estado.RO, versao3E4, "http://www.nfce.sefin.ro.gov.br"}, {Estado.RR, versao3E4, "http://200.174.88.103:8080/nfce/servlet/wp_consulta_nfce"}, @@ -302,7 +302,6 @@ private static List CarregarUrls() {Estado.PE, versao3E4, "nfce.sefaz.pe.gov.br/nfce/consulta"}, {Estado.PI, versao3E4, "www.sefaz.pi.gov.br/nfce/consulta"}, {Estado.RJ, versao3E4, "www.fazenda.rj.gov.br/nfce/consulta"}, - {Estado.RN, versao3E4, "www.set.rn.gov.br/nfce/consulta"}, {Estado.RS, versao3E4, "www.sefaz.rs.gov.br/nfce/consulta"}, {Estado.RO, versao3E4, "www.sefin.ro.gov.br/nfce/consulta"}, {Estado.RR, versao3E4, "www.sefaz.rr.gov.br/nfce/consulta"} @@ -320,6 +319,7 @@ private static List CarregarUrls() {Estado.BA, versao3E4, "www.sefaz.ba.gov.br/nfce/consulta"}, {Estado.MT, versao3E4, "http://www.sefaz.mt.gov.br/nfce/consultanfce"}, {Estado.PB, versao3E4, "www.receita.pb.gov.br/nfce/consulta"}, + {Estado.RN, versao3E4, "https://nfce.sefaz.rn.gov.br/portalDFE/NFCe/ConsultaNFCe.aspx"}, {Estado.SP, versao3E4, "https://www.nfce.fazenda.sp.gov.br/consulta"}, {Estado.SE, versao3E4, "http://www.nfce.se.gov.br/nfce/consulta"}, {Estado.GO, versao3E4, "www.sefaz.go.gov.br/nfce/consulta"}, @@ -339,6 +339,7 @@ private static List CarregarUrls() {Estado.BA, versao3E4, "http://hinternet.sefaz.ba.gov.br/nfce/consulta"}, {Estado.MT, versao3E4, "http://homologacao.sefaz.mt.gov.br/nfce/consultanfce"}, {Estado.PB, versao3E4, "www.receita.pb.gov.br/nfcehom"}, + {Estado.RN, versao3E4, "www.set.rn.gov.br/nfce/consulta"}, {Estado.SP, versao3E4, "https://www.homologacao.nfce.fazenda.sp.gov.br/consulta"}, {Estado.SE, versao3E4, "http://www.hom.nfe.se.gov.br/nfce/consulta"}, {Estado.GO, versao3E4, "https://nfewebhomolog.sefaz.go.gov.br/nfeweb/sites/nfce/danfeNFCe"}, @@ -392,13 +393,7 @@ public static string ObterUrlConsulta(this infNFeSupl infNFeSupl, Classes.NFe nf /// public static string ObterUrlQrCode(this infNFeSupl infNFeSupl, Classes.NFe nfe, VersaoQrCode versaoQrCode, string cIdToken, string csc, ConfiguracaoCertificado _cfgCertificado = null) { - Func msgErro = parametro => $"O {parametro} não foi informado!"; - - if (string.IsNullOrEmpty(cIdToken)) - throw new ArgumentNullException(nameof(cIdToken), msgErro("token")); - - if (string.IsNullOrEmpty(csc)) - throw new ArgumentNullException(nameof(cIdToken), msgErro("CSC")); + ValidarPreenchimentoDasInformacoesDeTokenECscSeNecessario(versaoQrCode, cIdToken, csc); var versaoServico = Conversao.StringParaVersaoServico(nfe.infNFe.versao); switch (versaoQrCode) @@ -414,6 +409,19 @@ public static string ObterUrlQrCode(this infNFeSupl infNFeSupl, Classes.NFe nfe, } } + private static void ValidarPreenchimentoDasInformacoesDeTokenECscSeNecessario(VersaoQrCode versaoQrCode, string cIdToken, string csc) + { + if (versaoQrCode == VersaoQrCode.QrCodeVersao3) return; + + Func msgErro = parametro => $"O {parametro} não foi informado!"; + + if (string.IsNullOrEmpty(cIdToken)) + throw new ArgumentNullException(nameof(cIdToken), msgErro("token")); + + if (string.IsNullOrEmpty(csc)) + throw new ArgumentNullException(nameof(csc), msgErro("CSC")); + } + /// /// Obtém a URL para uso no QR-Code, versão 1.0 - leiaute 3.10 /// diff --git a/NFe.Utils/Inutilizacao/ExtinutNFe.cs b/NFe.Utils/Inutilizacao/ExtinutNFe.cs index 9b0dab15b..db0b09cf5 100644 --- a/NFe.Utils/Inutilizacao/ExtinutNFe.cs +++ b/NFe.Utils/Inutilizacao/ExtinutNFe.cs @@ -32,6 +32,8 @@ /********************************************************************************/ using System; using System.Security.Cryptography.X509Certificates; +using DFe.Classes.Entidades; +using DFe.Classes.Flags; using DFe.Utils; using NFe.Classes.Servicos.Inutilizacao; using NFe.Utils.Assinatura; @@ -61,6 +63,36 @@ public static string ObterXmlString(this inutNFe pedInutilizacao) return FuncoesXml.ClasseParaXmlString(pedInutilizacao); } + /// + /// Obtém o Id de um pedido de inutilização (infInut/@Id): literal "ID" + cUF + ano com 2 dígitos + CNPJ + + /// modelo + série com 3 dígitos + número inicial e número final com 9 dígitos + /// + /// Uso opcional, para quando o pedido for montado fora da biblioteca — por exemplo, para assinar com o + /// certificado numa máquina cliente e depois transmitir com já feito, via a + /// sobrecarga que recebe o inutNFe pronto. O método que assina internamente continua calculando o Id + /// sozinho. + /// + /// + /// Código da UF do solicitante + /// Ano de inutilização da numeração + /// CNPJ do emitente + /// Modelo do documento + /// Série + /// Número inicial a ser inutilizado + /// Número final a ser inutilizado + /// Retorna o conteúdo do atributo infInut/@Id + public static string ObterId(Estado cUF, int ano, string cnpj, ModeloDocumento modelo, int serie, + int numeroInicial, int numeroFinal) + { + var numId = string.Concat((int)cUF, ano.ToString("D2"), + cnpj, (int)modelo, + serie.ToString().PadLeft(3, '0'), + numeroInicial.ToString().PadLeft(9, '0'), + numeroFinal.ToString().PadLeft(9, '0')); + + return "ID" + numId; + } + /// /// Assina um objeto inutNFe /// diff --git a/NFe.Utils/Tributacao/Estadual/ICMSGeral.cs b/NFe.Utils/Tributacao/Estadual/ICMSGeral.cs index 35fbadffc..c29a7eb64 100644 --- a/NFe.Utils/Tributacao/Estadual/ICMSGeral.cs +++ b/NFe.Utils/Tributacao/Estadual/ICMSGeral.cs @@ -129,6 +129,7 @@ public ICMSBasico ObterICMSBasico(CRT crt) icmsBasico = new ICMS15(); break; case Csticms.CstPart10: + case Csticms.CstPart20: case Csticms.CstPart90: icmsBasico = new ICMSPart(); break; @@ -242,6 +243,11 @@ public ICMSBasico ObterICMSBasico(CRT crt) /// public decimal pRedBC { get; set; } + /// + /// Código de Benefício Fiscal na UF aplicado ao item quando houver RBC. + /// + public string cBenefRBC { get; set; } + /// /// Valor do ICMS desonerado /// @@ -367,6 +373,21 @@ public ICMSBasico ObterICMSBasico(CRT crt) /// public decimal? vFCPST { get; set; } + /// + /// Percentual do diferimento do ICMS relativo ao Fundo de Combate à Pobreza (FCP) + /// + public decimal? pFCPDif { get; set; } + + /// + /// Valor do ICMS relativo ao Fundo de Combate à Pobreza (FCP) diferido + /// + public decimal? vFCPDif { get; set; } + + /// + /// Valor efetivo do ICMS relativo ao Fundo de Combate à Pobreza (FCP) + /// + public decimal? vFCPEfet { get; set; } + #endregion /// @@ -432,4 +453,4 @@ public ICMSBasico ObterICMSBasico(CRT crt) public decimal? vICMSMonoRet { get; set; } } -} \ No newline at end of file +} diff --git a/NFe.Utils/Validacao/Validador.cs b/NFe.Utils/Validacao/Validador.cs index dd6ac2010..28e4b23e8 100644 --- a/NFe.Utils/Validacao/Validador.cs +++ b/NFe.Utils/Validacao/Validador.cs @@ -1,4 +1,4 @@ -/********************************************************************************/ +/********************************************************************************/ /* Projeto: Biblioteca ZeusNFe */ /* Biblioteca C# para emissão de Nota Fiscal Eletrônica - NFe e Nota Fiscal de */ /* Consumidor Eletrônica - NFC-e (http://www.nfe.fazenda.gov.br) */ @@ -169,7 +169,7 @@ internal static string ObterArquivoSchema(ServicoNFe servicoNFe, VersaoServico v public static void Valida(ServicoNFe servicoNFe, VersaoServico versaoServico, string stringXml, bool validarLote = true, ConfiguracaoServico cfgServico = null) { - var pathSchema = String.Empty; + string pathSchema = string.Empty; if (cfgServico == null || (cfgServico != null && string.IsNullOrWhiteSpace(cfgServico.DiretorioSchemas))) pathSchema = ConfiguracaoServico.Instancia.DiretorioSchemas; @@ -181,7 +181,7 @@ public static void Valida(ServicoNFe servicoNFe, VersaoServico versaoServico, st public static string[] Valida(ServicoNFe servicoNFe, VersaoServico versaoServico, string stringXml, bool validarLote = true, string pathSchema = null) { - var falhas = new StringBuilder(); + StringBuilder falhas = new StringBuilder(); if (!Directory.Exists(pathSchema)) throw new Exception("Diretório de Schemas não encontrado: \n" + pathSchema); @@ -189,11 +189,18 @@ public static string[] Valida(ServicoNFe servicoNFe, VersaoServico versaoServico var arquivoSchema = Path.Combine(pathSchema, ObterArquivoSchema(servicoNFe, versaoServico, stringXml, validarLote)); // Define o tipo de validação - var cfg = new XmlReaderSettings { ValidationType = ValidationType.Schema }; + XmlReaderSettings cfg = new XmlReaderSettings + { + ValidationType = ValidationType.Schema, // Previne ataques XXE: nao permite resolver recursos externos + DtdProcessing = DtdProcessing.Prohibit, + XmlResolver = null + }; // Carrega o arquivo de esquema - var schemas = new XmlSchemaSet(); - schemas.XmlResolver = new XmlUrlResolver(); + XmlSchemaSet schemas = new XmlSchemaSet + { + XmlResolver = new XmlUrlResolver() + }; cfg.Schemas = schemas; // Quando carregar o eschema, especificar o namespace que ele valida @@ -205,14 +212,14 @@ public static string[] Valida(ServicoNFe servicoNFe, VersaoServico versaoServico string message = args.Message.ToLower().RemoverAcentos(); 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")) || + (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... + //no futuro adicionar novos aqui... )) { falhas.AppendLine($"[{args.Severity}] - {message} {args.Exception?.Message} " + @@ -223,17 +230,13 @@ public static string[] Valida(ServicoNFe servicoNFe, VersaoServico versaoServico }; // cria um leitor para validação - var validator = XmlReader.Create(new StringReader(stringXml), cfg); + XmlReader validator = XmlReader.Create(new StringReader(stringXml), cfg); try { // Faz a leitura de todos os dados XML - while (validator.Read()) - { - } - } - catch - { + while (validator.Read()) { } } + catch { } finally { validator.Close(); @@ -244,7 +247,5 @@ public static string[] Valida(ServicoNFe servicoNFe, VersaoServico versaoServico return falhas.ToString().Trim().Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); } - - } } \ No newline at end of file diff --git a/Shared.NFe.Danfe/DanfeSharedHelper.cs b/Shared.NFe.Danfe/DanfeSharedHelper.cs index 4688b45fc..64e05f02f 100644 --- a/Shared.NFe.Danfe/DanfeSharedHelper.cs +++ b/Shared.NFe.Danfe/DanfeSharedHelper.cs @@ -9,6 +9,7 @@ using NFe.Utils; using NFe.Utils.InformacoesSuplementares; using System; +using System.Collections.Generic; using System.Drawing; using System.IO; using System.Text.RegularExpressions; @@ -21,11 +22,11 @@ public static Report GenerateDanfeNfceReport(nfeProc proc, ConfiguracaoDanfeNfce { //Define as variáveis que serão usadas no relatório (dúvidas a respeito do fast reports consulte a documentação em https://www.fast-report.com/pt/product/fast-report-net/documentation/) - Report relatorio = new Report(); + Report relatorio = new Report(); if (!string.IsNullOrEmpty(arquivoRelatorio)) relatorio.Load(arquivoRelatorio); - else if(frx != null && frx.Length > 0) + else if (frx != null && frx.Length > 0) relatorio.Load(new MemoryStream(frx)); else throw new Exception("Erro em DanfeSharedHelper.GenerateDanfeNfceReport no Zeus.DFe. Relatório não encontrado, passe os parametros 'frx' com bytes ou 'arquivoRelatorio' com o caminho do arquivo"); @@ -83,8 +84,8 @@ public static Report GenerateDanfeFrEventoReport(nfeProc proc, procEventoNFe pro { //Define as variáveis que serão usadas no relatório (dúvidas a respeito do fast reports consulte a documentação em https://www.fast-report.com/pt/product/fast-report-net/documentation/) - Report relatorio = new Report(); - + Report relatorio = new Report(); + if (!string.IsNullOrEmpty(arquivoRelatorio)) relatorio.Load(arquivoRelatorio); else if (frx != null && frx.Length > 0) @@ -117,6 +118,59 @@ public static Report GenerateDanfeFrNfeReport(nfeProc proc, ConfiguracaoDanfeNfe relatorio.RegisterData(new[] { proc }, "NFe", 20); relatorio.GetDataSource("NFe").Enabled = true; + ConfigurarParametrosRelatorioNfe(relatorio, proc, configuracaoDanfeNfe, desenvolvedor); + + return relatorio; + } + + public static Report GenerateDanfeFrNfeBatchReport(List procs, ConfiguracaoDanfeNfe configuracaoDanfeNfe, byte[] frx, string desenvolvedor, string arquivoRelatorio) + { + if (procs == null || procs.Count == 0) + throw new ArgumentException("A lista de notas fiscais não pode estar vazia.", nameof(procs)); + + //Define as variáveis que serão usadas no relatório (dúvidas a respeito do fast reports consulte a documentação em https://www.fast-report.com/pt/product/fast-report-net/documentation/) + + Report relatorio = new Report(); + + if (!string.IsNullOrEmpty(arquivoRelatorio)) + relatorio.Load(arquivoRelatorio); + else if (frx != null && frx.Length > 0) + relatorio.Load(new MemoryStream(frx)); + else + throw new Exception("Erro em DanfeSharedHelper.GenerateDanfeFrNfeBatchReport no Zeus.DFe. Relatório não encontrado, passe os parametros 'frx' com bytes ou 'arquivoRelatorio' com o caminho do arquivo"); + + bool primeiroRelatorio = true; + + foreach (var proc in procs) + { + relatorio.RegisterData(new[] { proc }, "NFe", 20); + relatorio.GetDataSource("NFe").Enabled = true; + + ConfigurarParametrosRelatorioNfe(relatorio, proc, configuracaoDanfeNfe, desenvolvedor); + + if (primeiroRelatorio) + { + relatorio.Prepare(); + primeiroRelatorio = false; + } + else + { + relatorio.Prepare(true); + } + } + + return relatorio; + } + + /// + /// Public pois caso voce implemente na mão utilize esse metodo para configurar o relatorio de danfe + /// + /// + /// + /// + /// + public static void ConfigurarParametrosRelatorioNfe(Report relatorio, nfeProc proc, ConfiguracaoDanfeNfe configuracaoDanfeNfe, string desenvolvedor) + { string mensagem = string.Empty; string resumoCanhoto = string.Empty; string contingenciaDescricao = string.Empty; @@ -237,8 +291,188 @@ public static Report GenerateDanfeFrNfeReport(nfeProc proc, ConfiguracaoDanfeNfe relatorio.SetParameterValue("DecimaisValorUnitario", configuracaoDanfeNfe.DecimaisValorUnitario); relatorio.SetParameterValue("DecimaisQuantidadeItem", configuracaoDanfeNfe.DecimaisQuantidadeItem); relatorio.SetParameterValue("DataHoraImpressao", configuracaoDanfeNfe.DataHoraImpressao ?? DateTime.Now); + } + + public static Report GenerateDanfeFrNfeSimplificadoTipo2Report(nfeProc proc, ConfiguracaoDanfeNfeSimplificadoTipo2 configuracao, string cIdToken, string csc, byte[] frx, string desenvolvedor, string arquivoRelatorio, string textoRodape = "") + { + Report relatorio = new Report(); + + if (!string.IsNullOrEmpty(arquivoRelatorio)) + relatorio.Load(arquivoRelatorio); + else if (frx != null && frx.Length > 0) + relatorio.Load(new MemoryStream(frx)); + else + throw new Exception("Erro em DanfeSharedHelper.GenerateDanfeFrNfeSimplificadoTipo2Report no Zeus.DFe. Relatório não encontrado, passe os parametros 'frx' com bytes ou 'arquivoRelatorio' com o caminho do arquivo"); + + relatorio.RegisterData(new[] { proc }, "NFe", 20); + relatorio.GetDataSource("NFe").Enabled = true; + + relatorio.SetParameterValue("NfeSimplificadoTipo2DetalheVendaNormal", configuracao.DetalheVendaNormal); + relatorio.SetParameterValue("NfeSimplificadoTipo2DetalheVendaContigencia", configuracao.DetalheVendaContigencia); + relatorio.SetParameterValue("NfeSimplificadoTipo2ImprimeDescontoItem", configuracao.ImprimeDescontoItem); + relatorio.SetParameterValue("NfeSimplificadoTipo2ImprimeFoneEmitente", configuracao.ImprimeFoneEmitente); + + string foneEmitente = null; + + if (proc.NFe.infNFe.emit.enderEmit.fone != null) + foneEmitente = proc.NFe.infNFe.emit.enderEmit.fone.ToString(); + + if (foneEmitente != null && foneEmitente.Length == 10) + foneEmitente = string.Format("{0:(00)0000-0000}", Convert.ToInt64(foneEmitente)); + else if (foneEmitente != null && foneEmitente.Length == 11) + foneEmitente = string.Format("{0:(00)00000-0000}", Convert.ToInt64(foneEmitente)); + + relatorio.SetParameterValue("NfeSimplificadoTipo2FoneEmitente", foneEmitente); + relatorio.SetParameterValue("NfeSimplificadoTipo2ModoImpressao", configuracao.ModoImpressao); + relatorio.SetParameterValue("NfeSimplificadoTipo2Cancelado", configuracao.DocumentoCancelado); + relatorio.SetParameterValue("NfeSimplificadoTipo2LayoutQrCode", configuracao.LayoutQrCode); + relatorio.SetParameterValue("TextoRodape", textoRodape); + + ((ReportPage)relatorio.FindObject("PgNfeSimplificadoTipo2")).LeftMargin = configuracao.MargemEsquerda; + ((ReportPage)relatorio.FindObject("PgNfeSimplificadoTipo2")).RightMargin = configuracao.MargemDireita; + + var logomarcaEmitDefinida = configuracao.Logomarca != null && configuracao.Logomarca.Length > 0; + var rtbEmitLogo = relatorio.FindObject("rtbEmitLogo") as ReportTitleBand; + if (rtbEmitLogo != null) + { + rtbEmitLogo.Visible = logomarcaEmitDefinida; + if (logomarcaEmitDefinida) + { + var poEmitLogo = relatorio.FindObject("poEmitLogo") as PictureObject; + poEmitLogo?.SetImageData(configuracao.Logomarca); + } + } + + ((TextObject)relatorio.FindObject("txtUrl")).Text = string.IsNullOrEmpty(proc.NFe.infNFeSupl?.urlChave) ? proc.NFe.infNFeSupl.ObterUrlConsulta(proc.NFe, configuracao.VersaoQrCode) : proc.NFe.infNFeSupl.urlChave; + ((BarcodeObject)relatorio.FindObject("bcoQrCode")).Text = proc.NFe.infNFeSupl == null ? proc.NFe.infNFeSupl.ObterUrlQrCode(proc.NFe, configuracao.VersaoQrCode, cIdToken, csc) : proc.NFe.infNFeSupl.qrCode; + ((BarcodeObject)relatorio.FindObject("bcoQrCodeLateral")).Text = proc.NFe.infNFeSupl == null ? proc.NFe.infNFeSupl.ObterUrlQrCode(proc.NFe, configuracao.VersaoQrCode, cIdToken, csc) : proc.NFe.infNFeSupl.qrCode; + + string mensagem = string.Empty; + string resumoCanhoto = string.Empty; + string contingenciaDescricao = string.Empty; + string contingenciaValor = string.Empty; + string consultaAutenticidade = "Consulta de autenticidade no portal nacional da NF-e" + Environment.NewLine + + "www.nfe.fazenda.gov.br/portal ou no site da Sefaz autorizadora"; + + if (configuracao.ExibirResumoCanhoto) + { + resumoCanhoto = string.IsNullOrEmpty(configuracao.ResumoCanhoto) ? + string.Format("Emissão: {0: dd/MM/yyyy} Dest/Reme: {1} Valor Total: {2:C}", proc.NFe.infNFe.ide.dhEmi, + proc.NFe.infNFe.dest.xNome, proc.NFe.infNFe.total.ICMSTot.vNF) : + configuracao.ResumoCanhoto; + } + + if (proc.NFe.infNFe.ide.tpAmb == TipoAmbiente.Homologacao) + { + if (proc.NFe.infNFe.ide.tpEmis == TipoEmissao.teSCAN || + proc.NFe.infNFe.ide.tpEmis == TipoEmissao.teEPEC || + proc.NFe.infNFe.ide.tpEmis == TipoEmissao.teFSDA || + proc.NFe.infNFe.ide.tpEmis == TipoEmissao.teFSIA) + { + if (proc.protNFe != null && proc.protNFe.infProt != null && + (proc.protNFe.infProt.cStat == 101 || + proc.protNFe.infProt.cStat == 135 || + proc.protNFe.infProt.cStat == 151 || + proc.protNFe.infProt.cStat == 155)) + { + mensagem = "NFe sem Valor Fiscal - HOMOLOGAÇÃO" + Environment.NewLine + + "NFe em Contingência - CANCELADA"; + } + else + { + mensagem = "NFe sem Valor Fiscal - HOMOLOGAÇÃO" + Environment.NewLine + + "NFe em Contingência"; + } + } + else + { + mensagem = "NFe sem Valor Fiscal - HOMOLOGAÇÃO"; + } + } + else + { + if (configuracao.DocumentoCancelado || + (proc.protNFe != null && proc.protNFe.infProt != null && + !string.IsNullOrEmpty(proc.protNFe.infProt.nProt) && + (proc.protNFe.infProt.cStat == 101 || + proc.protNFe.infProt.cStat == 135 || + proc.protNFe.infProt.cStat == 151 || + proc.protNFe.infProt.cStat == 155))) + { + mensagem = "NFe Cancelada"; + } + else if (proc.protNFe != null && proc.protNFe.infProt != null && + (proc.protNFe.infProt.cStat == 110 || + proc.protNFe.infProt.cStat == 301 || + proc.protNFe.infProt.cStat == 302 || + proc.protNFe.infProt.cStat == 303)) + { + mensagem = "NFe denegada pelo Fisco"; + } + else if (proc.protNFe != null && proc.protNFe.infProt != null && + string.IsNullOrEmpty(proc.protNFe.infProt.nProt)) + { + mensagem = "NFe sem Autorização de Uso da SEFAZ"; + } + } + + switch (proc.NFe.infNFe.ide.tpEmis) + { + case TipoEmissao.teNormal: + case TipoEmissao.teSCAN: + case TipoEmissao.teSVCAN: + case TipoEmissao.teSVCRS: + contingenciaDescricao = "PROTOCOLO DE AUTORIZAÇÃO DE USO"; + contingenciaValor = ((proc.protNFe == null || proc.protNFe.infProt == null || string.IsNullOrEmpty(proc.protNFe.infProt.nProt)) ? "NFe sem Autorização de Uso da SEFAZ" : string.Format("{0} - {1:dd/MM/yyyy HH:mm:ss}", proc.protNFe.infProt.nProt, proc.protNFe.infProt.dhRecbto)); + if (configuracao.DocumentoCancelado || (proc.protNFe != null && proc.protNFe.infProt != null && (proc.protNFe.infProt.cStat == 101 || proc.protNFe.infProt.cStat == 151 || proc.protNFe.infProt.cStat == 155))) + { + contingenciaDescricao = "PROTOCOLO DE HOMOLOGAÇÃO DO CANCELAMENTO"; + } + else if (proc.protNFe != null && proc.protNFe.infProt != null && (proc.protNFe.infProt.cStat == 110 || proc.protNFe.infProt.cStat == 301 || proc.protNFe.infProt.cStat == 302 || proc.protNFe.infProt.cStat == 303)) + { + contingenciaDescricao = "PROTOCOLO DE DENEGAÇÃO DE USO"; + } + break; + + case TipoEmissao.teFSIA: + case TipoEmissao.teEPEC: + case TipoEmissao.teFSDA: + contingenciaDescricao = "DADOS DA NF-E"; + contingenciaValor = Regex.Replace(configuracao.ChaveContingencia, ".{4}", "$0 "); + consultaAutenticidade = string.Empty; + break; + + default: + contingenciaValor = string.Format("{0} - {1:dd/MM/yyyy HH:mm:ss}", proc.protNFe.infProt.nProt, proc.protNFe.infProt.dhRecbto); + break; + } + + relatorio.SetParameterValue("ResumoCanhoto", resumoCanhoto); + relatorio.SetParameterValue("Mensagem", mensagem); + relatorio.SetParameterValue("ConsultaAutenticidade", consultaAutenticidade); + relatorio.SetParameterValue("ContingenciaDescricao", contingenciaDescricao); + relatorio.SetParameterValue("ContingenciaValor", contingenciaValor); + relatorio.SetParameterValue("ContingenciaID", configuracao.ChaveContingencia); + relatorio.SetParameterValue("DuasLinhas", configuracao.DuasLinhas); + relatorio.SetParameterValue("Desenvolvedor", desenvolvedor); + relatorio.SetParameterValue("QuebrarLinhasObservacao", configuracao.QuebrarLinhasObservacao); + relatorio.SetParameterValue("ImprimirISSQN", configuracao.ImprimirISSQN); + relatorio.SetParameterValue("ImprimirDescPorc", configuracao.ImprimirDescPorc); + relatorio.SetParameterValue("ImprimirTotalLiquido", configuracao.ImprimirTotalLiquido); + relatorio.SetParameterValue("ImprimirUnidQtdeValor", configuracao.ImprimirUnidQtdeValor); + relatorio.SetParameterValue("ExibeCampoFatura", configuracao.ExibeCampoFatura); + relatorio.SetParameterValue("Logo", configuracao.Logomarca); + relatorio.SetParameterValue("ExibirTotalTributos", configuracao.ExibirTotalTributos); + relatorio.SetParameterValue("DecimaisValorUnitario", configuracao.DecimaisValorUnitario); + relatorio.SetParameterValue("DecimaisQuantidadeItem", configuracao.DecimaisQuantidadeItem); + relatorio.SetParameterValue("DataHoraImpressao", configuracao.DataHoraImpressao ?? DateTime.Now); + +#if !openfastreport && !fastskia + if (configuracao.SegundaViaContingencia) + relatorio.PrintSettings.Copies = (proc.NFe.infNFe.ide.tpEmis == TipoEmissao.teNormal | (proc.protNFe != null && proc.protNFe.infProt != null && NfeSituacao.Autorizada(proc.protNFe.infProt.cStat))) ? 1 : 2; +#endif return relatorio; } } -} +} \ No newline at end of file diff --git a/Zeus NFe.sln b/Zeus NFe.sln index 2c18b783f..7271f3e39 100644 --- a/Zeus NFe.sln +++ b/Zeus NFe.sln @@ -131,6 +131,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NFe.Danfe.AppTeste.PdfClown EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NFe.Danfe.AppTeste.QuestPdf", "NFe.Danfe.AppTeste.QuestPdf\NFe.Danfe.AppTeste.QuestPdf.csproj", "{F1983240-E8C8-2BAD-5588-DC75E719E5F0}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NFe.Danfe.QuestPdf.Testes", "NFe.Danfe.QuestPdf.Testes\NFe.Danfe.QuestPdf.Testes.csproj", "{0479CFCF-7976-4701-ADFA-BAF149F15277}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -523,6 +525,14 @@ Global {F1983240-E8C8-2BAD-5588-DC75E719E5F0}.Release|Any CPU.Build.0 = Release|Any CPU {F1983240-E8C8-2BAD-5588-DC75E719E5F0}.Release|x86.ActiveCfg = Release|Any CPU {F1983240-E8C8-2BAD-5588-DC75E719E5F0}.Release|x86.Build.0 = Release|Any CPU + {0479CFCF-7976-4701-ADFA-BAF149F15277}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0479CFCF-7976-4701-ADFA-BAF149F15277}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0479CFCF-7976-4701-ADFA-BAF149F15277}.Debug|x86.ActiveCfg = Debug|Any CPU + {0479CFCF-7976-4701-ADFA-BAF149F15277}.Debug|x86.Build.0 = Debug|Any CPU + {0479CFCF-7976-4701-ADFA-BAF149F15277}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0479CFCF-7976-4701-ADFA-BAF149F15277}.Release|Any CPU.Build.0 = Release|Any CPU + {0479CFCF-7976-4701-ADFA-BAF149F15277}.Release|x86.ActiveCfg = Release|Any CPU + {0479CFCF-7976-4701-ADFA-BAF149F15277}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -584,6 +594,7 @@ Global {9E2125F8-2367-444A-B5D5-B7C61FCB456B} = {164EF13E-7F27-4BC8-92A4-A82B1696B279} {60EEDECD-F064-4751-82D9-FCE07FFC8EC1} = {3AC1A3D4-91D0-471A-AF9C-5EF8442F3F27} {F1983240-E8C8-2BAD-5588-DC75E719E5F0} = {3AC1A3D4-91D0-471A-AF9C-5EF8442F3F27} + {0479CFCF-7976-4701-ADFA-BAF149F15277} = {164EF13E-7F27-4BC8-92A4-A82B1696B279} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C8C4D9F7-EF86-49A2-83AF-13FA5D4E8DBB}