quarta-feira, 9 de fevereiro de 2011

Ponto de Entrada ao acessar um módulo do Protheus

Pessoal, para executar uma rotina na abertura de um módulo do Protheus você poderá usar os seguintes pontos de entrada:

SIGAFAT - Módulo Faturamento
SIGAFIN - Módulo Financeiro
SIGAPCP - Módulo Planejamento e Controle de Produção.

Vale lembrar que isso é válido para todos os módulos disponíveis no Protheus.

Um abraço

sábado, 5 de fevereiro de 2011

Como trocar as cores de uma grid no Protheus

Pessoal, aqui vai uma dica de como alterar as cores das linhas nos objetos MSSelect, TMSNewGetDados, TNewGetDados, entre outros browsers.

#include "colors.ch"
User Function CorLinhaBrowse()
   Private _oBrowseColorido := ""
   Private _oDlg := ""
   @ 0,0 To 510,750 Dialog _oDlg Title "Mostrar Grid Colorida"
   @ 05,05 To 170,370 Browse "TZ09" Fields aCampos object _oBrowseColorido
   _oBrowseColorido:obrowse:acolumns[1]:BCLRFORE := {|SETVAL| SFMudaCor(1)} //Cor da Fonte
   _oBrowseColorido:obrowse:acolumns[1]:BCLRBACK := {|SETVAL| SFMudaCor(2)} //Cor da Linha     
   Activate Dialog _oDlg Centered
Return


Static Function SFMudaCor(nIOpcao)
   Private _cCor := ""
   if nIOpcao == 1 // Cor da Fonte
      _cCor := CLR_YELLOW
   else // Cor do Fundo
      _cCor := CLR_BLACK
   endif
Return _cCor

Se caso nao conseguir deixe seu comentário

quinta-feira, 19 de agosto de 2010

Consumindo um WebService usando ADVPL

Olá Pessoal, vou mostrar um exemplo de como consumir um webservice usando o advpl. Eu achei um site que possui alguns webservices que podem ser consumidos para teste. o site é http://www.webservicex.net/WCF/webServices.aspx. Este site possui vários webservices, eu escolhi para demonstrar a vocês um que converte byte em todas as outras unidades (Kilobyte, Gigabyte, TeraByte, PetaByte) ou vice-versa. O WebService que vamos usar chama-se ComputerUnit, veja http://www.webservicex.net/WCF/ServiceDetails.aspx?SID=68 para ver os detalhes. Nesta pagina ele mostra qual é o endereço para gerar o client deste serviço (http://www.webservicex.net/ConvertComputer.asmx?wsdl). Este WS recebe 3 parâmetros e retorna 1 parâmetro.
Primeiramente vamos gerar o client deste WS no TotvsDevStudio (IDE). Para isso crie um arquivo novo, vá até o menu Ferramentas - Gerar Cliente WebServices. Na janela que será exibida, informe o endereço do WSDL deste serviço que é http://www.webservicex.net/ConvertComputer.asmx?wsdl. O TotvsDevStudio criará automaticamente o client do WS, conforme abaixo.

#INCLUDE "PROTHEUS.CH"
#INCLUDE "APWEBSRV.CH"

/* ===============================================================================
WSDL Location    http://www.webservicex.net/ConvertComputer.asmx?wsdl
Gerado em        08/19/10 10:42:26
Observações      Código-Fonte gerado por ADVPL WSDL Client 1.090116
                 Alterações neste arquivo podem causar funcionamento incorreto
                 e serão perdidas caso o código-fonte seja gerado novamente.
=============================================================================== */

User Function _ZJNIQRC ; Return  // "dummy" function - Internal Use

/* -------------------------------------------------------------------------------
WSDL Service WSComputerUnit
------------------------------------------------------------------------------- */

WSCLIENT WSComputerUnit

    WSMETHOD NEW
    WSMETHOD INIT
    WSMETHOD RESET
    WSMETHOD CLONE
    WSMETHOD ChangeComputerUnit

    WSDATA   _URL                      AS String
    WSDATA   nComputerValue            AS double
    WSDATA   oWSfromComputerUnit       AS ComputerUnit_Computers
    WSDATA   oWStoComputerUnit         AS ComputerUnit_Computers
    WSDATA   nChangeComputerUnitResult AS double

ENDWSCLIENT

WSMETHOD NEW WSCLIENT WSComputerUnit
::Init()
If !FindFunction("XMLCHILDEX")
    UserException("O Código-Fonte Client atual requer os executáveis do Protheus Build [7.00.090818P-20100630] ou superior. Atualize o Protheus ou gere o Código-Fonte novamente utilizando o Build atual.")
EndIf
If val(right(GetWSCVer(),8)) < 1.040504
    UserException("O Código-Fonte Client atual requer a versão de Lib para WebServices igual ou superior a ADVPL WSDL Client 1.040504. Atualize o repositório ou gere o Código-Fonte novamente utilizando o repositório atual.")
EndIf
Return Self

WSMETHOD INIT WSCLIENT WSComputerUnit
    ::oWSfromComputerUnit := ComputerUnit_COMPUTERS():New()
    ::oWStoComputerUnit  := ComputerUnit_COMPUTERS():New()
Return

WSMETHOD RESET WSCLIENT WSComputerUnit
    ::nComputerValue     := NIL
    ::oWSfromComputerUnit := NIL
    ::oWStoComputerUnit  := NIL
    ::nChangeComputerUnitResult := NIL
    ::Init()
Return

WSMETHOD CLONE WSCLIENT WSComputerUnit
Local oClone := WSComputerUnit():New()
    oClone:_URL          := ::_URL
    oClone:nComputerValue := ::nComputerValue
    oClone:oWSfromComputerUnit :=  IIF(::oWSfromComputerUnit = NIL , NIL ,::oWSfromComputerUnit:Clone() )
    oClone:oWStoComputerUnit :=  IIF(::oWStoComputerUnit = NIL , NIL ,::oWStoComputerUnit:Clone() )
    oClone:nChangeComputerUnitResult := ::nChangeComputerUnitResult
Return oClone

// WSDL Method ChangeComputerUnit of Service WSComputerUnit

WSMETHOD ChangeComputerUnit WSSEND nComputerValue,oWSfromComputerUnit,oWStoComputerUnit WSRECEIVE nChangeComputerUnitResult WSCLIENT WSComputerUnit
Local cSoap := "" , oXmlRet

BEGIN WSMETHOD

cSoap += '<ChangeComputerUnit xmlns="http://www.webserviceX.NET/">'
cSoap += WSSoapValue("ComputerValue", ::nComputerValue, nComputerValue , "double", .T. , .F., 0 , NIL, .F.)
cSoap += WSSoapValue("fromComputerUnit", ::oWSfromComputerUnit, oWSfromComputerUnit , "Computers", .T. , .F., 0 , NIL, .F.)
cSoap += WSSoapValue("toComputerUnit", ::oWStoComputerUnit, oWStoComputerUnit , "Computers", .T. , .F., 0 , NIL, .F.)
cSoap += "ChangeComputerUnit>"

oXmlRet := SvcSoapCall(    Self,cSoap,;
    "http://www.webserviceX.NET/ChangeComputerUnit",;
    "DOCUMENT","http://www.webserviceX.NET/",,,;
    "http://www.webservicex.net/ConvertComputer.asmx")

::Init()
::nChangeComputerUnitResult :=  WSAdvValue( oXmlRet,"_CHANGECOMPUTERUNITRESPONSE:_CHANGECOMPUTERUNITRESULT:TEXT","double",NIL,NIL,NIL,NIL,NIL,NIL)

END WSMETHOD

oXmlRet := NIL
Return .T.


// WSDL Data Enumeration Computers

WSSTRUCT ComputerUnit_Computers
    WSDATA   Value                     AS string
    WSDATA   cValueType                AS string
    WSDATA   aValueList                AS Array Of string
    WSMETHOD NEW
    WSMETHOD CLONE
    WSMETHOD SOAPSEND
    WSMETHOD SOAPRECV
ENDWSSTRUCT

WSMETHOD NEW WSCLIENT ComputerUnit_Computers
    ::Value := NIL
    ::cValueType := "string"
    ::aValueList := {}
    aadd(::aValueList , "Bit" )
    aadd(::aValueList , "Byte" )
    aadd(::aValueList , "Kilobyte" )
    aadd(::aValueList , "Megabyte" )
    aadd(::aValueList , "Gigabyte" )
    aadd(::aValueList , "Terabyte" )
    aadd(::aValueList , "Petabyte" )
Return Self

WSMETHOD SOAPSEND WSCLIENT ComputerUnit_Computers
    Local cSoap := ""
    cSoap += WSSoapValue("Value", ::Value, NIL , "string", .F. , .F., 3 , NIL, .F.)
Return cSoap

WSMETHOD SOAPRECV WSSEND oResponse WSCLIENT ComputerUnit_Computers
    ::Value := NIL
    If oResponse = NIL ; Return ; Endif
    ::Value :=  oResponse:TEXT
Return

WSMETHOD CLONE WSCLIENT ComputerUnit_Computers
Local oClone := ComputerUnit_Computers():New()
    oClone:Value := ::Value
Return oClone


Salve o arquivo com o nome que desejar, e compile este fonte.
Veja agora no exemplo abaixo como consumir este WS:


#include "protheus.ch"
User Function FUConsumirWS()
    // Criando o objeto Web Service
    _oWSTeste := WSComputerUnit():New()
    // A Variavel NCOMPUTERVALUE é o numero que deseja converter
    _oWSTeste:NCOMPUTERVALUE := 1000   
    // A Variavel _oWSTeste:oWSFROMCOMPUTERUNIT:VALUE é de qual medida deseja 
    // converter
    _oWSTeste:oWSFROMCOMPUTERUNIT:VALUE := "Gigabyte"                            
    // A Variavel _oWSTeste:oWSFROMCOMPUTERUNIT:VALUE é para qual medida deseja
    // converter
    _oWSTeste:oWSTOCOMPUTERUNIT:VALUE        := "Kilobyte"
    // Executa o metodo ChangeComputerUnit
    _oWSTeste:ChangeComputerUnit()       
    // Mostra o resultado
    MsgStop(_oWSTeste:NCHANGECOMPUTERUNITRESULT)
Return

Estas variáveis que utilizo na função acima foram criadas pelo client do WS, todos os clients gerados pelo Protheus seguem esse modelo, portanto voce poderá consumir o WS que desejar.

Qualquer duvida deixe seu recado.

Um abraço

segunda-feira, 16 de agosto de 2010

Como usar a função StartJob

Dias atrás tive o seguinte problema: Precisava executar uma rotina dentro de uma função mas essa primeira rotina não poderia parar e aguardar a execução desta função. Ai conheci a função StartJob. Está função permite iniciar uma Thread, ou seja, uma conexão separada no monitor, e a função que à chamou continuar rodando normalmente.

Sintaxe da função StartJob:

StartJob(NomeDaRotina,Environment,FinalizaRotina,Empresa,Filial)
Esta sintaxe é o que o TOTVS disponibiliza.
Até ai tudo bem, mas eu tive mais um problema: Eu precisava passar parametros para esta rotina que eu estava chamando na função StartJob. Fiz vários testes até que descobri que ao invés de passar os parametros Empresa e Filial, eu poderia passar um vetor com os parametros, ou seja, no mesmo vetor poderia passar Empresa, Filial e mais os parametros que precisava. E para receber estes parametros na função destino bastou usar o PARAMIXB. Abaixo segue um exemplo, apenas escrevi este exemplo, nao compilei.

// Funcao principal que dentro dela voce chamará um Job
User Function FUAtualizaDados()
   Local _aParametros := {}
   _aParametros := {"01","02","000001","04"}
   // Inicia o Job
   StartJob("U_FUTesteJob()",GetEnvServer(),.F.,_aParametros)
   /* A Função GetEnvServer() retorna o environment atual, mas posso definir outro. */
Return

// Esta funcao e a funcao chamada pela funcao StartJob
User Function FUTesteJob()
   Local _cEmpresa := paramixb[1] // Usar o paramixb
   Local _cFilial  := paramixb[2]
   Local _cFornece := paramixb[3]
   Local _cLoja    := paramixb[4]
   /* A maioria das funcoes que sao chamadas de Job devem usar o prepare environment */
   prepare environment _cEmpresa Filial _cFilial Tables "SA2"
   DBSelectArea("SA2")
   SA2->(DBSetOrder(1))
   if SA2->(DBSeek(xFilial("SA2")+_cFornece+_cLoja))
      RecLock("SA2",.F.)
      SA2->A2_TESTE := "TESTANDO FUNCAO JOB"
      SA2->(MsUnLock())
   endif
Return

Pessoal lembre-se que ao iniciar um Job voce estara usando uma licenca e vc pode ter problemas com isso. Daqui uns dias eu posto uma maneira de voce criar jobs sem usar licenças.

Qualquer duvida sobre o conteudo acima é só deixar seu recado.

Um abraço...

domingo, 15 de agosto de 2010

Compilando o Protheus sem precisar parar os serviços

Olá pessoal, não sei se isso é novidade pra vocês mas achei interessante postar: Muitas vezes precisamos compilar o Protheus e nos deparamos com 20, 30, 100 usuários conectados. Vou passar como podemos compilar o Protheus sem precisar fazer com que os usuários saiam do sistema.

  • Neste exemplo as minhas pastas do Protheus de Produção (Chamo de Produção pois não é o Ambiente ou Protheus de testes) estão da seguinte forma: C:\Protheus10\apo, C:\Protheus10\system.
  • Dentro da pasta que esta o RPO (C:\Protheus10\apo) crie as seguintes pastas: APO01, APO02, APO03.
  • Copie o RPO original para dentro de cada pasta criadas acima. 
  • Crie um server separado somente para compilar, o mesmo não precisa estar como serviço e sim em console. Este serviço vamos chamar de Servico de Compilação.
  • No IDE ou Development Studio deste Serviço de Compilação, você irá criar 03 Configurações de Compilação
Vá em menu Arquivo - Configurações - 
Adicionar 
Descrição: APO01 
Ambiente: APO01 
Conexão: TCP (ou aquela que você definiu no .ini do SmartClient (Remote) 
Diretório de Include: Local aonde se encontram as suas includes 
  • Faca o mesmo procedimento acima para os outros dois APOs, (APO02, APO03) 
  • Após isso abra o .ini do Server de Compilação 
  • Crie os ambientes usando o exemplo abaixo: 
;Esta seção é do ambiente APO01 - para compilação 
[APO01] 
SourcePath=C:\Protheus10\apo\APO01 
RootPath=C:\Protheus10\ 
StartPath=\system\ 
RpoDb=dbf 
RpoLanguage=portuguese 
RpoVersion=101 
LocalFiles=ads 
Trace=0 
localdbextension=.dbf 
PictFormat=DEFAULT 
DateFormat=DEFAULT 

;Esta seção é do ambiente APO02 - para compilação 
[APO02] 
SourcePath=C:\Protheus10\apo\APO02 
RootPath=C:\Protheus10\ 
StartPath=\system\ 
RpoDb=dbf 
RpoLanguage=portuguese 
RpoVersion=101 
LocalFiles=ads 
Trace=0 
localdbextension=.dbf 
PictFormat=DEFAULT 
DateFormat=DEFAULT 

;Esta é a seção do ambiente APO03 - para compilação 
[APO03] 
SourcePath=C:\Protheus10\apo\APO03 
RootPath=C:\Protheus10\ 
StartPath=\system\ 
RpoDb=dbf 
RpoLanguage=portuguese 
RpoVersion=101 
LocalFiles=ads 
Trace=0 
localdbextension=.dbf 
PictFormat=DEFAULT 
DateFormat=DEFAULT 

  • Depois de criada as seções de compilação no .ini do Server de Compilação, você poderá compilar os fontes usando qualquer um dos ambientes criados (APO01, APO02, APO03). Use por exemplo o APO02
  • Agora é a vez de alteramos o caminho do RPO (SourcePath) que o Protheus de Produção esta configurado. Como compilamos no APO02, o caminho será: 
;Eu estou dizendo aqui que meu environment principal chama-se
;PRODUCAO, no caso de vocês provavelmente é outro nome 
[PRODUCAO] 
SourcePath=C:\Protheus10\apo\APO02 
RootPath=C:\Protheus10\ 
StartPath=\system\ 
RpoDb=dbf 
RpoLanguage=portuguese 
RpoVersion=101 
LocalFiles=ads 
Trace=0 
localdbextension=.dbf 
PictFormat=DEFAULT 
DateFormat=DEFAULT 

  • Veja acima como ficou o SourcePath (C:\Protheus10\apo\APO02), então significa que agora o Protheus de Produção esta sendo apontado para outro rpo; 
  • Salve e feche o .ini do Protheus de Produção. 
  • Agora quem acessar o sistema estará direcionado para o APO02, e quem esta no sistema, aparecera uma mensagem para o usuário dizendo que o RPO foi atualizado.
  • Na próxima compilação você usará o APO03, e depois o APO01, assim por diante. 
Se vocês possuem uma base teste, poderão fazer isso em teste antes de colocar em produção.


Pessoal qualquer dúvida deixe seu comentário.


Um abraço

domingo, 13 de junho de 2010

Usando o emulador da Bematech no Protheus

Toda vez que eu precisava testar alguma rotina ou customização no módulo SigaLoja em uma base teste, me deparava com a falta da impressora fiscal, pois vocês já sabem que existe toda aquela burocracia para a instalação de ECF em um PC. Então comecei tentar usar o emulador da Bematech no Protheus. Depois de muitas tentativas ele começou a funcionar. Segue abaixo todos os procedimentos para que você consiga fazer com que o Protheus use o Emulador da Bematech.


Para usar o emulador da Impressora Fiscal MP2100 TH FI no Protheus, siga os seguintes passos para a instalação:

1 - Instale o emulador que se encontra no link: http://www.bematech.com.br/suporte/downloads/fisc_win/Emul2100v101.zip
 
2 - Descompacte o arquivo: https://www.opendrive.com/files/6925822_kgOSf_1ea0 para dentro da pasta que se encontra o Remote do Protheus.(Eu sugiro você ter o remote local pois não testei a emulação com Remote instalado em outro computador.)

3 - Recorte o arquivo BemaFI32.INI da pasta aonde se encontra o Remote do Protheus e cole na pasta c:\windows\system32

4 - Edite esse arquivo BemaFI32.INI e na seção Sistema altere a variável EmulMFD para o conteúdo 1, ou seja, você esta dizendo que esta usando um emulador.

5 - No mesmo arquivo na seção Sistema altere a variável Porta para o conteúdo COM1 por exemplo. Use uma porta que o sistema não esteja usando. Essa mesma porta terá de ser configurada no Protheus e na Impressora fiscal mais adiante.

6 - Acesse o emulator da bematech em: INICIAR - PROGRAMAS - BEMATECH - Emul2100

7 - Primeiramente vamos alterar a porta do emulador, clique com o botão direito no emulador e selecione Porta Serial, altere para COM1.

8 - Agora vamos fazer as alterações necessárias no Protheus para que ele se comunique com o emulador.

9 - Acesse o Protheus com o seu usuário.

10 - Acesse o modulo Controle de Lojas

11 - Acesse a rotina Miscelania - Configurações - Estacao

12 - Exclua a estacao atual.

13 - Inclua a nova estação com as seguintes informações:

Estacao001
NomeESTACAO TESTE
FabricanteBEMATECH
ModeloBEMATECH MP2100 THFI - V. 01.00.01
PDV0001
SERIEECF
PORTACOM1

14 - Acessar o configurador e altere os seguinte parametros:
ParametroConteudo
MV_IMPFISBEMATECH MP2100 THFI
MV_PORTFISCOM1

15 - Ainda no configurador acesse o cadastro de empresas.

16 - Edite as informações da empresa e altere o CNPJ para: 82373077000171. Porque isso? Como é o emulador da Bematech o CNPJ cadastro no Emulador é o da própria Bematech. Se não fizer esta alteração não é possivel fazer uma venda. (Lembre-se que estou fazendo isso em um ambiente teste. Nao altere nada no cadastro de empresas em um ambiente de produção.)

17 - Após isso baixe o seguinte arquivo: https://www.opendrive.com/files/6925887_xbo7O_7c92. Esse aplicativo é um exemplo que a bematech disponibiliza os fontes em Delphi  para alterar e testar a ECF. Eu copiei os fontes do site da Bematech e compilei. Acesse o aplicativo Bematech.exe.

18 - Dentro do aplicativo Bematech, vamos informar quais aliquotas de ICMS que o Emulador terá. Acesse o menu Inicialização - Adicionar Aliquota Tributaria.

19 - Adicione as seguintes aliquotas: 12 ICMS - 17 ICMS - 18 ICMS. Após isso feche aplicativo.

20 - Acesse o Controle de Lojas com a senha de caixa, se o sistema mostrar a mensagem que o “numero de serie do ecf é diferente do cadastrado na estacao”, acesse o menu Miscelania e Gere os arquivos de criptografia. Saia do sistema e acesse novamente.

21- Se não ocorrer nenhum erro o sistema esta pronto para usar o Emulador.


Obs: Se caso não funcionar com essas dicas, deixe sua dúvida. Eu testei os passos acima com o PAF-ECF configurado no Protheus e não consegui emular mais a ECF. Não tenho certeza mais o que eu verifiquei é que o CNPJ da empresa que usará o PAF-ECF é liberado pela TOTVS por meio de um patch, ou seja, está no fonte e não mais no cadastro de empresas.

Apostilas de ADVPL

Essa apostila não possui todos os comandos ADVPL mas contêm os principais, é uma boa para quem está iniciando.  


Apostila contendo todos os pontos de entradas do Protheus, deve-se tomar cuidado ao usar um determinado ponto de entrada descrito nesta apostila, pois não há informação de quando este ponto de entrada é chamado pelo sistema.
   
Temos um grande problema quando começamos a desenvolver algo em ADVPL, a documentação existente além de ser limitada possui poucas explicações. Essa é a lista das funções existentes na linguagem ADVPL. Algumas funções possuem parâmetros como (CR - Caracter), (NR - Número), (BO - Boleano),(AR - Array). Assim que possível vou descrever algumas funções destas.