Classe para gerar xml nfe/nfce

Aqui você poderá oferecer suas Contribuições, Dicas e Tutoriais (Texto ou Vídeo) que sejam de interesse de todos.

Moderador: Moderadores

malcarli
Usuário Nível 3
Usuário Nível 3
Mensagens: 260
Registrado em: 20 Ago 2015 18:14
Localização: marilia/sp
Curtiram: 2 vezes

Classe para gerar xml nfe/nfce

Mensagem por malcarli »

Malc_GeraXml
Classe para Geração de XML de DF-e (NF-e Modelo 55 e NFC-e Modelo 65) em Harbour

Uma biblioteca nativa, profissional e de alta performance desenvolvida em Harbour para geração de arquivos XML destinados à Nota Fiscal Eletrônica (NF-e) e Nota Fiscal de Consumidor Eletrônica (NFC-e).

Esta classe foi totalmente atualizada e já contempla as novas tags da Reforma Tributária do Consumo (RTC), além de manter compatibilidade com os padrões atuais das Notas Fiscais estruturadas no padrão NF-e 4.00 e NFC-e 4.00.

📌 Considerações Importantes
⚠️ A Malc_GeraXml não inventa nada. Tudo o que é gerado e estruturado por esta classe segue estritamente as regras de negócio, notas técnicas e os manuais de orientação do contribuinte disponibilizados pelo governo (SEFAZ).

💡 Projeto em evolução contínua: Qualquer contribuição é extremamente válida! Esta ainda não é uma classe definitiva, uma vez que muitas alterações e regulamentações na legislação da Reforma Tributária ainda estão em processo de definição e publicação pelos órgãos competentes.

✨ Características Principais
Compatibilidade: Desenvolvida especificamente para ecossistemas Harbour e xHarbour.
Modelos Suportados: NF-e (Modelo 55) e NFC-e (Modelo 65).
Versão do Leiaute: Atualizada com o padrão nacional 4.00.
Pronta para a Reforma Tributária (RTC): Suporte nativo para os novos grupos de tributação do IBS (Imposto sobre Bens e Serviços) e CBS (Contribuição sobre Bens e Serviços).
Segurança e Manipulação Limpa: Métodos estruturados que automatizam a validação, formatação de tags vazias e tratamento de caracteres especiais inerentes ao formato XML.
🛠️ Principais Métodos Disponíveis
A classe organiza a nota fiscal de forma modularizada e hierárquica através de métodos intuitivos:

1. Inicialização e Configuração
New(): Instancia o objeto da classe e limpa o buffer do XML.
SetVersao( cVersao ): Define a versão do leiaute (Padrão: "4.00").
2. Estrutura e Identificação (Grupo A, B, C e D)
GeraA01( cId ): Cria o nó raiz da NF-e com a chave de acesso.
GeraB01( ... ): Identificação da Nota Fiscal Eletrônica (Série, Número, Datas, Tipo de Operação).
GeraC01( ... ): Dados do Emitente (CNPJ/CPF, Razão Social, IE, CRT).
GeraE01( ... ): Dados do Destinatário/Remetente.
3. Detalhamento de Produtos e Itens (Grupo H e I)
GeraH01( nItem ): Inicializa um novo item de produto na nota.
GeraI01( ... ): Dados do Produto/Serviço (Código, EAN, NCM, CFOP, Unidade, Quantidade, Valor).
4. Tributação Avançada (Grupo N)
Suporte a todos os regimes de ICMS comuns (CST e CSOSN).
Suporte aos grupos de PIS, COFINS e IPI.
Grupo RTC (Reforma Tributária): Métodos dedicados para inserção das novas tags de CBS e IBS conforme os novos manuais técnicos da SEFAZ.
🚀 Exemplo Básico de Uso
Abaixo, um exemplo simples de como instanciar a classe e iniciar a montagem de uma estrutura básica de nota fiscal no seu código Harbour:

Código: Selecionar todos

Static Procedure fGerarxml()
   Local oXml:= Malc_GeraXml():New(), i:= 0 // Chamar a classe para gerar xml nfe/nfce no objeto oXml 

   WaitWindow([Gerando Nfe ] + oXml:cVersao + [. Aguarde término do processo...], .T.)  /// pegou a versão padrão do lay-out da nfe/nfce

   * Padronização utilizada na nomenclatura das tags
   * oXml:cNf      => cNf o primeiro caracter (c) indica que é um valor caractér
   * oXml:dDatae   => dDatae  o primeiro caracter (d) indica que é um valor Date
   * oXml:nVlFrete => nVlFrete o primeiro caracter (n) indica que é um valor numérico
   * foi tentado manter o nome da varíavel da classe com o nome da tag, mas como existe algumas repetidas houve a distinção entre elas 
   * por exemplo   => oXml:cXnomee => razão social do emitente e oXml:cXnomed  => razão social do destinatário

   *** Cria o xml
   oXml:cNf      := [52]
   oXml:cUf      := [35] // se fosse omitido esse valor o padrão é 35 ou seja sp
   oXml:cCnpj    := [12.345.678/0001-90]    // pode ser enviado com pontos e barras ou sem sinais que será removido pela classe
   oXml:cNrdoc   := oXml:cNf + Strzero(Day(Date()), 2) 
   oXml:cSerie   := [1]
   oXml:cModelo  := [55] // se fosse omitido esse valor o padrão é 55 ou seja nfe
   oXml:cAmbiente:= [2]  // se fosse omitido esse valor o padrão é 2 Ambiente de Homologação 

   oXml:fCria_Xml()  // criando arquivo, chave e demais informações básicas

   *** Identificação - Tag Ide
   oXml:cNatop   := [VENDA DE MERCADORIA] 
   oXml:dDatae   := Date()
   oXml:cTimee   := Time()
   oXml:dDatas   := Date()
   oXml:cTimes   := Time()
   oXml:cTpnf    := [1]
   oXml:cIdest   := [1]
   oXml:cMunfg   := [3550308]
   oXml:cFinnfe  := [1]
   oXml:cIndfinal:= [0]
   oXml:cIndpres := [0]

   *** teste para nota para exterior / trocar por este valor
   * oXml:cIdest := [3]

   oXml:fCria_Ide()  // criando a tag ide

   *** pode repetir até 500 notas referenciadas
   oXml:cRefnfe:= [35250600123456000100550010000386485700411249]
   oXml:fCria_AddNfref()

   oXml:cRefnfe:= [35250600123456000100550010000386485700411250]
   oXml:fCria_AddNfref()

   oXml:cRefnfe:= [35250600123456000100550010000386485700411251]
   oXml:fCria_AddNfref()

   *** Emitente
   oXml:cXnomee  := [Empresa fictícia Ltda Me]
   oXml:cXfant   := [Mentira e Mentirinhas]
   oXml:cXlgre   := [Rua do Sossegão]
   oXml:cNroe    := [sn]
   oXml:cXBairroe:= [Centro]
   oXml:cXmune   := [São Paulo]   // com ou sem acentuação
   oXml:cUfE     := [SP]
   oXml:cCepe    := [04.815-130] // com ou sem acentuação
   oXml:cFonee   := [(11)99999-0234] // com ou sem acentuação
   oXml:cIee     := [551303380162]
   oXml:cIme     := [1234]
   oXml:cCnaee   := [4751201]
   oXml:cCrt     := [1]

   oXml:fCria_Emitente() // criando a tag emitente
  
   *** Destinatário
   oXml:cCnpjd    := [99999999000191]
   oXml:cXnomed   := [Empresa teste]
   oXml:cXlgrd    := [Rua do Sossego mais sossegada]
   oXml:cNrod     := [1234]
   oXml:cXBairrod := [Centro]
   oXml:cCmund    := [3550308] // com ou sem acentuação
   oXml:cXmund    := [Sao Paulo]
   oXml:cUfd      := [SP]
   oXml:cCepd     := [17514250]
   oXml:cFoned    := [(14)99888-1234]
   oXml:cIndiedest:= [2]
   oXml:cIed      := [197358979888]
   oXml:cEmaild   := [marceloalcarli@gmail.com]

   oXml:fCria_Destinatario() // criando a tag destinatário

   // ------------------------
   // DADOS DE ENTREGA
   // ------------------------
   oXml:cCnpjg   := "12345678000195"
   oXml:cXnomeg  := "Cliente Teste Ltda"
   oXml:cXfantg  := "Cliente Fantasia"
   oXml:cXlgrg   := "Rua das Flores"
   oXml:cNrog    := "123"
   oXml:cXcplg   := "Bloco A"
   oXml:cXBairrog:= "Centro"
   oXml:cMunfg   := "3550308"
   oXml:cXmung   := "Sao Paulo"
   oXml:cUfg     := "SP"
   oXml:cCepg    := "01001000"
   oXml:cPaisg   := "1058"
   oXml:cXpaisg  := "BRASIL"
   oXml:cFoneg   := "11987654321"
   oXml:cEmailg  := "cliente@teste.com.br"
   oXml:cIeg     := "123456789012"

   oXml:fCria_Entrega()

   // ------------------------
   // DADOS DE RETIRADA
   // ------------------------
   oXml:cCnpjr   := "12345678901"   // CPF neste caso
   oXml:cXnomer  := "Joao da Silva"
   oXml:cXlgrr   := "Avenida Brasil"
   oXml:cNror    := "456"
   oXml:cXBairror:= "Jardins"
   oXml:cMunfg   := "3304557"
   oXml:cXmunr   := "Rio de Janeiro"
   oXml:cUfE     := "RJ"
   oXml:cCepr    := "20040002"
   oXml:cPaisr   := "1058"
   oXml:cXpaisr  := "BRASIL"
   oXml:cFoner   := "21999999999"
   oXml:cIer     := "987654321000"

   oXml:fCria_Retirada()

   *** teste para nota para exterior / trocar por este valor
   * oXml:cIdestrangeiro:= [20250707]
   * oXml:cCmund        := [9999999]
   * oXml:cXmund        := [EXTERIOR]
   * oXml:cUfd          := [EX]
   * oXml:cPaisd        := [1694]
   * oXml:cXpaisd       := [COLOMBIA]
   * oXml:cIndiedest    := [9]


   *** Pode repetir até 10 vezes
   oXml:cAutxml   := [99999999000191]
   oXml:fCria_Autxml()     

   oXml:cAutxml   := [99999999000292]
   oXml:fCria_Autxml()     

   oXml:cAutxml   := [99999999000293]
   oXml:fCria_Autxml()     
      
   For i:= 1 to 3
       // Cria Produto
       oXml:nItem    := i
       oXml:cProd    := [7908454806175]
       oXml:cXprod   := [CHICOTE DA IGNICAO]
       oXml:cNcm     := [84835090]
       oXml:cCest    := [1111111]
       oXml:cCfOp    := [5.405]
       oXml:cUcom    := [UN]
       oXml:nQcom    := 1
       oXml:nVuncom  := 4.77
*      oXml:nVprod   := 4.77  // se não informar vai calcular automaticamente
       oXml:nVtottrib:= 4.77
       oXml:cCstIcms := [500]
       oXml:cOrig    := [0]
       oXml:nVdesc   := .50
       oXml:nVfrete  := .20
       oXml:nVseg    := .1
       oXml:nVoutro  := .01

       // teste para nota para exterior / comentar estas tags
       oXml:cCstPis   := [49]
       oXml:cCstCofins:= [49]

       // teste para nota para exterior / trocar por este valor
       * oXml:cCfOp       := [7101]
       * oXml:cCstIcms    := [041]
       * oXml:cCEnq       := [002]
       * oXml:cCstipint   := [54]
       * oXml:cCstPisnt   := [08]
       * oXml:cCstCofinsnt:= [08]

       // Reforma Tributária  - RTC
       oXml:cClasstribis := [000001]
       oXml:nVbcis       := 10
       oXml:nPisis       := 1
       oXml:cUtrib_is    := [UN]
       oXml:nQtrib_is    := 1
       oXml:nPredaliqgcbs:= 0.6

       oXml:cCclasstrib  := [000001]
       oXml:nVbcibs      := 10
       oXml:cCredPresgibs:= [01]
       oXml:cCredPrescbs := [01]

       oXml:fCria_Produto() // criando a tag dos produtos

       ** alterar para poder incluir dentro da det prod
       If i == 2  // como acrescentar tag arma no produto 2
          // Pode ocorrer até 500 vezes
          oXml:cTparma  := [0]
          oXml:cNserie_a:= [1234567890]
          oXml:cNcano   := [8888888TV8UOP]
          oXml:cDescr_a := [Descrição da arma com até 256 caracteres]

          oXml:fCria_ProdArmamento()

          oXml:cTparma  := [1]
          oXml:cNserie_a:= [KJO1234567890]
          oXml:cNcano   := [AAA8888888TV8UOP]
          oXml:cDescr_a := [Descrição da arma com até 256 caracteres]

          oXml:fCria_ProdArmamento()
          oXml:cTparma  := [0]
          oXml:cNserie_a:= [BC000123]
          oXml:cNcano   := [NCC000123]
          oXml:cDescr_a := [CALIBRE:9mm,- COMPRIMENTO DO CANO:95mm (3.74),- ESPECIE:PISTOLA,- FUNCIONAMENTO:2,- MARCA:FABRICANTE,- QTD.CANOS:1,- NUMERO DE TIROS:15,- QTD.RAIAS:06,- SENTIDO RAIAS:2]

          oXml:fCria_ProdArmamento()
       Endif
   Next i

*****************

   // Reforma Tributária  - RTC
   oXml:nVis_t    := (oXml:nVbcis * oXml:nQtrib_is) * (oXml:nPisis / 100)

   oXml:fCria_Totais() // criando a tag dos totais

   *** Transportadora
   oXml:cModFrete:= [9]
*  oXml:cXnomet  := 
*  oXml:cCnpjt   := 
*  oXml:cIet     := 
*  oXml:cXEndert := 
*  oXml:cXmunt   := 
*  oXml:cUft     := 
*  oXml:cPlaca   := 
*  oXml:cUfplacat:= 
*  oXml:cRntc    := 
*  oXml:nQvol    := 
*  oXml:cEsp     := 
*  oXml:cMarca   := 
*  oXml:cNvol    := 
*  oXml:nPesol   := 
*  oXml:nPesob   := 

   // teste para nota para exterior / trocar por este valor
*  oXml:cModFrete:= [1]
*  oXml:cXnomet  := [BRASIL TRANSPORTES LTDA]
*  oXml:cCnpjt   := [13.520.ABC/0001-69]
*  oXml:cIet     := [442131310119]
*  oXml:cXEndert := [Rua do sossego]
*  oXml:cXmunt   := [MARÍLIA]
*  oXml:cUft     := [SP]
*  oXml:nQvol    := 7
*  oXml:cEsp     := [PALETES]
*  oXml:nPesol   := 464.81
*  oXml:nPesob   := 816.90

   oXml:fCria_Transportadora() // criando a tag da transportadora

   oXml:cNfat  := [Fatura numero 1]
   oXml:nVorigp:= 1.00
   oXml:nVdescp:= 1.00
   oXml:nVliqup:= 1.00

   *** Cobrança pode repetir até 120 vezes
   oXml:cNDup  := [001 Duplicata]   
   oXml:dDvencp:= Ctod([01/04/2025])
   oXml:nVdup  := 1.00

   oXml:fCria_Cobranca() // criando a tag de cobrança

   oXml:cNDup  := [002 Duplicata]   
   oXml:dDvencp:= Ctod([01/05/2025])
   oXml:nVdup  := 2.00

   oXml:fCria_Cobranca() // criando a tag de cobrança

   oXml:cNDup  := [003 Duplicata]   
   oXml:dDvencp:= Ctod([01/06/2025])
   oXml:nVdup  := 5.00

   oXml:fCria_Cobranca() // criando a tag de cobrança

   *** Tipo de pagamento pode repetir até 100 vezes
   oXml:cIndPag:= [0]   // a vista
   oXml:cTpag  := [01]
   oXml:nVpag  := 1.00

   oXml:fCria_Pagamento()

   oXml:cIndPag:= [0]   // a vista
   oXml:cTpag  := [02]
   oXml:nVpag  := 1.00

   oXml:fCria_Pagamento()

   oXml:cIndPag:= [1]   // a prazo
   oXml:cTpag  := [03]
   oXml:nVpag  := 7.54
   oXml:nVtroco:= 0.01  // COLOCAR O TROCO NA ÚLTIMA FORMA DE PAGAMENTO OU SE FOR ÚNICA FORMA

   oXml:fCria_Pagamento()

   *** Informações Adicionais
   oXml:cInfcpl := [teste]
   oXml:cInfFisc:= [teste ao fisco]

   oXml:fCria_Informacoes() // criando a tag de informações

   *** observação: só será preenchido se o cfop começar com 7
   *** fica aqui demonstrado como alimentar as tags e local de inserção
   oXml:cUfSaidapais := [RJ]
   oXml:cXlocexporta := [Porto do Rio de janeiro]
   oXml:cXlocdespacho:= [Pier 150A]

   oXml:fCria_ProdExporta()

   *** Responsável Técnico
   oXml:cRespcnpj := [99999999000191]
   oXml:cRespNome := [responsável técnico]
   oXml:cRespemail:= [tecnico@tecnico.com.br]
   oXml:cRespfone := [11123456789]

   oXml:fCria_Responsavel()

   *** Fechamento da Nfe   
   oXml:fCria_Fechamento()  // criando a tag de fechamento do xml

   // Grava Arquivo XML colocar qq nome de preferencia
   hb_MemoWrit(oXml:cId + [-01-SemAssinatura.xml], oXml:cXml)
   hb_MemoWrit(oXml:cId + [-nfe.xml], oXml:cXml)  // padrão para envio pelo monitor da unimake
   WaitWindow()
Return (Nil)
https://github.com/malcarli1/Nfe_Classe

Att.

Marcelo A. L. Carli
Marília/SP
Capital Nacional do Alimento ®
https://malc-informatica.ueniweb.com
Insta: @malcarli25
Email / Skype: marceloalcarli@gmail.com
Editado pela última vez por Itamar M. Lins Jr. em 06 Jul 2026 15:14, em um total de 1 vez.
Razão: Editado para colocar a tag [code][/code]
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2844
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP
Curtiu: 3 vezes
Curtiram: 1 vez

Re: Classe para gerar xml nfe/nfce

Mensagem por Jairo Maia »

Olá Marcelo,

Não testei, mesmo assim, parabéns pelo trabalho.

Porém, uma questão: A classe gera o XML no padrão unimake, então uso o unimake para assinar e enviar o XML, certo? E para imprimir o DANFE, uso o UniDANFE (que é pago), está correto?

A pergunta é: Porque eu trocaria o ACBrMonitor pela sua Classe?
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
malcarli
Usuário Nível 3
Usuário Nível 3
Mensagens: 260
Registrado em: 20 Ago 2015 18:14
Localização: marilia/sp
Curtiram: 2 vezes

Re: Classe para gerar xml nfe/nfce

Mensagem por malcarli »

Gera no padrão nacional. Pode ser enviado pela classe do Mestre Quintas, pela unimake monitor que é free ou QQ outra mensageria de envio. Posteriormente vou incorporar o envio e retorno tornando-a completa. Muitos colegas tem dificuldade em interpretar o manual e gerar na prática um XML. É mais uma alternativa independente, que pode ser customizada pelo dev.. qtos ao DANFE a classe do Quintas supre tb
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2844
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP
Curtiu: 3 vezes
Curtiram: 1 vez

Re: Classe para gerar xml nfe/nfce

Mensagem por Jairo Maia »

Ok. Se no futuro, houver a impressão do DANFE da NFC-e, fica completo mesmo, e sem dúvidas, serei um que com serteza irá usar.

A Classe do José, muito boa aliás, não gera e não imprime o DANFE da NFC-e, essa é uma dificuldade de "sair do ACBrMonitor", que tem me atendido muito bem. Esse entrave vem desde quando tinha o SAT...
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 8137
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 6 vezes
Curtiram: 1 vez

Re: Classe para gerar xml nfe/nfce

Mensagem por Itamar M. Lins Jr. »

Olá!
A vantagem do ACBrMonitor, é que não trabalhamos com XML.
É um texto simples.
E temos 2 opções, usar a LIB ou o .EXE
Mas o sistema(classe) do Jose Quintas, imprime a NFCe, se não estou enganado.
A GRANDE diferença do Unimake são os fontes e a quantidade de programadores que o ACBr tem, o projeto ACBr não contempla apenas isso, são vários projetos, inclusive boletos, NFSe...
E o código vc baixa e compila se não desejar pagar.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20501
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP
Curtiram: 2 vezes

Re: Classe para gerar xml nfe/nfce

Mensagem por JoséQuintas »

Itamar M. Lins Jr. escreveu: 07 Jul 2026 10:51 A vantagem do ACBrMonitor, é que não trabalhamos com XML.
É um texto simples.
E temos 2 opções, usar a LIB ou o .EXE
Confusão aqui, até mesmo sobre "vantagem".
Além de muitas coisas coisas, tudo vai de gosto pessoal.

O que está no tópico é uma classe pra gerar XML.
De certa forma, XML é um arquivo texto simples.
Há quanto tempo existe XML, e pra quanta coisa o XML é usado ?
Muita.
Não sei se dá pra afirmar que "não saber XML" tem alguma vantagem.

Criar o XML segue o manual oficial do governo.
Tudo segue o manual, seja ACBR, uninfe, sefazclass, etc., ou a classe deste post.
A diferença é que o formato do governo é único pra todos, mesmo pra quem não usa.
Mas pra correções/atualizações, apesar de todos os produtos acabarem usando o formato do governo, cada um tem seu formato próprio, justamente pra fugir do formato XML. (ou fugir ou facilitar, se facilita ou não é outra história).
Essa "fuga" do formato XML é que torna cada componente dependente de alterações no componente, e torna soluções que seriam padronizadas gerais, pra padronizadas apenas por componente.

O formato adotado pelo governo foi o XML.
Os componentes nasceram, principalmente na época do Clipper, pra não ter que aprender XML.
Mas o XML veio e ficou, junto com outros formatos.
É só mais um, dos muitos formatos existentes.
O programa do governo também importava arquivos XMLs, não era apenas TXT.

Pra quem não sabe mexer com classe, esta classe deixa dependente de alguém que saiba mexer na classe, o que pode ser ruim.
Da mesma forma, o formato ACBR ou uninfe ou outro.
O formato XML também não isola o fato de precisar detalhes quando algo tem atualização.

vantagem/desvantagem de cada um ?
Sei lá...
harbour/xharbour
hwgui/minigui/fivewin
dbf/sql
window/linux
xml/json/classe/txt

Parece que tudo vira disputa, ou vira uma espécie de racismo ou fanatismo.

XML é um formato como qualquer outro.
Tem comunicação que usa XML, comunicação que usa json, comunicação com txt, e comunicação com nenhum dos dois.
Já o INI, geralmente é usado como configuração, e não como comunicação, mas na atualidade tá tudo misturado.
José M. C. Quintas
Harbour 3.2, mingw, multithread, gtwvg, fivewin 25.12, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui), (hmg3), (hmg extended), (oohg), PNotepad, ASP, (Linux/Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
malcarli
Usuário Nível 3
Usuário Nível 3
Mensagens: 260
Registrado em: 20 Ago 2015 18:14
Localização: marilia/sp
Curtiram: 2 vezes

Re: Classe para gerar xml nfe/nfce

Mensagem por malcarli »

Jairo Maia escreveu: 07 Jul 2026 10:36 Ok. Se no futuro, houver a impressão do DANFE da NFC-e, fica completo mesmo, e sem dúvidas, serei um que com serteza irá usar.

A Classe do José, muito boa aliás, não gera e não imprime o DANFE da NFC-e, essa é uma dificuldade de "sair do ACBrMonitor", que tem me atendido muito bem. Esse entrave vem desde quando tinha o SAT...

Bom dia colega, a classe do Mestre Quintas, gera sim a danfe da nfe/nfce, pois uso a anos sem problemas

Código: Selecionar todos

Procedure fNfeAssinar(nTipo, oArq, cId, cNf, cVarModelo, cAmbiente, cUf, cNrdoc, cCertificado, lCkVisual)
   Local oSefaz:= SefazClass():New(), oXml:= Malc_GeraXml():New(), cMsgGeraValXml:= cVarTickCar:= cArquivo:= []

   If !Empty(cCertificado)
      oSefaz:cCertificado:= cCertificado
   Else
      oSefaz:cCertificado:= Alltrim(parametrosiniciais->cerdanfe)
   Endif

   oSefaz:cAmbiente  := cAmbiente
   oSefaz:cUf        := cUf

   If cVarModelo == [65]  // Nfce
      oSefaz:cCSC         := parametrosiniciais->NRCSC
      oSefaz:cNFCE        := [S]
      oSefaz:cIdToken     := Hb_Ntos(parametrosiniciais->IDENTCSC)
*     oSefaz:cVersaoQrCode:= [3.00]
   Endif

   oSefaz:NFeLoteEnvia(oArq)
   Inkey(.10)

   If oSefaz:cStatus $ [100, 101, 202, 302]
      WaitWindow([Nota Autorizada: ] + oSefaz:cRecibo + [. Aguarde término do processo...], .T.)

      hb_MemoWrit(Alltrim(CAMINHON) + [\] + cId + [-Assinada.xml]     , oSefaz:cXmlDocumento)
      hb_MemoWrit(Alltrim(CAMINHON) + [\] + cId + [-05-Autorizado.xml], oSefaz:cXmlAutorizado)

      If parametrosiniciais->(DBRlock())  // Grava número da Nfe ou Nfce
         If cVarModelo == [65]
            parametrosiniciais->NRNFCE:= Val(cNf)
            hb_MemoWrit(Alltrim(CAMINHON) + [\] + cId + [-nfc-e.xml]  , oSefaz:cXmlAutorizado)
            fDanfe(2, StrTran(Alltrim(CAMINHON) + [\], [\], [/]) + cId + [-nfc-e.xml], lCkVisual)
         Else
            parametrosiniciais->NRDANF:= Val(cNf)
            hb_MemoWrit(Alltrim(CAMINHON) + [\] + cId + [-nfe.xml]    , oSefaz:cXmlAutorizado)
            fDanfe(2, StrTran(Alltrim(CAMINHON) + [\], [\], [/]) + cId + [-nfe.xml], lCkVisual)
         Endif
         parametrosiniciais->(DBUnlock())
      Endif

      If nTipo == 1
         // Grava Nr XML do Pedido 
         If CaixaNF30TXT->(DBRlock())
            CaixaNF30TXT->NRDANFE:= cId
            CaixaNF30TXT->NRNFE  := cNf
            CaixaNF30TXT->(DBUnlock())
         Endif
      
         // Grava Nr NFe no Conta a Receber
         If parametrosiniciais->PFTCK == 2
            cVarTickCar:= SubStr(Alltrim(cNrdoc) + Space(15), 1, 15)
         Else
            cVarTickCar:= SubStr([TCK.] + Alltrim(cNrdoc) + Space(15), 1, 15)
         Endif

         Use car_cab index cr_003 shared new
       
         If car_cab->(OrdSetFocus(1), DbSeek(cVarTickCar))
      // If car_cab->(OrdSetFocus(4), DbSeek(cVarTickCar))  Usar assim quando estiver usando CDX
            Do While car_cab->(!Eof())
               If car_cab->(DBRlock())
                  car_cab->NRNFE:= cNf
                  car_cab->(DBUnlock())
               Endif

               car_cab->(DbSkip())
               If car_cab->DUPLIC # cVarTickCar
                  Exit
               Endif
            Enddo
         Endif
         car_cab->(DbCloseArea())
      Endif      
      WaitWindow()
    Else
      hb_MemoWrit(AllTrim(CAMINHON)+ [\] + cId + [-Erro.xml], oSefaz:cXmlProtocolo)

      If !Empty(XmlNode(oSefaz:cXmlProtocolo, [infProt]))
         cMsgGeraValXml:= "Erro: "                                                                                + hb_OsNewLine() + ;
                          "Tipo de Ambiente: "    + XmlNode(XmlNode(oSefaz:cXmlProtocolo, "infProt"), "tpAmb")    + hb_OsNewLine() + ;
                          "Versão da Aplicação: " + XmlNode(XmlNode(oSefaz:cXmlProtocolo, "infProt"), "verAplic") + hb_OsNewLine() + ;
                          "Chave de Acesso: "     + XmlNode(XmlNode(oSefaz:cXmlProtocolo, "infProt"), "chNFe")    + hb_OsNewLine() + ;
                          "Data de Recebimento: " + XmlNode(XmlNode(oSefaz:cXmlProtocolo, "infProt"), "dhRecbto") + hb_OsNewLine() + ;
                          "Status: "              + XmlNode(XmlNode(oSefaz:cXmlProtocolo, "infProt"), "cStat")    + hb_OsNewLine() + ;
                          "Motivo: "              + XmlTransform(XmlNode(XmlNode(oSefaz:cXmlProtocolo, "infProt"), "xMotivo"))
      Else
         cMsgGeraValXml:= "Erro: "                                                                                + hb_OsNewLine() + ;
                          "Tipo de Ambiente: "    + XmlNode(oSefaz:cXmlProtocolo, "tpAmb")                        + hb_OsNewLine() + ;
                          "Versão da Aplicação: " + XmlNode(oSefaz:cXmlProtocolo, "verAplic")                     + hb_OsNewLine() + ;
                          "Chave de Acesso: "     + XmlNode(oSefaz:cXmlProtocolo, "chNFe")                        + hb_OsNewLine() + ;
                          "Data de Recebimento: " + XmlNode(oSefaz:cXmlProtocolo, "dhRecbto")                     + hb_OsNewLine() + ;
                          "Status: "              + XmlNode(oSefaz:cXmlProtocolo, "cStat")                        + hb_OsNewLine() + ;
                          "Motivo: "              + XmlTransform(XmlNode(oSefaz:cXmlProtocolo, "xMotivo"))
      Endif

      If nTipo == 1
         If Hb_FileExists(Alltrim(CAMINHO) + [\nfe_v4.00.xsd]) 
            cArquivo:= oSefaz:ValidaXml(StrTran(oArq, [</NFe>], FakeSignature() + [</NFe>]), Alltrim(CAMINHO) + [\nfe_v4.00.xsd])

            If cArquivo # [OK]
               cMsgGeraValXml+= hb_OsNewLine() + hb_OsNewLine() + [=======================================] + hb_OsNewLine() + [Mensagem de Validação do XML:] + hb_OsNewLine() + cArquivo
            Endif
         Endif
      Endif

      MsgExclamation(cMsgGeraValXml, [Erro])
   Endif
Return (Nil)

Procedure fDanfe(nTipo, cArqXml, lCkVisual) // não colocar STATIC
   Local cStilo:= "<style> "                    +;
                  "body{ "                      +;
                   "font-family: Courier New;"  +;
                   "background-color: #ffffff;" +;
                   "font-size: 75%;"            +;
                   "color: #000000;"            +;
                   "}"                          +;
                  "h1{"                         +;
                   "font-family: Courier New;"  +;
                   "font-size: 150%;"           +;
                   "color: #0000cc;"            +;
                   "font-weight: bold;"         +;
                   "background-color: #f0f0f0;" +;
                   "}"                          +;
                  ".updated{"                   +;
                   "font-family: Courier New;"  +;
                   "color: #cc0000;"            +;
                   "font-size: 110%;"           +;
                   "}"                          +;
                  ".normaltext{"                +;
                   "font-family: Courier New;"  +;
                   "font-size: 100%;"           +;
                   "color: #000000;"            +;
                   "font-weight: normal;"       +;
                   "text-transform: none;"      +;
                   "text-decoration: none;"     +;
                   "}"                          +;
                  "</style>", oDanfe, oEmail, aRetorno, nModelo:= 55, cFilePDF, cPrinter:= GetDefaultPrinter()

   hb_Default(@cArqXml, [])
   hb_Default(@lCkVisual, .T.)
 
   If nTipo == 1  
      cArqXml:= GetFile({{[Arquivos Xml´s - Todos], [*NFE.XML], [*NFC-E.XML]}}, [Abrir o Arquivo Xml´s], Alltrim(CAMINHON) + [\], .F., .T.)
   Endif

   If !Empty(Alltrim(cArqXml))
      nModelo:= Val(XmlNode(hb_MemoRead(cArqXml), [mod]))
      If nModelo == 55
         oDanfe:= hbnfeDanfe():new()

         oDanfe:cEmailEmitente   := Alltrim(parametrosiniciais->de)
         oDanfe:cSiteEmitente    := Alltrim(parametrosiniciais->site)
         oDanfe:cTelefoneEmitente:= XmlNode(hb_MemoRead(cArqXml), [fone])
      Elseif nModelo == 65
         oDanfe:= hbNFeDaNFCe():new()
         oDanfe:lBarcodeChave:= .T.
      Endif

      oDanfe:cDesenvolvedor:= SISTEMA

      If Hb_FileExists([logonfe.JPG])
         oDanfe:cLogoFile:= [logonfe.JPG]       // Arquivo da Logo Marca em jpg 
         If nModelo == 55
            oDanfe:nLogoStyle:= 1               // 1-esquerda, 2-direita, 3-expandido
         Endif   
      Endif
      cFilePDF:= StrTran(cArqXml, [xml], [pdf])

      oDanfe:ToPDF(hb_MemoRead(cArqXml), cFilePDF)
      If oDanfe:cRetorno # [OK]
         MsgInfo(cArqXml, [Erro em: ] + cArqXml)
         MsgInfo(oDanfe:cRetorno, [Erro ao Gerar o Pdf])
      Else
         If lCkVisual
            WAPI_SHELLEXECUTE(cFilePDF,, cFilePDF,,, 1)
         Else
            If !Hb_FileExists(GetCurrentFolder() + [\sumatrapdf.exe])
               fOpenFTP([sumatrapdf.exe])
            Endif

            If WAPI_SHELLEXECUTE(Nil, [open], GetCurrentFolder() + [\sumatrapdf.exe], [-print-to "] + cPrinter + [" "] + cFilePdf + ["], Nil, 0 ) > 32
            Else
               MsgExclamation([Não foi possível Impressão do Pdf!!!], [Erro])
            Endif
         Endif
      Endif

      // Envio de e-mail
      If !Empty(XmlNode(hb_MemoRead(cArqXml), [email]))
         oEmail         := hbNFeEmail()
         oEmail:cSubject:= hb_ansitooem([Nota Fiscal Eletrônica recebida de ]) + hb_ansitooem(parametrosiniciais->razao)
         oEmail:cMsgHTML:= '<html><head><title>' + hb_ansitooem([Envio Automático de Nota Fiscal Eletrônica (NF-e)]) + '</title></head>' + cStilo + '<body>' + hb_OsNewLine() + ;
                           '<h1 Align=Center>' + hb_ansitooem([Envio Automático de Nota Fiscal Eletrônica (NF-e)]) + '</h1><br>' + ; 
                           '<dt><div align="center"><font face="Courier New" size="3"><b>' + hb_ansitooem([*** Esse é um e-mail automático. Não é necessário respondê-lo ***]) + '</b></font><dt><br>' + ;
                           '<dt><div align="left"><font face="Courier New" size="3">Prezado(a) Sr(a),</font></div><br>' + hb_OsNewLine() + ;
                           '<dt><div align="left"><font face="Courier New" size="3">' + hb_ansitooem([Você está recebendo em anexo o arquivo XML e Pdf referente a uma Nota Fiscal Eletrônica.]) + '</font></div><br>' + ;
                           '<dt><div align="center"><font face="Courier New" size="3" color="red">' + hb_ansitooem([Este é um email automático e respostas devem ser enviadas diretamente ao emissor de NF-e.]) + '</font></div><br>' + ;
                           '<dt><div align="left"><font face="Courier New" size="3">' + hb_ansitooem([Como consultar o status da sua Nota Fiscal Eletrônica:]) + '</font></div><br>' + ;
                           '<dt><div align="left"><font face="Courier New" size="3">' + hb_ansitooem([Acesse o Portal da Nota Fiscal Eletrônica do Ministério da Fazenda em www.nfe.fazenda.gov.br e clique em Consultar NF-e Completa. Digite a chave de acesso: ] + SubStr(hb_MemoRead(cArqXml), At([Id=], hb_MemoRead(cArqXml)) + 7, 44) + [ para acessar todas as informações da NF-e.]) + '</font></div><br><br><br>' + ;
                           '<dt><div align="left"><font face="Courier New" size="4">NF-e emitida por:</font></div><br>' + ;
                           '<dt><div align="left"><font face="Courier New" size="2" color="blue">' + hb_ansitooem(PROPRIEDADE) + '</font></div><br></body></html>'
         oEmail:cServerIP:= Alltrim(parametrosiniciais->Smtp)
         oEmail:cFrom    := hb_ansitooem(parametrosiniciais->razao) + [<] + Alltrim(parametrosiniciais->De) + [>]
         oEmail:cUser    := Alltrim(parametrosiniciais->De)
         oEmail:cPass    := Alltrim(parametrosiniciais->Senha)
         oEmail:nPortSMTP:= Alltrim(parametrosiniciais->Porta)
         oEmail:lConf    := .T.
         oEmail:lSSL     := parametrosiniciais->ssl
         oEmail:lAut     := parametrosiniciais->MEUS
         oEmail:aFiles   := {cArqXml, StrTran(cArqXml, [xml], [pdf])}
         oEmail:aTo      := XmlNode(hb_MemoRead(cArqXml), [email])
         aRetorno        := oEmail:execute()

         If aRetorno['OK'] == .F.
            MsgInfo(aRetorno['MsgErro'], [Erro])
         Endif
      Endif
   Else // Erro de não encontrar o xml
      MsgExclamation([Arquivo Xml da Nfe/Nfce Não Encontrado em:] + hb_OsNewLine() + cArqXml, [Erro])
      Return (Nil)
   Endif
Return (Nil)


nesse fragmento de programa, após gerar o xml com a classe acima, assino e envio usando a classe do quintas, depois gero o danfe tb usando a classe do quintas e envio xml e pdf gerado peleo hbnfeemail
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20501
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP
Curtiram: 2 vezes

Re: Classe para gerar xml nfe/nfce

Mensagem por JoséQuintas »

Jairo Maia escreveu: 07 Jul 2026 10:36 Ok. Se no futuro, houver a impressão do DANFE da NFC-e, fica completo mesmo, e sem dúvidas, serei um que com serteza irá usar.

A Classe do José, muito boa aliás, não gera e não imprime o DANFE da NFC-e, essa é uma dificuldade de "sair do ACBrMonitor", que tem me atendido muito bem. Esse entrave vem desde quando tinha o SAT...
Neste post a classe é apenas XML.
A sefazclass gera danfe da NFCe faz tempo.
Tem também a classe do Queiróz, que roda via navegador que faz tudo da sefazclass e mais.

open source é colaboração.
Se considerar que tive infarto...... se não houver colaboração, melhor ACBR ou outro, com equipe viva garantindo continuidade.
José M. C. Quintas
Harbour 3.2, mingw, multithread, gtwvg, fivewin 25.12, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui), (hmg3), (hmg extended), (oohg), PNotepad, ASP, (Linux/Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 8137
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 6 vezes
Curtiram: 1 vez

Re: Classe para gerar xml nfe/nfce

Mensagem por Itamar M. Lins Jr. »

Olá!
Já o INI, geralmente é usado como configuração
Pois é.
É mais simples(besteira), por conta da abstração. Não preciso usar alguns comandos. Até pq XML é texto.

Código: Selecionar todos

LOCAL oXML:GeraXML:New()
oXml:fCria_Xml()  // criando arquivo, chave e demais informações básicas
...
Salvar, validar, e assinar...
Usando a abstração do .INI, Já cria, assina e envia. A parte de ler token, CSC... algumas coisas fica por conta do ACBrMonitor, não precisa colocar no .INI

Código: Selecionar todos

NFe.CriarEnviarNFe("[Identificacao]
...
Não se trata de fanatismo nenhum.
Inclusive já escrevi aqui, algumas vezes que uso(ACBr) pq, na época comecei a emitir NFe bem antes de existir a classe, "PRIMÁRIA", que depois foi adaptada para SefazClass...
Agora eu prefiro MIL vezes não usar DLL, LIB etc... Prefiro PRG como é o caso da SefazClass.
Se na época já existisse eu com certeza usaria a Classe. Se não desse esse trabalho de mudar, já teria mudado, mesmo com esses comandos a mais.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20501
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP
Curtiram: 2 vezes

Re: Classe para gerar xml nfe/nfce

Mensagem por JoséQuintas »

Tenho clientes combustível.
É sempre o primeiro ramo em tudo do governo.
Naquela época não existia nada de coisa nenhuma.
O começo foi mesmo com TXT, e o emissor do governo.
O emissor do governo também aceitava em XML.
E naquela época eu usava CLIPPER, nem passava pela cabeça um dia criar sefazclass ou até mesmo classe de alguma coisa.

De lá pra cá apenas continuei.

Isso de usar DLL, LIB, PRG, etc. é relativo.

Comunicação:
Temos o SOAP embutido no Windows, ou LIBCURL Windows e Linux, sendo que pelo harbour antigamente era DLL, atualmente não sei.
É comunicação com certificado https, essa NÃO ERA nativa no Windows 7, foi adicionada depois por instalação EM SEPARADO, sem fazer parte do windows update.
Isso já dá uma diferença entre windows/linux, e também em windows 7.

Assinatura
O windows até tem api de criptografia, e o harbour também.
Mas os melhores resultados acabam sendo com capicom e msxml5 - uma lib que a microsoft só liberou como parte do OFFICE.
MSXML5 faz algum ajuste no XML, e assinatura com capicom.
O windows tem todas as outras versões de MSXML, incluindo MSXML2, MSXML3, MSXML4, MSXML6, menos MSXML5 que ficou pra office.
Outra alternativa é OPENSSL, no harbour antigamente dependia de DLL ou EXE externo, atualmente não sei.

Essa parte acima causa diferença entre sistema operacional.
E também pode causar diferença, se for, por exemplo, ACBR usando capicom ou não.
E também diferença de harbour/xharbour, se for vindo de fivewin pode ser diferente por exemplo, etc.
Itamar M. Lins Jr. escreveu: 08 Jul 2026 11:59 Não se trata de fanatismo nenhum.
É que, Apesar de indicar como resposta, meu post tinha mais coisas do que resposta.
Me referi ao modo geral de tudo, e não a nada específico.
DLL e LIB também pode entrar nisso, afinal, tem horas que achamos normal, tem horas que não.
José M. C. Quintas
Harbour 3.2, mingw, multithread, gtwvg, fivewin 25.12, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui), (hmg3), (hmg extended), (oohg), PNotepad, ASP, (Linux/Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 8137
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 6 vezes
Curtiram: 1 vez

Re: Classe para gerar xml nfe/nfce

Mensagem por Itamar M. Lins Jr. »

Olá!
No caso, não tinha NFCe, SP era SAT, enquanto a maior parte do país não usou SAT.
Já usava o ACBr nas "IMPRESSORAS FISCAIS", só fiz adaptar para NFCe, mudei pouca coisa.
Depois saiu a classe PRIMÁRIA(NFe)... do (Athaide)... Só que já tinha tudo pronto(NFe) no ACBr, com balança, email, boleto...
Outro assunto que não entendi. Essa nova classe(desse post) é concorrente da SefazClass ?
Saudações,
Itamar M. Lins Jr.
malcarli
Usuário Nível 3
Usuário Nível 3
Mensagens: 260
Registrado em: 20 Ago 2015 18:14
Localização: marilia/sp
Curtiram: 2 vezes

Re: Classe para gerar xml nfe/nfce

Mensagem por malcarli »

Esta classe gera somente xml de nfe/nfce. A classe do Mestre Quintas, assina, envia e imprime danfe. São complementares. São independentes. E a ideia não é ser melhor ou concorrer, mas apenas contribuir. Seja efetivamente para usar ou apenas como objeto de estudo para implementações pessoais de qq dev em qq linguagem, sem ter que se aprofundar horas lendo manuais, mas apenas consultando em caso de dúvidas


Att.

Marcelo A. L. Carli
Marília/SP
Capital Nacional do Alimento ®
https://malc-informatica.ueniweb.com
Insta: @malcarli25
Email / Skype: marceloalcarli@gmail.com
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 8137
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 6 vezes
Curtiram: 1 vez

Re: Classe para gerar xml nfe/nfce

Mensagem por Itamar M. Lins Jr. »

Olá!
Até onde sei a SefazClass faz isso, gerar XML da NFe e NFCe, e mais outras coisas.
Quanto a concorrer, é correr JUNTO, quem desejar que avalie e use uma ou outra, as duas ou crie a sua própria.
Essas variações, são bem vindas. Concorre para o bem da comunidade xBase.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 8137
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 6 vezes
Curtiram: 1 vez

Re: Classe para gerar xml nfe/nfce

Mensagem por Itamar M. Lins Jr. »

Olá!
Sim, baixei aqui no Windows, a SefazClass e não achei essa parte que vc criou.
Facilita muito a vida do programador.
No caso cada um(que usa a classe) estava fazendo o XML da forma que convêm.
Saudações,
Itamar M. Lins Jr.
Responder