SAT-Fiscal a mistica está desvendada.

Fórum sobre desenvolvimento de software para atender as exigências da legislação fiscal e tributária (NFe, NFCe, NFSe, SPEED, Projeto ACBr, TEF, ECD, EFD, etc.)

Moderador: Moderadores

Avatar do usuário
paulovirt
Usuário Nível 2
Usuário Nível 2
Mensagens: 69
Registrado em: 29 Jan 2007 10:00
Contato:

SAT-Fiscal a mistica está desvendada.

Mensagem 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?
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

SAT-Fiscal a mistica está desvendada.

Mensagem 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.
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

SAT-Fiscal a mistica está desvendada.

Mensagem 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.
Compilador xHarbour 1.2.3 + Embarcadero C++ 7.30
MySQL c/ SQLRDD
HwGui + GTWVG
Edvaldo
Usuário Nível 1
Usuário Nível 1
Mensagens: 32
Registrado em: 17 Fev 2016 12:09
Localização: ubatuba

SAT-Fiscal a mistica está desvendada.

Mensagem 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.
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

SAT-Fiscal a mistica está desvendada.

Mensagem 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?
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Edvaldo
Usuário Nível 1
Usuário Nível 1
Mensagens: 32
Registrado em: 17 Fev 2016 12:09
Localização: ubatuba

SAT-Fiscal a mistica está desvendada.

Mensagem 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().
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

SAT-Fiscal a mistica está desvendada.

Mensagem 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.
Anexos
DLL667KB.ZIP
satDLL Dimep com tamanho de 667kb
(304.79 KiB) Baixado 99 vezes
DLL250KB.ZIP
satDLL Dimep com tamanho de 250kb
(122.29 KiB) Baixado 118 vezes
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

SAT-Fiscal a mistica está desvendada.

Mensagem 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 !
Compilador xHarbour 1.2.3 + Embarcadero C++ 7.30
MySQL c/ SQLRDD
HwGui + GTWVG
Edvaldo
Usuário Nível 1
Usuário Nível 1
Mensagens: 32
Registrado em: 17 Fev 2016 12:09
Localização: ubatuba

SAT-Fiscal a mistica está desvendada.

Mensagem 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.
Edvaldo
Usuário Nível 1
Usuário Nível 1
Mensagens: 32
Registrado em: 17 Fev 2016 12:09
Localização: ubatuba

SAT-Fiscal a mistica está desvendada.

Mensagem 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.
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

SAT-Fiscal a mistica está desvendada.

Mensagem 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
Anexos
ActiveXXX.rar
Visualiza controles OCX e DLL.
(562.51 KiB) Baixado 132 vezes
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Edvaldo
Usuário Nível 1
Usuário Nível 1
Mensagens: 32
Registrado em: 17 Fev 2016 12:09
Localização: ubatuba

SAT-Fiscal a mistica está desvendada.

Mensagem 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.
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

SAT-Fiscal a mistica está desvendada.

Mensagem 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
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar do usuário
paulovirt
Usuário Nível 2
Usuário Nível 2
Mensagens: 69
Registrado em: 29 Jan 2007 10:00
Contato:

SAT-Fiscal a mistica está desvendada.

Mensagem 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.




Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

SAT-Fiscal a mistica está desvendada.

Mensagem 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.
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Responder