Fala galera!
Uma das coisa mais interessantes de se aprender durante o desenvolvimento de algumas rotinas em ADVPL, é o uso de classes. Confesso que para mim isso é um pouco recente, mas estou aplicando sempre que possível em meus fontes.
Com o uso de classes, você tem a possibilidade de reduzir as linhas código do seu fonte, evitar repetição de funções e centralizar uma atividade específica em um único arquivo.
Para ficar melhor exemplificado, vou passar à vocês uma forma que utilizei para simplificar/facilitar o processo de envio de emails (worflow) do Protheus. Anteriormente em nossa base havia um fonte onde possuía uma função de usuário que era chamada sempre que fosse necessário enviar os e-mails, ou seja,  em meio ao meu código fonte - caso eu precisasse enviar e-mail - chamaria a função desta forma:
user function envioMail(cMsg, cDe, cPara, cAssunto) local cCc := "" local cBcc := "" local cAnexo := "" local cTitulo := "" cEnvMail := u_EnvMail( cDe,; //cDe - origem cPara,; //cPara cCc,; //cCc cBcc,; //cBCC cAssunto,; //cTitulo cAssunto,; //cAssunto cAnexo,; //cAnexo cMsg) //cMsg return
A função envioMail() é do fonte que estou desenvolvendo e para enviar o e-mail, preciso "chamar" a outra função (outro fonte/arquivo) chamado u_EnvMail() definindo todos os parâmetros.
Tudo bem! Desta forma é funcional, mas nosso objetivo é tornar o acesso a atividade de envio de e-mail através de uma classe, onde poderíamos - futuramente - trabalhar com objetos e configurar outras funções para nossa classe.
Vamos aos códigos!
Primeiramente vamos adicionar um novo arquivo ao projeto e salvá-lo com o nome ClassMail e adicionaremos o código abaixo:
class ClassMail
      //dados de conexão com o server
      data cServer    //Nome do servidor de envio de e-mail
      data cEmail     //Conta a ser utilizada no envio de e-mail
      data cEmailA    //Usuário para autenticação no servidor de e-mail
      data cPass      //Senha para autenticação no servidor de e-mail
      data lAuth      //Verifica se servidor necessita de autenticação
      data lResulConn //Flag de conexão com o servidor
      data lResulSend //Flag de sucesso de envio de e-mail
      data cError     //Mensagem de erro
      //variáveis para envio do email
      data cDe      //E-mail de origem
      data cPara    //E-mail de destino
      data cCc      //E-mail de cópia
      data cBcc     //E-mail de cópia oculta
      data cTitulo  //Título do e-mail
      data cAssunto //Assunto do e-mail
      data cAnexo   //Arquivo que será anexado
      data cMsg     //Mensagem/Conteúdo do e-mail
      //metodo construtor da classe com as variáveis que são enviadas por parâmetro
      method new(cDe, cPara, cCc, cBcc, cTitulo, cAssunto, cAnexo, cMsg) CONSTRUCTOR
      //método de validação dos dados recebidos
      method valDados()
      //método de validação de conexão com o servidor de envio de e-mail
      method valConn()
      //método responsável para efetuar o envio do e-mail
      method sendMail()
endClass
Nesse primeiro ponto, temos a definição das variáveis e métodos de nossa classe. Temos as variáveis responsáveis para efetuar, autorizar e obter o retorno de conexão com o servidor de e-mails e as variáveis que receberemos por parâmetro através do método construtor da nossa classe. depois temos os métodos da classe que utilizaremos durante a execução como validação de dados, conexão e o envio de e-mail.
Em nosso método construtor, vamos receber os dados e atribuir as variáveis da nossa classe. Observe que, quando for referenciar uma variável da classe deve-se utilizar o '::' na frente dela, ou seja, seria algo como ::cEmail. É importante também adicionar ao final do método o nome da classe.
Os métodos podem e devem obter um retorno, somente o tipo do conteúdo/variável que será retornado dependendo da sua aplicação. Veja que em nosso método construtor, não há necessidade retorno, então inserimos a palavra reservada self.
method new(cDe, cPara, cCc, cBcc, cTitulo, cAssunto, cAnexo, cMsg) class ClassMail ::cDe := cDe ::cPara := cPara ::cCc := cCc ::cBcc := cBcc ::cTitulo := cTitulo ::cAssunto := cAssunto ::cAnexo := cAnexo ::cMsg := cMsg return self
Agora vamos aplicar a validação dos dados principais de nossa classe. através do método valDados() Não é possível enviar um e-mail sem um e-mail de origem, destino e assunto - ou qualquer outro campo que você desejar.
method valDados() class ClassMail
local lRet := .T.
if empty(::cDe) .or. empty(::cPara) .or. empty(::cAssunto)
 msgAlert("Os campos 'De','Para' ou 'Assunto' devem ser preenchidos corretamente!","ERRO")
 lRet := .F.
endIf
return lRet
Precisamos agora do método responsável por efetuar a conexão com o servidor de e-mails e, para isso, vamos definir outro método nomeado valConn().
method valConn() class ClassMail
local lRet := .T.
::cServer := allTrim(getMv("MV_RELSERV")) //Nome do servidor de envio de e-mail
::cEmail  := allTrim(getMv("MV_RELACNT")) //Conta a ser utilizada no envio de e-mail
::cEmailA := allTrim(getMv("MV_RELAUSR")) //Usuário para autenticação no servidor de e-mail
::cPass   := allTrim(getMv("MV_RELAPSW")) //Senha para autenticação no servidor de e-mail
::lAuth   := getMv("MV_RELAUTH") //Verifica se servidor necessita de autenticação
if (empty(::cServer) .or. empty(::cEmail) .or. empty(::cEmailA) .or. empty(::cPass)) .and. ::valDados()
 msgAlert("Não foi possível obter os dados dos parâmetros de envio de e-mail do Protheus!","Erro envio de e-mail")
 lRet := .F.
else
 //Efetua a conexão com o servidor
 CONNECT SMTP SERVER ::cServer ACCOUNT ::cEmail PASSWORD ::cPass RESULT ::lResulConn
 //se necessita a autenticação do servidor
 if ::lAuth
  lOk := MailAuth(::cEmailA, ::cPass)
  if !lOk
   lOk := QAGetMail()
  endIf
 endIf
 if !::lResulConn
  get MAIL ERROR ::cError
  msgAlert("Falha na conexão: " + ::cError,"Erro - Problema de conexão")
  lRet := .F.
 endIf
endIf
return lRet
Depois desses métodos desenvolvidos precisamos fazer o envio do e-mail. Então o método sendMail() fará isso para nós.
method sendMail() class ClassMail
//se as validações (conexão e dados) estiverem ok. Efetua o envio do e-mail
if ::valConn() .and. ::valDados()
 SEND MAIL from ::cDe;
  to         ::cPara;
  CC         ::cCc;
  BCC        ::cBcc;
  SUBJECT    ::cAssunto;
  BODY       ::cMsg;
  ATTACHMENT allTrim(::cAnexo);
  RESULT     ::lResulSend
 get MAIL ERROR ::cError
 if !::lResulSend
  msgAlert("Falha no envio do e-mail: " + ::cError,"Erro - E-mail não enviado")
 endif
 DISCONNECT SMTP SERVER
else
 msgInfo("Email não enviado!")
endIf
return self
Bom, com o intuito de evitar tentativa de conexão desnecessária, condicionaremos essa ação ao retorno dos métodos valConn() e valDados() - Note que, assim como as variáveis, os métodos devem ser tratados dentro da classe com '::'.
Assim que testarmos o nosso fonte e compilarmos, podemos substituir a chamada na função original onde precisamo enviar o email. Então ele ficará modificado da seguinte forma:
user function envioMail(cMsg, cDe, cPara, cAssunto)
local cCc := ""
local cBcc := ""
local cAnexo := ""
local cTitulo := ""
objMail := ClassMail():new(cDe, cPara, cCc, cBcc, cTitulo, cAssunto, cAnexo, cMsg)
objMail:sendMail()
return
Em nossa função de usuário teremos um objeto - objMail - que será uma instancia da nossa classe ClassMail() e passará em seu método construtor as informações para o envio do e-mail. Após isso, basta chamar o método sendMail(). 
Com o desenvolvimento de classes podemos incrementar nossas possibilidades de uso de funções e aplicações específicas do sistema, tornando mais fácil o desenvolvimento e manutenção do fonte. Claro que aqui foi dado um exemplo simples, mas é possível adicionar mais funcionalidades de acordo com o que precisar.
Até mais!
;)

 

 

Nenhum comentário:
Postar um comentário