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