segunda-feira, 14 de março de 2011

Erros na Rotina Automática

Alguns erros que ocorrem nas rotinas automáticas podem ser exibidos através do comando MostraErro(). Porém alguns erros não são detectados e a rotina roda como se estivesse tudo certo, ou seja, como se a gravação tivesse ocorrido com sucesso. Mas quando vamos procurar o registro, ele não se encontra. Passei várias vezes por isso, principalmente em cadastro que tem uma série de validações como por exemplo o cadastro de clientes. O primeiro problema foi quando eu estava fazendo a integração do Protheus com outro sistema e o CPF vinha em branco ou errado. O controle de erro da rotina automática não era acionado e eu não sabia o motivo pelo qual o cliente não estava sendo inserido até que resolvi olhar o CPF e pronto... primeiro problema resolvido. Verifiquei se o sistema mandava todos os campos obrigatórios para o Protheus e criei um log que avisava carro algum estivesse em branco. Para isso usei a função X3Obrigat(cCampo).
Só que não parou por aí pois alguns clientes continuavam a chegar e não eram gravados. Investiguei e descobri que o número do IBGE estava vindo '0000' em muitos.. ou seja.... o sistema que mandava as informações deixava muito a desejar em algumas validações. Mais uma vez isso foi corrigido. Funcionou por um bom tempo até que em alguns clientes de pessoa Jurídica o erro de não gravar continuava. De novo, investigando, descobri que o sistema mandava de forma incorreta a inscrição estadual, ou seja, não vazia a validação antes de mandar para o Protheus e em alguns casos a inscrição vinha nula ou com números digitados de forma aleatória. Depois de corrigido, até o momento a integração de clientes funciona muito bem.

sexta-feira, 11 de março de 2011

Conectar o Protheus a outra Base de Dados






Uma integração entre o Protheus e outros sistemas pode ser feita de várias formas, xml, arquivo txt etc. Eu resolvi fazer algo mais direto, ou seja, uma aplicação no Protheus(BD Sql Server) que enxerga o banco de dados do outro sistema, que usa o BD Postgres, e monta uma tabela temporária tratando esses dados e logo depois inserindo-os no Protheus através de rotinas automáticas. Apesar do banco do outro sistema não ter nada haver com o banco de dados do Protheus, podemos conectar a ele da seguinte forma:
1- Crie uma ODBC no servidor do BD do Protheus para o outro banco. No caso do Postgres, eu tive que baixar um drive para conexão ODBC específica para ele. Observe configuração de porta, senha e tal. No final, verifique se a conexão foi bem sucedida. Caso tenha sido, deveremos executar o próximo passo.
2- Valide a conexão ODBC da mesma forma que se faz com uma ODBC criada para o Protheus, ou seja, vá ao TOTVSDBMonitor e na aba configurações, escolha a aba Postgres ou a do BD do outro sistema que você quer se conectar. Crie um ambiente, coloque a senha correta e no assistente é só fazer a validação da conexão.
3- Com a validação ok, é hora de enxergar o outro banco. Vamos então criar uma rotina básica de comunicação com nosso BD da outra aplicação.

-----------------------------------------------------------------------------------------------
User Function JOBATAE1()
Private cBDProd := "MSSQL/Interface" // comunicacao com BD Protheus. Usado na funcao //TCLINK.
Private cBDAtae := "POSTGRES/atae" // comunicacao com BD sistema ATAE. Usado na //funcao.
Private cIPBD := "192.168.1.244" // IP do servidor de aplicacoes

Private _nTcConn // conectar com ATAE
Private _nTcCon2 // conectar com Protheus


TCCONTYPE("TCPIP") // tipo de conexao que sera usada

_nTcConn := TCLink(cBDAtae,cIPBD) // conexao com ATAE(sistema que usa o BD PostGres)
_nTcCon2 := TCLink(cBDProd,cIPBD) // conexao com Protheus

-----------------------------------------------------------------------------------------------

Neste primeiro trecho observe que criei duas variáves :
cBDProd
cBDAtae

Elas guardam a string de conexao com os respectivos BD. Logo depois temos a variável
cIPBD que contém o IP do servidor de aplicações do Protheus. Essas variáveis serão usadas na função TCLink pois ela tem a seguinte sintaxe:

TCLink(cConectString,cServer)

cConectString: String composta conforme a regra:

Para TOPConnect NT : Nome do Banco de Dados / Nome do Ambiente

Para TOPConnect/400: Nome do Ambiente

cServer: Endereço IP do servidor TOPConnect.

As variáveis _nTcConn e _nTcCon2 recebem o resultado da conexão, ou seja, o TCLink retorna um número negativo caso a conexão não tenho tido êxito. Neste caso existe a possibilidade de algum dos servidores de BD estarem offline ou a string de conexão está incorreta.

Continuando nossa aplicação temos:

-----------------------------------------------------------------------------------------------

If ( _nTcConn <>
//mostra alerta de erro com a conexão BD postgres ou BD Protheus

Alert("*** Erro de conexão ***")
Else
Alert("*** Conexão OK ***")
TCSETCONN(_nTcConn) // setando conexao com Postgres
LerTab() // lendo uma tabela Postgres
InsProt() // pegando os dados do Postgres e inserindo no Protheus
EndIf

Return

Static Function LerTab()
Local cQuery := " SELECT * FROM CLIENTE "
dbUseArea(.T., "TOPCONN", TCGenQry(,,cQuery), "TRS", .F., .T.)
TRS->(DbGoTop())
Alert(TRS->NOME)
Return



Static Function InsProt()
TCSETCONN(_nTcCon2) // conectando com o Protheus
RPCSetType(3)
RPCSetEnv("01","01","user","senhaUser") // logando no Protheus
// faca um loop para carregar os dados da tabela TRS para seu array
// e execute sua rotina automática
TRS->(DbCloseArea())
Return
-----------------------------------------------------------------------------------------------
Na segunda parte da rotina podemos ver que após verificar se as conexões estão Ok, usamos o comando TCSETCONN(_nTcConn) para setar a conexão da rotina para o BD postgres. A partir daí é tudo quase igual a qualquer rotina para criar uma tabela temporária baseada em informações do Protheus. Observe apenas a sintaxe usada na variável cQuery que terá que obedecer as regras do banco. Depois de recuperar as informações da tabela CLIENTE do postgres, é só usar o comando TCSETCONN(_nTcCon2) para se comunicar com o Protheus e a parti daí usar os comandos RPCSetType e RPCSetEnv para logar na empresa e filial. Depois disso, execute sua rotina automática e pronto, sua integração foi feita.



sexta-feira, 4 de março de 2011

Rotinas Automáticas

Uma ferramenta importante para a integração são as rotinas automáticas. No projeto em que eu estou, toda a integração é baseada em rotinas automáticas, salvo algumas exceções em que o Protheus não disponibiliza tais rotinas como uma para gerar uma nota fiscal de saída pelo faturamento. Tive algumas dores de cabeça com algumas rotinas automáticas pois elas são bem rígidas e não deixam passar em branco alguns erros. Inclusive, alguns desses erros são bem difíceis de identificar . Irei listar abaixo alguns deles e suas soluções:


eu estava gerando Notas Fiscais de entrada através da rotina MSExecAuto({|x,y,z| mata103(x,y,z)},aCabec,aItens,3)

Conferi os dados, tudo certinho. Só que na hora de gerar a nota, a função MostraERRO() gerava o seguinte aviso:

HELP: REGNOIS
Não existe registro relacionado a este
código.

Tabela SF1 18/02/11 16:48:56
- cTipo :=N
- cFormul :=N
- cNFiscal :=102454
- cSerie :=01
- dDEmissao :=18/02/11
- cA100For :=000005
- cLoja :=01 < -- Invalido - cEspecie :=NFE - cUfOrig :=PB

Só que a loja era realmente do fornecedor e todos os outros dados estavam corretos. A não ser por um detalhe. O código do fornecedor está com tamanho igual a 6, porém o campo correspondente do Protheus estava com tamanho 14. Nada muito haver com o erro apresentado pelo Protheus, mas que causou bastante dor de cabeça. Então na linha:

aadd(aCabec,{"F1_FORNECE","000005"})

Eu fiz assim:
aadd(aCabec,{"F1_FORNECE","000005 "})
E a rotina funcionou normalmente.
Resumo da história, é altamente recomendável usar códigos com o mesmo tamanho do campo.


quarta-feira, 2 de março de 2011

Integração

Hoje, muitas empresas tem a necessidade de migrar para sistemas mais robustos e confiáveis. O problema é que essa migração não pode ser feita de uma hora para outra. Na verdade para a migração ocorrer, muitas vezes é necessário que os dois sistemas funcionem em paralelo e assim integrem informações até que naturalmente ocorra a total substituição do sistema antigo pelo mais moderno. Outra situação é quando a empresa quer trabalhar com dois sistemas em paralelo, por exemplo, um sistema específico para front de loja e outro para ficar na retaguarda. No meu caso estou fazendo justamente isso. Estou integrando um sistema usado no front de loja e caixa com o sistema Protheus que fica na retaguarda. A grande dificuldade é justamente tratar as diferente regras e situações mas nada impossível de se fazer. Nas próximas publicações irei mostrar toda a arquitetura usada como também como foi feita a primeira parte da integração aonde clientes cadastrados no sistema front de loja vão automaticamente ser cadastrados no Protheus.
Em meu outro Blogger (http://sap-b1-sdk.blogspot.com) estarei falando do sistema SAP B1 e irei mostrar além de exemplos de customizações, integrações com o sistema Protheus na parte de compras, vendas e cadastros. Até breve.