Você está na página 1de 77

Workflow

Workflow

A automação de processos de negócio corresponde, em partes ou totalmente, às


informações, documentos ou tarefas que são passadas de uma pessoa à outra para
a realização de uma ação que é baseada em um conjunto de regras.

Através da implantação de uma ferramenta de Workflow nos processos críticos de


uma organização, estes tornam-se mais ágeis e seguros, evitando o travamento
operacional do complexo fluxo existente entre os processos.

Principais benefícios:
 Aumento da eficiência: automação de processos eliminam vários passos
desnecessários.
 Melhor controle dos processos: melhora do gerenciamento dos processos
através da padronização dos métodos de trabalho.
 Melhora nos serviços ao cliente: consistência nos processos leva a uma
maior previsibilidade e rapidez nos níveis de resposta ao cliente.
 Flexibilidade: controle sobre os processos através de uma ferramenta
permite uma rápida mudança nos fluxos de acordo com a necessidade.

A ferramenta de Workflow existente no Protheus 8 permite o rápido alcance dos


benefícios acima citados, além de:

 Forte rastreabilidade dos processos: pode-se saber a atual situação de


qualquer processo através da consulta da rastreabilidade.
 Transformação do sistema Protheus em ativo em vez de reativo: a
informação e a ação necessária a ser tomada é levada ao usuário e não o
contrário.
 Controle de time-out dos processos: os processos nunca ficam parados
por falta de resposta de uma pessoa.
 Qualquer processo existente pode ser automatizado através da
construção de um Workflow.

As ações a serem tomadas pelas pessoas em cobrança podem ser realizadas


através de quatro meios, evitando que um processo tenha seu ciclo interrompido
por falta de comunicação, são eles:

 e-mail: os processos são respondidos através de um cliente de e-mail


homologado.
 browser de internet: através do Internet Explorer, pode-se tomar a ação
pedida pelo processo.
 Protheus: através do recurso de Messenger do Protheus, pode-se tomar
a ação pedida pelo processo.
 Pontos de entrada: através de pontos de entradas existentes no sistema,
pode-se tomar a ação pedida pelo processo.

Fluxo operacional

2
           

3
Parâmetros

O Workflow faz uso de uma série de parâmetros que determinam a maneira como
ele se comportará perante alguns pontos estratégicos na execução dos fluxos de
processo. O acesso à janela de parâmetros está disponível na opção do menu do
configurador “Ambiente | Workflow | Parâmetros WF”

Correio
Opção Item Parâmetro Descrição
Conta Caixa de correio a ser
Caixa de utilizada pelo workflow para o
MV_WFMLBOX
correio envio e recebimento de
mensagens.
Envia figura do Recurso ainda não disponível.
html como anexo MV_WFIMAGE
da mensagem
Envia html no Selecionando esta opção, o
corpo da html passara a fazer parte do
MV_WFHTML
mensagem corpo da mensagem. O
Composição da
contrário, irá como anexo.
mensagem
Envio automático Após a criação do processo, o
MV_WFSNDAU workflow enviará a
mensagem imediatamente.
Usa Java Script No html, o Workflow
MV_WFJAVAS adicionará rotinas semi-
prontas em Java script.

4
Processos
Opção Item Parâmetro Descrição
Execução(ões) de Define a quantidade de
retorno(s) processos de retorno que
simultâneos de poderão ser executados por
processos. vez.
Esteja atento ao
número de licenças
Execução de disponíveis e à
MV_WFMAXJB
retornos capacidade de
processamento da
máquina. A
quantidade
influenciará na
performance do
servidor.
Reativar Caso esta opção seja
processos selecionada, ocorrerá erro na
automaticamente execução de retornos. O
Workflow reativará o
MV_WFREACT processo imediatamente para
ser executado de novo. Caso
Tratamento de contrário, será reativado
erros somente quando o
Scheduler for reiniciado.
Usar TRANSAÇAO Habilita o recurso de
na execução de transação com a finalidade de
funções de MV_WFTRANS conservar a integridade dos
“RETORNO” e dados em caso de falha de
“TIMEOUTs” execução.

5
Notificação
Opção Item Parâmetro Descrição
Endereço Endereço eletrônico do
administrador (es) do
sistema. Separe entre “;”
E-mail do (ponto-e-vírgula) caso deseje
MV_WFADMIN
administrador informar mais do que um
endereço. Exemplo:
Adm1@prov.com.br;
adm2@prov.com.br
Quando ocorrer Notificar por e-mail a lista de
erro ao executar endereços dos
funções MV_WFNF001 administradores sobre o erro
“Retorno” e ocorrido.
“Timeout”.
Ao reativar Notificar por e-mail a lista de
processos endereços dos
Enviar pendentes. administradores no momento
MV_WFNF002
notificação em que forem reativados os
processos que ocorreram
erro.
Ao receber Notificar por e-mail a lista de
mensagens não endereços dos
reconhecidas. MV_WFNF003 administradores sobre as
mensagens não reconhecidas
pelo Workflow.

6
Messenger
Opção Item Parâmetro Descrição
Caminho Arquivo executável do
MV_WFBROWS browser Internet que deverá
estar no path da estação.
Browser Servidor IP ou Nomed PIPE do
Internet servidor Protheus para uso
MV_WFBRWSR do serviço http. Adicione “:”
+ a porta, caso seja diferente
do padrão.
Caminho Diretório de trabalho do
serviço http. Verifique o
identificador “Path=” na
Diretório HTTP MV_WFDHTTP
seção “[HTTP]” do arquivo
mp8Srv.ini para obter o
diretório de trabalho.
Habilitar Messenger O messenger será executado
automaticamente. automaticamente no próximo
Habilitar MV_WFMESSE
(próximo logon) login de qualquer ambiente
Protheus.

7
Configuração

1. Requisitos
Software: o Workflow, que é uma ferramenta embutida dentro do Server
do Protheus, não necessita de instalação própria, apenas configurações.
Toda configuração se dá através do ambiente Configurador do Protheus.

Servidor de e-mail (quando necessário para os processos): o


Workflow necessita obter acesso a algum servidor de e-mail, caso se deseje
utilizar e-mails como forma de comunicação. Esse servidor pode estar em
um provedor remoto, acessado através de um proxy server ou através de
uma linha discada (totalmente não recomendável), caso se queira enviar e-
mails para fora da sua empresa. Se a troca de e-mails for interna, poderá
ser utilizado um Exchange Server, Lotus Domino Server ou outro servidor de
e-mail interno. O único requisito imprescindível é que esses servidores
trabalhem com protocolos SMTP e POP3 ou IMAPI.

Conta de e-mail: caso utilize-se a opção de e-mail, o Workflow necessita


que seja criada uma conta de e-mail especificamente para ele. Isto é, não
poderá ser utilizada para mais nenhum fim. Para cada empresa do sistema,
deverá ser criada uma conta específica. Peça para o seu provedor criar esta
nova conta. Sugerimos com o nome da conta Workflow.

Exemplo: workflow@suaempresa.com.br

Clientes de e-mail: para recebimento dos e-mails gerados a partir do


Workflow, são utilizados os clientes de e-mails que devem ser aptos a
responder os e-mails gerados pelo Workflow, gerando arquivos de retorno
chamados octetos.

Para saber se o cliente de e-mail é compatível com o Workflow, ele deverá


automaticamente gerar um e-mail de saída enviado para a conta do
Workflow com um arquivo do tipo postdata atachado, quando houver a
resposta do e-mail pelo usuário.

Os seguintes clientes de e-mail funcionam com o Workflow: OutLook Express


4.01, OutLook Express 5.5x, OutLook Express 6.0 e OutLook 2000 e XP,
Lotus Notes 5.x. Outros clientes de e-mail podem não funcionar,
principalmente os webmails. Portanto, garanta que as pessoas que irão
receber e responder os e-mails tenham os clientes acima instalados em suas
estações. Quando não houver a certeza de que todos conseguirão responder
os e-mails e possuir os clientes de e-mail homologados, use a opção de
Workflow sem uso de e-mails, conforme será descrito nesta apostila. As
opções de execução de Java Script e Cookies deverão estar liberadas.

Servidor do Protheus: é necessário que o Workflow execute em um Server


do Protheus exclusivo para ele, ou seja, deve haver um binário somente
para o Workflow.

Memória do servidor: o servidor no qual será executado o Workflow deve


possuir memória suficiente para que se processem vários retornos ao
mesmo tempo. O mínimo recomendado é de 512 MB de memória RAM para
processar cinco retornos por vez. Um número maior do que isso,
provavelmente necessitará de mais memória.

8
2. Correio Eletrônico

2.1. Protocolo
O Workflow faz uso do recurso de envio e recebimento de mensagens
eletrônicas (e-mails). Para que esse procedimento seja possível,
devemos configurar que tipo de protocolo de recebimento o Protheus
deverá usar.

Se omitido, o padrão assumido será POP3. Caso necessite mudar,


localize a seção “[Mail]” no arquivo mp8srv.ini e altere para o protocolo
utilizado.

Protocolos atualmente homologados:

 POP3

 IMAP

Exemplo:

[Mail]

Protocol=IMAP

Folder=inbox

Atenção: O protocolo MAPI não é suportado pelo Protheus.

2.2. Contas de e-mail


Através do cadastro de contas de e-mails, é possível realizar o envio e
recebimentos de mensagens. Para acessar o cadastro de e-mails,
selecione a seguinte opção de menu do configurador:

9
Após a realização do cadastro de uma conta de e-mail, é possível realizar
algumas operações extras como:

 Enviar: esta opção executará o envio de todas as mensagens


contidas na pasta outbox (caixa de saída).

 Enviar Todos: esta opção realizará a mesma operação do item


anterior; entretanto, efetuará o envio de todas as mensagens
para todas as contas cadastradas.

 Receber: esta opção executará o recebimento de todas as


mensagens contidas no servidor de e-mail especificado no
cadastro para a pasta inbox (caixa de entrada).

 Receber todos: esta opção realizará a mesma operação do


item anterior. Contudo, realizará para todas as contas
cadastradas.

10
2.3. Cadastrar a conta de e-mail do Workflow
Para cada empresa do Protheus, deverá existir uma conta exclusiva para uso
do Workflow.
A seguir, veremos quais campos necessários deverão fazer parte do
preenchimento do cadastro.

Caixa de Correio
Opção Item Descrição
Correio Nome da caixa de correio. Esse
nome será usado para criar a pasta,
em que serão identificadas as
mensagens pertinentes a cada conta.
Correio Tempo Espera Tempo máximo (em segundos) de
espera para conexão com o servidor
de e-mails, tanto no envio como
recebimento de mensagens. O
tempo padrão é 60 segundos.
Nome Nome do remetente da mensagem.
Remetente
Endereço Endereço eletrônico.

Incluir esta conta ao Esta opção habilita o uso da conta


Habilitar
enviar e receber e-mails para enviar e receber mensagem.

11
Receber mensagens
Opção Item Descrição
Nome IP ou Named Pipe do servidor. Será
exibido conforme o tipo utilizado na
Servidor (POP3 seção “[Mail]” no arquivo
ou IMAP) mp8srv.ini
Porta Porta de acesso dependendo do tipo.
POP3 = 110; IMAP = 143 (defaults).
Conta Nome da conta.
Login
Senha Senha de acesso à conta.

12
Enviar mensagens
Opção Item Descrição
Nome
IP ou Named Pipe do servidor SMTP.
Servidor SMTP
Porta
Porta de acesso. Valor padrão: 25.
Usuário Nome do usuário para autenticação.
Alguns servidores exigem esta
Autenticação
informação para envio de e-mails.
Senha Senha de acesso para autenticação.

* Os campos para autenticação de envio somente deverão ser preenchidos


caso sejam obrigatórios, conforme a regra de segurança estabelecida pela
empresa. Consulte o administrador do servidor de mensagens para obter as
informações necessárias para os preenchimentos dos campos “Usuário” e “Senha”.

13
Conexão
Opção Item Descrição
LAN Utiliza a conexão já estabelecida pelo
usuário em uma intranet.
Tipo DIAL-Up Utiliza o recurso de discagem através
de uma linha telefônica (não
recomendável). Somente funciona
em estações e servidores Windows.
*Conexões Lista de conexões disponíveis do tipo
Dial-up, obtidas a partir do cadastro
de conexões dial-up criado
previamente no Microsoft Windows.
Conta Nome da conta (usuário) de acesso
Discagem ao provedor internet.
Senha Senha de acesso à conta no
provedor.
Telefone Número da linha de acesso ao
provedor internet.

* Os campos Conta, Senha e Telefone são obtidos automaticamente a partir da


seleção da lista de conexões disponíveis no campo “Conexões:”. Esses campos
são meramente informativos, já que foram obtidos através da conexão criada
previamente no Windows. Veja no manual do Microsoft Windows como criar
conexões dial-up.

14
Estrutura de diretório de mensagens
A partir da versão 8.11, a estrutura de diretórios de armazenamento de mensagens
mudou. A pasta “Workflow” passou a ser o “Root” por questões de organização
de acesso aos respectivos arquivos de controle e mensagens a cada empresa.

Estrutura de diretórios
Pastas Descrição
Pasta principal da estrutura de diretórios do
Workflow. Esta pasta é útil para armazenar os html
e arquivos comuns entre as empresas.
Pasta individual de trabalho para cada empresa.

Esta pasta contém a estrutura de


diretórios para uso exclusivo de
Mail armazenamento de mensagens
enviadas e recebidas para cada caixa
de correio existente.
Contém arquivos de controle criados
Process pelo Workflow para gerar e manipular
processos.
Tasks Contém temporariamente arquivos de
agendamento de rotinas utilizados
para serem inseridos dentro da tabela
SXM (scheduler).

15
Temp Diretório temporário de trabalho.
A partir da pasta Mail, serão criadas todas as caixas
de correio existentes no cadastro de contas de
correio do Workflow.
Esta pasta foi criada exclusivamente
para uso da caixa de correio do
Workflow. Todas as mensagens que
Archive não sejam relacionadas aos processos
de Workflow, serão armazenadas
nesta pasta.
Ex: Spam.
Esta pasta foi criada exclusivamente
para uso da caixa de correio do
Workflow. As mensagens recebidas e
Ignored
já identificadas anteriormente serão
armazenadas nessa pasta (mensagens
recebidas em duplicidade)
Esta é uma pasta comum entre as
caixas de correio existentes. Ela é
Inbox
responsável pelo armazenamento de
mensagens recebidas.
Esta é uma pasta comum entre as
caixas de correio existentes, sendo
responsável pelo armazenamento de
Outbox mensagens que deverão ser enviadas.
Caso ocorra erro durante o envio das
mensagens, elas serão armazenadas
na sub-pasta “Erro”.
Esta é uma pasta comum entre as
caixas de correio existentes, sendo
Sent
responsável pelo armazenamento das
mensagens enviadas.

16
3. Scheduler

O Scheduler (agenda) é uma ferramenta responsável pela execução das


funções de usuários ou funções padronizadas do sistema (chamaremos de
Jobs), em determinados horários específicos entre um intervalo de tempo,
sem que haja a intervenção do usuário. Para que essa ferramenta esteja
habilitada a realizar execuções dos jobs, é necessário que ela esteja ativada
no servidor do Protheus.

3.1. Ativação

Para que os jobs sejam executados nos horários pré-determinados, é


importante que após a carga do servidor do Protheus, o Scheduler seja
executado. Dessa forma, ele poderá verificar a cada minuto se há jobs a
serem executados.

Essa ativação ocorre a partir do recurso disponível na seção “[OnStart]”


contido no arquivo mp8srv.ini. Exemplo a ser adicionado ao arquivo
MP8SRV.INI:

[ONSTART]
Jobs=Scheduler

[Scheduler]
Main=WFONSTART
Environment=EnvTOP

A função “WFOnStart” é responsável pela carga inicial do Scheduler e


requer informações contidas no arquivo auxiliar chamado
“Scheduler.wf”, localizado no diretório system do Protheus. O conteúdo
desse arquivo servirá para obter a lista de parâmetros necessária para
executar o Scheduler.

Caso o arquivo não exista, será criado automaticamente com o seguinte


conteúdo padrão: 99,01,ENVTOP,T,MOD.

1. 99 – código da empresa.
2. 01 – código da filial.
3. ENVTOP – ambiente no qual será executado o Scheduler.
4. T – Valor lógico (True ou False). True, Indicará que realizará
reativação dos processos nas tabelas do Workflow.
5. MOD – Nome do ambiente do qual o Workflow obterá licenças.

A partir da versão 8.11 do Protheus, passou-se a aceitar os parâmetros


passados através da própria seção sem a necessidade de utilizar o
arquivo auxiliar “Scheduler.wf”, apenas acrescentando as seguintes
linhas:

17
Exemplo:
[Scheduler]
Main=WFOnStart
Environment=ENVTOP
nParams=5
Parm1=99
Parm2=01
Parm3=ENVTOP
Parm4=T
Parm5=TMK

3.2. Agendando

Através do configurador, é possível acessar a janela de cadastro de jobs


a serem executados pelo Scheduler. Basta que se selecione a opção de
menu correspondente à figura abaixo:

Selecione: “Processos Especiais”.

18
Janela de cadastro de jobs

19
Scheduler – Processos Especiais
Agrupamento Campos Descrição
Código Código único identificador do job.
Identificação Nome Nome simplificado.
Descrição Descrição do job.
Diária Executa diariamente entre os horários inicial e
final a cada intervalo de tempo.
Semanal Executa nos dias selecionados da semana
(domingo, segunda, terça, quarta, quinta, sexta
Freqüência e sábado), entre os horários inicial e final a cada
intervalo de tempo.
Mensal Executa nos meses selecionados do ano (janeiro
a dezembro), entre os horários inicial e final a
cada intervalo de tempo.
Data Início Data inicial que passará a vigorar a execução.
Período Inicial
Hora Início Horário inicial de execução.
Data final Dia limite de execução.
Período Final
Hora final Horário limite de execução.
Intervalo Intervalo de tempo a cada execução entre o
Período
horário inicial e final.
Ação Função de usuário ou função interna do Protheus
a ser executado. Os parâmetros passados para
Job
esta função deverão ser sempre tratados como
um array.
Environment Ambiente Ambiente em que o job será executado.

3.3. Agendar recebimento de mensagens do Workflow

Para que o Workflow possa receber as mensagens e executar os retornos


de processos, é necessário cadastrar no Scheduler a função
WFReturn(“Código_Empresa”, ”Código_Filial”).

A função “WFReturn” é responsável por:

 baixar (download) todas as mensagens contidas na caixa postal


de mensagens do correio eletrônico do Workflow e gravar na
pasta “Inbox” (veja acima ”estrutura de diretórios” para
melhor esclarecimento);

 separar as mensagens reconhecidas (retornos de aprovação etc.)


pelo Workflow e mover para a pasta “Process”;

 separar as mensagens não reconhecidas (spam etc.) pelo


Workflow e mover para a pasta “Archive”. Em seguida, notificar
à lista de e-mails de administradores informados no cadastro de
parâmetros do Workflow;

 executar cada um dos retornos de processos.

Exemplo:

WFReturn( “99”, “01” )

20
3.4. Agendar envio de mensagens do Workflow

Apesar de ter a opção “Enviar Automaticamente” disponível no cadastro


de parâmetros do Workflow, é importante saber que nem sempre é possível
enviar as mensagens em um determinado momento. Poderão ocorrer alguns
problemas que podem acarretar fila de espera e, com isso, crescerá o
número de processos parados. Entre os problemas mais comuns está a
perda da comunicação com o servidor de e-mail.

Para evitar tais problemas, é interessante agendar a função WFSendMail


(“Código_Empresa”, “Código_Filial”) da mesma forma que a função
“WFReturn”. Assim, haverá a garantia de que a qualquer momento as
mensagens que, eventualmente, tenham ficado na fila de espera serão
enviadas.

A função “WFSendMail” é responsável por:

 enviar cada uma das mensagens contidas na pasta “Outbox”


(caixa de saída);

 mover para a pasta “Sent” (itens enviados) as mensagens que


foram enviadas com sucesso;

 mover para a pasta “Outbox\Error” as mensagens que tiveram


problemas durante o envio. Caso queira reenviá-las, basta movê-
las para a pasta “Outbox” (caixa de saída).

Exemplo:

WFSendMail( “99”, “01” )

21
Requisitos para Desenvolvimento

Para construir um processo de Workflow que automatize de forma correta, são


necessários quatro requisitos fundamentais:

1. conhecer o sistema de ERP como um todo, inclusive tecnicamente. Isso


corresponde a conhecer todos os recursos de configuração e
programação do Protheus, bem como suas tabelas e respectivos
relacionamentos;

2. saber programar em linguagem ADVPL, nível avançado, com


conhecimento em objetos e classes;

3. conhecimento em linguagem HTML, para construção de páginas, além de


saber programar em Java Script, para refinamento e validação das
páginas;

4. software e hardware necessários.

Cadastros

Além dos cadastros de parâmetros do Workflow e de e-mails, já mostrados


anteriormente, existem outros cadastros que auxiliam no processo do Workflow que
serão aqui descritos.

1. Processos Workflow

O cadastro de processos do Workflow, apesar de não ser obrigatório, tem a


importância de “amarrar” a seqüência de passos de um fluxo de processo para
ser visualizado a partir da janela de consulta da rastreabilidade.

Exemplo de processos a serem cadastrados:

 Aprovação de solicitação de compras.

 Aprovação de pedido de compras.

 Cotação de preços.

 Liberação de crédito.

Esse cadastro encontra-se no ambiente Configurador. Observe as telas:

22
23
Cadastro de Processos
Agrupamento Campos Descrição
Código Código único identificador.
Codificação
Nome Nome do processo.
Tabelas Especificações das tabelas utilizadas para
Informativo
execução do processo.
Pesquisa Pesquisa Código da pesquisa padrão utilizada para
genérica Padrão localizar um determinado processo.
Arquivo .vsd Arquivo visio document (fluxo do processo
Visio
desenhado a partir do Microsoft Visio).

2. Status Workflow

O cadastro de Status é o complemento do cadastro de processo. Através dele,


determina-se cada etapa que se realizará em um fluxo de processo, sendo
muito útil para determinar pontos de rastreabilidade dentro de um grande
processo.

24
25
Cadastro de Status
Agrupamento Campos Descrição
Cód
Código do processo.
Processo
Cód Status Código do status de processo. Esse código deve
Codificação ser um valor numérico acima de 999. A faixa de
valores entre 0 e 999 está reservada ao
Workflow.
Descrição Descrição do Status do processo.
Tempo Tempo médio de execução deste status. Este
Informativo
médio tempo é calculado pelo sistema.

26
3. E-mails substitutos

O cadastro de e-mails substitutos é um recurso disponível no Workflow que tem


por finalidade delegar para um outro endereço eletrônico todas as mensagens
dirigidas a um determinado participante por um período de tempo estipulado.
Esse recurso é importante quando se tratar de eventuais problemas em que um
dos participantes do fluxo do processo permaneça ausente por motivos diversos
(férias, afastamento etc.).

27
Cadastro de e-mails substitutos
Agrupamento Campos Descrição
Do e-mail Endereço eletrônico do participante que
Endereço permanecerá ausente por um período de tempo.
eletrônico Para o e- Endereço eletrônico do participante que ficará
mail responsável por receber as mensagens.
Data início Data inicial em que passará a vigorar a
substituição dos e-mails.
Período
Data final Data final do período.
Dias Cálculo de dias entre a data inicial e final.

28
Html – Modelo Workflow

O Workflow faz uso de formulários html para realizar interações entre o(s)
participante(s) e o sistema ERP. Além de informá-los, é possível responder
determinadas requisições através do recurso “Post message” oferecido pelos
navegadores internet. Os formulários desenhados e utilizados para interagir com os
participantes, são denominados modelos (templates) e deverão estar disponíveis
em algum diretório abaixo do rootpath do Protheus. Ao ser utilizado algum desses
modelos nos processos de Workflow, apenas a cópia do modelo será modificado. É
necessário bons conhecimentos de programação HTML e Java Script para a
construção de páginas no Workflow.

1. Post message

O recurso “Post message”, nas páginas html a partir dos navegadores internet,
permite que as respostas sejam enviadas ao Workflow via correio eletrônico (e-
mail) ou serviço http. Para que isso seja possível é necessário incluir o tag
<form action=”mailto:%WFMailTo%” method=”post”> nos formulários
html.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
<title>Aprovação de Pedido de Compra</title>
</head>
<body bgcolor="#FFFFFF">
<form action="mailto:%WFMailTo%" method="POST" name ="FormPedComp">
...
</form>
</body>
</html>

29
2. Macro substituição

Esta rotina consiste na substituição de todas as palavras encontradas nos


formulários html que estiverem entre “%” ou “!”. Essa palavra-chave terá seu
conteúdo modificado por outra informação durante a execução do processo.

Observe um formulário modelo de aprovação de pedido de compras com suas


respectivas palavras-chaves (macros):

%macro% - Toda palavra encontrada entre este sinal (%), além da


substituição do conteúdo por outra informação, também haverá a necessidade
de incluir no formulário (cópia do modelo) as linhas de tags <input
type=hidden...> para cada palavra-chave (macro) encontrada.

Exemplo:

<input type=hidden name="EMISSAO" value="01/04/05">


<input type=hidden name="FORNECEDOR" value="100100">
<input type=hidden name="LB_NOME" value="RM SUPRIMENTOS INFO LTDA">
<input type=hidden name="LB_COND" value="30D">
<input type=hidden name="PEDIDO" value="000003">

É importante saber que o uso desse símbolo é necessário somente para campos
editáveis que esperam modificações de seus conteúdos e que serão tratados no
retorno das mensagens. Use este símbolo nos controles do tipo TextField,
TextArea, Radio Button, Combo Box e Check Box.

TextField:
<input type="text" size="13" name="T7" value=%quantidade%>

TextArea:

30
<textarea name="S1" rows="4" cols="74">%observacao%</textarea>
Radio Button:
<input type="radio" checked name="%aprovacao%" value="Sim">Sim.
<br>
<input type="radio" name="%aprovacao%" value="Nao">Não.

Combo Box:
<select name="list" size="1"><option selected>%itens%</option>
</select>

Check Box:
<input type="checkbox" name="checkbox" value="%item1%">Item 1

!macro! – Toda palavra encontrada entre este sinal (!) terá somente seu
conteúdo substituído. Não será incluído <input hidden...> no html para essas
palavras-chaves. Utilize-o em texto fixo.

Exemplo: títulos, mensagens, cabeçalhos e rodapés.

3. Tabelas

As tabelas são identificadas pelo Workflow através do nome que precede o


ponto (.) nas palavras-chaves. Contudo, essas palavras-chaves devem
realmente pertencer a uma tabela (tag <table>...</table>) do formulário html.

Veja em itens do html da aprovação do pedido de compras que há algumas


palavras-chaves com o nome precedido da palavra “produto.”. Neste caso, o
Workflow irá referir-se a essa tabela pelo nome de “produto” (sem o ponto).
Poderá conter várias tabelas em um html que o Workflow saberá identificar
através do nome.

31
Criando um processo em ADVPL - Funções

Não existem processos de Workflow nativos dentro do Protheus, sendo necessária a


construção de acordo com a necessidade.

Um processo de Workflow poderá ser iniciado a partir de uma destas opções:


 pontos de entrada;
 item de menu de qualquer ambiente;
 job agendado através do Scheduler;
 manualmente através do remote.

A opção mais utilizada é o ponto de entrada. Se for realizado um pedido de


compras, por exemplo, automaticamente é gerada uma aprovação para os itens do
pedido e enviado para um aprovador. Qualquer ponto de entrada do sistema pode
ser utilizado.

Para ser iniciado o processo em qualquer das opções escolhidas, será necessário
fazer uso do código fonte Advpl para determinar a forma como irá proceder a
execução do fluxo do processo.

Na maior parte, o Workflow baseia-se, no uso de classes referenciadas aos objetos,


que se tornam a ponte de acesso para uso de seus métodos e propriedades. A
principal classe do Workflow é a “TWFProcess”, o que veremos a seguir (é
necessário conhecimento de programação orientada a objetos).

Classe TWFProcess

A classe TWFProcess é responsável pela criação e gerenciamento do processo.


Como toda classe, a TWFProcess é dividida em métodos e propriedades. Veremos
alguns dos principais métodos e propriedades que iremos usar para criação de um
processo.

Métodos
:New(<cCodProc>,<cDescr>,<cProcID>)
O método New() é responsável pela criação e inicialização da classe WFProcess.
Parâmetros:
1. cCodProc: este parâmetro recebe o código do processo usado em “Cadastro
de Processos”.
2. cDescr: este parâmetro recebe a descrição do processo que está sendo
criado no momento. Se não for informado, será usada a descrição contida no
cadastro de processo, localizada através do parâmetro anterior cCodProc.
3. cProcID: este parâmetro recebe o ID do processo criado anteriormente.
Normalmente, é utilizado para reconstruir um processo anterior, dando
seqüência a ele.
Exemplo:
oP := TWFProcess():New("PEDCOM","Aprovacao do Pedido de Compras")

32
:NewTask(<cDescr>,<cArqHtml>,<lCopiar>)
Este método é responsável por criar a seqüência de tarefas a serem executadas
e identificar qual html será utilizado pelo processo.
Parâmetros:
1. cDescr: este parâmetro recebe a descrição da tarefa.
2. cArqHtml: recebe o caminho e o nome do arquivo html que fará uso no
processo.
3. lCopiar: este parâmetro, do tipo lógico, é responsável por copiar todos os
campos utilizados em uma tarefa anterior, ou seja, para a tarefa que está
sendo criada no momento.
Exemplo:
oP:NewTask("Criando Aprovacao", "\Workflow\WFW120p.htm" )

:AttachFile(<cArquivo>)
Este método é responsável pela inclusão de arquivos anexos à mensagem.
Esses arquivos deverão estar abaixo do root path do Protheus.
Parâmetros:
1. cArquivo: caminho e nome do arquivo a ser anexo à mensagem.
Exemplo:
oP:AttachFile(“\Workflow\teste.txt”)

:Start(<cHtmlCopiarPara>) -> cProcessKey


Este método é responsável por construir todo o processo, gravar os registros
nas tabelas do Workflow e enviar a mensagem para os destinatários. O valor de
retorno é uma chave composta pela codificação ProcessID + TaskID e números
aleatórios, no total de 17 algarismos em hexadecimal.
Parâmetros:
1. cHtmlCopiarPara: Caminho em que o Workflow deverá realizar uma cópia
do html final.
Exemplo:
cID := oP:Start(“\Workflow\copia”)
if file( “\Workflow\copia\” + cID)
conout(“Arquivo copiado com sucesso.”)
endif

:Finish()
Este método é responsável por finalizar o processo. Após a finalização, ele não
estará mais disponível para execuções do tipo retorno e timeout.
Exemplo:
oP:Finish()

:Track(<cCodStatus>,<cDescr>,<cUsuario>)
Este método é responsável por incluir as descrições dos passos seguidos pelo
fluxo do processo e apresentá-los na consulta da rastreabilidade.

33
Parâmetros:
1. cCodStatus: código do status do processo.
2. cDescr: descrição do passo ocorrido.
3. cUsuario: nome do usuário a que se destinou a tarefa.
Exemplo:
oP:Track(“100200”, “Enviando o pedido para aprovacao”, “AprovadorA”)

Propriedades
:cTo, :cCC e :cBCC
Estas propriedades definem o endereço dos destinatários. Poderá ser informado
mais que um destinatário ao mesmo tempo. Basta incluir um ponto-e-vírgula “;”
entre eles. Se for informada uma palavra qualquer que não seja um endereço
de e-mail válido, o Workflow irá considerar que se trata de um diretório em que
o html gerado deverá ser gravado. Pode-se mesclar os tipos.
Exemplo:
oP:cTo := “aluno1@microsiga.com.br;aluno2@microsiga.com.br”
oP:cCC := “aluno3@microsiga.com.br;Aluno”
oP:cBCC := “aluno4@microsiga.com.br”

:cSubject
Esta propriedade define o assunto da mensagem.
Exemplo:
oP:cSubject := “Aprovado do pedido de compras no. 1028”

:cBody
Esta propriedade armazenará um texto que permanecerá no corpo da
mensagem. Caso seja utilizado, o html irá como anexo da mensagem.
Exemplo:
oP:cBody := “Testando...”

:bReturn
Esta propriedade contém o nome da função que será executada no momento
em que o Workflow receber a mensagem de resposta de um dos destinatários
via e-mail ou serviço http.

Exemplo:
oP:bReturn := “U_Retorno”

:bTimeOut
Esta propriedade recebe um array de timeouts contendo nomes das funções e
tempo de espera. Caso o tempo seja alcançado, serão executadas as funções
mencionadas no 1º item do array. Poderão ser especificados mais do que um
array de timeouts.

{ { <cFuncao>, <nDias>, <nHoras>, <nMinutos> }, { ... } }

34
Exemplo:
oP:bTimeOut := { { “TimeOut1”, 0, 5, 30 } }
ou
oP:bTimeOut := { { “TimeOut1”, 0, 5, 30 }, { “TimeOut2”, 1, 10, 0 } }

:fProcessID
Esta propriedade fornece o número ID do processo.

Exemplo:
cProcID := oP:fProcessID

:fTaskID
Esta propriedade fornece o número ID da tarefa criada para um determinado
processo, através do método :NewTask().

Exemplo:
oP:NewTask( "100100", "\Workflow\WFW120p.htm" )
cTaskID := oP:fTaskID

:oHTML
Esta propriedade é responsável pelo tratamento das palavras-chaves no html
mencionado no método :NewTask(). Esse objeto é uma referência da classe
TWFHtml() e disponibiliza dois dos métodos mais importantes :RetByName() e
ValByName().

:oHTML:RetByName( <cNome da macro> )


Esta propriedade tem como objetivo obter o conteúdo da “macro” quando as
respostas retornarem para o Workflow. O método somente deverá ser usado na
função de retorno.

Exemplo:
cNome := oP:oHtml:RetByName( “Nome” )

Em uma tabela:
aCodigo := oP:oHtml:RetByName( “produto.Codigo” )

:oHTML:ValByName(<cMacro>,<uConteudo>)
Este método tem como objetivo atribuir ou obter um valor a uma “macro”
existente no html. Deverá ser usado somente no momento em que estiver
assinalando valores ao html ou na função de timeouts, em que o uso é
necessário por motivo de não haver recebido resposta.
Parâmetros:
1. cMacro: nome da macro (palavra-chave) encontrada no html e identificada
entre os símbolos “%” e “!”.

35
2. uConteudo: valor a ser atribuído à macro.
Exemplo:
Assinalando um valor:
oP:oHtml:ValByName( “Nome”, “Aluno1” )

Usando na função de timeout:


cNome := oP:oHtml:ValByName( “Nome” )

Atribuindo um valor a uma tabela:


AAdd( oP:oHtml:ValByName( “produto.codigo” ), SB1->SB1_COD )

36
Case – Atualização do preço de venda de produto

A partir do ponto de entrada (“MT010INC”) no cadastro de produtos, criaremos um


processo de Workflow que enviará um html via e-mail para um destinatário que
deverá atualizar o preço de venda do produto e, em seguida, enviar a resposta para
ser atualizada na base de dados do Protheus. Esse ponto de entrada será
executado após a inclusão de um novo produto.

Conforme os passos descritos abaixo, realizaremos um cadastro de processos e de


status para futuras pesquisas com o uso da rastreabilidade de processos.
Criaremos, também, um html e um arquivo de programa para descrevermos o fluxo
do processo em código Advpl, usando as classes e as funções de Workflow.

PASSO 1 – Criar novo campo no SB1

Crie um novo campo “B1_WFID” no SB1 para que possa ser gravado o ID do
processo de Workflow e ser utilizado em consultas na janela de rastreabilidade.

Definição do campo B1_WFID: tipo Caracter; tamanho 7; decimais 0

PASSO 2 – Pesquisa padrão SXB

Crie uma pesquisa SXB com o nome “WFSB1” que faça referência à tabela SB1 e
retorne o conteúdo do campo B1_WFID.

PASSO 3 - Cadastro de Processos

A partir do configurador, selecione a opção de menu “Ambiente | Workflow |


Processos Workflow” e crie um novo processo conforme o conteúdo dos campos
apresentados na tabela abaixo:

Código Descrição Pesq Padrão


ATUAPV ATUALIZACAO DO PRECO DE VENDA WFSB1 - Produto

PASSO 4 – Cadastro de Status

Ainda no configurador, selecione a opção de menu “Ambiente | Workflow |


Status Workflow” e cadastre alguns status para o processo mencionado,
conforme o conteúdo dos campos apresentados abaixo:

Cód Processo Cód Status Descrição


ATUAPV 100100 INICIANDO
ATUAPV 100200 GERANDO PROCESSO PARA ENVIO
ATUAPV 100300 ENVIANDO MENSAGEM
ATUAPV 100400 AGUARDANDO RETORNO
ATUAPV 100500 ATUALIZANDO PRECO DE VENDA
ATUAPV 100600 TIMEOUT
ATUAPV 100700 REENVIANDO A MENSAGEM
ATUAPV 100800 FINALIZANDO
ATUAPV 100900 ERRO DE EXECUÇÃO

37
PASSO 5 – Criar html modelo para o processo

Crie um html modelo, chamado ATUAPV.HTM, no diretório \WORKFLOW (abaixo do


rootpath) que será utilizado no e-mail para que o destinatário altere o valor do
preço de venda do produto e envie a resposta através do botão “Enviar”.

Código fonte:

<html><head><title>Atualização preco de venda</title>


<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body><form action="mailto:%WFMailTo%" method="post"
name="form1">
<table width="100%" height="130" border="1" bordercolor="#66CCFF" >
<tr bordercolor="#DFEFFF">
<td height="71" colspan="4" bgcolor="#DFEFFF">
<p align="center"><strong><font color="#3333FF" size="4" face="Verdana,
Arial, Helvetica, sans-serif">Atualiza&ccedil;&atilde;o do Pre&ccedil;o de
Venda</font></strong></p>
</td></tr><tr bordercolor="#66CCFF">
<td height="20" bgcolor="#DFEFFF">
<font size="1">C&oacute;digo:</font></td>
<td bgcolor="#DFEFFF"><font size="1">Descri&ccedil;&atilde;o:</font></td>
<td bgcolor="#DFEFFF"><font size="1">Pre&ccedil;o de venda R$:</font>
</td>
</tr>
<tr bordercolor="#66CCFF">
<td width="17%" height="28"><strong>!B1_COD!</strong></td>
<td width="53%">!B1_DESC!</td>

38
<td width="30%"><em><strong>
<input name="pvenda" type="math" id="pvenda"
value="%B1_PRV1%"></strong></em></td>
</tr>
</table><p>
<input type="submit" name="Submit" value="Enviar"></p>
</form>
</body>
</html>

PASSO 6 – Criar processo de Workflow a partir do ponto de entrada

No IDE, geraremos um arquivo de programa chamado ATUAPV.PRW onde será


criada a função representativa do ponto de entrada MT010INC, em que
descreveremos o fluxo do processo com o uso das classes e funções do Workflow.
Essa função (ponto de entrada) será executada a partir do momento em que for
pressionado o botão “OK”, na confirmação da inclusão dos dados do produto na
tabela SB1.

ATUAPV.PRW

#INCLUDE “PROTHEUS.CH”

/*
// MT010INC - Corresponde ao ponto de entrada do sistema que somente
// será executado na inclusão de novos produtos.
*/
User Function MT010INC(nOpcao,oProcess)

// Inicialmente, os parâmetros nOpcao e oProcess estarão com valores iguais a NIL.


// se nOpcao for NIL, terá o seu valor inicial igual a 0 (zero).
default nOpcao := 0

do case
case nOpcao == 0
U_APVInicio()
case nOpcao == 1
U_APVRetorno(oProcess)
case nOpcao == 2
U_APVTimeOut(oProcess)
endcase

Return

/*
// APVInicio - Esta função é responsável por iniciar a criação do processo e por
// enviar a mensagem para o destinatário.
*/
User Function APVInicio(oProcess)
Local nDias := 0, nHoras := 0, nMinutos := 10
Local cCodProcesso, cCodStatus, cHtmlModelo
Local cUsuarioProtheus, cCodProduto, cTexto, cAssunto

cCodProduto := SB1->B1_COD

// Código extraído do cadastro de processos.


cCodProcesso := "ATUAPV"

39
// Arquivo html template utilizado para montagem da aprovação
cHtmlModelo := "\Workflow\atuapv.htm"

// Assunto da mensagem
cAssunto := "Atualização do preço de venda"

// Registre o nome do usuário corrente que está criando o processo:


cUsuarioProtheus:= SubStr(cUsuario,7,15)

// Inicialize a classe TWFProcess e assinale a variável objeto oProcess:


oProcess := TWFProcess():New(cCodProcesso, cAssunto)

// Crie uma tarefa.


oProcess:NewTask(cTitulo, cHtmlModelo)

// Crie um texto que identifique as etapas do processo que foi realizado


// para futuras consultas na janela de rastreabilidade.
cTexto := "Iniciando a solicitação de " + cAssunto + " do produto: " + cCodProduto

// Informe o código de status correspondente a essa etapa.


cCodStatus := "100100" // Código do cadastro de status de processo.

// Repasse as informações para o método responsável pela rastreabilidade.


oProcess:Track(cCodStatus, cTexto, cUsuarioProtheus) // Rastreabilidade

// Adicione informacões a serem incluídas na rastreabilidade.


cTexto := "Gerando solicitação para envio..."
cCodStatus := "100200"
oProcess:Track(cCodStatus, cTexto, cUsuarioProtheus)

// Assinale novos valores às macros existentes no html:


oProcess:oHtml:ValByName("B1_COD", cCodProduto)
oProcess:oHtml:ValByName("B1_DESC", SB1->B1_DESC)
oProcess:oHtml:ValByName("B1_PRV1", SB1->B1_PRV1)

// Repasse o texto do assunto criado para a propriedade específica do processo.


oProcess:cSubject := cAssunto

// Informe o endereço eletrônico do destinatário.


oProcess:cTo := "bi@microsiga.com.br"

// Utilize a funcao WFCodUser para obter o código do usuário Protheus.


oProcess:UserSiga := WFCodUser("BI")

// Antes de assinalar o ID do processo no campo, é verificado se realmente o


// campo existe na tabela SB1.
If SB1->(FieldPos("B1_WFID")) > 0
If RecLock("SB1",.f.)
SB1->B1_WFID := oProcess:fProcessID
MsUnLock()
EndIf
EndIf

// Informe o nome da função de retorno a ser executada quando a mensagem de


// respostas retornar ao Workflow:
oProcess:bReturn := "U_MT010INC(1)"

40
// Informe o nome da função do tipo timeout que será executada se houver um
timeout
// ocorrido para esse processo. Neste exemplo, ela será executada cinco minutos
após o envio
// do e-mail para o destinatário. Caso queira-se aumentar ou diminuir o tempo,
altere
// os valores das variáveis: nDias, nHoras e nMinutos.
oProcess:bTimeOut := {"U_MT010INC(2)", nDias, nHoras, nMinutos}

// Adicione as informacões a serem incluídas na rastreabilidade


cTexto := "Enviando solicitação..."
cCodStatus := "100300"
oProcess:Track(cCodStatus, cTexto , cUsuarioProtheus)

// Após ter repassado todas as informacões necessárias para o Workflow,


// execute o método Start() para gerar todo o processo e enviar a mensagem
// ao destinatário.
oProcess:Start()

// Adicione as informacões a serem incluídas na rastreabilidade


cTexto := "Aguarde retorno..."
cCodStatus := "100400"
oProcess:Track(cCodStatus, cTexto , cUsuarioProtheus) // Rastreabilidade
Return

/*
// APVRetorno - Esta função é executada no retorno da mensagem enviada
// pelo destinatário. O Workflow recria o processo em que
// parou anteriormente na função APVInicio e repassa a
// variável objeto oProcess por parâmetro.
*/
User Function APVRetorno(oProcess)
Local nPrecoVenda
Local cCodProduto, cCodStatus, cTexto

// Obtenha o código do produto a partir do html


cCodProduto := oProcess:oHtml:RetByName("B1_COD")

// Obtenha o novo preço de venda informado pelo destinatário:


nPrecoVenda := Val(oProcess:oHtml:RetByName("B1_PRV1"))

dbSelectArea("SB1")
SB1->(dbSetOrder(1))

// Localize o produto cadastrado na tabela SB1


If SB1->(dbSeek(xFilial("SB1") + cCodProduto))
// Adicione as informacões a serem incluídas na rastreabilidade.
cTexto := "Atualizando o preço de venda..."
cCodStatus := "100500"

// Através do atributo :cRetFrom da classe twfprocess, é possível obter o endereço


// eletrônico de quem respondeu a mensagem. Obtenha-o para adicioná-lo à
rastreabilidade.
oProcess:Track(cCodStatus, cTexto, oProcess:cRetFrom)

// Atualize o preço de venda:

41
If RecLock( "SB1", .f. )
SB1->B1_PRV1 := nPrecoVenda
MsUnLock()
EndIf
Else
// Adicione as informacões a serem incluídas na rastreabilidade.
cTexto := "Não foi possível encontrar o produto: " + cCodProduto
cCodStatus := "100900"
oProcess:Track(cCodStatus, cTexto, oProcess:cRetFrom)
EndIf

// Adicione as informacões a serem incluídas na rastreabilidade.


cTexto := "Finalizando o processo..."
cCodStatus := "100800" // Código do cadastro de status de processo
oProcess:Track(cCodStatus, cTexto, oProcess:cRetFrom) // Rastreabilidade
Return

/*
// APTimeOut - Esta função será executada a partir do Scheduler no tempo
// estipulado pela propriedade :bTimeout da classe TWFProcess.
// Caso o processo tenha sido respondido em tempo hábil, essa
// execução será descartada automaticamente.
*/
User Function APTimeOut(oProcess)
Local nDias := 0, nHoras := 0, nMinutos := 10
Local cCodStatus, cHtmlModelo
Local cCodProduto, cTexto, cTitulo

cHtmlModelo := "\Workflow\atuapv.htm"
cTitulo := "Atualização do preço de venda"

// Adicione as informacões a serem incluídas na rastreabilidade.


cTexto := "Executando TIMEOUT..."
cCodStatus := "100600"
// A função APTimeOut é executada, automaticamente, pelo sistema.
// Devido não haver usuário associado à execução, será omitido o parâmetro
// correspondente.
oProcess:Track(cCodStatus, cTexto) // Rastreabilidade

// Na execução da função de timeout, não se caracteriza retorno de mensagem.


// Neste caso, deve usar o método :ValByName() no lugar do
método :RetByName()
// para obter os valores contidos no html.
cCodProduto := oProcess:oHtml:ValByName("B1_COD")

// Finalize a tarefa anterior para não ficar pendente.


oProcess:Finish()

dbSelectArea("SB1")
SB1->(dbSetOrder(1))

// Localize o produto na tabela SB1:


If SB1->(dbSeek(xFilial("SB1") + cCodProduto))

42
// Crie uma nova tarefa, aproveitando o conteúdo do html preenchido
anteriormente
// com o uso do terceiro parâmetro com o valor lógico igual a .T. (verdadeiro)
oProcess:NewTask(cTitulo, cHtmlModelo, .T.)

// Antes de assinalar o ID do processo no campo, verifique se realmente o campo


// existe na tabela SB1:
If SB1->(FieldPos("B1_WFID")) > 0
If RecLock("SB1",.f.)
SB1->B1_WFID := oProcess:fProcessID
MsUnLock()
EndIf
EndIf

// Acrescente a palavra "(REENVIO)" no início do assunto da mensagem para


// reforçar que houve um timeout executado.
If (Left(oProcess:cSubject,9) != "(REENVIO)")
oProcess:cSubject := "(REENVIO)" + oProcess:cSubject
EndIf

oProcess:cTo := "bi@microsiga.com.br"

// Utilize a função WFCodUser para obter o código do usuário Protheus.


oProcess:UserSiga := WFCodUser("BI")

// Redefina a função de retorno a ser executada.


oProcess:bReturn := "U_MT010INC(1)"

// Redefina a função de timeout a ser executada.


oProcess:bTimeOut := {"U_MT010INC(2)", nDias, nHoras, nMinutos}

// Adicione as informções a serem incluídas na rastreabilidade


cTexto := "Reenviando a solicitação..."
cCodStatus := "100700"
oProcess:Track(cCodStatus, cTexto)

// Inicie o processo
oProcess:Start()
Else
// Adicione as informacões a serem incluídas na rastreabilidade.
cTexto := "Não foi possível encontrar o produto: " + cCodProduto
cCodStatus := "100900" // Código do cadastro de status de processo
oProcess:Track(cCodStatus, cTexto) // Rastreabilidade
EndIf

Return

PASSO 7 – Compilar e executar o ambiente COMPRAS.

Após compilar o programa ATUAPV.PRW, execute o ambiente de compras, selecione


a opção de menu “Atualizações | Cadastros | Produtos” e inclua um novo
produto. Ao confirmar a gravação pressionando o botão “Ok”, será enviado um e-
mail ao destinatário contendo, no corpo o html, os dados do produto e o campo do
valor do preço de venda a ser alterado.

43
Ao receber o e-mail no cliente de e-mail, coloque o valor no campo ‘Preço de Venda
R$’ e clique em Enviar.

Garanta que o Scheduler esteja ativo e a função de recebimento de mensagens do


Workflow esteja agendada (faça o agendamento de 1 em 1 minuto para que a
resposta seja quase prontamente processada). Passados alguns segundos, consulte
o cadastro do produto recém-incluído e veja que o preço de venda foi atualizado
com o valor informado no e-mail.

44
PASSO 8 – Consultas (Rastreabilidade de processo)

A qualquer momento, poderão ser realizadas consultas na janela de rastreabilidade


para saber em que situação está um determinado processo. A partir da opção de
menu “Miscelânea | Workflow | Rastreabilidade” no próprio ambiente de
compras (ou qualquer outro), é possível realizar tais consultas.

No campo “Pesq Padrão:”, selecione a pesquisa padrão “WFSB1” e, no campo


“Processo:”, pressione “F3” para realizar a pesquisa da tabela SB1 (produtos). Ao
selecionar o produto, você terá algumas informações inerentes ao processo gerado
para o produto escolhido. Observe que todos os textos que incluímos através do
método oprocess:track(...) serão vistos nesta janela.

45
PASSO 9 – Consultas (Processo por usuários)

A qualquer momento, o usuário do sistema poderá realizar consultas sobre


pendências geradas pelo Workflow, simplesmente selecionando a opção de menu
“Miscelânea | Workflow | Processos Usuarios” disponível nos ambientes.

Se o usuário atual for administrador, ele poderá ver as pendências geradas para
qualquer outro usuário cadastrado no sistema. Caso contrário, somente visualizará
as pendências relacionadas a ele próprio.

46
Integração com o Microsoft Visio
Versão homologada: Microsoft Office Visio 2003

Através do Microsoft Visio, é possível desenhar fluxos de processos que possam


interagir com o Workflow com o uso da rastreabilidade. Caso queira-se construir
um novo fluxo de processo no Visio e que venha interagir com o Workflow, basta
usar o stencil Workflow fornecido pela Microsiga. Esse stencil (veja lista de figuras
no canto esquerdo do Visio), contém shapes (desenhos) que em suas propriedades
foram configurados para interagir com o Workflow.

Caso queira-se incluir qualquer outro shape que não faça parte do stencil Workflow,
não há problemas. Só não será possível interagir com o evento duplo click do
mouse para executar uma função de usuário.

47
Após criar o arquivo .vsd (visio document) relacionado ao processo, especifique-o
no cadastro de processo no campo “Arquivo .vsd:”.

Ao pressionar o botão “Microsoft Visio”, a partir do browser de cadastro de


processos, será aberto o .vsd automaticamente pelo aplicativo Microsoft Visio.

48
O botão “Visio template”, localizado no browser de cadastro de processos, é
responsável por cadastrar as propriedades dos shapes na tabela WFCxxx (em que
xxx refere-se ao código da empresa) do banco de dados no Protheus. Esse cadastro
faz- se necessário para identificar e nomear cada um dos shapes contido no fluxo.
Os nomes associados aos shapes serão identificados nas linhas de programas
através do método :Track(...) pertencente a classe TWFProcess().

Exemplo:

cCodigoStatus := “100400”
cEmail := “aprovador@dominio.com.br”
cDescricao := “Aprovação enviado para: “ + cEmail
cNomeUsuario := Subs(cUsuario,7,15)
cVisioShape := “ENVIAR_SOLICITACAO”
oProcess:Track( cCodigoStatus, cDescricao, cNomeUsuario, cVisioShape )
oProcess:cTo := cEmail
oProcess:Start()
Return nil

49
Após pressionar o botão “Visio template”, o Microsoft Visio abrirá o arquivo .vsd
relacionado ao processo e bastará pressionar duas vezes o botão do mouse (doublé
click) sobre cada shape para que a janela de cadastro de propriedades seja exibida.

Templates – Propriedades dos shapes


Campo Descrição
Shape Id Código interno
de controle do
Microsoft Visio.
Somente
leitura.
Nome O próprio Visio
Shape sugere um
nome para
este shape.
Porém, poderá
ser modificado
para melhor
identificá-lo no
programa.
Descr Descrição do
Shape passo a que
este shape
está associado
ao fluxo do
processo.

50
Templates - Propriedades dos Shapes
Campo Descrição
Dependênci Causa uma
a dependência
de execução
desse shape
em relação ao
selecionado.
Neste caso, só
poderá ser
executado se o
selecionado
estiver sido
executado
anteriormente.
Ação Função de
usuário a ser
executado,
caso seja
pressionado
duas vezes o
botão do
mouse (doublé
ckick).

Cada shape contido no stencil Workflow é responsável por um tipo de evento (ação)
a ser executado no Protheus. Alguns shapes possuem janelas padrões de diálogo
após serem selecionados com o duplo clique do mouse durante a apresentação do
fluxo de processo. Essas janelas só aparecerão nos casos em que não for informada
a função de usuário ao shape selecionado.
Observe os tipos de janelas padrões existentes:

Propriedades
Shape Janela de diálogo Descrição

Realiza uma
nova pesquisa
de processo.

51
Apresenta a
data e a hora
em que foi
enviada a
mensagem ao
destinatário e
a data e a
hora em que o
Workflow
recebeu a
resposta.

Apresenta
todos os
timeouts
relacionados
ao processo e
informa a
situação atual
de cada um
deles,
permitindo
alterar o
tempo de
execução,
bem como
remover da
lista de
execução.

Possibilita a
finalização do
processo
atual.

52
Se o aplicativo Microsoft Visio for localizado no sistema operacional do usuário, o
botão “Visio” será exibido na janela de rastreabilidade.

O Microsoft Visio exibirá o fluxo do processo e colorirá em verde o trajeto em que


foi executado pelo processo e o vermelho a situação inversa.

53
Realizando uma nova pesquisa ...

Verificando os timeouts associados ao processo...

54
Verificando o destinatário...

Finalizando um processo a partir do Visio...

Exercício – Aprovação de Pedido de Compras

55
A partir do ponto de entrada (“WFW120P”), contido no cadastro de pedido de
compras no ambiente de compras, criaremos um processo de Workflow e usaremos
o método Track() da classe TWFProcesso com o uso dos shapes.

Passo 1 – Criar um novo campo na tabela SC7 (pedido de compras)

Crie um novo campo C7_WFID do tipo caracter e tamanho igual a 7 na tabela SC7
para usarmos em futuras pesquisas que possam nos trazer o código do processo
relacionado ao pedido na janela de rastreabilidade.

Passo 2 – Criar uma nova pesquisa padrão no SXB

Crie uma nova pesquisa no SXB com o nome “WFSC7” que faça referência à tabela
SC7 e retorne o conteúdo do campo C7_WFID.

Passo 3 – Microsoft Visio Document (.vsd)

Crie um fluxo de processo de pedido de compras com o Microsoft Visio e grave na


pasta do Workflow com o nome PEDCOMPRAS.VSD.

Modelo exemplo:

Passo 4 – Cadastro Visio Template

56
A partir do botão “Visio Template” no browser do cadastro de processos,
cadastre todos os shapes relacionados ao fluxo de processo.

Use para cada um dos shapes apresentados no fluxo os seguintes nomes e, em


seguida, confirme pressionando o botão “OK”:

Shape Nome Shape

INICIO

INCLUSAO

ENVIAR

APROVADOR_A

TIMEOUT

57
TIMEOUTS

REENVIO

APROVADOR_B

RECEBE

APROVADO?

APROVA

NOTIFICACAO

SOLICITANTE

TERMINO

Passo 5 – Cadastro de processos

A partir do configurador, selecione a opção de menu “Ambiente | Workflow |


Processos Workflow” e crie um novo processo, conforme o conteúdo dos campos
apresentados na tabela abaixo:

Campo Conteudo
Código PEDCOM
Descrição APROVACAO DE PEDIDO DE COMPRAS
Pesq Padrão WFSC7 - PEDIDO DE COMPRAS
Arquivo .vsd C:\MP8\AP_DATA\WORKFLOW\PEDCOMPRAS.VSD

* O arquivo .vsd poderá existir em outros lugares, basta informar o caminho e


nome do arquivo a ser usado.

58
PASSO 6 – Cadastro de Status

Ainda no configurador, selecione a opção de menu “Ambiente | Workflow |


Status Workflow” e cadastre alguns status para o processo mencionado acima,
conforme o conteúdo dos campos apresentados abaixo:

Cód Processo Cód Status Descrição


PEDCOM 100100 INICIO
PEDCOM 100200 GERANDO A SOLICITACAO
PEDCOM 100300 ENVIANDO MENSAGEM
PEDCOM 100400 RECEBENDO APROVACAO
PEDCOM 100500 PEDIDO APROVADO
PEDCOM 100600 PEDIDO REPROVADO
PEDCOM 100700 ENVIANDO NOTIFICACAO
PEDCOM 100800 EXECUTANDO TIMEOUT
PEDCOM 100900 REENVIANDO SOLICITACAO
PEDCOM 101000 FINALIZANDO PROCESSO

PASSO 7 – Criar dois htmls modelos para o processo

Criar dois htmls modelos chamado WFW120P1.htm (utilizado para aprovação) e


WFW120P2.htm (utilizado para notificação) no diretório \WORKFLOW (abaixo do
rootpath do protheus).

WFW120p1.htm (modelo para aprovação do pedido)

59
Código fonte:

<html>

<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
<title>Aprovação de Pedido de Compra</title>
</head>

<body bgcolor="#FFFFFF">
<script language="JavaScript">

function ValidaObs(AForm)
{
if ((AForm.RBAPROVA[1].checked) && (AForm.LBMOTIVO.value == "Aa"))
{
alert("Campo Observação é obrigatório, favor informar o motivo da reprovação.");
}
else
{
AForm.submit();
alert("Sua mensagem foi enviada.");
}
}
</script><noscript>

<pre><font color="#FF0000" size="2"


face="Verdana"><b>%WFAvisoJS%</b></font></pre>
</noscript>
<form action="mailto:%WFMailTo%" method="POST"
name="FrontPage_Form1">
<h2><font color="#FF0000" face="Verdana"><b>Aprovação de
Pedido de Compra</b></font></h2>
<p><font color="#0000FF" face="Verdana"><b>Cabeçalho do
Pedido</b></font></p>
<table border="1" width="845">
<tr>
<td width="100" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Emissão</b></font></td>
<td width="460" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Fornecedor</b></font></td>
<td width="253" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Nome</b></font></td>
<td width="110" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Cond.Pagto</b></font></td>
<td width="110" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Número</b></font></td>
</tr>
<tr>
<td width="100"><font size="2" face="Arial">!emissao!</font></td>
<td width="460"><font size="2" face="Arial">!fornecedor!</font></td>
<td width="253"><font size="2" face="Arial">!lb_nome!</font></td>
<td width="110"><font size="2" face="Arial">!lb_cond!</font></td>
<td width="110"><font size="2" face="Arial">!pedido!</font></td>
</tr>

60
</table><p><font color="#0000FF"
face="Verdana"><b>Itens</b></font></p>
<table border="1" width="846">
<tr>
<td width="65" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Item</b></font></td>
<td width="222" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Descrição</b></font></td>
<td width="99" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Quantidade</b></font></td>
<td width="32" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Unid</b></font></td>
<td width="99" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Preço</b></font></td>
<td width="43" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>total</b></font></td>
<td width="48" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Entrega</b></font></td>
<td bgcolor="#01C5FE"><strong>Condição de Pag.</strong></td>
</tr>
<tr>
<td width="50"><font size="2" face="Arial">!produto.item!</font></td>
<td width="222"><font size="2" face="Arial">!produto.codigo! - !
produto.descricao!</font></td>
<td width="99"><font size="2" face="Arial"><input
type="text" size="13" name="T7"
value=%produto.quant%></font></td>

<td width="32"><font size="2" face="Arial">!produto.unid!</font></td>


<td width="99"><font size="2" face="Arial"><input
type="text" size="13" name="T9"
value=%produto.preco%></font></td>
<td width="43"><font size="2" face="Arial"><input
type="text" size="5" name="T10"
value=%produto.total%></font></td>
<td width="48"><font size="2" face="Arial"><input
type="text" size="5" name="T11"
value=%produto.entrega%></font></td>
<td><select name="D1" size="1">
<option selected>%produto.condpag%</option>
</select></td>
</tr>
</table>
<table border="1" width="275">
<tr>
<td width="155" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Valor Total</b></font></td>
<td width="121"><input type="text" size="13"
name="T15" value=%lbvalor%></td>
</tr>
<tr>
<td width="155" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Valor Frete</b></font></td>
<td width="121"><input type="text" size="13"
name="T16" value=%lbfrete%></td>
</tr>
<tr>

61
<td width="155" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Total + IPI</b></font></td>
<td width="121"><input type="text" size="13"
name="T16" value=%lbtotal%></td>
</tr>
</table>
<h4><font color="#0000FF"
face="Verdana"><strong>APROVAÇÃO:</strong></font></h4>
<p><input type="radio" checked name="%RBAPROVA%" value="Sim">
Sim.<br>
<input type="radio" name="%RBAPROVA%" value="Nao">
Não. (Favor especificar motivo)<br>
<h4><font size="2" face="Arial">Motivo: <textarea name="S1"
rows="4" cols="74">%lbmotivo%</textarea></font><br>
</h4>
<p><input type="button" name="B1" value="Enviar"
onclick="ValidaObs(FrontPage_Form1)"> <input type="reset"
name="B2" value="Limpar"> </p>
</form>
</body>
</html>

WFW120p2.htm (modelo para notificação)

62
Código fonte:

<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
<title>Aprovação de Pedido de Compra</title>
</head>

<body bgcolor="#FFFFFF">

<form action="mailto:%WFMailTo%" method="POST"


name="FrontPage_Form1">

<h2><font color="#FF0000" face="Verdana"><b>!Titulo!</b></font></h2>


<p><font color="#0000FF" face="Verdana"><b>Cabeçalho do
Pedido</b></font></p>
<table border="1" width="845">
<tr>
<td width="100" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Emissão</b></font></td>
<td width="460" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Fornecedor</b></font></td>
<td width="253" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Nome</b></font></td>
<td width="110" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Cond.Pagto</b></font></td>
<td width="110" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Número</b></font></td>
</tr>
<tr>
<td width="100"><font size="2" face="Arial">%emissao%</font></td>
<td width="460"><font size="2"
face="Arial">%fornecedor%</font></td>
<td width="253"><font size="2" face="Arial">%lb_nome%</font></td>
<td width="110"><font size="2" face="Arial">%lb_cond%</font></td>
<td width="110"><font size="2" face="Arial">%pedido%</font></td>
</tr>
</table>
<p><font color="#0000FF" face="Verdana"><b>Itens</b></font></p>
<table border="1" width="846">
<tr>
<td width="65" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Item</b></font></td>
<td width="222" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Descrição</b></font></td>
<td width="99" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Quantidade</b></font></td>
<td width="32" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Unid</b></font></td>
<td width="99" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Preço</b></font></td>
<td width="43" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>total</b></font></td>
<td width="48" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Entrega</b></font></td>

63
<td bgcolor="#01C5FE"><strong>Condição de Pag.</strong></td>
</tr>
<tr>
<td width="50"><font size="2"
face="Arial">%produto.item%</font></td>
<td width="222"><font size="2" face="Arial">%produto.codigo%
- %produto.descricao%</font></td>
<td width="99"><font size="2" face="Arial"><input
type="text" size="13" name="T7"
value=%produto.quant%></font></td>
<td width="32"><font size="2"
face="Arial">%produto.unid%</font></td>
<td width="99"><font size="2" face="Arial"><input
type="text" size="13" name="T9"
value=%produto.preco%></font></td>
<td width="43"><font size="2" face="Arial"><input
type="text" size="5" name="T10"
value=%produto.total%></font></td>
<td width="48"><font size="2" face="Arial"><input
type="text" size="5" name="T11"
value=%produto.entrega%></font></td>
<td><select name="D1" size="1">
<option selected>%produto.condpag%</option>
</select></td>
</tr>
</table>
<table border="1" width="275">
<tr>
<td width="155" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Valor Total</b></font></td>
<td width="121"><input type="text" size="13"
name="T15" value=%lbvalor%></td>
</tr>
<tr>
<td width="155" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Valor Frete</b></font></td>
<td width="121"><input type="text" size="13"
name="T16" value=%lbfrete%></td>
</tr>
<tr>
<td width="155" bgcolor="#99CCFF"><font size="2"
face="Verdana"><b>Total + IPI</b></font></td>
<td width="121"><input type="text" size="13"
name="T16" value=%lbtotal%></td>
</tr>
</table>
</form>
</body>
</html>

64
Passo 8 – Criar um processo de Workflow a partir do ponto de entrada

A partir do IDE, crie um arquivo de programa chamado WFW120p1.prw e associe a


um de seus projeto. Abaixo, crie as seguintes linhas de programas que farão parte
do processo:

WFW120p.PRW

#INCLUDE “PROTHEUS.CH”

/*
// WFW120P – Ponto de entrada do sistema do pedido de compras que será
// executado tanto na inclusão como alteração do pedido de compras
// a partir do botão “OK”.
*/
User Function WFW120p()
U_APCIniciar()
Return

/*
// APCIniciar – Esta função é responsável por iniciar a criação do processo e o
// envio da mensagem para o destinatário.
*/
User Function APCIniciar()
Local oProcess, oHtml
Local cNumPed, cDestinatario, cShape, cArqHtml, cAssunto, cUsrCorrente
Local cCodigoStatus, cDescricao, cValor
Local aCond := {}
Local nTotal := 0, nDias := 0, nHoras := 0, nMinutos := 10

// Obtenha o número do pedido:


cNumPed := SC7->C7_NUM

// Monte uma descrição para o assunto:


cAssunto := "Aprovacao do pedido de compras No: " + cNumPed

// Informe o caminho e o arquivo html que será usado.


cArqHtml := "\Workflow\wfw120p1.htm"

// Obtenha o nome do usuário corrente:


cUsrCorrente := Subs(cUsuario,7,15)

// Informe a lista de destinatários, separando-os entre “;”


cDestinatario := “aprovador@microsiga.com.br”

// Inicialize a classe de processo:


oProcess := TWFProcess():New( "PEDCOM", cAssunto )

// Crie uma nova tarefa, informando o html template a ser utilizado:


oProcess:NewTask( "Aprovação do pedido", cArqHtml )

// Informe o nome do shape correspondente a este ponto do fluxo:


cShape := “INICIO”

// Informe o código do status do processo correspondente a este ponto do fluxo.


cCodigoStatus := "100100"

65
cDescricao := "Iniciando processo..."

// Repasse as informações para o método track() que registrará as informações


// para a rastreabilidade e visio.
oProcess:Track( cCodigoStatus, cDescricao, cUsrCorrente, cShape )

// Informe a função que deverá ser executada quando as respostas chegarem


// ao Workflow.
oProcess:bReturn := "U_APCRetorno"
oProcess:cSubject := cAssunto

// Determine o tempo necessário para executar o timeout. 5 minutos será


// suficiente para respondermos o pedido. Caso contrário, será executado.
oProcess:bTimeOut := {{"U_APCTimeout(1)", nDias, nHoras, nMinutos }}

// Informe qual usuário do Protheus será responsável por esta tarefa.


// Dessa forma, ele poderá ver a pendência na consulta por usuário.
oProcess:UserSiga := WFCodUser( “APROVADOR” )
oHtml := oProcess:oHTML

// Crie novas informações a serem passadas para o método Track(), baseado


// no novo passo em que o fluxo se encontra.
cShape := “INCLUSAO”
cCodigoStatus := "100200"
cDescricao := "Gerando solicitação de aprovação de pedido de compras..."
oProcess:Track(cCodigoStatus, cDescricao, cUsrCorrente, cShape )

// Preencha os campos contidos no html com as informações colhidas no


// banco de dados.
oHtml:ValByName( "EMISSAO", SC7->C7_EMISSAO )
oHtml:ValByName( "FORNECEDOR", SC7->C7_FORNECE )

dbSelectArea(”SA2”)
dbSetOrder(1)
dbSeek(xFilial(“SA2”) + SC7->C7_FORNECE)
oHtml:ValByName( "lb_nome", SA2->A2_NOME )
oHtml:ValByName( "lb_cond", SC7->C7_COND )

// Obtenha as condições de pagamento.


dbSelectArea(“SE4”)

If dbSeek(xFilial(“SE4”))
While !Eof() .and. xFilial(“SE4”) == SE4->E4_FILIAL
AAdd(aCond, "'" + SE4->E4_DESCRI + "'" )
dbSkip()
end
end

dbSelectArea(“SB1”)
dbSetOrder(1)
dbSelectArea(“SC7”)
oHtml:ValByName( "PEDIDO", SC7->C7_NUM )
cNum := SC7->C7_NUM

dbSetOrder(1)
dbSeek(xFilial(“SC7”) + cNum )

66
// Preencha a tabela do html chamada “produto.” com seus respectivos campos.
While !Eof() .and. ( C7_NUM == cNum )
SB1->( dbSeek( xFilial(“SB1”) + SC7->C7_PRODUTO ) )
nTotal := nTotal + C7_TOTAL
AAdd( ( oHtml:ValByName( "produto.item" )),C7_ITEM )
AAdd( ( oHtml:ValByName( "produto.codigo" )),C7_PRODUTO )
AAdd( ( oHtml:ValByName( "produto.descricao" )),SB1->B1_DESC )
cValor := Transform( C7_QUANT,'@E 99,999.99' )
AAdd( ( oHtml:ValByName( "produto.quant" )), cValor)
cValor := Transform( C7_PRECO,'@E 99,999.99' )
AAdd( ( oHtml:ValByName( "produto.preco" )), cValor)
cValor := Transform( C7_TOTAL,'@E 99,999.99' )
AAdd( ( oHtml:ValByName( "produto.total" )), cValor)
AAdd( ( oHtml:ValByName( "produto.unid" )),SB1->B1_UM )
AAdd( ( oHtml:ValByName( "produto.entrega" )), '0' )
AAdd( ( oHtml:ValByName( "produto.condPag" )),aCond )

// Grave o novo campo criado e o ID do processo juntamente com o ID da tarefa


// para ser obtida a partir da pesquisa padrão na janela da rastreabilidade.
if RecLock("SC7",.f. )
C7_WFID := oProcess:fProcessID + oProcess:fTaskID
MsUnLock("SC7")
end

dbSkip()
Enddo

oHtml:ValByName("lbValor" , Transform( nTotal,'@E 99,999.99' ) )


oHtml:ValByName("lbFrete" , Transform( 0,'@E 99,999.99' ) )
oHtml:ValByName("lbTotal" , Transform( nTotal,'@E 99,999.99' ) )
oProcess:cTo := cDestinatario

// Finalize a primeira etapa do fluxo do processo, informando em que ponto o


// fluxo do processo foi executado e, posteriormente, repasse para o método
track().
cShape := “ENVIAR;APROVADOR_A”
cCodigoStatus := “100300”
cDescricao := "Enviando solicitacao para: " + cDestinatario
oProcess:Track( cCodigoStatus, cDescricao, cUsrCorrente, cShape )

// Neste ponto, o processo será criado e será enviada uma mensagem para a lista
// de destinatários.
oProcess:Start()

Return

67
/*
// APCRetorno – Esta função é responsável por atualizar o pedido de compras
// com as respostas vindas do aprovador.
*/
User Function APCRetorno(oProcess)
Local cFindKey, cAssunto, cNumPed, cShape, cCodigoStatus, cDescricao

// Obtenha o número do pedido:


cNumPed := oProcess:oHtml:RetByName(“Pedido”)

// Monte a lista de argumentos para ser passada para o método track():


// Pode ser informado mais do que um nome de shape para uma mesma
// ação do fluxo. Basta informá-los utilizando o “;” para identificar cada um deles.
cAssunto := “Pedido de compras no: “ + cNumPed
cShape := “RECEBE;REMETENTE;APROVADO?”
cCodigoStatus := “100400”
cDescricao := "Recebendo resultado aprovação..."
oProcess:Track( cCodigoStatus, cDescricao,,cShape )

// Verifique se a resposta é diferente de “SIM”, ou seja, reprovado.


if Upper(oProcess:oHtml:RetByName(“RBAPROVA”)) <> “SIM”
dbSelectarea("SCR") // Posicione a liberação
dbSetorder(2)

If dbSeek( xFilial("SCR") + "PC" + cNumPed )


RecLock("SCR",.f.)
CR_DATALIB := dDataBase
CR_OBS := ""
CR_STATUS := "04" // Bloqueado
CR_OBS := oProcess:oHtml:RetByName('lbmotivo')
MsUnLock()
End

// Gere novas informações a serem passadas para a rastreabilidade:


cCodigoStatus := “100600”
cDescricao := cAssunto + “ – REPROVADO”

// Dessa vez, não informe nenhum shape associado à reprovação por não
// haver nenhum shape relacionado à reprovação.
oProcess:Track( cCodigoStatus, cDescricao )

// Execute a função responsável pela notificação ao usuário solicitante.


U_APCNotificar( oProcess, cDescricao )
return .t.
end

// Libere o pedido:
dbSelectArea("SCR")
dbSetOrder(2)
cFindKey := xFilial("SCR") + "PC" + cNumPed

If dbSeek( cFindKey )
RecLock("SCR",.f.)
SCR->CR_DATALIB := dDataBase
SCR->CR_OBS := ""

68
SCR->CR_STATUS := "03"
MsUnLock()
end

dbselectarea("SC7")
dbSetOrder(1)
cFindKey := xFilial("SC7") + cNumPed
dbSeek( cFindKey ) // Posiciona o Pedido

while !Eof() .and. ( C7_FILIAL + C7_NUM == cFindKey )


RecLock("SC7",.f.)
C7_CONAPRO := "L"
MsUnLock()
dbSkip()
end

cShape := “APROVA”
cCodigoStatus := “100500”
cDescricao := cAssunto + “ – APROVADO”
oProcess:Track( cCodigoStatus, cDescricao,,cShape )
// Execute a função responsável pela notificação ao usuário solicitante.
U_APCNotificar( oProcess, cDescricao)
Return

/*
// APCNotificar – Essa função é responsável por notificar ao solicitante o
// resultado da aprovação do pedido.
*/
User Function APCNotificar( oProcess, cDescricao )
Local oHtml
Local aValues := Array(17)
Local cNumPed, cShape, cCodigoStatus, cArqHtml

// Informe o 2º html para notificação que é diferente do wfw120p1.htm


cArqHtml := "\Workflow\wfw120p2.htm"

// Gere informações para a rastreabilidade:


cShape := “NOTIFICACAO;SOLICITANTE”
cCodigoStatus := “100700”
oProcess:Track( cCodigoStatus, cDescricao,, cShape )

// Devido os htmls serem diferentes, não será possível usar o terceiro parâmetro
// com o valor .T. no método NewTask() da classe TWFProcess(). Neste caso,
// deve-se obter todas as informações necessárias para montar o novo html
// para notificação ao solicitante.
oHtml := oProcess:oHtml

aValues[01] := oHtml:ValByName("EMISSAO")
aValues[02] := oHtml:ValByName("FORNECEDOR")
aValues[03] := oHtml:ValByName("lb_nome")
aValues[04] := oHtml:ValByName("lb_cond")
aValues[05] := oHtml:ValByName("PEDIDO")
aValues[06] := oHtml:ValByName("Produto.item")
aValues[07] := oHtml:ValByName("Produto.codigo")
aValues[08] := oHtml:ValByName("Produto.descricao")
aValues[09] := oHtml:ValByName("Produto.quant")

69
aValues[10] := oHtml:ValByName("Produto.preco")
aValues[11] := oHtml:ValByName("Produto.total")
aValues[12] := oHtml:ValByName("Produto.unid")
aValues[13] := oHtml:ValByName("Produto.entrega")
aValues[14] := oHtml:ValByName("Produto.condPag")
aValues[15] := oHtml:ValByName("lbValor")
aValues[16] := oHtml:ValByName("lbFrete")
aValues[17] := oHtml:ValByName("lbTotal")

// Após obter as informações desejadas, crie uma nova tarefa:


oProcess:NewTask("Resultado da Aprovação", cArqHtml )
oHtml := oProcess:oHtml

// Repasse as informações do outro html para esse novo.


oHtml:ValByName("EMISSAO", aValues[01] )
oHtml:ValByName("FORNECEDOR", aValues[02] )
oHtml:ValByName("lb_nome", aValues[03] )
oHtml:ValByName("lb_cond", aValues[04] )
oHtml:ValByName("PEDIDO", aValues[05] )
AEval( aValues[06],{ |x| AAdd( oHtml:ValByName( "produto.item" ), x ) } )
AEval( aValues[07],{ |x| AAdd( oHtml:ValByName( "produto.codigo" ), x ) } )
AEval( aValues[08],{ |x| AAdd( oHtml:ValByName( "produto.descricao" ), x ) } )
AEval( aValues[09],{ |x| AAdd( oHtml:ValByName( "produto.quant" ), x ) } )
AEval( aValues[10],{ |x| AAdd( oHtml:ValByName( "produto.preco" ), x ) } )
AEval( aValues[11],{ |x| AAdd( oHtml:ValByName( "produto.total" ), x ) } )
AEval( aValues[12],{ |x| AAdd( oHtml:ValByName( "produto.unid" ), x ) } )
AEval( aValues[13],{ |x| AAdd( oHtml:ValByName( "produto.entrega" ), x ) } )
AEval( aValues[14],{ |x| AAdd( oHtml:ValByName( "produto.condPag" ), x ) } )
oHtml:ValByName( "lbValor", aValues[15])
oHtml:ValByName( "lbFrete", aValues[16])
oHtml:ValByName( "lbTotal", aValues[17])
oHtml:ValByName( "Titulo", cDescricao )

// Informe o endereço eletrônico do solicitante. Esta informação pode estar


// armazenada em um campo na tabela SC7, por exemplo:
oProcess:cTo := “solicitante@microsiga.com.br”
oProcess:cSubject := "Retorno da Aprovacao do Pedido de Compras"

// Envie a mensagem para o solicitante:


oProcess:Start()

// Como não houve informações geradas para essa tarefa nos campos bReturn
// e bTimeout, esse processo será finalizado automaticamente. De qualquer
// forma, informe, na rastreabilidades sobre esse passo alcançado no fluxo.
cShape := “TERMINO”
cCodigoStatus := “101000”
cDescricao := "Termino do processo"
oProcess:Track( cCodigoStatus, cDescricao,, cShape )
Return

/*
// APCTimeout – Esta função é responsável pela execução do timeout
// do processo.
*/
User Function APCTimeOut( nVezes, oProcess )
Local nDias := 0, nHoras := 0, nMinutos := 10

70
Local cNumPed, cShape, cCodigoStatus, cDescricao, cArqHtml

// Informe o html:
cArqHtml := "\Workflow\wfw120p1.htm"

// Obtenha o número do pedido:


// Veja que o método Valbyname() deve ser usado na função de timeout.
cNumPed := oProcess:oHtml:ValByName(“Pedido”)

// Verifique o número de vezes que o timeout foi executado para este processo.
If ( nVezes == 1 )

// Se for a primeira vez, finalize a tarefa anterior.


oProcess:Finish()

// Crie uma nova tarefa de reenvio, aproveitando as mesmas informações do


// html preenchido anteriormente através do terceiro parâmetro do método
// NewTask(), usando o valor .T. (verdadeiro).
oProcess:NewTask("Reenvio de aprovação", cArqHtml, .t. )

// Determine uma nova informação a ser gravada na rastreabilidade.


cShape := “TIMEOUT”
cCodigoStatus := “100800”
cDescricao := "Executando timeout"
oProcess:Track( cCodigoStatus, cDescricao,, cShape )
oProcess:cTo := "aprovador@microsiga.com.br"
oProcess:bReturn := "U_APCRetorno"

// Desta vez, informe ao timeout que ser for executado, será pela segunda vez.
oProcess:bTimeOut := {{"U_APCTimeout(2)", nDias, nHoras, nMinutos }}

// Incremente o assunto da mensagem para ficar ressaltado que se trata


// de um reenvio indicando o timeout.
oProcess:cSubject := "(Timeout)" + oProcess:cSubject

// Prepare novas informações a serem inseridas na rastreabilidade.


cShape := “REENVIO;APROVADOR_B”
cCodigoStatus := “100900”
cDescricao := "Reenviando aprovacao do pedido de compras no. " + cNumPed
oProcess:Track( cCodigoStatus, cDescricao,, cShape )

// Gere o processo e envie a mensagem.


oProcess:Start()
else
// Envie uma notificação ao usuário, indicando que o processo foi descartado.
cDescricao := “Pedido de compras no. “ + cNumPed + “ não foi atendido.”
U_APCNotificar(oProcess, cDescricao )
end

Return

71
PASSO 9 – Compilar e executar o módulo de compras

Após compilar o programa WFW120P.PRW, execute o ambiente de compras,


selecione a opção de menu “Atualizações | Pedidos | Pedidos de Compras” e
inclua um novo pedido. Ao confirmar a gravação pressionando o botão “Ok”, será
enviado um e-mail ao aprovador.

Garanta que o Scheduler esteja ativo e a função de recebimento de mensagens do


Workflow esteja agendada (faça o agendamento de 1 em 1 minuto para que essa
resposta seja quase prontamente processada ). Passados alguns minutos após
responder o e-mail (1 a 2 minutos no máximo), verifique se o pedido foi ou não
aprovado.

PASSO 10 – Consultas (rastreabilidade de processo)

A qualquer momento, poderão ser realizadas consultas na janela de rastreabilidade


para saber a situação em que se encontra um determinado processo. A partir da
opção de menu “Miscelânea | Workflow | Rastreabilidade”, no próprio
ambiente de compras( ou qualquer outro ), é possível realizar tais consultas.

No campo “Pesq Padrão:”, selecione a pesquisa padrão “WFSC7” e, no campo


“Processo:”, pressione “F3” para realizar a pesquisa da tabela SC7 (pedido de
compras). Ao selecionar o pedido, você terá algumas informações inerentes ao

72
processo gerado para o produto escolhido. Observe que todos os textos que
incluímos através do método oprocess:track(...) serão vistos nesta janela.

73
PASSO 11 – Consultas (Processo por usuários)

A qualquer momento, o usuário do sistema poderá realizar consultas sobre


pendências geradas pelo Workflow, simplesmente selecionando a opção de menu
“Miscelânea | Workflow | Processos Usuarios” disponível nos ambientes.

Se o usuário atual for administrador, ele poderá ver as pendências geradas para
qualquer outro usuário cadastrado no sistema. Caso contrário, somente poderá ver
as pendências relacionadas a ele mesmo.

74
Glossário

75
Autenticação SMTP: validação de usuário e senha no servidor de e-mail
para envio de mensagens.

Browser internet: programa que permite navegar nas páginas disponíveis


na internet. O Internet Explorer é um exemplo de browser.

Caixa de correio: nome dado a um diretório em que serão armazenadas


todas as mensagens recebidas, a enviar, enviadas etc. Em agrupamento de
pastas nomeadas inbox, outbox, sent etc. pertencentes a uma determinada
conta de e-mail.

Cliente de e-mail: sofware de controle de e-mails pelo usuário final.


Exemplos: OutLook Express e OutLook XP.

Conta de e-mail: endereço de e-mail existente em um servidor de e-mail.

Cookies: arquivos gravados na estação do usuário, pelos diversos sites,


para leitura de informações daquela estação.

Html (Hyper Text Mark-up Language): é um arquivo no formato texto


que contém diversos tipos de comando que controlam a apresentação visual
no browser internet.

Java Script: linguagem contida nos HTMLs, permitindo validações e ações


diversas.

Messenger do Protheus: recurso disponível no Protheus que serve para


avisar aos usuários de algum processo ou mensagem de Workflow que
esteja disponível no aguardo de uma ação a ser tomada.

Processo: conjunto de tarefas a serem executadas, baseadas em uma


regra de negócio que determina um ou mais caminhos a serem seguidos
denominados fluxo.

Protocolo POP3 ou IMAP: recurso disponível pelos servidores de e-mails


para permitir o acesso à caixa de correio (leitura).

Protocolo SMTP: recurso disponível pelos servidores de e-mails para o


envio de mensagens através de uma conta de e-mail.

Rastreabilidade: recurso necessário para localizar e identificar as


propriedades (status, descrição, data, participante etc.) de um determinado
processo de Workflow.

Retorno: conjunto de respostas obtidas por e-mail ou pela postagem de um


html via browser internet, através do serviço http que serão usados para
realizar atualizações na base de dados do Protheus.

Serviço http: serviço utilizado pelos servidores internet que disponibiliza


aos usuários o acesso à internet.

Servidor de e-mail: software de controle de envios e recebimento de e-


mails. Exemplos: Exchange e Domino.

Timeout: tempo fora do prazo limite (tempo excedido). Procedimento a ser


executado após o tempo limite esperado por uma ação a ser tomada por um
participante na trajetória de um fluxo de processo.

76
Workflow: automação do fluxo de processo.

77

Você também pode gostar