segunda-feira, 15 de setembro de 2014

Webservice no Protheus - Parte 2 - Montando uma aplicação básica

A partir deste post, você vera como testar uma aplicação básica

Montagem da classe do Webservice

Este Webservice terá a finalidade retornar os dados do cliente no Protheus, a aplicação .NET ira enviar uma solicitação que poderia ser no formato de um XML ou por passagem simples por parâmetros.
Para não complicar muito, o primeiro exemplo de passagem de parâmetros é mais indicado.

O resultado final é o retorno do Nome do cliente, endereço, bairro, cidade, uf e CEP.
A passagem de parâmetros será o código do cliente e a loja.

No exemplo abaixo, não fiz nenhum tipo de validação e não estou preocupado com isso neste momento, fica a cargo de meus leitores corrigir o programa.
Em meus projetos consulto usuários, bloqueio senhas, envio estruturas complexas de XML, etc.

Então, mão na massa.

Primeiro, crie um arquivo no seu projeto, no meu caso criei com o nome MeuPrimeiroWebService.PRW

#INCLUDE 'PROTHEUS.CH'
#INCLUDE "XMLXFUN.CH"
#INCLUDE "APWEBSRV.CH"
#include "topconn.ch"
#INCLUDE "RWMAKE.CH"
#INCLUDE "TBICONN.CH"
#INCLUDE "ERROR.CH"

// Estrutura de dados. Montagem do Array de retorno
// Não necessariamente retorna-se em um Array, pode ser possível retornar em uma string simples,
// neste caso não utilizaria uma Estrutura
WSSTRUCT AWSRTDados
    WSDATA ClienteNome     AS String
    WSDATA ClienteEndereco AS String
    WSDATA ClienteBairro   AS String
    WSDATA ClienteCidade   AS String
    WSDATA ClienteUF           AS String
    WSDATA ClienteCEP          As String
ENDWSSTRUCT 

// WebService
WSSERVICE MeuPrimeiroWebService DESCRIPTION "Descrição do meu primeiro WebService"
       // Passagem dos parâmetros de entrada
       WSDATA ClienteCodigo  AS string
       WSDATA ClienteLoja    AS string
      
       // Retorno de um array que deve retornar a COLUNA 1, COLUNA 2
       WSDATA aRetornoCliente AS ARRAY OF AWSRTDados

       // Descrição dos métodos que o WEBSERVICE pode possuir
       /*WSMETHOD ExcluiOrdem     DESCRIPTION "Efetua a exclusão de uma ordem de faturamento"
       WSMETHOD DeletaNfSaida   DESCRIPTION "Consulta ou exclui uma nota fiscal de vendas"
       WSMETHOD DeletaNfEntrada DESCRIPTION "Consulta ou exclui uma nota fiscal de compras"
       WSMETHOD AtualizaProduto DESCRIPTION "Inclui / Altera um produto no Microsiga SB1"
       WSMETHOD MeuXML          DESCRIPTION "Meu XML"
       WSMETHOD SenhaProtheus   DESCRIPTION "Teste se a senha esta Ok"*/
      
       WSMETHOD ConsultarCliente DESCRIPTION "Retorna os dados do cliente"
      
ENDWSSERVICE

/************************************************************************************
** Consulta os dados do cliente
** Abaixo, separei o que se refere do webservice da aplicação que realmente ira
** processar os dados. Lembrando que não é obrigatório
************************************************************************************/
WSMETHOD ConsultarCliente WSRECEIVE ClienteCodigo, ClienteLoja WSSEND aRetornoCliente WSSERVICE MeuPrimeiroWebService
Local aRetFuncao := {}

    aRetFuncao     := u_xxRtCliente(::ClienteCodigo,::ClienteLoja) // Passagem de parâmetros para rotina
  
    aAdd(::aRetornoCliente, WSClassNew("AWSRTDados") )
    ::aRetornoCliente[01]:ClienteNome    := aRetFuncao[1][1]
    ::aRetornoCliente[01]:ClienteEndereco:= aRetFuncao[2][1]
    ::aRetornoCliente[01]:ClienteBairro  := aRetFuncao[3][1]
    ::aRetornoCliente[01]:ClienteCidade  := aRetFuncao[4][1]
    ::aRetornoCliente[01]:ClienteUF      := aRetFuncao[5][1]
    ::aRetornoCliente[01]:ClienteCEP     := aRetFuncao[6][1]

Return .T.

/*************************************************************
** Retorna os dados do cliente
**************************************************************/
User Function xxRtCliente(pClienteCodigo, pClienteLoja)
Local aRetornoDados         := {}
Local aTables    := { "SA1","SM0" }

Conout(dtoc( Date() )+" "+Time()+ " == Abrindo ambiente TOP CONNECT =======")
RPCSetType( 3 )
RpcSetEnv ( "01", "01", Nil, Nil, "FAT", Nil, aTables )

SA1->(DbSetOrder(1))
SA1->(DbGoTop())

If SA1->(DbSeek(xFilial("SA1") + pClienteCodigo+ pClienteLoja))
         aAdd(aRetornoDados ,{SA1->A1_NOME                       })  // 1
         aAdd(aRetornoDados ,{SA1->A1_END                       })  // 2
         aAdd(aRetornoDados ,{SA1->A1_BAIRRO                     })  // 3
         aAdd(aRetornoDados ,{SA1->A1_MUN                        })       // 4
         aAdd(aRetornoDados ,{SA1->A1_EST                        })       // 5
         aAdd(aRetornoDados ,{SA1->A1_CEP                        })  // 6
Else
         aAdd(aRetornoDados ,{Nil})  // 1
         aAdd(aRetornoDados ,{Nil})  // 2
         aAdd(aRetornoDados ,{Nil})  // 3
         aAdd(aRetornoDados ,{Nil})  // 4
         aAdd(aRetornoDados ,{Nil})  // 5
         aAdd(aRetornoDados ,{Nil})  // 6     
Endif

Return aRetornoDados

Feito isto, vamos verificar se não existe nenhum erro na compilação pesquisando pelo o endereço ja configurado. A configuração expliquei na Parte 1

http://192.168.15.86:889/ws/WSINDEX.apw 



Ao clicar no link, aparece a configuração que deve ser utizada no Visual Studio ou qualquer outra aplicação


Vamos agora no Visual Studio...

Em adicionar referência, colar o link MEUPRIMEIROWEBSERVICE.apw?WSDL conforme figura abaixo :


No visual Studio vamos montar uma telinha


Agora, vamos montar um código simples, quero deixar claro que não sou especialista em c#, sou um mero fuçador.

private void button1_Click(object sender, EventArgs e)
        {
            // Instanciamos a nossa referência com o WebService do Protheus
            ClientWSProtheus.MEUPRIMEIROWEBSERVICESOAPClient aleksandro = new ClientWSProtheus.MEUPRIMEIROWEBSERVICESOAPClient();

            // Montamos uma ILIST, poderia ser uma string qualquer, existem diversas formas de fazer
            IList<AWSRTDADOS> aRetorno;

            // Chamo o método e retorno em um array
            aRetorno = aleksandro.CONSULTARCLIENTE(ParamCodigo.Text, ParamLoja.Text);

            // Jogo nos campos os dados da empresa
            textBox3.Text = aRetorno[0].CLIENTENOME.ToString();
            textBox4.Text = aRetorno[0].CLIENTEENDERECO.ToString();
            textBox5.Text = aRetorno[0].CLIENTEBAIRRO.ToString();
            textBox6.Text = aRetorno[0].CLIENTECIDADE.ToString();
            textBox7.Text = aRetorno[0].CLIENTECEP.ToString();
            textBox8.Text = aRetorno[0].CLIENTEUF.ToString();

        }

Executando o programa, vejamos o que o Protheus ira retornar


Pronto, a consulta foi feita unicamente pelo WEBSERVICE sem se conectar diretamente na base de dados.

Da mesma forma que podemos fazer uma consulta, também é possível fazer um programa EXECAUTO, ou rodar rotinas padrão do Protheus.

Esta foi uma forma de fazer, mas existem diversas maneiras. Queria somente ilustrar uma delas.



3 comentários:

  1. Olá Aleksandro! Obrigado por compartilhar isto, muito legal o seu exemplo... e essa de colocar o consumo do web service pelo visual studio foi bem legal mesmo, muito didático...

    Também mantenho um blog sobre o Protheus e sei como é difícil manter uma frequencia de posts com essa correria que temos no nosso dia a dia. Parabéns e obrigado!

    Até mais Aleksandro!

    George
    www.userfunction.com.br

    ResponderExcluir
  2. Muito bom, lendo o seu tutorial, consegui fazer todas as configurações no protheus e no c# em menos de uma hora. Basta agora, habilitar um ip e uma porta externa e pronto, ficará aberto para todas as aplicações consumirem! Muito Obrigado, continue postando (y)

    ResponderExcluir
  3. Muito bom, lendo o seu post, consegui configurar o protheus e VS + c# em 1 hora.
    Realmente funciona como o esperado. Parabéns, continue postando material com essa qualidade! www.consultaadvpl.com.br

    ResponderExcluir