Clipper On Line • Ver Tópico - Uso da classesefaz

Uso da classesefaz

Projeto hbNFe (Nota Fiscal Eletronica/Danfe) para [x]Harbour

Moderador: Moderadores

 

Uso da classesefaz

Mensagempor JoséQuintas » 28 Set 2016 20:16

Não vi sua mensagem antes.
Mas a classe não é pra gerar, e sim pra ler, por exemplo pra importar XMLs de fornecedores.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18149
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Uso da classesefaz

Mensagempor malcarli » 29 Set 2016 08:40

heheh depois vendo com mais atenção, vi que era para ler, mas mesmo assim obrigado. Sabe de alguma classe ou função que gere?
malcarli
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 184
Data de registro: 20 Ago 2015 18:14
Cidade/Estado: marilia/sp
Curtiu: 83 vezes
Mens.Curtidas: 4 vezes

Uso da classesefaz

Mensagempor JoséQuintas » 29 Set 2016 10:18

Pra gerar o XML vai precisar de informações do seu aplicativo, muitas, então não vai encontrar nada pronto, talvez alguma coisa que apenas ajude.
Já gera o TXT ?
Se gera é usar a mesma rotina e ajustar pra XML.

Se vai começar do zero, cole um XML no fonte e comece os ajustes, primeiro gerando o mesmo XML.

cXml := "texto do xml"


A partir daí, comece a separar o XML, não se preocupe com a quantidade de linhas do fonte, porque vai precisar sim, muiiiitas linhas.

cXml := ""
cXml += "pedaco do xml"
cXml += "pedaço do xml"
cXml ++ "<texto>pedaco do xml</texto"


E no final, troque as partes internas pelos seus campos/variáveis.

Não é complicado, é trabalhoso, porque são muitos campos.
Considerando uns 500 campos, vão ser no mínimo umas 500 linhas de fonte, uma pra cada campo.

Se já tem geracão em TXT, já está praticamente na ordem e com os campos que precisa.

Se for usar um componente de terceiros, vai estar aprendendo sobre o componente e não sobre o XML.
Como isso vai ser usado muito daqui pra frente, o negócio é enfiar a cara e coragem e ir em frente.
Começar é trabalho, por causa disso que eu disse: são uns 500 campos, umas 500 linhas no mínimo.
Mas não é nada complicado, só ir somando string, igual qualquer txt.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18149
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Uso da classesefaz

Mensagempor malcarli » 29 Set 2016 10:35

Mestre, gerei na unha mesmo, como vc respondeu acima, demorei muito até acertar, todas as tags, achei que conhecia alguma coisa pronta, mas perfeita e com menos dor de cabeça. Sou contra usar dlls, coisas de terceiros, pois ficamos na dependência de atualizações e sem ter como fazer customizações necessárias. Obrigado pela resposta. Seu trabalho é maravilhoso, simples de usar e perfeito
malcarli
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 184
Data de registro: 20 Ago 2015 18:14
Cidade/Estado: marilia/sp
Curtiu: 83 vezes
Mens.Curtidas: 4 vezes

Uso da classesefaz

Mensagempor JoséQuintas » 29 Set 2016 10:45

Umas coisas que eu uso, vai encontrar na classe, são funçõeszinhas pra reduzir um pouco o fonte e evitar esquecimento.

XmlTag()
NumberXml()
StringXml()
DateXml()


Por exemplo...
Toda hora no fonte Ltrim(Str(numero)), troque por NumberXml( numero )
Toda hora no fonte Transform( Dtos( date() ), "@R 9999-99-99" ), troque por DateXml( date() )
Toda hora no fonte <cliente>123</cliente>, troque por XmlTag( "cliente", "123" )
E por ai vai.

Tambem pode organizar por blocos, se achar interessante.

BlocoIde( @cXml )
BlocoProduto( @cXml )

FUNCTION BlocoProduto( cXml )
   cXml += [<det nItem="1">]
   ...
   BlocoIcms( @cXml )
   BlocoPis( @cXml )
   BlocoCofins( @cXml )
   cXml += {</det>]
   RETURN NIL
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18149
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Uso da classesefaz

Mensagempor JoséQuintas » 29 Set 2016 10:52

Minha idéia seria usar aquela mesma classe de importação pra gerar, igual alguns componentes fazem.
Mas não fiz nada sobre isso ainda.

Queria fazer até pra poder acrescentar validações, isso sim seria interessante.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18149
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Uso da classesefaz

Mensagempor malcarli » 29 Set 2016 10:59

Hum, tb criei funções para otimizar isso, como geracodigodeacesso, tags etc para otimizar e minimizar o tamanho do monstro. Sim, com certeza criar uma função ou classe para gerar, igual a de leitura ficaria top. O problema que não tenho conhecimento suficiente da legislação e a maldita falta de tempo, mas tem várias pessoas que com certeza ajudaria, inclusive eu, se precisar

Fiz assim (trecho)


Static Procedure fGera_xml(cNf, cCnpj)
   Local cId:= GetChaveAcesso(cNf, cCnpj), oXml:= iCSTIPI:= iBCST:= iValorST:= iDesconto:= iValorIPI:= vPis:= vCofins:= iEAN:= iRedBC:= iAliqIPI:= iFabrica:= iValidade:= iIndST:= [], i:= vBC:= vICMS:= vProduto:= iLote:= vIPI:= vBCST:= vValorST:= vDescont:= vIPI:= vBaseIPI:= vPis:= iOutroDes:= 0
       
  * oXml:= '<?xml version="1.0" encoding="UTF-8"?>'
         oXml:= '<NFe xmlns="http://www.portalfiscal.inf.br/nfe">'
            oXml+= '<infNFe versao="3.10" Id="NFe' + cId + '" >'
       
               oXml+= '<ide>'                           // Inicio da TAG (ide)
                  oXml+= '<cUF>' + AllTrim(f_AcessaIni(PATHDADOS + [MALC.INI], [NFe], [Uf Emitente])) + '</cUF>'                                    // UF do Emitente no caso SP = 35 DEIXEI FIXO
                  oXml+= '<cNF>' + Padl(cNf, 8 , "0" ) + '</cNF>'                     // Controle da Nota ou numero do pedido
                  oXml+= '<natOp>' + SubStr(AllTrim(fRetiraAcento(GetProperty([f_Generico], [Cb_Cfop], [DisplayValue]))), 9) + '</natOp>'          // Natureza da Operação
        oXml+= '<indPag>' + Str(GetProperty([f_Generico], [Cb_Pagamento], [Value]) - 1, 1) + '</indPag>'     // Indice de Pagamento
                  oXml+= '<mod>55</mod>'                                         // Modalidade (FIXO)
                  oXml+= '<serie>' + AllTrim(f_AcessaIni(PATHDADOS + [MALC.INI], [NFe], [Série])) + '</serie>'                                      // Serie (FIXA)
                  oXml+= '<nNF>' + cNf + '</nNF>'                                // Numero da Nota Fiscal
                  oXml+= '<dhEmi>' + DateTimeXml(GetProperty([f_Generico], [Dp_Emissao], [Value]), GetProperty([f_Generico], [Tm_Hora], [Value])) + '</dhEmi>'     // Data Emissão Formato yyyy-mm-dd
        If !Empty(GetProperty([f_Generico], [Dp_saida], [Value]))
                     oXml+= '<dhSaiEnt>' + DateTimeXml(GetProperty([f_Generico], [Dp_saida], [Value]), GetProperty([f_Generico], [Tm_Hora], [Value])) + '</dhSaiEnt>'    // Data da Saida da mercadoria
        Endif

malcarli
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 184
Data de registro: 20 Ago 2015 18:14
Cidade/Estado: marilia/sp
Curtiu: 83 vezes
Mens.Curtidas: 4 vezes

Uso da classesefaz

Mensagempor JoséQuintas » 29 Set 2016 12:06

Talvez pra "clarear" o fonte, melhor usar variável temporária.

Static Procedure fGera_xml(cNf, cCnpj)
Local cId:= GetChaveAcesso(cNf, cCnpj), oXml:= iCSTIPI:= iBCST:= iValorST:= iDesconto:= iValorIPI:= vPis:= vCofins:= iEAN:= iRedBC:= iAliqIPI:= iFabrica:= iValidade:= iIndST:= [], i:= vBC:= vICMS:= vProduto:= iLote:= vIPI:= vBCST:= vValorST:= vDescont:= vIPI:= vBaseIPI:= vPis:= iOutroDes:= 0
   
    oXml:= '<NFe xmlns="http://www.portalfiscal.inf.br/nfe">'
      oXml+= '<infNFe versao="3.10" Id="NFe' + cId + '" >'
   
       oXml+= '<ide>'             // Inicio da TAG (ide)
       cText := f_AcessaIni(PATHDADOS + [MALC.INI], [NFe], [Uf Emitente])
         oXml+= XmlTag( "cUF", StringXml( cText ))                  // UF do Emitente no caso SP = 35 DEIXEI FIXO
         oXml+= XmlTag( "cNF", StringXml( cNf ) )          // Controle da Nota ou numero do pedido
        cText := SubStr(AllTrim(fRetiraAcento(GetProperty([f_Generico], [Cb_Cfop], [DisplayValue]))), 9)
         oXml+=XmlTag( "natOp", cText )     // Natureza da Operação
      cText := Str(GetProperty([f_Generico], [Cb_Pagamento], [Value]) - 1, 1)   // Indice de Pagamento
   oXml+= XmlTag( "indPag", cText )
         oXml+= XmlTag( "mod", "55" )                    // Modelo NFE=55
        cText := AllTrim(f_AcessaIni(PATHDADOS + [MALC.INI], [NFe], [Série])
         oXml+= XmlTag( "serie", cText )               // Serie (FIXA)
         oXml+= XmlTag( "nNF", cNf )                // Numero da Nota Fiscal
       cText := GetProperty([f_Generico], [Dp_Emissao], [Value]), GetProperty([f_Generico], [Tm_Hora], [Value])
         oXml+=XmlTag( "dhEmi", DateXml( cText ) // Data Emissão Formato yyyy-mm-dd
   If !Empty(GetProperty([f_Generico], [Dp_saida], [Value]))
          oXml+= XmlTag( "dhSaiEnt",  DateTimeXml(GetProperty([f_Generico], [Dp_saida], [Value]), GetProperty([f_Generico], [Tm_Hora], [Value])) )  // Data da Saida da mercadoria
   Endif

FUNCTION XmlTag( cNome, cConteudo )

   RETURN "<" + cNome + ">" + cConteudo + "</" + cNome + ">"


Tem que pensar que não vai ser apenas fazer, depois vai ter manutenção.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18149
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Uso da classesefaz

Mensagempor JoséQuintas » 29 Set 2016 12:14

Quer ter um trabalho duplo que talvez facilite ?
Vai ter que testar se realmente facilita.

Usar a classe de importar nota.

Vai ter que trabalhar com 3 fontes de uma vez, mas talvez facilite, por causa desse seu modo de pegar conteúdo de valores.

1) Fonte da classe
2) Fonte de carregar informação
3) Fonte de gerar XML

Exemplo:

// fonte 1 = carregar dados
oNota:Numero := "1"
oNota:DataEmissao := 11/11/11

// fonte 2 = gerar xml
cXml += XmlTag( "cNF", oNota:Numero )
cXml += XmlTag( "dhEmi", DateXml( oNota:DataEmissao ) )

// fonte  3 - a classe
// acrescentar campos que possam estar faltando


À primeira vista, pelo menos pode deixar o fonte mais "legível".
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18149
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Uso da classesefaz

Mensagempor malcarli » 29 Set 2016 13:06

blz, vou partir deste raciocínio
malcarli
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 184
Data de registro: 20 Ago 2015 18:14
Cidade/Estado: marilia/sp
Curtiu: 83 vezes
Mens.Curtidas: 4 vezes

Uso da classesefaz

Mensagempor depaula.jau » 29 Set 2016 14:25

Bem interessante essa idéia de programar em Blocos, ficaria mais ou menos igual ao que é o Evento.

Enviando e retornando a mesma váriavel @cXml.

O Código ficaria mais Limpo e de fácil manutenção
Avatar de usuário

depaula.jau
Usuário Nível 2

Usuário Nível 2
 
Mensagens: 98
Data de registro: 15 Mai 2007 17:07
Cidade/Estado: JAU
Curtiu: 9 vezes
Mens.Curtidas: 14 vezes

Uso da classesefaz

Mensagempor malcarli » 29 Set 2016 18:05

Bom, seguindo suas orientações criei estas funções Gostaria de saber se estou sendo coerente nas funções. Agradeço opiniões, críticas e aperfeiçoamento. Espero que possa ajudar a todos. Não tenho conhecimento suficiente para desenvolver classes, mas acho que serve de partida.

Procedure GeraXml(cNf, cCnpj)
   Private cXml:= [teste.xml], cId:= GetChaveAcesso(cNf, cCnpj)
 
   *** Cria o xml
   cXml:= fCria_Xml(@cXml, cId)

   *** Identificação - Tag Ide
   fCriaIde(@cXml, [35], [000000001], [Venda mercadoria adquirida ou recebida de terceiros], [0], [1], dtoc(date()), time(), dtoc(date()), time(), [0], [1], [2], [0], [1], [3550308], [1], [])

   *** Fechamento do Cfe   
   fCriaFechamento(@cXml)
Return (Nil)

Procedure fCria_Xml(cXml, cId)
   Local nHandle:= 0

   If !Empty(cXml)
      cXml+= '<NFe xmlns="http://www.portalfiscal.inf.br/nfe">' + hb_OsNewLine()
      cXml+= '<infNFe versao="3.10" Id="NFe' + cId + '" >'      + hb_OsNewLine()
   Endif
Return (nHandle)

Procedure fCriaFechamento(cXml)
   Local nHandle

   If Empty(cXml)
      Return (Nil)
   Endif

   cXml+= '</NFe>'
   If (nHandle:= FCREATE(oArq, 0)) == -1
       MsgInfo([Não foi possível criar o arquivo rascunho XML])
       Return (Nil)
   Endif
   FWRITE(nHandle, cXml)
   FCLOSE(nHandle)
Return (Nil)

Procedure fCriaIde(cXml, cUf, cNf, cCfop, cIndPag, cSerie, cDataE, cTimeE, cDataS, cTimeS, cTipoNf, cDv, cAmbiente, cIndPres, cIdest, cMunIbged, cFinalidade, Nfrefencia)
   If Empty(cXml)
      Return (Nil)
   Endif

   cXml+= '<ide>') // Inicio da TAG (ide)
   cXml+= XmlTag( "cUF", cUf)                              // UF do Emitente no caso SP = 35
   cXml+= XmlTag( "cNF",  cNf  )                           // Controle da Nota ou numero do pedido
   cXml+= XmlTag( "natOp", cCfop)                          // Natureza da Operação
   cXml+= XmlTag( "indPag", cIndPag )                      // Indice de Pagamento
   cXml+= XmlTag( "mod", "55" )                            // Modelo NFE=55 (FIXA)
   cXml+= XmlTag( "serie", cSerie )                        // Serie
   cXml+= XmlTag( "nNF", cNf )                             // Numero da Nota Fiscal
   cXml+=XmlTag( "dhEmi",  DateTimeXml(cDataE, cTimeE)     // Data Emissão Formato yyyy-mm-dd
   If !Empty(cDataS)
      cXml+= XmlTag( "dhSaiEnt", DateTimeXml(cDataS, cTimeS)) // Data da Saida da mercadoria
   Endif
   cXml+= XmlTag( "<tpNF>", cTipoNf)                       // Tipo de Emissão da NF
   cXml+= XmlTag( "<idDest>", cIdest)                      // Identificador de Local de destino da operação (1-Interna;2-Interestadual; 3-Exterior)
   cXml+= XmlTag( "<cMunFG>" + cMunIbged )                 // IBGE do destinatário
   cXml+= XmlTag( "<tpImp>", "1")                          // Tipo de Impressão (Paisagem/Retrato) (FIXO)
   cXml+= XmlTag( "<tpEmis>", "1")                         // Tipo de Emissão  (FIXO)
   cXml+= XmlTag( "<cDV>" + Right(cDv, 1))                 // Dígito da Chave de Acesso
   cXml+= XmlTag( "<tpAmb>" , cAmbiente)                   // Ambiente de Emissão (Hom./Producao)

   cXml+= XmlTag( "<finNFe>" + cFinalidade )               // NF Complementar
   If cAmbiente == [2]                                     // Alteração para Homologação vigente a partir de 01/05/2011
      cXml+= XmlTag( "<indFinal>", "1")                    // Indica operação com consumidor final (0-Não;1-Consumidor Final)
   Else
      cXml+= XmlTag( "<indFinal>", "0")                     // Indica operação com consumidor final (0-Não;1-Consumidor Final)
   Endif
   cXml+= XmlTag( "<indPres>" , cIndPres)                  // Indicador de Presença
*                 cXml+= '<indPres>' + Iif(oPresencial,'1',;
*                   Iif(GetProperty([f_Generico], [Cb_Finalidade], [Value]) == 2 .or.  GetProperty([f_Generico], [Cb_Finalidade], [Value]) == 3, [0], [2])) + '</indPres>'    // Indicador de presença do comprador no estabelecimento comercial no momento da
*                                                                                    // operaçã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, tele-atendimento;4-NFC-e entrega
*                                                                                    // em domicílio;9-Não presencial, outros.
  cXml+= XmlTag( "<procEmi>", "3")                                      // Fixo
  cXml+= XmlTag( "<verProc>", "3.10.86")                                // Versão do XML
  If !Empty(Nfrefencia)
     cXml+= "<NFref>"
     cXml+= XmlTag( "<refNFe>" + CharRem("/;-:,\.(){}[] ", Nfrefencia))
     cXml+= "</NFref>"
  Endif
  cXml += '</ide>')     // Final da TAG (ide)
Return (Nil)

FUNCTION XmlTag( cTag, cConteudo )  /// esta função está em ze_xmlfun.prg - postei somente para funcionar

   LOCAL cTexto := ""

   hb_Default( @cConteudo, "" )
   cConteudo := AllTrim( cConteudo )
   IF Len( Trim( cConteudo ) ) = 0
      cTexto := [<]+ cTag + [/>]
   ELSE
      cConteudo := AllTrim( cConteudo )
      IF Len( cConteudo ) == 0
         cConteudo := " "
      ENDIF
      cTexto := cTexto + [<] + cTag + [>] + cConteudo + [</] + cTag + [>]
   ENDIF

   RETURN cTexto

FUNCTION DateTimeXml( dDate, cTime, cUF, lUTC )  /// esta função está em ze_xmlfun.prg - postei somente para funcionar

   LOCAL cText, lHorarioVerao

   hb_Default( @dDate, Date() )
   hb_Default( @cTime, Time() )
   hb_Default( @cUF, "SP" )
   hb_Default( @lUTC, .T. )

   lHorarioVerao := ( dDate >= HorarioVeraoInicio( Year( dDate ) ) .AND. dDate <= HorarioVeraoTermino( Year( dDate - 1 ) ) )
   cText := Transform( Dtos( dDate ), "@R 9999-99-99" ) + "T" + cTime

   DO CASE
   CASE ! lUTC ; cText += "" // no UTC
   CASE cUF $ "AC"                                             ; cText += "-05:00"
   CASE cUF $ "MT,MS" .AND. lHorarioVerao                      ; cText += "-05:00"
   CASE cUF $ "DF,ES,GO,MG,PR,RJ,RS,SC,SP" .AND. lHorarioVerao ; cText += "-04:00"
   CASE cUF $ "AM,MT,MS,RO,RR"                                 ; cText += "-04:00"
   OTHERWISE                                                   ; cText += "-03:00"
   ENDCASE

   RETURN cText

malcarli
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 184
Data de registro: 20 Ago 2015 18:14
Cidade/Estado: marilia/sp
Curtiu: 83 vezes
Mens.Curtidas: 4 vezes

Uso da classesefaz

Mensagempor JoséQuintas » 29 Set 2016 18:28

Só pra lembrar:
função STATIC, mesmo que use nome repetido que existe em outro fonte, só vale para o fonte aonde ela está.

STATIC FUNCTION QualquerNome()


Assim pode criar qualquer nome à vontade, que não sofre interferência de fora, e nem interfere com alguma coisa de fora.
Por exemplo, em todos os meus relatórios eu tenho a função Imprime(). CADA relatório tem sua própria Imprime().
Facilita criar nomes nessa geração, pra não se preocupar por ter algum nome igual em outro lugar.

Mas você é que deve analisar pra quando for fazer manutenção.
Pode ter BlocoEmitente(), BlocoDestinatario(), BlocoProduto(), BlocoImpostos(), etc.
Se tiver que mexer no emitente, só procurar "emitente", ou "blocoemitente".

E se precisar adicionar particularidades, também facilita.
Por exemplo, medicamentos, que tem detalhes a mais.
Só encontrar a posição e colocar BlocoMedicamentos( @cXml )
E na rotina BlocoMedicamentos só se preocupa com medicamentos.

E pode fazer subdivisões, por exemplo, o BlocoImpostos(), chamando BlocoIcms(), BlocoIpi(), BlocoPis(), BlocoCofins(), etc.
Vai dividindo o que era um problemão, em probleminhas.... rs

Isso vale pra txt e pra xml.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18149
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Uso da classesefaz

Mensagempor malcarli » 29 Set 2016 19:31

Veja Mestre, este fragmento está gerando corretamente.

/*****************************************************************************
* SISTEMA  : ROTINA EVENTUAL                                                *
* PROGRAMA : TESTE_GERAR_XML.PRG                                      *
* OBJETIVO : Gerar Xml de Nfe                                               *
* AUTOR    : Marcelo Antonio Lázzaro Carli                                  *
* DATA     : 29.09.2016                                                     *
* ULT. ALT.: 29.09.2016                                                     *
*****************************************************************************/
#include "minigui.ch"

#define DOW_DOMINGO   1  /// este define está em ze_xmlfun.prg - postei somente para funcionar

Procedure Main()
   REQUEST HB_LANG_PT
   HB_LangSelect([PT])
   REQUEST HB_CODEPAGE_PT850 &&& PARA INDEXAR CAMPOS ACENTUADOS
   HB_SETCODEPAGE([PT850])   &&& PARA INDEXAR CAMPOS ACENTUADOS

   Set wrap on
   Set talk off
   Set date briti             &&& data no formato dd/mm/aaaa
   Set dele on                &&& ignora registros marcados por deleção
   Set score off
   Set exact on
   Set ToolTip on
   Setcancel(.F.)             &&& evitar cancelar sistema c/ ALT + C
   Set cent on                &&& ano com 4 dígitos
   Set epoch to 2000          &&& ano a partir de 2000
   Set excl off               &&& abre arquivos em modo compartilhado
   Set navigation extended    &&& enter no lugar do tab
   Set language to portuguese &&& mensagens em português
   Set multiple off warning   &&& abrir 1 cópia somente
   Set browsesync on          &&& para o comando browse funcionar ok
   Set tooltipstyle balloon   &&& para mensagem dos campos em forma de balão
   Set menustyle extended     &&& padrão é standard, extended estilo office 2007
   Set programmaticchange off &&& introduzida na build 1.9.94

   define window fTeste_Xml at 0, 0 width 500 height 300 ICON [demo.ico] NOTIFYICON [demo.ico] MAIN title [Gerar Xml de Nfe] NOSIZE NOMAXIMIZE

      DEFINE STATUSBAR FONT "Arial" SIZE 9
        STATUSITEM [Sistemas] ICON [demo.ico] DEFAULT ACTION MsgInfo([Cliquei no ícone])
        KEYBOARD
        CLOCK
        DATE
      END STATUSBAR

      define button btn_GerarXml
         row 50
         col 90
         width 120
         caption [&Gerar Xml]
         action {|| fGeraXml([0000000001], [99.999.999/0001-91])}
         DEFAULT .t.
      end button

      on key escape action {|| Thiswindow.Release}
   end window

   fTeste_Xml.center()
   fTeste_Xml.activate()
Return (Nil)

Static Procedure fGeraXml(cNf, cCnpj)
   Local cXml:= [], cId:= GetChaveAcesso(cNf, cCnpj, [35], [1])
 
   *** Cria o xml
   fCria_Xml(@cXml, cId)

   *** Identificação - Tag Ide
   fCriaIde(@cXml, [35], [000000001], [Venda mercadoria adquirida ou recebida de terceiros], [0], [1], dtoc(date()), time(), dtoc(date()), time(), [0], [1], [2], [0], [1], [3550308], [1], [])

   *** Fechamento do Cfe   
   fCriaFechamento(@cXml)
Return (Nil)

Static Procedure fCria_Xml(cXml, cId)
   cXml+= '<NFe xmlns="http://www.portalfiscal.inf.br/nfe">' + hb_OsNewLine()
   cXml+= '<infNFe versao="3.10" Id="NFe' + cId + '" >'      + hb_OsNewLine()
Return (Nil)

Static Procedure fCriaFechamento(cXml)
   Local nHandle

   If Empty(cXml)
      Return (Nil)
   Endif

   cXml+= '</NFe>'
   If (nHandle:= FCREATE([teste.xml], 0)) == -1
       MsgInfo([Não foi possível criar o arquivo rascunho XML])
       Return (Nil)
   Endif
   FWRITE(nHandle, cXml)
   FCLOSE(nHandle)
Return (Nil)

Static Procedure fCriaIde(cXml, cUf, cNf, cCfop, cIndPag, cSerie, cDataE, cTimeE, cDataS, cTimeS, cTipoNf, cDv, cAmbiente, cIndPres, cIdest, cMunIbged, cFinalidade, Nfrefencia)
   If Empty(cXml)
      Return (Nil)
   Endif

   cXml+= '<ide>' // Inicio da TAG (ide)
   cXml+= XmlTag( "cUF", cUf)                              // UF do Emitente no caso SP = 35
   cXml+= XmlTag( "cNF",  cNf  )                           // Controle da Nota ou numero do pedido
   cXml+= XmlTag( "natOp", cCfop)                          // Natureza da Operação
   cXml+= XmlTag( "indPag", cIndPag )                      // Indice de Pagamento
   cXml+= XmlTag( "mod", "55" )                            // Modelo NFE=55 (FIXA)
   cXml+= XmlTag( "serie", cSerie )                        // Serie
   cXml+= XmlTag( "nNF", cNf )                             // Numero da Nota Fiscal
   cXml+=XmlTag( "dhEmi",  DateTimeXml(cDataE, cTimeE))     // Data Emissão Formato yyyy-mm-dd
   If !Empty(cDataS)
      cXml+= XmlTag( "dhSaiEnt", DateTimeXml(cDataS, cTimeS)) // Data da Saida da mercadoria
   Endif
   cXml+= XmlTag( "tpNF", cTipoNf)                       // Tipo de Emissão da NF
   cXml+= XmlTag( "idDest", cIdest)                      // Identificador de Local de destino da operação (1-Interna;2-Interestadual; 3-Exterior)
   cXml+= XmlTag( "cMunFG", cMunIbged )                  // IBGE do destinatário
   cXml+= XmlTag( "tpImp", "1")                          // Tipo de Impressão (Paisagem/Retrato) (FIXO)
   cXml+= XmlTag( "tpEmis", "1")                         // Tipo de Emissão  (FIXO)
   cXml+= XmlTag( "cDV", Right(cDv, 1))                 // Dígito da Chave de Acesso
   cXml+= XmlTag( "tpAmb" , cAmbiente)                   // Ambiente de Emissão (Hom./Producao)

   cXml+= XmlTag( "finNFe" + cFinalidade )               // NF Complementar
   If cAmbiente == [2]                                     // Alteração para Homologação vigente a partir de 01/05/2011
      cXml+= XmlTag( "indFinal", "1")                    // Indica operação com consumidor final (0-Não;1-Consumidor Final)
   Else
      cXml+= XmlTag( "indFinal", "0")                     // Indica operação com consumidor final (0-Não;1-Consumidor Final)
   Endif
   cXml+= XmlTag( "indPres" , cIndPres)                  // Indicador de Presença
*                 cXml+= '<indPres>' + Iif(oPresencial,'1',;
*                   Iif(GetProperty([f_Generico], [Cb_Finalidade], [Value]) == 2 .or.  GetProperty([f_Generico], [Cb_Finalidade], [Value]) == 3, [0], [2])) + '</indPres>'    // Indicador de presença do comprador no estabelecimento comercial no momento da
*                                                                                    // operaçã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, tele-atendimento;4-NFC-e entrega
*                                                                                    // em domicílio;9-Não presencial, outros.
  cXml+= XmlTag( "procEmi", "3")                                      // Fixo
  cXml+= XmlTag( "verProc", "3.10.86")                                // Versão do XML
  If !Empty(Nfrefencia)
     cXml+= "<NFref>"
     cXml+= XmlTag( "refNFe" + CharRem("/;-:,\.(){}[] ", Nfrefencia))
     cXml+= "</NFref>"
  Endif
  cXml += '</ide>'     // Final da TAG (ide)
Return (Nil)

Static Function GetChaveAcesso(cNF, cCnpj, cUfEmit, cSerie)  // Manual cUf + AAMM + CNPJ + Mod + Serie + NrNota + cNF + cDV  - Marcelo de Paula 22/06/2016
   Local cKey:= cUfEmit                  /// no caso sp = 35
         cKey+= SubStr(Dtoc(date()), 9, 2) + SubStr(Dtoc(date()), 4, 2)
         cKey+= CharRem("/;-:,\.(){}[] ", cCnpj)
         cKey+= [55] + Padl(cSerie, 3, [0])
         cKey+= Padl(cNF, 9, [0])
         cKey+= [1]
         cKey+= Padl(cNF, 8, [0])
Return (cKey + fDv_nfe(cKey))

Static Function fDv_nfe(cVarchave) // Função para Calculo de Digito - Marcelo de Paula 22/06/2016
   Local nCont1:= Len(cVarchave) + 1, nCont2:= x_Cont:= 1, nSoma:= 0, cDigito:= [0]

   For x_Cont:= 1 to Len(cVarchave)
       nCont1-= 1
       nCont2+= 1

       If nCont2 == 10
          nCont2:= 2
       Endif
       nSoma+= Val(SubStr(cVarchave, nCont1, 1)) * nCont2
   Next
   If Mod(nSoma, 11) <= 1
      cDigito:= [0]
   Else
      cDigito:= AllTrim(Str(11 - Mod(nSoma, 11), 10))
   Endif
Return(cDigito)

FUNCTION XmlTag( cTag, cConteudo )  /// esta função está em ze_xmlfun.prg - postei somente para funcionar

   LOCAL cTexto := ""

   hb_Default( @cConteudo, "" )
   cConteudo := AllTrim( cConteudo )
   IF Len( Trim( cConteudo ) ) = 0
      cTexto := [<]+ cTag + [/>]
   ELSE
      cConteudo := AllTrim( cConteudo )
      IF Len( cConteudo ) == 0
         cConteudo := " "
      ENDIF
      cTexto := cTexto + [<] + cTag + [>] + cConteudo + [</] + cTag + [>]
   ENDIF

   RETURN cTexto

FUNCTION DateTimeXml( dDate, cTime, cUF, lUTC )  /// esta função está em ze_xmlfun.prg - postei somente para funcionar

   LOCAL cText, lHorarioVerao

   hb_Default( @dDate, Date() )
   hb_Default( @cTime, Time() )
   hb_Default( @cUF, "SP" )
   hb_Default( @lUTC, .T. )

   lHorarioVerao := ( dDate >= HorarioVeraoInicio( Year( dDate ) ) .AND. dDate <= HorarioVeraoTermino( Year( dDate - 1 ) ) )
   cText := Transform( Dtos( dDate ), "@R 9999-99-99" ) + "T" + cTime

   DO CASE
   CASE ! lUTC ; cText += "" // no UTC
   CASE cUF $ "AC"                                             ; cText += "-05:00"
   CASE cUF $ "MT,MS" .AND. lHorarioVerao                      ; cText += "-05:00"
   CASE cUF $ "DF,ES,GO,MG,PR,RJ,RS,SC,SP" .AND. lHorarioVerao ; cText += "-04:00"
   CASE cUF $ "AM,MT,MS,RO,RR"                                 ; cText += "-04:00"
   OTHERWISE                                                   ; cText += "-03:00"
   ENDCASE

   RETURN cText

FUNCTION HorarioVeraoInicio( iAno )  /// esta função está em ze_xmlfun.prg - postei somente para funcionar

   LOCAL dPrimeiroDeOutubro, dPrimeiroDomingoDeOutubro, dTerceiroDomingoDeOutubro

   dPrimeiroDeOutubro := Stod( StrZero( iAno, 4 ) + "1001" )
   dPrimeiroDomingoDeOutubro := dPrimeiroDeOutubro + iif( Dow( dPrimeiroDeOutubro ) == DOW_DOMINGO, 0, ( 7 - Dow( dPrimeiroDeOutubro ) + 1 ) )
   dTerceiroDomingoDeOutubro := dPrimeiroDomingoDeOutubro + 14

   RETURN dTerceiroDomingoDeOutubro

FUNCTION DomingoDePascoa( iAno )  /// esta função está em ze_xmlfun.prg - postei somente para funcionar

   LOCAL iA, iB, iC, iD, iE, iF, iG, iH, iI, iK, iL, iM, iMes, iDia

   iA := iAno % 19
   iB := Int( iAno / 100 )
   iC := iAno % 100
   iD := Int( iB / 4 )
   iE := iB % 4
   iF := Int( ( iB + 8 ) / 25 )
   iG := Int( ( iB - iF + 1 ) / 3 )
   iH := ( 19 * iA + iB - iD - iG + 15 ) % 30
   iI := Int( iC / 4 )
   iK := iC % 4
   iL := ( 32 + 2 * iE + 2 * iI - iH - iK ) % 7
   iM := Int( ( iA + 11 * iH + 22 * iL) / 451 )
   iMes := Int( ( iH + iL - 7 * iM + 114 ) / 31 )
   iDia := ( ( iH + iL - 7 * iM + 114 ) % 31 ) + 1

   RETURN Stod( StrZero( iAno, 4 ) + StrZero( iMes, 2 ) + StrZero( iDia, 2 ) )

FUNCTION TercaDeCarnaval( iAno )  /// esta função está em ze_xmlfun.prg - postei somente para funcionar

   RETURN DomingoDePascoa( iAno ) - 47

FUNCTION HorarioVeraoTermino( iAno )  /// esta função está em ze_xmlfun.prg - postei somente para funcionar

   LOCAL dPrimeiroDeFevereiro, dPrimeiroDomingoDeFevereiro, dTerceiroDomingoDeFevereiro

   dPrimeiroDeFevereiro := Stod( StrZero( iAno + 1, 4 ) + "0201" )
   dPrimeiroDomingoDeFevereiro := dPrimeiroDeFevereiro + iif( Dow( dPrimeiroDeFevereiro ) == DOW_DOMINGO, 0, ( 7 - Dow( dPrimeiroDeFevereiro ) + 1 ) )
   dTerceiroDomingoDeFevereiro := dPrimeiroDomingoDeFevereiro + 14
   IF dTerceiroDomingoDeFevereiro == TercaDeCarnaval( iAno + 1 ) - 2 /* nao pode ser domingo de carnaval */
      dTerceiroDomingoDeFevereiro += 7
   ENDIF

   RETURN dTerceiroDomingoDeFevereiro
malcarli
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 184
Data de registro: 20 Ago 2015 18:14
Cidade/Estado: marilia/sp
Curtiu: 83 vezes
Mens.Curtidas: 4 vezes

Uso da classesefaz

Mensagempor JoséQuintas » 29 Set 2016 19:43

Melhor não deixar o fonte dependendo de formato de data.

cKey+= SubStr(Dtoc(date()), 9, 2) + SubStr(Dtoc(date()), 4, 2)


mais seguro assim:

cKey += Right( StrZero( Year( Date() ), 4 ), 2 ) + StrZero( Day( Date() ), 2 )


Assim tem trabalho uma vez só...
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18149
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Anterior Próximo



Retornar para Projeto hbNFe

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 1 visitante


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro