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: 258
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: 258
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: 8132
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.
Responder