Ir para conteúdo
  • Cadastre-se

dev botao

NFE_Finalizar com retorno -2 quando utilizo NFE_EnviarEmail


Ver Solução Respondido por Juliomar Marchetti,
  • Este tópico foi criado há 1436 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Postado

Bom dia amigos!

Estou com um problema para utilizar o método NFE_Finalizar, apenas quando meu programa utiliza o método NFE_EnviarEmail antes do NFE_Finalizar em uma nfe já autorizada.

Vou colocar em negrito o por onde o programa passa quando dá o erro.

Vou colocar um trecho simplificado do meu programa:

Tenho uma função que ACBR_CRIA_ASSINA_VALIDA_ENVIA(xChaveNfe), primeira coisa que faço e consultar a chave, para ver se é uma Nfe já autorizada, se for obtenho o caminho do xml para carrega-lo, caso contrário carrego o .INI e assino, valido etc.

NFE_Inicializar
 if cRet:="Autorizado o uso da NF-e"
          NFE_CarregarXML

else
          NFE_CarregarINI
          NFE_ValidarRegrasdeNegocios
          NFE_Assinar
          NFE_Validar
          NFE_GravarXml
          NFE_Enviar
endif

NFE_ImprimirPDF
NFE_EnviarEmail  //Se comentar a chamada deste método, não dá erro no NFE_Finalizar
NFE_Finalizar          //SetRetorno(-2, Access violation)

Nfe Nova             : NFe Nova.log sem erros, entra no else
Nfe já autorizada: NFe Autorizada.log com erro, entra no if

 

Agradeço desde já a ajuda de todos.

Postado

Boa noite @Juliomar Marchetti

Estou usando a lib com xHarbour.

Carrego a dll com o DllLoad -> DllNfe:=DllLoad("ACBrNFe32.dll")
Executo os métodos com DLLCALL -> DLLCALL(DllNfe,32,"NFE_Inicializar","SP_NFE.INI","")
Descarrego a DLL com DllUnload -> DllUnload(DllNfe)

 

 

 

Postado

Obrigado @Juliomar Marchetti e @Rafael Dias

Eu estou usando as dll's ACBrLibNFe-0.4.6.110

Vou postar o código fonte que utilizo.

 

FUNCTION ACBR_CRIA_ASSINA_VALIDA_ENVIA(xTxt,xChaveNfe)
	LOCAL nRetMet,cRet,xLocalXml,xXml,lAssinaValidaEnvia:=.T.
	LOCAL xPara,xCopias,xAssunto,xMensagem
	LOCAL pDllNfe:=DllLoad("ACBrNFe32.dll")
	
	** Nome do XML e local de onde será salvo
	xXml:=xChaveNfe+"-nfe.xml"
	xLocalXml:=pDisco+":\xHB\nfe\"+UPPER(pUnidadeUf)+"\XML\"
	xPdf:=xChaveNfe+"-nfe.pdf"
	xLocalPdf:=pDisco+":\xHB\nfe\"+UPPER(pUnidadeUf)+"\PDF\"

	** Iniciar arquivo de configurações do ACBR
	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Inicializar",pUnidadeUf+"_NFE.INI","")
	if nRetMet<0
		alert("Erro ao iniciar o arquivo de configuracao;"+pUnidadeUf+"_NFE.INI")
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","")
		DllUnload(pDllNfe)
		RETURN .F.
	endif
	
	** Consulta a chave para saber se já é uma NFe Autorizada para uso
	cRet:=space(256)
	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Consultar",xChaveNfe,.T.,cRet)	
	if at("Consumo Indevido",cRet)>0
		alert("Consumo Indevido;;Aguarde alguns minutos e tente novamente")
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","")
		DllUnload(pDllNfe)			
		RETURN .F.
	endif
	
	if at("Autorizado o uso da NF-e",cRet)>0
		lAssinaValidaEnvia:=.F.
		
		** Pega a data correta em que a Nfe foi emitida
		q:="select concat(year(b09demi),lpad(month(b09demi),2,'0')) as pasta from nfec where chavenfe='"+xChaveNfe+"'"
		v:=F_GETCON(q)
		if len(v)==0
			alert("Erro ao localizar a chave no Nfec;"+xChaveNfe)
			nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","")
			DllUnload(pDllNfe)				
			RETURN .F.
		endif
		xPastaAno:=v[1,1]
		xLocalXml:=xLocalXml+xPastaAno+"\"
		xLocalPdf:=xLocalPdf+xPastaAno+"\"
		
		** Verifica se o arquivo XML existe na pasta
		if ! FILE(xLocalXml+xXml)
			** Para garantir cria a pasta do anomes do XML e PDF
			FT_MKDIR(xLocalXml)
			FT_MKDIR(xLocalPdf)
			alert("NFe autorizada, porem arquivo xml nao localizado na pasta:;"+xLocalXml+xXml+";Faca o download pelo site do SEFAZ e coloque na pasta indicada")
			nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","")
			DllUnload(pDllNfe)				
			RETURN .F.
		endif
	else
		xLocalXml:=xLocalXml+strZero(year(date_sql()),4)+strZero(month(date_sql()),2)+"\"
		xLocalPdf:=xLocalPdf+strZero(year(date_sql()),4)+strZero(month(date_sql()),2)+"\"
	endif
	
	** Para garantir cria a pasta do anomes do XML e PDF
	FT_MKDIR(xLocalXml)
	FT_MKDIR(xLocalPdf)
	
	if lAssinaValidaEnvia
		** Carrega o arquivo TXT da NFe
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_CarregarINI",xTxt)
		if nRetMet<0
			alert("Erro ao carregar o arquivo txt da NFe;"+xTxt)
			nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","")
			DllUnload(pDllNfe)				
			RETURN .F.
		endif
		
		** Valida regras de negócio da NFe
		cRet:=space(256)
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_ValidarRegrasdeNegocios",cRet)
		cRet:=strTran(cRet,chr(0),"")	//Elimina um quadrado "[]" do retrono 
		cRet:=strTran(cRet,chr(32),"")	//Elimina um quadrado "[]" do retrono 
	
		if ! empty(cRet)
			alert(cRet)
			nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","")
			DllUnload(pDllNfe)			
			RETURN .F.
		endif	
		
		** Assina NFe que está carregada pelo NFE_CarregarINI
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_Assinar")
		if nRetMet<0
			alert("Erro Assinar a NFe;"+xTxt)
			nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","")
			DllUnload(pDllNfe)
			RETURN .F.
		endif

		** Validar XML assinado na pasta correta
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_Validar")
		if nRetMet<0
			alert("Erro Validar a NFe;"+xXml)
			nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","")
			DllUnload(pDllNfe)
			RETURN .F.
		endif

		** Grava XML assinado na pasta correta
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_GravarXml",0,xXml,xLocalXml)
		if nRetMet<0
			alert("Erro GravarXml da NFe;"+xTxt)
			nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","")
			DllUnload(pDllNfe)
			RETURN .F.
		endif

		** Enviar XML par ao SEFAZ
		cRet:=space(256)
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_Enviar",0,.T.,.T.,.F.,cRet)
		if nRetMet<0
			alert("Erro Enviar a NFe para o SEFAZ;"+xXml)
			nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","")
			DllUnload(pDllNfe)
			RETURN .F.
		endif
	else
		** Se o XML já está autorizado apenas o carrga
		** Para poder imprimir e enviar por e-mail
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_CarregarXML",xLocalXml+xXml,"")
	endif

	nRetMet:=DLLCALL(pDllNfe,32,"NFE_ImprimirPDF")
	if nRetMet<0
		alert("Erro Imprimir NFe;"+xXml)
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","")
		DllUnload(pDllNfe)
	else
		FileCopy(pDisco+":\xHB\nfe\"+UPPER(pUnidadeUf)+"\PDF\"+xPdf,xLocalPdf+xPdf)
	endif

	mVar:=ACBR_EMAIL(xChaveNfe)
	xPara:=mVar[1]
	xCopias:=mVar[2]
	xAssunto:=mVar[3]
	xMensagem:=mVar[4]

	nRetMet:=DLLCALL(pDllNfe,32,"NFE_EnviarEmail",xPara,xLocalXml+xXml,.T.,xAssunto,xCopias,,xMensagem)
	if nRetMet<0
		alert("Erro Enviar a E-mail para os contatos;"+xPara+";"+xCopias)
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","")
		DllUnload(pDllNfe)
	endif
	
	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","")
	if nRetMet<0
		alert("Erro ao Finalizar o arquivo de configuracao;"+pUnidadeUf+"_NFE.INI")
		DllUnload(pDllNfe)
		RETURN .F.
	endif
	
	DllUnload(pDllNfe)
	
	RETURN .T.

 

Postado

@Rafael Dias, consegui resolver esse erro aumentando o cRet, de space(256) para space(1024).

Antes de emitir uma NFe eu faço uma consulta com a chave, nRet:=DLLCALL(pDllNfe,32,"NFE_Consultar",xChaveNfe,.T.,cRet) 

Se achar a expressão "Autorizado o uso da NF-e" eu apenas carrego o xml e utilizo o método de enviar e-mail e imprimir, senão, assina, valida, envia.

Com o cRet:=space(256) o retorno era -2 com o cRet:=space(1024) o retorno é 0 e não dá erro no método NFe_Finalizar.

Agora estou enfrentando um outro problema, esporadicamente o meu programa fecha sem mensagens de erros, em sem muitas pistas no log, pois ele chega a rodar o método NFE_Finalizar certinho e em seguida fecha o programa.

Uso pDllNfe:=DllLoad("ACBrNFe32.dll") para carregar a DLL e DllUnload(pDllNfe) para descarregar a DLL.

Estou usando a dll da pasta Cdecl, mas já tentei mudar para a StdCall também.

 

Se acharem melhor eu encerro esse tópico e abro outro com esse novo problema.

 

 

×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.