Página 14 de 21

SAT-Fiscal a mistica está desvendada.

Enviado: 04 Mar 2016 13:00
por paulovirt
Boa tarde

Seria algo mais ou menos assim?

Código: Selecionar todos

dados:="c:\sat\xml\venda.xml"
retorno:=DLLCall(h1,32,"EnviarDadosVenda",Random(), CCHAVE_SAT, dados)
E o retorno? Como consigo obter o arquivo XML "validado" pelo SAT?

SAT-Fiscal a mistica está desvendada.

Enviado: 04 Mar 2016 14:01
por rochinha
Amiguinhos,

paulovirt postou:
dados:="c:\sat\xml\venda.xml"
retorno:=DLLCall(h1,32,"EnviarDadosVenda",Random(), CCHAVE_SAT, dados)
Na verdade é mais assim:

Código: Selecionar todos

dados := MemoRead( "c:\sat\xml\venda.xml" )
retorno := DLLCall(h1,32,"EnviarDadosVenda",Random(), CCHAVE_SAT, dados)
A variável retorno conterá uma string com informações separadas por |, pipe, sendo que se hourver erro a string terá somente 2 pipes separando os 3 parametros onde o terceiro é o erro.

Se tudo correr bem serão retornados 7 parametros divididos por 6 pipes onde o parametro da posição 7 é o conteúdo do cupom já assinado e protocolado.

Este cupom já assinado e protocolado virá codificado em formato Base64 e você terá de decodificá-lo para ter o XML e poder a partir dele tirar as informações necessárias para impressão do extrato.

SAT-Fiscal a mistica está desvendada.

Enviado: 10 Mar 2016 12:39
por alaminojunior
rochinha escreveu:A variável retorno conterá uma string com informações separadas por |
Caro amiguinho Rochinha !

Está ai a questão de um milhão de dólares ...

Eu utilizo xHarbour, e faço como está no exemplo do colega.
Ocorre que o retorno daquela função (no meu caso) é um ponteiro, o qual preciso depois, submeter ao método HB_Pointer2String.
Este último sim, me devolve a bendita string.

Tem funcionado a uns 95%, pois em alguns casos específicos dá uns paus muito doidos.

SAT-Fiscal a mistica está desvendada.

Enviado: 10 Mar 2016 19:48
por Edvaldo
É verdade, eu também utilizo o xharbour e percebí o mesmo erro. Consegui minimizar o erro aumentando o valor do segundo parâmetro da função HB_Pointer2String( Retorno, 1000 ), ou seja se a venda tem até 10 itens envio um numero de 11 a 20 outro numero e assim por diante.

SAT-Fiscal a mistica está desvendada.

Enviado: 11 Mar 2016 10:32
por rochinha
Amiguinhos,

alaminojunior
A versão que uso do Harbour ainda é a 0.45, não tive oportunidade de usar as maravilhas das mais novas versões.

Mostre-me a string capturada após o hb_Pointer2String()

Você diz que ela vem cortada, será que o valor 1000 no segundo parâmetro não seja o tamanho que se deseja no final?

Código: Selecionar todos

xRet:= HB_Pointer2String(retorno,1000)
Aumente-o para 5000. Sei-lá.

Tive de usar a seguinte função para os meus contentos:

Código: Selecionar todos

FUNCTION HB_BASE64DECODE( cString )
   LOCAL cResult

   LOCAL nLen
   LOCAL nGroupPos
   LOCAL nGroup
   LOCAL nCharPos
   LOCAL nDataLen
   LOCAL nData

   /* remove white spaces, If any */
   cString := StrTran( cString, Chr( 10 ) )
   cString := StrTran( cString, Chr( 13 ) )
   cString := StrTran( cString, Chr( 9 ) )
   cString := StrTran( cString, " " )

   /* The source must consists from groups with Len of 4 chars */
   IF ( nLen := Len( cString ) ) % 4 != 0
      RETURN "" /* Bad Base64 string */
   ENDIF

//#if 0
//    IF nLen > Int( MAXSTRINGLENGTH / 1.34 ) /* Base64 is 1/3rd larger than source text. */
//      RETURN "" /* Not enough memory to decode */
//    ENDIF
//#endif

   cResult := ""

   /* Now decode each group: */
   FOR nGroupPos := 1 TO nLen STEP 4

      /* Each data group encodes up To 3 actual bytes */
      nDataLen := 3
      nGroup := 0

      FOR nCharPos := 0 TO 3

         /* Convert each character into 6 bits of data, And add it To
            an integer For temporary storage. If a character is a '=', there
            is one fewer data byte. (There can only be a maximum of 2 '=' In
            the whole string.) */

         nData := At( SubStr( cString, nGroupPos + nCharPos, 1 ), "=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ) - 2

         DO CASE
         CASE nData >= 0
            /* Do nothing (for speed) */
         CASE nData == -1
            nData := 0
            nDataLen--
         CASE nData == -2
            RETURN "" /* Bad character In Base64 string */
         ENDCASE

         nGroup := 64 * nGroup + nData
      NEXT

      /* Convert the 24 bits to 3 characters
         and add nDataLen characters To out string */
      cResult += Left( Chr( nGroup / 65536 ) +;          /* bitwise AND 255, which is done by Chr() automatically */
                       Chr( nGroup /   256 ) +;          /* bitwise AND 255, which is done by Chr() automatically */
                       Chr( nGroup         ), nDataLen ) /* bitwise AND 255, which is done by Chr() automatically */
   NEXT

   RETURN cResult
Em minhas andanças pela internet pude entender que DLLCall() sempre retornará um inteiro. Se o valor for menor que 256 deve ser tratado como inteiro, mas se for maior que 256 deve ser tratado como pointer. Procede?

SAT-Fiscal a mistica está desvendada.

Enviado: 11 Mar 2016 10:59
por Edvaldo
Ok, o problema é antes desta etapa, na hora de pegar o retorno da função EnviarDadosVenda. Tentei declarar as funções da Dll conforme uso com todas as ECFs, mas não funciona com a Dll do SAT. Só funciona, mesmo com insegurança, usando a função DllCall, que por sua vez recebe uma cadeia de números ao invés de receber já o retorno do SAT e dai ser obrigado a usar as funções HB_Pointer2String() e StringToArray().

SAT-Fiscal a mistica está desvendada.

Enviado: 11 Mar 2016 11:36
por rochinha
Amiguinhos,

edvaldo
- Você usa xHarbour?
- Você está implementando em qual equipamento?

Veja o exemplo abaixo e veja se você consegue algum resultado:

Código: Selecionar todos

// #include "fivewin.ch"

FUNCTION MAIN()

   PUBLIC nSec := 0, xmlSAT := ""
   PUBLIC ctlSAT := 0, cModelo := "12", cPorta := "COM2"

   //RegisterServer( "ctlSAT.ocx" )

   //IF Isactivex( "shSAT.ctlSAT" )
   
      ctlSAT := CreateObject( "shSAT.ctlSAT" ) 

      // ----------------------------------
      // GERA UM NUMERO DE SESSAO ALEATORIO
      nSec := int(hb_Random( 99999 )) // ctlSAT:NumeroSessao()

      // ----------------------------------
      // ESTE METODO GERA UM XML USANDO UMA
      // FUNCÇÃO INTERNA DO OCX CHAMADO DE
      //          ctlSAT.GeraCFe
      // CODE PODE USAR ELE PARA GERAR O SEU
      // OU PODE GERAR MANUALMENTE E IR DIRETO
      // PARA A FUNÇÃO ENVIAR DADOS VENDA
    
      xmlSAT := GeraXML()

      // ----------------------------------
      // CHAMA A FUNÇÃO DO COMPONENTE
      // ? "xRetorno := ctlSAT:SATEnviarDadosVenda( nSec, xmlSAT )",;
      xRetorno := ctlSAT:SATEnviarDadosVenda( nSec, xmlSAT )

      // ----------------------------------
      // USE ESTA FUNÇÃO PARA INTERPRETAR O ULTIMO BUFFER (RESPOSTA) RECEBIDA PELO COMPONENTE
      ? "numeroSessao=" + ctlSAT:SplitBufferItem(0),;
               "EEEEE=" + ctlSAT:SplitBufferItem(1),;
                "CCCC=" + ctlSAT:SplitBufferItem(2),;
            "mensagem=" + ctlSAT:SplitBufferItem(3)
          
      ? xChave:Text := ctlSAT:SplitBufferItem(8)

   //ENDIF
   
   return nil

FUNCTION ConsultarSAT()
   LOCAL nSec := 0
   // ----------------------------------
   // GERA UM NUMERO DE SESSAO ALEATORIO
   nSec = ctlSAT:NumeroSessao
   // ----------------------------------
   // CHAMA A FUNÇÃO DO COMPONENTE
   xRetorno:Text := ctlSAT:SATConsultarSAT(nSec)
   // ----------------------------------
   // USE ESTA FUNÇÃO PARA INTERPRETAR O ULTIMO BUFFER (RESPOSTA) RECEBIDA PELO COMPONENTE
   ? "numeroSessao=" + ctlSAT:SplitBufferItem(0),;
            "EEEEE=" + ctlSAT:SplitBufferItem(1),;
         "mensagem=" + ctlSAT:SplitBufferItem(2)
   RETURN xRetorno:Text
   
FUNCTION geraXML()
   RETURN MemoRead( "CFeTeste.xml" )
CTLSAT.ZIP
OCX de acesso as funções do SAT
(268.18 KiB) Baixado 153 vezes
Amiguinhos,
No caso da .OCX é necessário regisrá-la. Use o REGISTRA.REG, mesclando-o ao registro(duplo clique) e depois pelo Windows Explorer, encontre a ctlSAT.ocx e com botão direito use REGISTRAR ou REGISTER.

REGISTRA.REG:

Código: Selecionar todos

Windows Registry Editor Version 5.00

;================================================
; \\\\\\\\\\\\\\   Context Menus   //////////////
;================================================
;------------------------------------------------------------------------------------------------------------
;Add register / unregister to the context menu for .dll files
[HKEY_CLASSES_ROOT\.dll]
;"Content Type"="application/x-msdownload"
@="dllfile"
[HKEY_CLASSES_ROOT\dllfile]
@="Application Extension"
@="DLL"
[HKEY_CLASSES_ROOT\dllfile\Shell\Registra\command]
@="regsvr32.exe /s \"%1\""
[HKEY_CLASSES_ROOT\dllfile\Shell\DeRegistra\command]
@="regsvr32.exe /u \"%1\""

;------------------------------------------------------------------------------------------------------------
;Add register / unregister to the context menu for .ocx files
[HKEY_CLASSES_ROOT\.ocx]
@="ocxfile"
[HKEY_CLASSES_ROOT\ocxfile]
@="OCX"
[HKEY_CLASSES_ROOT\ocxfile\Shell\Registra\command]
@="regsvr32.exe /s \"%1\""
[HKEY_CLASSES_ROOT\ocxfile\Shell\DeRegistra\command]
@="regsvr32.exe /u \"%1\""
Salve o conteúdo acima, usando o Notepad, em um arquivo de nome registra.reg e dê dois cliques nele para iniciar a mesclagem.

SAT-Fiscal a mistica está desvendada.

Enviado: 11 Mar 2016 12:13
por alaminojunior
O retorno da função enviardadosvenda com dllcall() é um pointer.
Recebido este pointer, eu aciono a função HB_pointer2string que recebe como parâmetros este ponteiro, e também um segundo parâmetro que segundo eu entendi deve ser um inteiro com o tamanho aproximado (?) da string que consta naquele endereço de memória. E é aí que está o problema: se você passa um valor menor, a string vem cortada, se passa um valor muito maior, pode causar erros absurdos no Windors !

SAT-Fiscal a mistica está desvendada.

Enviado: 11 Mar 2016 12:43
por Edvaldo
Ok, estou usando além do simulador, o SAT da DImep com impressora Daruma DR700, mais por enquanto estou usando a Dll DarumaFrameWork e preciso usar conforme este fórum pra que sirva pra todos os equipamentos SATs.

SAT-Fiscal a mistica está desvendada.

Enviado: 11 Mar 2016 14:34
por Edvaldo
Compilei o exemplo e está dando os erros:
Descrição do erro: TOleauto/65535 TOLEAUTO NEW
THROW(0)
TOLEAUTO:NEW(346)
CREATOBJECT(78)
TESTESAT(2692)
CHAMADA DE MAIN(515)
Na linha 2692 do prg tem: ctlSAT := CreateObject( "shSAT.ctlSAT" )
Registrei a ocx com sucesso.

SAT-Fiscal a mistica está desvendada.

Enviado: 11 Mar 2016 15:27
por rochinha
Amiguinhos,

Edvaldo
O xHarbour tem suas próprias função para o tratamento OLE, CreateOLEObject(), win_OleCreate(), verifique a que mais se adequa ao seu uso.

Execute o ActiveXXX.exe e visualize se o controle realmente apareceu. Se não, entre no prompt do DOS como administrador e execute o registro: %windir%\system32\regsvr32 cltSAT.ocx

SAT-Fiscal a mistica está desvendada.

Enviado: 11 Mar 2016 22:11
por Edvaldo
Executei o regsvr32 e deu a mensagem:
o modulo ctlsat.ocx foi carregado mas houve uma falha na chamada para DllRegisterServer, com o código de erro 0x80004005.

SAT-Fiscal a mistica está desvendada.

Enviado: 11 Mar 2016 23:44
por rochinha
Amiguinhos,

Seguiu minha recomendação?
...entre no prompt do DOS como administrador e execute o registro: %windir%\system32\regsvr32 cltSAT.ocx...
ctlSAT.png

SAT-Fiscal a mistica está desvendada.

Enviado: 16 Mar 2016 11:49
por paulovirt
Amigos, por favor uma luz. To tentando fazer o tratamento do retorno para obter o XML validado, mas ta tudo muito obscuro.
Cheguei até este ponto, mas não consigo compreender:

Código: Selecionar todos

dados := MemoRead( "c:\proemp\xml\sat\sat"+minio+".xml" )
retorno := DLLCall(h1,32,"EnviarDadosVenda",Random(), CCHAVE_SAT, dados)


xRet:= HB_Pointer2String(retorno,1000)

xTxt:= StringToArray( trim(xRet), "|" )


If xTxt[2] != '10000'
// '10000' RESPOSTA COM SUCESSO

@ 1,1 Say (xTxt[3] + ' - ' + xTxt[2])

 return .F.
 
Else

@ 1,1 Say (xTxt[3] + ' - ' + xTxt[2])

 return .F.

Endif

if !empty(xTxt[5])

@ 1,1 Say (xTxt[5] + ' - ' + xTxt[4])

Endif

// MATRIZ COM INFORMACOES PERDIDAS

@ 1,1 Say valtoprg(xTxt)


Return .T.





SAT-Fiscal a mistica está desvendada.

Enviado: 16 Mar 2016 23:24
por rochinha
Amiguinhos,

Edvaldo, paulovirt e alaminojunior não sei porque o xHarbour está ocasionando tanta dificuldade neste quesito. Uso Harbour .45, super antigo e roda numa boa os meus exemplos.

Esta funções novas do xHarbour ou compativeis não devem ter bugs. Alguma coisa não está sendo passada ou bem recebida.

Perguntei se poderiam trocar o 1000 por 5000 no HB_Point2String() poderia ser usado as não lembro de ter tido resposta.

Coloquei duas DLLs dimep diferentes para testes, não tive resposta.

O acesso a qualquer DLL podemos usar PASCAL ou não, portanto devemos testar todas hipóteses e finalmente.

Exemplos compilados para os testes da equipe PC Toledo(todos nós) são de grande ajuda.