Pra quem ainda não resolveu NFE/CTE/MDFE

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

Moderador: Moderadores

Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Pra quem ainda não resolveu NFE/CTE/MDFE

Mensagem por JoséQuintas »

Aproveitem enquanto o emissor do governo ainda funciona.

O emissor do governo é algo como:

- um conversor de TXT pra XML
- um assinador
- um "enviador" de mensagens pra Fazenda
- um "receptor" de mensagens pra Fazenda
- um "montador" de XMLs autorizados
- também "monta" os XMLs de carta de correção e cancelamento

Dá pra fazer algumas etapas fora do emissor, isso ajuda a ir deixando pronto, sem ter que fazer tudo de uma vez.

1. Ao invés de gerar TXT, gerar XML, pode até usar uma assinatura falsa, só pra poder importar o XML no emissor mesmo com alerta de assinatura inválida
Feito isso, sua geração XML vai estar do jeito que precisa ser transmitido, mas sem assinatura
No emissor do governo vai validar, assinar, transmitir, fazer cancelamento, carta de correção, etc.

2. Assinar o XML, assim já importa no emissor do governo assinado.
Já vai testar a assinatura, e feito isso, seu XML vai estar do jeito que precisa ser transmitido.
No emissor do governo vai transmitir, cancelamento, carta de correção, etc.

3. Pode testar transmissão e já criar autorizado sem o emissor do governo.
Qualquer coisa, ainda pode usar o emissor do governo pra completar, ou baixar direto do site

4. As próximas etapas serão cancelamento e carta de correção e Danfe

Então dá pra ir trocando um processo de cada vez, os usuários também poderão fazer isso por conta própria.
Assim vai poder ter mais flexibilidade nos testes, não tendo que fazer correria pra resolver problemas.
O que falhar de um jeito, vai de outro.

Vai poder usar um pra conferir o outro, ou um pra completar o outro.

É bom aproveitar agora, que ainda tem o emissor do governo, e ainda tem essa opção de misturar.
Depois não vai ter opção: ou funciona, ou vai outro aplicativo no lugar do seu.
Mas podendo fazer parcial, vai fazer com muito mais tranquilidade.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, 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
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Pra quem ainda não resolveu NFE/CTE/MDFE

Mensagem por JoséQuintas »

Um jeito simples de gerar xml.
Cole um xml no fonte:

Código: Selecionar todos

cXml := [<det nItem="39"><prod><cProd>000587</cProd><cEAN/><xProd>FILTRO VOX MOD.LB2801 LB45 (E-3)</xProd><NCM>84212300</NCM><CFOP>5405</CFOP><uCom>UND.</uCom><qCom>50.0000</qCom><vUnCom>6.1100</vUnCom><vProd>305.50</vProd><cEANTrib/><uTrib>UND.</uTrib><qTrib>50.0000</qTrib><vUnTrib>6.1100</vUnTrib><indTot>1</indTot></prod>-<imposto>-<ICMS>-<ICMS60><orig>0</orig><CST>60</CST><vBCSTRet>0.00</vBCSTRet><vICMSSTRet>0.00</vICMSSTRet></ICMS60></ICMS><IPI><cEnq>999</cEnq>-<IPINT><CST>03</CST></IPINT></IPI><PIS><PISAliq><CST>01</CST><vBC>305.50</vBC><pPIS>1.65</pPIS><vPIS>5.04</vPIS></PISAliq></PIS><COFINS><COFINSAliq><CST>01</CST><vBC>305.50</vBC><pCOFINS>7.60</pCOFINS><vCOFINS>23.21</vCOFINS></COFINSAliq></COFINS></imposto></det>]
Separe em blocos, sem se importar com o tamanho do fonte:

Código: Selecionar todos

cXml := [<det nItem="39">]
cXml += [<prod>]
cXml += [<cProd>000587</cProd>]
cXml += [<cEAN/>]
cXml += [<xProd>FILTRO VOX MOD.LB2801 LB45 (E-3)</xProd>]
cXml += [<NCM>84212300</NCM>]
cXml += [<CFOP>5405</CFOP>]
cXml += [<uCom>UND.</uCom>]
cXml += [<qCom>50.0000</qCom>]
...
A função que já postei por aqui XmlTag é so pra reduzir essa quantidade de texto, usar pode facilitar um pouco, ou melhorar o fonte:

Código: Selecionar todos

cXml := [<det nItem="39">]
cXml += [<prod>]
cXml += XmlTag( "cProd", "000587" )
cXml += [<cEAN/>]
cXml += XmlTag( "xProd", "FILTRO VOX MOD.LB2801 LB45 (E-3)" )
cXml += XmlTag( "NCM", "84212300" )
cXml += XmlTag( "CFOP", "5405" )
cXml += XmlTag( "uCom", "UND" )
cXml += XmlTag( "qCom", "50.0000" )
...
Por último, é trocar o valor pelas variáveis do seu banco de dados.

Também pode dividir o fonte em blocos pra facilitar, e pra dividir o problemão em probleminhas:

Código: Selecionar todos

cXml := [<det item="39">]
...
BlocoImpostos( @cXml )

FUNCTION BlocoImpostos( cXml )
BlocoIpi( @cXml )
BlocoIcms( @cXml )
BlocoPis( @cXml )
BlocoCofins( @cXml )
RETURN NIL
Partindo de um XML já existente, pode criar o fonte numa boa.
Partindo de uma geração de TXT, idem, já que o XML segue a mesma ordem do TXT, e contém os mesmos blocos.

A coisa não é complicada, é TRABALHOSA, porque tem muita informação.
Dividindo em blocos, vai trabalhar com um pouco de informação por vez, o que facilita pra não encher de variáveis e se perder no meio de tanta variável.

Só imaginar que talvez vá usar mais de 1.000 informações diferentes dentro do XML.
Então não é se preocupar em fazer rápido, e sim em fazer um fonte que vai facilitar manutenção/correção.
Ficando fácil de corrigir, pode até errar à vontade... rs

Deu problema no emitente... vai no bloco do emitente
Deu problema no destinatário... vai no bloco do destinatário
Deu problema em impostos... vai no bloco de impostos

Então... o fonte organizado e de fácil manutenção vai ajudar muuuuito.
No XML, os próprios nomes de campos no XML ajudam a localizar tudo.
Já no TXT não existe nome, então um fonte de TXT é mais complicado de mexer, ou vai precisar muito mais anotações.

Pra importar no emissor do governo, o XML precisa estar assinado, então só colocar no seu fonte pra acrescentar uma assinatura qualquer, de qualquer XML, que vai conseguir importar no emissor.
Isso já vai permitir trabalhar com XML antes mesmo de ter o restante pronto.

Se fizer o fonte correndo, bagunçado, vai ter cada vez mais trabalho pra consertar o fonte.
Se fizer o fonte devagar, organizado, vai consertar fácil.
É por ai.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, 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
rubens
Colaborador
Colaborador
Mensagens: 1520
Registrado em: 16 Ago 2003 09:05
Localização: Nova Xavantina - MT

Pra quem ainda não resolveu NFE/CTE/MDFE

Mensagem por rubens »

Bom dia...

José Quintas,

Primeiramente vai aqui meus votos de estima e consideração por você... Não gosto de bajulação, mas é de coração mesmo... A minha regra de fé e prática diz que "Honra a quem honra!!!". E você tem nos honrado muito com suas postagens e vontade de transferir conhecimentos...

Quanto a classe SEFAZ e ao seu uso acho que poderia ser feito assim, parecido com o que é feito no ACBR.
Fazer um levantamento aqui de quem realmente quer tocar isso para frente;
Criar um grupo com responsáveis por cada área para te ajudar;
O que quero dizer é, Se conseguirmos montar um grupo focado nisso e interessado nisso, vai pra frente, senão você vai ficar dando murro em ponta de faca...
Porque quando alguns passarem a ter certas responsabilidades aquela parte do algorítimo vai melhorar e todos adotarão um padrão. O que vejo hoje é que você desenvolve e otimiza a classe, alguém vem pega o que fez implanta e não compartilha, pode até funcionar para quem implantou mas não para o restante, daí não tem uso não anda...
Então se eu não estiver falando besteira e você concordar, vamos criar uma postagem para buscar/recrutar os interessados em fazer parte, seja como desenvolvedor, seja como testador, mas de alguma forma que queira se envolver. Daí vamos sugerir ao Toledo criar uma sessão fiz referente somente ao desenvolvimento e manutenção dessa classe.
Você pode dizer existe muito código disso aqui no Fórum, mas está muito fragmentado.. Temos que ler muitas coisas e muita fuga de assunto.
O que você acha dessa linha de pensamento?

Rubens...
"Eu e minha casa servimos ao Senhor e você ???"
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Pra quem ainda não resolveu NFE/CTE/MDFE

Mensagem por JoséQuintas »

Confundiu um pouco também:

Não há o que fugir do que acontece, é sempre a mesma coisa:

um texto.
mais texto no texto.
Transmissão do texto pra Fazenda.
Texto que retorna da Fazenda
Uma junção de textos pra gerar o autorizado.

Isso não tem a ver com a classe Sefaz, tem a ver com qualquer uso, use o que usar.

Seja gerando TXT, ou gerando ACBR, ou gerando INI, ou qualquer outro tipo de geração, isso vai acabar chegando ao mesmo XML.
Se passarmos a gerar em formato XML, estamos eliminando algo intermediário cujo aprendizado não ensina nada, e aí sim, estaremos aprendendo algo útil, que é o XML oficial, aceito por todos os componentes.
E fica todo mundo falando a "mesma língua", governo, componente, programador, etc.

A parte que comentei aqui é essa, comum pra tudo, não tem a ver com a classe Sefaz, é apenas o formato padrão que todos aceitam, inclusive a classe Sefaz.
Se após estar gerando XML vão usar a classe Sefaz ou não, isso não importa.

É só disso que se trata: todo mundo que gera em formato XML, pode ajudar todo mundo que gera em formato XML.
Não importa nem mesmo qual a linguagem de programação, e nem mesmo o que usa pra completar o processo.

Até o emissor do governo aceita em formato XML, o que ajuda qualquer fase intermediária, mas justamente essa ajuda está com dias contados.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, 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/
lugab
Colaborador
Colaborador
Mensagens: 843
Registrado em: 19 Mai 2009 15:58

Pra quem ainda não resolveu NFE/CTE/MDFE

Mensagem por lugab »

Concordo com o Rubens. Há tempos precebe-se a vontade do Quintas em ajudar geral no tocante a NFE, postando
idéias avulsas...

José Quintas poderia fazer um tutorial "bê-a-bá padrão super-híper-iniciante" como fez o Rubens no caso do AcbrMonitorPlus, que ajudou até mesmo gente do meu baixo nível, levando em consideração que o objetivo é "atender quem não tem nem de longe um nível de conhecimento similar ao dele...

Espero que J.Quintas faça mesmo isso aconteçer, pois a assinatura do AcbrMonitorPlus já está custando R$150,00/mês e quando janeiro chegar ninguém sabe quanto custará...
lugab
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Pra quem ainda não resolveu NFE/CTE/MDFE

Mensagem por JoséQuintas »

a assinatura do AcbrMonitorPlus já está custando R$150,00/mês
Eita, não sabia disso.

Então é mais um motivo pra aprender o formato padrão, e já ter mais opções de escolha.

Um "bê-a-bá", só se for assim:

1. ENXERGAR O QUE ESTÁ NA FRENTE DO NARIZ

Importante, se não enxergar, não vai sair do lugar

2. SABER LER

Importante, se não souber ler, não vai saber

3. SABER PROGRAMAR

Importante, se não souber programar, não vai saber

4. Conhecer função, e se possível método/classe

Isso é importante, ajuda a clarear as coisas

Sabendo disso, vamos lá.
O que quer fazer? autorizar nota?

Vamos lá no fonte da classe, ver os nomes de métodos disponíveis.
Por exclusão, tudo indica que é este:

Código: Selecionar todos

   METHOD NFeLoteEnvia( cXml, cLote, cUF, cCertificado, cAmbiente, cIndSinc )
Pelos nomes, precisa do XML, de um número de lote, da UF, de um certificado, e do ambiente

XML: uma variável texto contendo o xml
LOTE: pode ser "1"
UF: "SP" ou outra
certificado: o nome do certificado, por exemplo "FORUM PCTOLEDO"
ambiente: 1=produção, 2=homologação.

Então, pra autorizar uma nota é:

Código: Selecionar todos

oSefaz := SefazClass():New()
oSefaz:NfeLoteEnvia( "<xmlnota>", "1", "SP", "FORUM PCTOLEDO", "1" )
E agora?

Olhando lá no fonte as variáveis disponíveis:

Código: Selecionar todos

   /* XMLs de cada etapa */
   VAR    cXmlDocumento  INIT ""                      // O documento oficial, com ou sem assinatura, depende do documento
   VAR    cXmlEnvio      INIT ""                      // usado pra criar/complementar XML do documento
   VAR    cXmlSoap       INIT ""                      // XML completo enviado pra Sefaz, incluindo informações do envelope
   VAR    cXmlRetorno    INIT "Erro Desconhecido"     // Retorno do webservice e/ou rotina
   VAR    cXmlRecibo     INIT ""                      // XML recibo (obtido no envio do lote)
   VAR    cXmlProtocolo  INIT ""                      // XML protocolo (obtido no consulta recibo e/ou envio de outros docs)
   VAR    cXmlAutorizado INIT ""                      // XML autorizado, caso tudo ocorra sem problemas
   VAR    cStatus        INIT ""                      // Status obtido da resposta final da Fazenda
   VAR    cRecibo        INIT ""                      // Número do recibo
   VAR    cMotivo        INIT ""                      // Motivo constante no Recibo
Então:
Se quiser o XML que será usado como nota autorizada: oSefaz:cXmlAutorizado
Se quiser o documento assinado, é oSefaz:cXmlDocumento
Se quiser o XML que foi usado pra enviar: oSefaz:cXmlEnvio
Se quiser o XML usado na comunicação: oSefaz:cXmlSoap
Se quiser saber a situação final da nota: oSefaz:cMotivo
Se quiser saber o que a Sefaz respondeu: oSefaz:cXmlRetorno

É tudo texto, nada em disco, salva aonde quiser, do jeito que quiser.
Quer salvar o autorizado? hb_MemoWrit( "autorizado.xml", oSefaz:cXmlAutorizado )


A questão não é um bê-á-bá.
A questão é ter interesse. Se tem interesse, tá tudo lá, de um jeito ou de outro descobre como usar.
Corrigindo: a questão é entender como funciona, enviar um texto e pegar a resposta
A questão é simples, a classe é simples.
Tudo que no ACBR é arquivo, aqui são apenas variáveis com texto

Parece piada dizer isso, mas:
não tem o que explicar, só tem mesmo que entender.

Veja só... vou tentar explicar:

XML é um XML
XmlAutorizado é..... Xml autorizado
XMLEnvio é .... XML usado pra envio
XMLRetorno é.... XML que veio no retorno
XMLSoap é.... XML usado no SOAP
XMLDocumento é... XML que é considerado um documento - não tem autorização, mas é o documento antes do processo
XMLProtocolo é... XML que contém o protocolo
Parâmetro de função é... parâmetro de função, não importa se é função ou método de classe
Variável é.... variável, não importa se é variável comum ou variável dentro da classe
NFeLoteEnvia é... rotina de NFe que envia lote
NFeEventoCancela é... rotina de NFe para o evento de cancelamento
NFeEventoCarta é.... rotina de NFe para o evento de carta de correção
NFeInutiliza é.... rotina de NFe para inutilização
variável é variável, seja dentro ou fora da classe
parâmetro de função é parâmetro de função, seja função ou método de classe


É tudo auto-explicativo, percebeu?
Dá pra dizer que todo mundo deveria entender tudo isso.
Tudo bem, talvez classe seja considerado um "mundo novo" pra muita gente, mas podemos dizer que são variáveis e funções, apenas neste caso usando o prefixo oSefaz:
E volta a ser o que todo mundo conhece.
E volta à questão: explicar o que?
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, 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
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Pra quem ainda não resolveu NFE/CTE/MDFE

Mensagem por JoséQuintas »

E pode usar variáveis da classe se achar que isso pode facilitar em alguma coisa:

Código: Selecionar todos

oSefaz := SefazClass():New()
oSefaz:cAmbiente := "1"
oSefaz:cCertificado := "nome do certificado"
oSefaz:cUF := "SP"
oSefaz:NfeLoteEnvia( cXml, "1" )
IF oSefaz:cStatus == "100"
   hb_MemoWrit( "xmlautorizado.xml", oSefaz:cXmlAutorizado )
ELSE
   hb_MemoWrit( "xmloriginal.xml", oSefaz:cXmlDocumento )
   hb_MemoWrit( "xmlretorno.xml", oSefaz:cXmlRetorno )
ENDIF
Isso acima seria tudo que precisa pra autorizar uma NFE.
É só isso mesmo, os nomes são auto-explicativos.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, 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
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Pra quem ainda não resolveu NFE/CTE/MDFE

Mensagem por JoséQuintas »

Uia que legal.
Acabou de rolar no grupo UNINFE, e tem tudo a ver com o assunto.
o usuário:
de onde pego o valor
<idLote>000000000038313</idLote>

o autor do componente:
É um número sequencial, seu sistema pode gerar ele (1,2,3,4,5,6,7,etc...) mas coloque ele com 15 digitos e zeros a esquerda.
o manual do governo
"tamanho de 1 a 15 dígitos, Identificador de controle do Lote de envio do Evento. Número sequencial autoincremental único para identificação do Lote. A responsabilidade de gerar e controlar é exclusiva do autor do evento. O Web Service não faz qualquer uso deste identificador."
Em outras palavras:
Não serve pra bost. nenhuma.
Se inventar de usar e controlar lote, é problema seu e da sua conta.

Pode até ser sempre "1", mas sem olhar o manual do governo, a orientação é inclusive preencher com 15 dígitos.

Essa é a diferença entre aprender pelo manual do governo, e aprender por algum manual/autor/usuário do componente de NFE.
É sobre isso que venho falando, isso não tem nada a ver com usar ou não a classe Sefaz, mas sobre aprender corretamente sofre NFE.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, 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
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

Pra quem ainda não resolveu NFE/CTE/MDFE

Mensagem por fladimir »

Uso o ACBR

Comecei usar a classe hbNFe e Sefaz...


Fiz o DFe com elas

Demais projetos permanecem no ACBR

O q o Qi tas demonstrou neste tópico é exatamente comum aos projetos

Despertou a galera pra focar novamente no q muitos (estou incluso) pararam por X ou Y motivos.

Então podemos retomar o assunto em um tópico q já existe sobre isto pq o deste tópico acredito q ficou ok.

[]'s
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Pra quem ainda não resolveu NFE/CTE/MDFE

Mensagem por JoséQuintas »

Agora vamos lá, limpem a mente para acompanhar o tópico.
Não precisa pensar em nada, é só olhar o que acontece.
Acompanhem o que acontece, vamos ver se assim fica mais fácil.

Depois das últimas mexidas, acho que ficou separado o que é "diferente".

Consulta protocolo:

Código: Selecionar todos

METHOD NFeConsultaProtocolo( cChave, cCertificado, cAmbiente ) CLASS SefazClass

   ::Setup( ::UFSigla( Substr( cChave, 1, 2 ) ), cCertificado, cAmbiente, WS_NFE_CONSULTAPROTOCOLO )

   ::cVersaoXml  := "3.10"
   ::cXmlEnvio   := [<consSitNFe versao="] + ::cVersaoXml + [" xmlns="http://www.portalfiscal.inf.br/nfe">]
   ::cXmlEnvio   +=    XmlTag( "tpAmb", ::cAmbiente )
   ::cXmlEnvio   +=    XmlTag( "xServ", "CONSULTAR" )
   ::cXmlEnvio   +=    XmlTag( "chNFe", cChave )
   ::cXmlEnvio   += [</consSitNFe>]
   IF ! Substr( cChave, 21, 2 ) $ "55,65"
      ::cXmlRetorno := "*ERRO* Chave não se refere a NFE"
   ELSE
      ::XmlSoapPost()
   ENDIF

   RETURN ::cXmlRetorno
Só tem criação de variável e soma de string.
Numa chave de acesso, os dois primeiros dígitos representam a UF, então estou retirando a UF desses dois primeiros dígitos.

O que a rotina faz?
- chama Setup()
- cria o cXmlEnvio, que é o XML que vai ser enviado
- Tem o teste só pra confirmar se é realmente nota fiscal
- Chama a rotina de comunicação XmlSoapPost()
- A resposta da comunicação vai ficar em cXmlRetorno

Neste caso, o cXmlEnvio é uma consulta de nota.
Na autorização de nota fiscal é outro XML diferente, mas tudo bem, não pense nisso agora.

Esse XML de consulta é padrão da Fazenda, mas só precisa passar os parâmetros e a classe cria o XML.
Não vai usar a classe, tudo bem, pode aproveitar essa rotina e criar seu XML de consulta desse jeito, pra qualquer componente de NFe.
Mesmo que não queira usar a classe..... tem muita coisa úti, tem exatamente o que precisa e acontecel

Podemos até dizer que isso é tudo, tudo funciona assim.
Lógico, não é, existem diferenças.... como sempre digo... strings diferentes.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, 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
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Pra quem ainda não resolveu NFE/CTE/MDFE

Mensagem por JoséQuintas »

A diferença em geral é na comunicação.
A comunicação é composta de um envelope, e a comunicação propriamente dita, incluindo endereço de internet.
Então vamos lá; primeira parte diferente, STRINGS que mudam conforme a operação
E como sempre digo.... é padrão.... mas não é padrão, aqui está bem visível

Lembrando:
É pra entender o que acontece, não necessariamente entender a classe.

Código: Selecionar todos

METHOD Setup( cUF, cCertificado, cAmbiente, nWsServico ) CLASS SefazClass

   LOCAL nPos, aSoapList := { ;
      { "**", WS_CTE_CONSULTAPROTOCOLO, WS_PROJETO_CTE,  "cteConsultaCT",        "http://www.portalfiscal.inf.br/cte/wsdl/CteConsulta" }, ;
      { "**", WS_CTE_RETRECEPCAO,       WS_PROJETO_CTE,  "cteRetRecepcao",       "http://www.portalfiscal.inf.br/cte/wsdl/CteRetRecepcao" }, ;
      { "**", WS_CTE_RECEPCAOEVENTO,    WS_PROJETO_CTE,  "cteRecepcaoEvento",    "http://www.portalfiscal.inf.br/cte/wsdl/CteRecepcaoEvento" }, ;
      { "**", WS_CTE_INUTILIZACAO,      WS_PROJETO_CTE,  "cteInutilizacaoCT",    "http://www.portalfiscal.inf.br/cte/wsdl/CteInutilizacao" }, ;
      { "**", WS_CTE_RECEPCAO,          WS_PROJETO_CTE,  "cteRecepcaoLote",      "http://www.portalfiscal.inf.br/cte/wsdl/CteRecepcao" }, ;
      { "**", WS_CTE_STATUSSERVICO,     WS_PROJETO_CTE,  "cteStatusServicoCT",   "http://www.portalfiscal.inf.br/cte/wsdl/CteStatusServico" }, ;
      { "**", WS_MDFE_CONSNAOENC,       WS_PROJETO_MDFE, "mdfeConsNaoEnc",       "http://www.portalfiscal.inf.br/mdfe/wsdl/MDFeConsNaoEnc" }, ;
      { "**", WS_MDFE_CONSULTA,         WS_PROJETO_MDFE, "mdfeConsultaMDF",      "http://www.portalfiscal.inf.br/mdfe/wsdl/MDFeConsulta" }, ;
      { "**", WS_MDFE_RETRECEPCAO,      WS_PROJETO_MDFE, "mdfeRetRecepcao",      "http://www.portalfiscal.inf.br/mdfe/wsdl/MDFeRetRecepcao" }, ;
      { "**", WS_MDFE_DISTRIBUICAODFE,  "??????",        "mdfeDistDFeInteresse", "http://www.portalfiscal.inf.br/nfe/wsdl/MDFeDistribuicaoDFe" }, ;
      { "**", WS_MDFE_RECEPCAOEVENTO,   WS_PROJETO_MDFE, "mdfeRecepcaoEvento",   "http://www.portalfiscal.inf.br/mdfe/wsdl/MDFeRecepcaoEvento" }, ;
      { "**", WS_MDFE_RECEPCAO,         WS_PROJETO_MDFE, "MDFeRecepcao",         "http://www.portalfiscal.inf.br/mdfe/wsdl/MDFeRecepcao" }, ;
      { "**", WS_MDFE_STATUSSERVICO,    WS_PROJETO_MDFE, "MDFeStatusServico",    "http://www.portalfiscal.inf.br/mdfe/wsdl/MDFeStatusServico/mdfeStatusServicoMDF" }, ;
      { "**", WS_NFE_CONSULTACADASTRO,  WS_PROJETO_NFE,  "CadConsultaCadastro2", "http://www.portalfiscal.inf.br/nfe/wsdl/CadConsultaCadastro2" }, ;
      { "**", WS_NFE_CONSULTADEST,      WS_PROJETO_NFE,  "nfeConsultaNFDest",    "http://www.portalfiscal.inf.br/nfe/wsdl/NfeConsultaDest/nfeConsultaNFDest" }, ;
      { "**", WS_NFE_DISTRIBUICAODFE,   "???",           "nfeDistDFeInteresse",  "http://www.portalfiscal.inf.br/nfe/wsdl/NFeDistribuicaoDFe" }, ;
      { "**", WS_NFE_RECEPCAOEVENTO,    WS_PROJETO_NFE,  "nfeRecepcaoEvento",    "http://www.portalfiscal.inf.br/nfe/wsdl/RecepcaoEvento" }, ;
      { "**", WS_NFE_INUTILIZACAO,      WS_PROJETO_NFE,  "NfeInutilizacaoNF2",   "http://www.portalfiscal.inf.br/nfe/wsdl/NfeInutilizacao2" }, ;
      { "**", WS_NFE_AUTORIZACAO,       WS_PROJETO_NFE,  "NfeAutorizacao",       "http://www.portalfiscal.inf.br/nfe/wsdl/NfeAutorizacao" }, ;
      { "**", WS_NFE_RETAUTORIZACAO,    WS_PROJETO_NFE,  "NfeRetAutorizacao",    "http://www.portalfiscal.inf.br/nfe/wsdl/NfeRetAutorizacao" }, ;
      { "**", WS_NFE_STATUSSERVICO,     WS_PROJETO_NFE,  "nfeStatusServicoNF2",  "http://www.portalfiscal.inf.br/nfe/wsdl/NfeStatusServico2" }, ;
      { "BA", WS_NFE_STATUSSERVICO,     WS_PROJETO_NFE,  "nfeStatusServicoNF",   "http://www.portalfiscal.inf.br/nfe/wsdl/NfeStatusServico" }, ;
      { "**", WS_NFE_CONSULTAPROTOCOLO, WS_PROJETO_NFE,  "NfeConsulta2",         "http://www.portalfiscal.inf.br/nfe/wsdl/NfeConsulta2" }, ;
      { "BA", WS_NFE_CONSULTAPROTOCOLO, WS_PROJETO_NFE,  "nfeConsultaNF",        "http://www.portalfiscal.inf.br/nfe/wsdl/NfeConsulta" }, ;
      { "AC,AL,AP,DF,ES,PB,RJ,RN,RO,RR,SC,SE,TO", ;
              WS_NFE_CONSULTAPROTOCOLO, WS_PROJETO_NFE,  "nfeConsultaNF2",       "http://www.portalfiscal.inf.br/nfe/wsdl/NfeConsulta2" } }

   ::cUF          := iif( cUF == NIL, ::cUF, cUF )
   ::cCertificado := iif( cCertificado == NIL, ::cCertificado, cCertificado )
   ::cAmbiente    := iif( cAmbiente == NIL, ::cAmbiente, cAmbiente )

   IF nWsServico == NIL
      RETURN NIL
   ENDIF
   IF ( nPos := AScan( aSoapList, { | oElement | oElement[ 1 ] == ::cUF .AND. oElement[ 2 ] == nWsServico } ) ) != 0
      ::cProjeto     := aSoapList[ nPos, 3 ]
      ::cSoapAction  := aSoapList[ nPos, 4 ]
      ::cSoapService := aSoapList[ nPos, 5 ]
   ELSEIF ( nPos := AScan( aSoapList, { | oElement | oElement[ 1 ] == "**" .AND. oElement[ 2 ] == nWsServico } ) ) != 0
      ::cProjeto     := aSoapList[ nPos, 3 ]
      ::cSoapAction  := aSoapList[ nPos, 4 ]
      ::cSoapService := aSoapList[ nPos, 5 ]
   ENDIF
   ::SetSoapURL( nWsServico )

   RETURN NIL
O que é tudo isso?
Apenas está escolhendo strings.

Para o que começou aqui, é consulta protocolo, vai limitar a um destes três:

Código: Selecionar todos

      { "**", WS_NFE_CONSULTAPROTOCOLO, WS_PROJETO_NFE,  "NfeConsulta2",         "http://www.portalfiscal.inf.br/nfe/wsdl/NfeConsulta2" }, ;
      { "BA", WS_NFE_CONSULTAPROTOCOLO, WS_PROJETO_NFE,  "nfeConsultaNF",        "http://www.portalfiscal.inf.br/nfe/wsdl/NfeConsulta" }, ;
      { "AC,AL,AP,DF,ES,PB,RJ,RN,RO,RR,SC,SE,TO", ;
              WS_NFE_CONSULTAPROTOCOLO, WS_PROJETO_NFE,  "nfeConsultaNF2",       "http://www.portalfiscal.inf.br/nfe/wsdl/NfeConsulta2" } }
Veja não é padrão. Depende da UF.
Mas trata-se apenas de escolher a string, de acordo com o que está sendo feito.

Neste aqui tem o SetSoapUrl()
Essa não vou colocar aqui porque é gigante.
É apenas a escolha do endereço de internet, conforme operação/UF/etc.

Acompanhou até aqui?
String formando um XML.
Strings que variam conforme operação/UF/normal e contingência/etc.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, 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
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Pra quem ainda não resolveu NFE/CTE/MDFE

Mensagem por JoséQuintas »

Agora a XmlSoapPost(), usada em TUDO, pra comunicação

Código: Selecionar todos

METHOD XmlSoapPost() CLASS SefazClass

   DO CASE
   CASE Empty( ::cSoapURL )
      ::cXmlRetorno := "Erro SOAP: Não há endereço de webservice"
      RETURN NIL
   CASE Empty( ::cSoapService )
      ::cXmlRetorno := "Erro SOAP: Não há nome do serviço"
      RETURN NIL
   CASE Empty( ::cSoapAction )
      ::cXmlRetorno := "Erro SOAP: Não há endereço de SOAP Action"
      RETURN NIL
   ENDCASE
   ::XmlSoapEnvelope()
   ::MicrosoftXmlSoapPost()
   IF Upper( Left( ::cXmlRetorno, 4 ) )  == "ERRO"
      RETURN NIL
   ENDIF
   IF "<soap:Body>" $ ::cXmlRetorno .AND. "</soap:Body>" $ ::cXmlRetorno
      ::cXmlRetorno := XmlNode( ::cXmlRetorno, "soap:Body" ) // hb_UTF8ToStr()
   ELSEIF "<soapenv:Body>" $ ::cXmlRetorno .AND. "</soapenv:Body>" $ ::cXmlRetorno
      ::cXmlRetorno := XmlNode( ::cXmlRetorno, "soapenv:Body" ) // hb_UTF8ToStr()
   ELSE
      ::cXmlRetorno := "Erro SOAP: XML retorno não está no padrão " + ::cXmlRetorno
   ENDIF

   RETURN NIL
Veja bem. Praticamente só tem validação, só pra garantia.
Sempre, qualquer problema que aconteça (ou não) fica na variável cXmlRetorno
A rotina chama XmlSoapEnvelope() e MicrosoftXmlSoapPost()

Aqui nada "anormal", somente alguns testes.
E uma checagenzinha pra facilitar a limpeza do retorno.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, 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
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Pra quem ainda não resolveu NFE/CTE/MDFE

Mensagem por JoséQuintas »

A XmlEnvelope()
O que é isso?
TUDO na Fazenda, pra comunicar precisa estar dentro de um envelope.
TODOS os envelopes, DE TUDO, consegui reduzir pra uma única função.

Código: Selecionar todos

METHOD XmlSoapEnvelope() CLASS SefazClass

   ::cXmlSoap    := ""
   ::cXmlSoap    += [<?xml version="1.0" encoding="UTF-8"?>] //  encoding="utf-8"?>]
   ::cXmlSoap    += [<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ]
   ::cXmlSoap    +=    [xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">]
   ::cXmlSoap    +=    [<soap12:Body>]
   ::cXmlSoap +=       [<] + ::cProjeto + [DadosMsg xmlns="] + ::cSoapService + [">]
   ::cXmlSoap    += ::cXmlEnvio
   ::cXmlSoap    +=    [</] + ::cProjeto + [DadosMsg>]
   ::cXmlSoap    +=    [</soap12:Body>]
   ::cXmlSoap    += [</soap12:Envelope>]

   RETURN NIL
Olhem bem, é só soma de string.
Está usando as strings que foram escolhidas em Setup()
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, 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
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Pra quem ainda não resolveu NFE/CTE/MDFE

Mensagem por JoséQuintas »

Pronto, é só isso.
Acabaram de ver TUDO de NFE, CTE, MDFE.
Sim, TUDO.

TUDO: conforme a operação (consulta,cancela,carta,autoriza) escolhe uma string, cria um envelope, que manda pra Fazenda e pega a resposta.

A rotina de comunicação, é uma rotina comum qualquer, É ESTE COMPONENTE de comunicação que envia e pega a resposta.
Isso não é o componente de NFE, é a linguagem de programação ou, neste caso da classe Sefaz, o MSXML5 da Microsoft.

E no caso da emissão da nota, inutilização, e não lembro se mais algum, o XML é assinado antes do envio.


Aqui mostrei exatamente o consulta protocolo.
Como deu pra ver, é igual pra autorizar nota, autorizar CTE, autorizar MDFE, carta de correção, etc.
As rotinas de "escolha de strings" é a mesma pra tudo.
A rotina de envelope é a mesma pra tudo.

O que os "negos" cobram pelo componente de NFe:
Apenas colocar no programa as STRINGS corretas.

Como deu pra ver, altera conforme UF, então quando dá problema, é colocar no programa a string correta daquela UF.

Não é complicado, é TRABALHOSO.
É ir criando a lista de strings, conforme a UF.
Se tiver fonte de outro componente, com código aberto, é só copiar de um componente para o outro.

O que pode dar errado?
Já disse: pode ter string errada, porque uma UF pode ser diferente, e precisa acrescentar a UF na lista com as strings corretas.

Mas é tudo string.
strings e um monte de IFs/CASEs... rs


O que altera na autorização de nota: Tudo isso acontece em dobro.
Primeiro envia a nota e recebe um retorno contendo número de recibo, depois faz tudo de novo pra consultar o recibo.
Não é diferente, é a mesma coisa duas vezes.


A partir de agora, qualquer um pode criar um componente de NFe.
É somar strings, e colocar IFs/CASEs.


Eu até digo o seguinte:
A classe Sefaz faz o que qualquer componente faz.
O ponto interessante é que consegui agrupar todas as partes comuns (ou diferentes).
É ótima pra entender como tudo funciona, pra pegar exemplos de XML, etc.

É ótima até pra quem paga por algum componente, pra entender pelo que está pagando.
Ele está indo lá nos fontes e alterando uma string.... e cobrando mensal pra CASO A STRING ALTERE ALGUM DIA.

Comece a prestar atenção no suporte de componentes de NFe, pra ver o que acontece.
Geralmente é problema com alguma UF nova, ou alguma UF que alterou "suas strings".
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, 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
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Pra quem ainda não resolveu NFE/CTE/MDFE

Mensagem por JoséQuintas »

Faltou dizer:

A clase Sefaz funciona?
Pra mim e alguns outros que usam SP sim.

Pra outras UFs
A UF só libera o acesso pra contribuintes que tenham cadastro na UF.
O interessado deverá fazer seus próprios testes.
Pode ser que a UF use a string padrão, pode ser que precise acrescentar uma string diferente pra determinada UF.

Aliás... nem sei dizer se a "padrão" é padrão. Apenas é a string que aceita em SPaulo, que foi o ponto de partida.
Mas agora sim, a classe está preparada pra qualquer diferença, vai ser só acrescentar no array.
Achei que o array ficou mais interessante do que um DO CASE

Exemplo:

Código: Selecionar todos

// Estas 3 linhas do array
      { "**", WS_NFE_CONSULTAPROTOCOLO, WS_PROJETO_NFE,  "NfeConsulta2",         "http://www.portalfiscal.inf.br/nfe/wsdl/NfeConsulta2" }, ;
      { "BA", WS_NFE_CONSULTAPROTOCOLO, WS_PROJETO_NFE,  "nfeConsultaNF",        "http://www.portalfiscal.inf.br/nfe/wsdl/NfeConsulta" }, ;
      { "AC,AL,AP,DF,ES,PB,RJ,RN,RO,RR,SC,SE,TO", ;
              WS_NFE_CONSULTAPROTOCOLO, WS_PROJETO_NFE,  "nfeConsultaNF2",       "http://www.portalfiscal.inf.br/nfe/wsdl/NfeConsulta2" } }
// do case precisa 12 linhas, aonde array são só 3
DO CASE
CASE nWsServico == WS_NFE_CONSULTAPROTOCOLO .AND. ::cUF == "BA"
   cProjeto := WS_PROJETO_NFE
   cSoapAction := "NfeConsulta2" 
    cServico := "http://www.portalfiscal.inf.br/nfe/wsdl/NfeConsulta2"
CASE nWsServico == WS_NFE_CONSULTAPROTOCOLO .AND. ::cUF $ "AC,AL,AP,DF,ES,PB,RJ,RN,RO,RR,SC,SE,TO"
   cProjeto := WS_PROJETO_NFE
   cSoapAction := "nfeConsultaNF2"
   cServico := "http://www.portalfiscal.inf.br/nfe/wsdl/NfeConsulta2" 
CASE nWsServico == WS_NFE_CONSULTAPROTOCOLO
   cProjeto := WS_PROJETO_NFE
   cSoapAction := "NfeConsulta2"
   cServico := "http://www.portalfiscal.inf.br/nfe/wsdl/NfeConsulta2"
ENDCASE
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, 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/
Responder