Página 2 de 4

Simplificando fontes - hbnfe (Harbour -w3 -es2)

Enviado: 18 Set 2015 18:56
por JoséQuintas
É por isso que chamo -w3 -es2 de "tolerância zero".
Qualquer coisa suspeita é barrada, e só compila se isso for resolvido.
Declarei as variáveis, e a lista reduziu:
Compiling 'hbMDFe.prg'...
hbMDFe.prg(99) Warning W0001 Method <LinkWebService(cServ)> not declared or declaration mismatch in class <hbMDFe>
hbMDFe.prg(121) Warning W0032 Variable 'NSCAN' is assigned but not used in function 'HBMDFE_LINKWEBSERVICE(105)'
hbMDFe.prg(243) Warning W0032 Variable 'MI' is assigned but not used in function 'HBMDFE_XMLIDE(127)'
hbMDFe.prg(509) Warning W0032 Variable 'MI' is assigned but not used in function 'HBMDFE_XMLMODALRODOVIARIO(362)'
hbMDFe.prg(811) Warning W0032 Variable 'MI' is assigned but not used in function 'HBMDFE_XMLDOCUMENTOS(516)'
hbMDFe.prg(811) Warning W0032 Variable 'CI' is assigned but not used in function 'HBMDFE_XMLDOCUMENTOS(516)'
hbMDFe.prg(901) Warning W0032 Variable 'MI' is assigned but not used in function 'HBMDFE_XMLTOT(818)'
hbMDFe.prg(1108) Warning W0032 Variable 'CXMLSIG' is assigned but not used in function 'HBMDFE_ASSINA_XML(908)'
hbMDFe.prg(1108) Warning W0032 Variable 'POSINI' is assigned but not used in function 'HBMDFE_ASSINA_XML(909)'
hbMDFe.prg(1108) Warning W0032 Variable 'POSFIM' is assigned but not used in function 'HBMDFE_ASSINA_XML(909)'
hbMDFe.prg(1108) Warning W0032 Variable 'NP' is assigned but not used in function 'HBMDFE_ASSINA_XML(909)'
hbMDFe.prg(1108) Warning W0032 Variable 'NRESULT' is assigned but not used in function 'HBMDFE_ASSINA_XML(909)'
hbMDFe.prg(1296) Warning W0032 Variable 'CURLWS' is assigned but not used in function 'HBMDFE_COMUNICAWEBSERVICE(1210)'

hbMDFe.prg(1365) Warning W0003 Variable 'OSERVERWS' declared but not used in function 'HBMDFE_RECEPCAOMDFE(1301)'
hbMDFe.prg(1365) Warning W0032 Variable 'CCERT' is assigned but not used in function 'HBMDFE_RECEPCAOMDFE(1303)'
hbMDFe.prg(1365) Warning W0032 Variable 'CURLWS' is assigned but not used in function 'HBMDFE_RECEPCAOMDFE(1303)'
hbMDFe.prg(1365) Warning W0032 Variable 'CXMLRESP' is assigned but not used in function 'HBMDFE_RECEPCAOMDFE(1303)'
hbMDFe.prg(1453) Warning W0032 Variable 'CXMLRESP' is assigned but not used in function 'HBMDFE_RETRECEPCAOMDFE(1371)'
hbMDFe.prg(1565) Warning W0032 Variable 'CXMLRESP' is assigned but not used in function 'HBMDFE_CONSULTAMDF(1459)'
hbMDFe.prg(1565) Warning W0032 Variable 'CXMLINFPROT' is assigned but not used in function 'HBMDFE_CONSULTAMDF(1459)'
hbMDFe.prg(1565) Warning W0032 Variable 'CXMLEVENTOMDFE' is assigned but not used in function 'HBMDFE_CONSULTAMDF(1459)
'
hbMDFe.prg(1565) Warning W0032 Variable 'CXMLEVCANCMDFE' is assigned but not used in function 'HBMDFE_CONSULTAMDF(1459)
'
hbMDFe.prg(1565) Warning W0032 Variable 'CXMLRETEVENTOMDFE' is assigned but not used in function 'HBMDFE_CONSULTAMDF(14
59)'
hbMDFe.prg(1619) Warning W0001 Method <MDFeEvento(cXMLeve)> not declared or declaration mismatch in class <hbMDFe>
hbMDFe.prg(1619) Warning W0032 Variable 'CXMLRESP' is assigned but not used in function 'HBMDFE_STATUSSERVICO(1571)'
hbMDFe.prg(1816) Warning W0032 Variable 'CXMLRESP' is assigned but not used in function 'HBMDFE_MDFECANCELA(1745)'
2000
Agora sobraram variáveis inúteis, valores inúteis, e declaração de método errada,
Este último é algo como declarar que vai ser Metodo( numero ), e fazer Metodo( outracoisa ), ou quantidade de parâmetros diferentes.
Declarar que vai ser Metodo( a ), mas criar a rotina como Método( a, b )

Mas isso é o "tolerância zero" ( -w3 -es2 ).
Qualquer coisa suspeita é rejeitada, obrigatoriamente tem que corrigir.

Pode ser apenas resto de fonte perdido, mas pode ser erro também.
Com isso podemos mais uma vez encontrar erro "sem querer".
De repente pode ser nome de variável errado, e não variável inútil.
O compilador OBRIGA que isso seja revisto.

Se nesse meio tempo precisar liberar programa, é só compilar normalmente, sem o -w3 -es2.
Não é porque usou isso que vai ser obrigado a terminar todo fonte de uma vez.

Nesta parte de avisos, usar variáveis PUBLIC e PRIVATE faz muita diferença.
Significa que boa parte dessa checagem vai ser DESPREZADA.
Em PUBLIC e PRIVATE o compilador não sabe se elas existiam antes, ou se vão ser usadas depois, então se existir variável desse tipo que seja inútil, vai continuar existindo.Mesmo que o nome esteja errado, o compilador não tem como saber.

Parece que é perder tempo, fazendo coisa que não precisava antes.
Mas o compilador está te AJUDANDO, CONFERINDO seu fonte, e já te AVISANDO de erros que poderiam acontecer depois.
Pra conferir direito, ele precisa de mais informações, que justamente estão nas declarações de variáveis.

E quanto estiver usando pra valer, vai mexer nos fontes sem medo, porque seu ajudante não vai deixar escapar nada.

Simplificando fontes - hbnfe (Harbour -w3 -es2)

Enviado: 18 Set 2015 21:47
por JoséQuintas
Achei até interessante mostrar o ajuste de -w3 -es2.
Entra toda declaração de variável que faltava, mas....
hbnfe.png
hbnfe.png (2.13 KiB) Exibido 2946 vezes
Não houve mudança de tamanho.
Ao mesmo tempo que entraram as declarações, foi eliminado lixo - fonte inútil.

Exemplos:

Código: Selecionar todos

nCont := 0
FOR nCont = 1 TO 10
...
Iniciar nCont com zero é algo inútil, não faz diferença.

Código: Selecionar todos

LOCAL x := ""
x := MemoRead( "arquivo" )
Mesmo caso anterior.

Apesar que quase tudo já estava declarado, não houve aumento de fonte.
Então não precisa se preocupar com tamanho de fonte por declarar variáveis.
O fonte vai ter o que precisa, e só, o que não precisa vai ser eliminado.

Isso foi só o primeiro fonte.
Ainda faltam muitos.
Como eu disse várias vezes, não precisa pressa, porque não é algo que se faça em alguns minutos.
E é bom sempre que der, olhar alguma coisa a mais.

Agora é ajustar os demais.
Deve ser o mesmo tipo de coisa em todos, então só vou postar se aparecer algo diferente.

Simplificando fontes - hbnfe (Harbour -w3 -es2)

Enviado: 19 Set 2015 10:47
por JoséQuintas
uia
Compiling 'hbnfefuncoes.prg'...
hbnfefuncoes.prg(272) Warning W0033 Variable 'ARETORNO' is never assigned in function 'HBNFEFUNCOES_VALIDAEAN(246)'
Mais outro erro detectado "sem querer".
Tá faltando definir o valor dessa variável que é usada como retorno.

Lembrando: não estou adivinhando erro nenhum, é apenas mensagem do compilador, ao usar -w3 -es2.

Tá ficando velho pra programar?
O compilador tá sempre jovem e nunca fica cansado.
Ponha ele pra fazer a parte cansativa, que é conferir o fonte.
Com certeza, ele não deixa escapar nada.
Só vai te encher de mensagens/perguntas, e basta responder.

A deste post é algo como:
Tá usando a variável, mas cadê o valor dela?

Simplificando fontes - hbnfe (Harbour -w3 -es2)

Enviado: 19 Set 2015 11:08
por JoséQuintas
E mais outro:
Compiling 'hbNFeIniToXML.prg'...
hbNFeIniToXML.prg(141) Warning W0001 Ambiguous reference 'ONFE'
A linha acima:

Código: Selecionar todos

      oCancela:ohbNFe := oNfe // Objeto hbNFe
Mas olhando algumas linhas acima:

Código: Selecionar todos

      oValida:ohbNFe := ::ohbNfe // Objeto hbNFe
Significa que o nome da variável estava errado.
Mais outro erro corrigido "sem querer", com ajuda do compilador.
êita compilador arretado....

Simplificando fontes - hbnfe (Harbour -w3 -es2)

Enviado: 19 Set 2015 11:34
por JoséQuintas
Mais um:
hbNFeRecepcaoLote.prg(257) Warning W0028 Unreachable code
Nesta parte:

Código: Selecionar todos

   EXIT
NEXT
O EXIT causa saída do FOR/NEXT, então o NEXT nunca será executado.
A mensagem é sobre isso.
Ou não precisa do FOR/NEXT, ou o EXIT está aonde não deveria estar.
Pelo nome do método, deve trabalhar com lote de apenas uma nota, e está pendente confirmar se ok pra várias notas.

Simplificando fontes - hbnfe (Harbour -w3 -es2)

Enviado: 19 Set 2015 19:59
por JoséQuintas
Criei funções novas.
TODA comunicação usa envelope, e quase tudo é igual.

https://github.com/JoseQuintas/hbnfe/bl ... FeSped.prg

Criei duas, uma pra NFE e outra pra MDFE.
Dá pra deixar uma, mas deixar uma por projeto já está bom.
(Já se sabe que manifestação do destinatário usa um envelope diferente).

Simplificando fontes - hbnfe (Harbour -w3 -es2)

Enviado: 19 Set 2015 20:16
por fladimir
Obrigado pela Contribuição Zé... muito explicativo.

[]´s

Simplificando fontes - hbnfe (Harbour -w3 -es2)

Enviado: 20 Set 2015 10:33
por JoséQuintas
Dei uma separada nas funções, só pra facilitar pesquisa.
Com isso, o post anterior apontou para um fonte sem as funções.

Apontar para a lista dos fontes:
https://github.com/JoseQuintas/hbnfe/tree/master/source

No momento separei pra facilitar reorganização depois:
hbNFeSoapEnvelope.prg - com as funções de envelope
hbNFeSoapWebService.prg - com a função de WebService, que ainda vai sofrer alterações

Talvez deixar funções independentes facilite usar rotinas dentro e fora da hbnfe, mantendo fontes atualizados e em uso.

Simplificando fontes - hbnfe (Harbour -w3 -es2)

Enviado: 20 Set 2015 11:36
por JoséQuintas
Estou só procurando reduzir/simplificar fonte.
Ao adotar a nova função de webservice na consulta status, encontrei algo:

Código: Selecionar todos

cSOAPAction := 'http://www.portalfiscal.inf.br/nfe/wsdl/NfeStatusServico2/nfeConsultaNF2'
Isso é pra consultar nota fiscal, e não pra consultar status.

Novamente, corrigindo erro "sem querer".

Fugindo um pouco do tópico, como disse antes, havia feito tudo isso no ano passado.
Devem estar com o mesmo pensamento que eu: afinal, quem usa a hbnfe?

Mas é um bom motivo pra tentar rotinas isoladas, permitir o uso dentro e fora da hbnfe.
Acho que quanto mais "genérico", maior o número de colaboradores/usuários.

Simplificando fontes - hbnfe (Harbour -w3 -es2)

Enviado: 20 Set 2015 12:33
por JoséQuintas
Agora a parte mais legal:
Das 190 linhas originais, agora tem 83.
Eliminado mais da metade do fonte.
De quebra, a rotina geral de webservice foi melhorada, sendo adicionadas as checagens a mais encontradas na rotina de status.
Significa que essa melhora já vai servir para a consulta também (que foi a base inicial da rotina).


Recapitulando:

Peguei a rotina que estava em consultanfe e apenas copiei/separei, sem usar.
Ao colocar em prática, essa rotina foi melhorada, com fonte que existia na consultastatus.
A consultastatus ficou menor e já foi corrigido um erro.
Quando for usar no lugar que deu origem a ela, já vai ter a melhoria.

Continuo apenas simplificando fontes, coisa que QUALQUER UM pode fazer, mas ESQUECE de fazer.
Isso está rendendo correções e melhorias.

Na maioria das vezes um programador acha que só pode melhorar fontes se usar recursos mais avançados.
Mas a chave é esta: SIMPLIFICAR
Não estou criando nada novo, estou usando o que já existe, pra melhorar o que já existe.
E sem pressa, uma coisa de cada vez.

O que foi modificado nesse uso da rotina, a parte em vermelho foi eliminada:

https://github.com/JoseQuintas/hbnfe/co ... cb33f306b2

Simplificando fontes - hbnfe (Harbour -w3 -es2)

Enviado: 20 Set 2015 12:49
por JoséQuintas
Agora que a função ficou menor, deu pra ver outra parte que dá pra simplificar, mas não vou fazer isso agora.

Código: Selecionar todos

  cUrlWS := ::ohbNFe:getURLWS(_STATUSSERVICO)
  if cUrlWS = nil
      cMsgErro := "Serviço não mapeado" + hb_EOL()+;
                  "Serviço solicitado : STATUS DO SERVIÇO."
      aRetorno['OK']       := .F.
      aRetorno['MsgErro']  := cMsgErro
      RETURN(aRetorno)
  endif
O que dá pra simplificar depois:
GetUrlWs() vai pegar o endereço, e se retornar NIL é porque deu problema.
Porque não acrescentar essa mensagem de erro dentro da própria GetUrlWs() ? Isso vai reduzir fonte em TODAS as rotinas.
Ok, mas vai ficar pra depois.

Mas é algo curioso: acabei de reduzir mais de 50% do fonte, e já encontrei algo que pode reduzir mais ainda.

Mas é assim que funciona: é ir simplificando fonte, conforme vai fazendo, vai enxergando melhor o que sobra.
Não precisa pressa. Uma coisa de cada vez pra não se complicar.
Por enquanto comecei a usar a nova rotina de webservice, e vou continuar com isso.
Depois vejo o que vai sobrar.

Simplificando fontes - hbnfe (Harbour -w3 -es2)

Enviado: 20 Set 2015 14:01
por JoséQuintas
E mais outro erro corrigido "sem querer".

Na consulta cadastro está usando 'SOAPAction: "StatusServico2'

É o nome pra consultar status do serviço, e não pra consultar cadastro.

Continuo só simplificando, só estou alterando pra usar a rotina de webservice padrão.
É que um dos parâmetros é justamente a SOAPAction, então obrigatoriamente a enxergo.

Simplificando fontes - hbnfe (Harbour -w3 -es2)

Enviado: 22 Set 2015 12:59
por sygecom
José,
Muito boa essas suas alterações, de fato o projeto estava com W2 que é menos restrito, até mesmo para quando o trabalho é em equipe, nem todos conseguem se adptar facilmente com o W3.

Aqui usamos HBNFE e conheço mais uma meia duzia que também usa diariamente a hbnfe, evoluções no projeto sempre haverá e lhe parabenizo por essas evoluções, espero que consiga alcançar seus objetivos, se eu poder testar algo para você sinta a vontade em postar no fórum ou me enviar por email que terei o maior prazer em testar.

Fiz muitas alterações no HBNFE, uma delas para rodar com NFCe, porém está distante das suas evoluções, então assim que você concluir suas mudanças, posso tentar implementar nos seus padrões e testar para você outros assim podem ter mais benefícios.

Mais uma vez parabéns pelas contribuições.

Simplificando fontes - hbnfe (Harbour -w3 -es2)

Enviado: 22 Set 2015 13:32
por JoséQuintas
-w3 -es2 existia no próprio Clipper, há mais de 20 anos.
Só recentemente entendi a vantagem e passei a usar, e tem me facilitado muito.
A intenção do post foi tentar demonstrar isso na prática.
Isso dá vida nova a tudo, e a nós mesmos.
Passamos a alterar qualquer fonte sem medo, porque qualquer erro de nome de variável o compilador avisa.

Quanto à hbnfe, agora vou comparar um fonte dela com o fonte daquela minha classe. Acho que vai explicar tudo que tentei explicar lá nas postagens da hbnfe, ao mesmo tempo que pode mostrar que o pessoal ainda se perde com classe.

Código: Selecionar todos

#include "hbnfe.ch"

CLASS hbNFeStatus
   DATA ohbNFe
   DATA cUFWS
   DATA versaoDados
   DATA tpAmb
   DATA cUF

   METHOD Execute()
   ENDCLASS

METHOD Execute() CLASS hbNFeStatus

   LOCAL cUrlWS, cXML, cMsgErro, cXmlResp, aRetorno := hash(), oFuncoes := hbNFeFuncoes(), cFileEnvRes, cXMLDadosMsg

   IF ::cUFWS = NIL
      ::cUFWS := ::ohbNFe:cUFWS
   ENDIF
   IF ::versaoDados = NIL
      ::versaoDados := ::ohbNFe:versaoDados
   ENDIF
   IF ::tpAmb = Nil
      ::tpAmb := ::ohbNFe:tpAmb
   ENDIF

   cXMLDadosMsg := '<consStatServ xmlns="http://www.portalfiscal.inf.br/nfe" versao="2.00">' +;
                   hbnfeXmlTag( "tpAmb", ::tpAmb ) + ;
                   hbnfeXmlTag( "cUF", ::cUf ) + ;
                   hbnfeXmlTag( "xServ", "STATUS" ) + ;
                   '</consStatServ>'

   cXml := hbNfeSoapEnvelope( cXmlDadosMsg, ::versaoDados, ::cUfWs, "http://www.portalfiscal.inf.br/nfe/wsdl/NfeStatusServico2" )

   cFileEnvRes := oFuncoes:formatDate( Date(), "YYMMDD" ) + Substr( Time(), 1, 2 ) + Substr( Time(), 4, 2 ) + Substr( Time(), 7, 2 )

   TRY
      hb_MEMOWRIT( ::ohbNFe:pastaEnvRes + "\" + cFileEnvRes + "-ped-sta.xml", cXMLDadosMsg )
   CATCH
      aRetorno[ 'OK' ]       := .F.
      aRetorno[ 'MsgErro' ]  := 'Problema ao gravar pedido de status ' + ::ohbNFe:pastaEnvRes + "\" + cFileEnvRes + "-ped-sta.xml"
      RETURN aRetorno
   END

   cUrlWS := ::ohbNFe:getURLWS( _STATUSSERVICO )
   IF cUrlWS = NIL
      cMsgErro := "Serviço não mapeado" + hb_EOL() + ;
                  "Serviço solicitado : STATUS DO SERVIÇO."
      aRetorno[ 'OK' ]       := .F.
      aRetorno[ 'MsgErro' ]  := cMsgErro
      RETURN aRetorno
   ENDIF

   aRetorno := hbNFESoapWebService( cXml, "http://www.portalfiscal.inf.br/nfe/wsdl/NfeStatusServico2", "NFeStatusServico2", cUrlWs, ::ohbNFe )
   IF .NOT. aRetorno[ "OK" ]
      RETURN aRetorno
   ENDIF
   cXmlResp := aRetorno[ "MsgErro" ]

   TRY
      hb_MemoWrit( ::ohbNFe:pastaEnvRes + "\" + cFileEnvRes + "-sta.xml", cXMLResp )
   CATCH
      aRetorno[ 'OK' ]       := .F.
      aRetorno[ 'MsgErro' ]  := 'Problema ao gravar retorno de status ' + ::ohbNFe:pastaEnvRes + "\" + cFileEnvRes + "-sta.xml"
      RETURN aRetorno
   END
   aRetorno[ 'OK' ]       := .T.
   aRetorno[ 'MsgErro' ]  := ""
   aRetorno[ 'tpAmb' ]    := oFuncoes:pegaTag( cXMLResp, "tpAmb" )
   aRetorno[ 'verAplic' ] := oFuncoes:pegaTag( cXMLResp, "verAplic" )
   aRetorno[ 'cStat' ]    := oFuncoes:pegaTag( cXMLResp, "cStat" )
   aRetorno[ 'xMotivo' ]  := oFuncoes:pegaTag( cXMLResp, "xMotivo" )
   aRetorno[ 'cUF' ]      := oFuncoes:pegaTag( cXMLResp, "cUF" )
   aRetorno[ 'dhRecbto' ] := oFuncoes:pegaTag( cXMLResp, "dhRecbto" )
   aRetorno[ 'tMed' ]     := oFuncoes:pegaTag( cXMLResp, "tMed" )

   RETURN aRetorno
O que o fonte faz?

- A montagem do XML
- Gravar o XML em pasta
- Pegar webservice
- Montar o envelope
- Define os parâmetros para o Soap, e executa a comunicação Soap
- Gravar o resultado em pasta
- Também já separar os parâmetros do XML de retorno

Simplificando fontes - hbnfe (Harbour -w3 -es2)

Enviado: 22 Set 2015 15:55
por JoséQuintas
E agora o equivalente daquela minha classe, que é onde a hbnfe pode chegar:

Código: Selecionar todos

METHOD NFeStatus( cUF, cCertificado, cAmbiente ) CLASS SefazClass

   cCertificado   := iif( cCertificado == NIL, ::cCertificado, cCertificado )
   cAmbiente      := iif( cAmbiente == NIL, ::cAmbiente, cAmbiente )
   cUF            := iif( cUF == NIL, ::cUF, cUF )
   ::cVersaoXml   := "3.10"
   ::cServico     := "http://www.portalfiscal.inf.br/nfe/wsdl/NfeStatusServico2"
   ::cSoapAction  := "nfeStatusServicoNF2"
   ::cWebService  := ::GetWebService( cUF, WSNFESTATUSSERVICO, cAmbiente, WSPROJETONFE )
   ::cXmlDados    := ""
   ::cXmlDados    += [<consStatServ versao="] + ::cVersaoXml + [" xmlns="http://www.portalfiscal.inf.br/nfe">]
   // precisava disto antes, de repente alguma UF ainda precisa
   ::cXmlDados    +=    XmlTag( "tpAmb", cAmbiente )
   ::cXmlDados    +=    XmlTag( "cUF", UFCodigo( cUF ) )
   ::cXmlDados    +=    XmlTag( "xServ", "STATUS" )
   ::cXmlDados    += [</consStatServ>]
   ::XmlSoapPost( cUF, cCertificado, WSPROJETONFE )
   RETURN ::cXmlRetorno
O que esse fonte faz:

- Define os parâmetros do webservice
- Monta o XML
- pega o endereço de webservice
- já chama o soap, que já faz o envelope e a comunicação
- Tanto a entrada e saída da função, é variável da função ou da classe. (::cXmlRetorno é o mesmo conteúdo de cXmlResp na hbnfe)

No final é a mesma coisa, o principal diferencial é não usar pastas, e aproveitar mais de variáveis na classe principal.

Justamente o controle de pastas usa bastante fonte.

Ao agrupar tudo numa única classe, tanto da forma da hbnfe quanto da forma da minha classe, parecem ter gerado confusão.
O que resta pra pensar é como deixar claro pra quem usar os fontes.

Por enquanto só simplificando os fontes, mantendo um fonte pra cada tipo de serviço.
Mas acho que já dá pra atualizar pra 3.10.

Enquanto isso vamos pensando como redefinir: tentar evitar o que confundiu antes.