sexta-feira, 29 de maio de 2009

Workflow Builder

Olá pessoal!

Segue a última parte sobre Workflow!

Até mais.

Os componentes vistos no outro post estão dispostos da seguinte forma no Workflow Builder:

O primeiro passo é a criação de um conjunto de fluxos.



Selecione o botão “Novo” (circulado no desenho acima) ou escolha a opção de Menu “File à New”.

Um novo store (arquivo) com o nome “Untitled” será criado na barra de navegação:
Com o botão direito no ícone deste store, selecione a opção “New Item Type”.

A seguinte tela deverá aparecer:


Escolha um nome interno (sem espaços com tamanho máximo de 8 dígitos), um nome para apresentação e uma descrição.

A partir de então toda a árvore de componentes de um fluxo será criada conforme figura abaixo:




Então é hora de criar os subfluxos/processos.

Para criar um processo, com o botão direito do mouse no ícone “Processes” (segundo nível), selecione a opção “New Process”.
A seguinte tela deverá aparecer:


Da mesma forma, escolha um nome interno, um nome de apresentação e uma descrição.
Se o processo resultar em algum domínio, selecione o “Lookup Type” a partir da opção “Result Type”.
Se o processo não for apenas um subfluxo, mas um fluxo disparado externamente por alguma aplicação, selecione também a opção “Runnable”.
Se desejar altere o ícone do fluxo para caracterizar melhor a operação de negócio que está sendo mapeada.

Para inserir atividades (funções, notificações e processos) no seu novo processo:
- Abra seu processo a partir de um clique duplo
- Selecione os objetos e os arraste para dentro do processo.
Lembre-se que todo processo deve ter um início e pelo menos um fim.
As funções de Start e End encontram-se no conjunto de fluxos Standard.

Para criar funções, com o botão direito do mouse no ícone “Functions” (segundo nível), selecione a opção “New Function”.

A seguinte tela deverá aparecer:


Da mesma forma, escolha um nome interno, um nome de apresentação e uma descrição.
Escolha também no campo “Function” o programa PLSQL que deverá respaldar esta função.
Em geral costumamos criar uma única package por Item Type e agrupar nela os códigos (procedures/funções) que irão respaldar as funções de cada processo.
Se a função resultar em algum domínio, selecione o “Lookup Type” a partir da opção “Result Type”.
Se desejar também altere o ícone da função para caracterizar melhor a atividade que está sendo mapeada.

Após criada a função você ainda pode criar atributos (variáveis) que farão parte dela.
Para isso, selecione a opção “New Attribute” a partir do botão direito do mouse no ícone “Functions” (segundo nível).

A seguinte tela deverá aparecer:



Escolha um nome interno, um nome de apresentação e uma descrição.
Escolha também o tipo de dado que será armazenado (Texto, Número, Data, etc..) e em caso textos, escolha também o tamanho da informação.
Se desejar, especifique um valor default na opção “Default Value”.

Atributos também podem ser criados de forma global (não específicos para uma função), através do botão direito do mouse no ícone “Attributes” (segundo nível), opção “New Attribute”.

Além disso também posso associar um atributo global a uma função arrastando o atributo até a função.

Os domínios, por sua vez, são criados também com o botão direito do mouse no ícone “Lookup Types” (segundo nível), selecionando a opção “New Lookup Type”.

A seguinte tela deverá aparecer:


Escolha um nome interno, um nome de apresentação e uma descrição.
Com o botão direito sobre o ícone do seu novo Lookup Type (terceiro nível), selecione a opção “New Lookup Code” para criar os valores do seu domínio.




Aqui você também deverá escolher um nome interno, um nome de apresentação e uma descrição.

Se você ainda não entendeu toda a idéia de um fluxo, pelo menos você já gravou que deve sempre criar objetos no Workflow Builder com o botão direito do mouse e deve sempre escolher um nome interno, uma nome de apresentação e uma descrição.

Mas não se preocupe porque até o final deste post você terá toda a idéia de um fluxo em mente.

Para as notificações temos um conceito novo.
Primeiro montamos o corpo da notificação, o qual chamamos de mensagem e em seguida criamos uma notificação para esta mensagem.

Com o botão direito do mouse no ícone “Messages”, selecione “New Message”:




Escolha um nome interno, um nome de apresentação e uma descrição.
Na subpasta Body, escolha o título da mensagem (Subject) e o corpo (Body).
O corpo pode ser um texto simples ou uma referência a um atributo criado anteriormente cujo valor será alimentação em uma função antes do envio da notificação correspondente.
A referência ao atributo é feita da seguinte forma: &atributo.
Todos os atributos referenciados na mensagem deverão ser criados ou associados a ela como foi feito com as funções.
Um atributo em uma mensagem pode ter o objetivo de envio (send) ou resposta (respond) de informações.
Esta configuração é feita através da opção “Source” da tela de atributos da mensagem.
Um atributo com objetivo de envio não é atualizável, contém uma informação que será mostrada na mensagem.
Um atributo com o objetivo de resposta armazenará a resposta do usuário destinatário da notificação.

Criada a mensagem e seus respectivos atributos, selecione a opção “New Notification” a partir do botão direito do mouse sobre o ícone “Notification”:

A seguinte tela deverá aparecer:



Escolha um nome interno, um nome de apresentação e uma descrição.
Associe a Mensagem já criada e um Lookup Type já criado se esta notificação resultar em um domínio.
Se esta notificação tiver um tempo limite para ser visualizada/respondida, especifique um “Timeout“ em dias, horas ou minutos na pasta Details.

Conforme já dito anteriormente, quando uma atividade resulta em um domínio, todos os valores destes domínios devem ser mapeados no fluxo.
Da mesma forma, se uma notificação pode resultar em um Timeout pré-determinado, este também deve ser mapeado no fluxo.

Todas as atividades, quando adicionadas a um processo, têm uma opção que descreve seu objetivo:
- Start
- End
- Normal

As atividades (funções) de Start e End devem ter o objetivo Start e End respectivamente.
Mas a atividades comuns do meio do fluxo, bem como as notificações devem ter o objetivo Normal.

As notificações, quando adicionadas a um processo, têm ainda a opção “Perfomer” que indica a quem será destinada a notificação.

Em geral esta opção recebe um atributo do tipo role que será alimentado através de uma função prévia com as roles existentes nas tabelas que compõem o Serviço de Diretório do WorkFlow, descrito na subdivisão “Servidor Oracle” do nosso quadro (página 1).

Quando o destinatário de uma notificação for um conjunto de usuários, a opção “Expand Roles” da tela de notificações determinará se todos os usuários precisam ler/responder a notificação ou basta que o primeiro usuário da lista faça isso para que a notificação seja dada como encerrada.

Após criado seu conjunto de fluxos (Item Type) com subfluxos (processos), você pode salvá-lo em um Arquivo de Definição (.WFT) em seu diretório corrente no seu computador ou diretamente na base de dados.

Diferentemente de triggers, funções e procedures de banco, um fluxo WF não é um objeto único de banco. Ele é um conjunto de informações distribuídas em tabelas.



Escolha um nome interno, um nome de apresentação e uma descrição.
Associe a Mensagem já criada e um Lookup Type já criado se esta notificação resultar em um domínio.
Se esta notificação tiver um tempo limite para ser visualizada/respondida, especifique um “Timeout“ em dias, horas ou minutos na pasta Details.

Conforme já dito anteriormente, quando uma atividade resulta em um domínio, todos os valores destes domínios devem ser mapeados no fluxo.
Da mesma forma, se uma notificação pode resultar em um Timeout pré-determinado, este também deve ser mapeado no fluxo.

Todas as atividades, quando adicionadas a um processo, têm uma opção que descreve seu objetivo:
- Start
- End
- Normal

As atividades (funções) de Start e End devem ter o objetivo Start e End respectivamente.
Mas a atividades comuns do meio do fluxo, bem como as notificações devem ter o objetivo Normal.

As notificações, quando adicionadas a um processo, têm ainda a opção “Perfomer” que indica a quem será destinada a notificação.

Em geral esta opção recebe um atributo do tipo role que será alimentado através de uma função prévia com as roles existentes nas tabelas que compõem o Serviço de Diretório do WorkFlow, descrito na subdivisão “Servidor Oracle” do nosso quadro (página 1).

Quando o destinatário de uma notificação for um conjunto de usuários, a opção “Expand Roles” da tela de notificações determinará se todos os usuários precisam ler/responder a notificação ou basta que o primeiro usuário da lista faça isso para que a notificação seja dada como encerrada.

Após criado seu conjunto de fluxos (Item Type) com subfluxos (processos), você pode salvá-lo em um Arquivo de Definição (.WFT) em seu diretório corrente no seu computador ou diretamente na base de dados.

Diferentemente de triggers, funções e procedures de banco, um fluxo WF não é um objeto único de banco. Ele é um conjunto de informações distribuídas em tabelas.
Entre elas podemos destacar as principais tabelas de estrutura:

- WF_ITEM_TYPES = contem os conjuntos de fluxos
- WF_PROCESSES = contem os processos (subfluxos) criados para um Item Type
- WF_PROCESS_ACTIVITIES = contem as atividades que compoem os processos acima descritos, bem como as suas versões.

E as principais tabelas de execução:

- WF_ITEMS = contem as diversas execuções de um fluxo (processo principal) de um conjunto de fluxos (Item Type)
- WF_ACTIVITY_STATUSES = contem o detalhe (atividades) das execuções acima descritas. Ou seja, data de início e fim, status, etc...
- WF_ITEM_ATTRIBUTE_VALUES = contem os valores dos atributos das execuções acima descritas.

Podemos também criar um “Arquivo de Definição” e carregá-lo na base de dados (alimentando as tabelas de estrutura) através do “WF Loader” descrito na subdivisão “Cliente de Desenvolvimento Workflow” do nosso quadro (página 1).

Quem dará vida ao seu fluxo e controlará a execução de suas atividades será o “WF Engine”, descrito na subdivisão “Servidor Oracle” do nosso quadro (página 1).

A execução de um fluxo WF também é chamada de processo e armazenada nas tabelas do WF como “Item Keys”.
Um “Item Key” deve ser único por “Item Type”.
O WF Engine é um conjunto de packages API que nos permite criar, disparar, suspender, reativar e abortar processos.
Além disso ele também nos permite manipular as atividades, atribuir e ler valores de atributos, etc...

Vamos considerar o conjunto de fluxos abaixo:



Processo: PRINCIPAL



Package TESTE is

--=======================================================================
-- REG_ESTQ_TOXICO :
-- Registra Compra de Material Tóxico
--=======================================================================


Procedure REG_ESTQ_TOXICO ( ItemType in varchar2,
ItemKey in varchar2,
Actid in number,
Funcmode in varchar2,
Resultout out varchar2 ) is

Begin
--=========================================
-- RUN mode - normal process execution
--=========================================


If (funcmode = 'RUN') then

<>

--==========================================
-- Initializa atributos do workflow
--==========================================


Wf_engine.SetItemAttrDate(itemtype => ItemType,
itemkey => ItemKey,
aname => 'DATA_COMPRA',
avalue => sysdate );

resultout := 'COMPLETE:';
return;
End If;

Exception
When others then
Wf_core.context('TESTE',' REG_ESTQ_TOXICO',itemtype,itemkey,actid,funcmode);
raise;
End REG_ESTQ_TOXICO;

--=======================================================================
-- REG_ESTQ_COMUM :
-- Registra Compra de Material Comum
--=======================================================================


Procedure REG_ESTQ_COMUM ( ItemType in varchar2,
ItemKey in varchar2,
Actid in number,
Funcmode in varchar2,
Resultout out varchar2 ) is

Begin
--=========================================
-- RUN mode - normal process execution
--=========================================


If (funcmode = 'RUN') then

<>

--============================================
-- Atribuindo valores a atributos do workflow
--============================================


Wf_engine.SetItemAttrDate(itemtype => ItemType,
itemkey => ItemKey,
aname => 'DATA_COMPRA',
avalue => sysdate );

resultout := 'COMPLETE:';
return;
End If;

Exception
When others then
Wf_core.context('TESTE',' REG_ESTQ_COMUM',itemtype,itemkey,actid,funcmode);
raise;
End REG_ESTQ_COMUM;

--=======================================================================
-- VERIF_TIPO_MATERIAL :
-- Verifica o Tipo de Material a ser comprado
--=======================================================================


Procedure VERIF_TIPO_MATERIAL( ItemType in varchar2,
ItemKey in varchar2,
Actid in number,
Funcmode in varchar2,
Resultout out varchar2 ) is

V_tipo_material varchar2(240);

Begin
--=========================================
-- RUN mode - normal process execution
--=========================================

If (funcmode = 'RUN') then

<>

Select tipo_material
Into v_tipo_material
From tabela
Where condição;

< ... >

resultout := 'COMPLETE:'v_tipo_material;
return;
End If;

Exception
When others then
Wf_core.context('TESTE',
' VERIF_TIPO_MATERIAL',itemtype,itemkey,actid,funcmode);
raise;
End REG_ESTQ_COMUM;

End;

Para criação e disparo de um processo, considere o script abaixo:

--=============================================
--Disparando um processo
--Obs.: Vale lembrar que um Item Key é único!
--=============================================


Declare
v_itemtype varchar2 := 'TESTE';
v_workflowprocess varchar2 := 'PRINCIPAL';
v_itemkey varchar2 := 'T01';

Begin

wf_engine.CreateProcess(ItemType => v_itemtype,
ItemKey => v_itemkey,
Process => v_workflowprocess );

wf_engine.StartProcess( ItemType => v_itemtype,
ItemKey => v_itemkey );
End;


Para suspender um processo:

--=============================================
--Suspendendo um processo
--=============================================


Declare
v_itemtype varchar2 := 'TESTE';
v_workflowprocess varchar2 := 'PRINCIPAL';
v_itemkey varchar2 := 'T01';

Begin

wf_engine.SuspendProcess( ItemType => v_itemtype,
ItemKey => v_itemkey,
Process => v_workflowprocess );

End;

Para reativar um processo:

--=============================================
--Reativando um processo
--=============================================


Declare
v_itemtype varchar2 := 'TESTE';
v_workflowprocess varchar2 := 'PRINCIPAL';
v_itemkey varchar2 := 'T01';

Begin

wf_engine.ResumeProcess( ItemType => v_itemtype,
ItemKey => v_itemkey,
Process => v_workflowprocess );

End;

Para abortar um processo:

--=============================================
--Abortando um processo
--=============================================


Declare
v_itemtype varchar2 := 'TESTE';
v_workflowprocess varchar2 := 'PRINCIPAL';
v_itemkey varchar2 := 'T01';

Begin

wf_engine.AbortProcess( ItemType => v_itemtype,
ItemKey => v_itemkey,
Process => v_workflowprocess );

End;

Para atribuir valores a atributos de um processo:

--=============================================
--Atribuindo valores a atributos de um processo WF
--=============================================

Declare
v_itemtype varchar2 := 'TESTE';
v_itemkey varchar2 := 'T01';

Begin

Wf_engine.SetItemAttrDate(itemtype => v_itemtype,
itemkey => v_itemkey,
aname => 'DATA_COMPRA',
avalue => sysdate );

End;

Para ler valores de atributos de um processo:

--=============================================
--Lendo valores de atributos de um processo WF
--=============================================

Declare
v_itemtype varchar2 := 'TESTE';
v_itemkey varchar2 := 'T01';
v_datacompra date;

Begin

V_datacompra := Wf_engine.GetItemAttrDate(itemtype => v_itemtype,
itemkey => v_itemkey,
aname => 'DATA_COMPRA');

End;

Para consultar os valores de todos os atributos de um processo:

select *
from wf_item_attribute_values
where item_type = 'TESTE'
and item_key = 'T01';

Para acompanhar um processo:

select WPA.process_name
, WPA.activity_name
, to_char(WIAS.begin_date,'dd-mon-yyyy hh24:mi:ss') inicio
, to_char(WIAS.end_date,'dd-mon-yyyy hh24:mi:ss') fim
, wias.*
from wf_item_activity_statuses WIAS
, wf_process_activities WPA
where WIAS.process_activity = WPA.instance_id
and WPA.process_item_type = 'TESTE'
and WIAS.item_type = 'TESTE'
and WIAS.item_key = 'T01'
order by WPA.process_name;

A tabela wf_item_activity_statuses_H guarda todo o histórico da tabela wf_item_activity_statuses.

Por esta razão é preciso definir uma regra para limpeza da mesma.

Para as intalações de Workflow incorporadas ao ERP existe um concurrent responsável por este trabalho:

Purgue Obsolete Workflow (Parâmetros: Item Type, Número de dias de histórico).

Normalmente este Concurrent é programado para rodar diariamente mantendo um histórico de 2 dias.
Apenas os processos concluídos são excluídos.

Na versão mais nova do Workflow (WF Builder 2.6 – tanto incorporado ao ERP 11i quanto Standalone) o acompanhamento de um processo pode ser feito de forma gráfica através da opção WEB Process List do Workflow Monitor, descrita na subdivisão “Cliente do Usuário Final” do nosso quadro (página 1):


Os caminhos pintados em verde são os caminhos já percorridos pelo Background Engine.
Os subprocessos (em geral ícones do tipo engrenagem) podem ser vistos clicando duas vezes no mesmo, ou através dos botões “Zoom In” e “Zoom Out”.

A descrição, status, tipo, e outras informações de cada atividade podem ser vistas nas pastinhas:
- Definition
- Usage
- Status
- Notification (quando se trata de uma)
- Item

Também através do Workflow Monitor é possível visualizar os valores dos atributos através do botão “Attribute” e controlar a vida do processo através dos botões “Abort Process”, “Suspend Process” e “Resume Process”.

No Workflow Monitor, opção WEB Notification List, também descrita na subdivisão “Cliente do Usuário Final” do nosso quadro (página 1) é possível verificar e responder as notificações pendentes:


As notificações podem ainda ser verificadas e respondidas através de e-mail ou através da tela do módulo ERP a que pertencem.



Postar um comentário