Neste documento, será abordada uma estratégia para desenvolvimento de um processo de Workflow. Utilizando esta estratégia, será desenvolvido um processo simples. Ao final de cada seção, esta será exemplificada no processo que está sendo desenvolvido. = Desenvolvimento de um Processo = O processo de desenvolvimento pode, grosseiramente, ser dividido em três etapas: 1. Especificação 1. Projeto 1. Implementação == Especificação == Esta etapa é realizada através de reuniões como cliente que solicitou o processo de Workflow.Todos os dados relevantes ao processo devem ser documentados,conforme indicado no documento [wiki:WF_Documentacaominimadeprojeto Documentação mínima do Projeto] .Ao final desta etapa,o modo como o processo irá funcionar deve estar bem definido. === Exemplo === No nosso exemplo, devemos desenvolver um processo que gerencie "Solicitações". Antes de ser executada, a solicitação deve ser avaliada e aprovada por um distribuidor (pessoa que gerencia as solicitações). Dessa forma, temos dois caminhos distintos: 1. Caso a solicitação seja aprovada, ela vai para execução de um técnico que descreve o procedimento que foi feito para solucionar o problema. Ao final da execução, o solicitante recebe um e-mail passando informações sobre sua solicitação; 1. Caso a solicitação seja rejeitada, o solicitante recebe um e-mail informando sobre sua solicitação. ---- == Projeto == Nesta etapa os dados obtidos na etapa de especificação são mapeados para a realidade do Workflow. E, é possível definir alguns dados sobre o processo, por exemplo: quantos perfis ele terá, o número de atividades, o relacionamento entre elas, etc. === Exemplo === No nosso exemplo podemos perceber claramente a existência de três perfis: 1. Solicitante: grupo de pessoas que podem fazer solicitações; 1. Distribuidor: grupo de pessoas que avaliam as solicitações; 1. Técnico: grupo de pessoas que executam as solicitações aprovadas. As atividades são quatro: 1. Compor Solicitação: o perfil "solicitante" faz uma solicitação; 1. Avaliar: o perfil "distribuidor" avalia a solicitação; 1. Executar: o perfil "tecnico" executa as solicitações aprovadas; 1. Informar Resultado: o perfil "solicitante" vê as informações referentes à sua solicitação. Possíveis caminhos de execução: 1. Compor Solicitação -> Avaliar (Aprovada) -> Executar -> Informar Resultado 1. Compor Solicitação -> Avaliar (Rejeitada) -> Informar Resultado === Criação do Fluxo === Um dos passos mais importantes no desenvolvimento de um processo de Workflow é definir o fluxo do processo. O fluxo consiste no relacionamento das atividades através de transições. É importante também, quando retratar o fluxo, informar os perfis relacionados a cada atividade. O resultado da criação do fluxo é um dos mais importantes documentos para o processo de Workflow e que por si só é capaz de demonstrar o funcionamento de todo o sistema. === Exemplo === No nosso exemplo, foi criado o seguinte fluxo: [[Image(http://doc.workflow.celepar.parana/wiki/tutorial_solicitacoes.png)]] === Criação do Processo === Uma vez definido o fluxo do processo, é possível mapeá-lo para a engine do Workflow que estamos utilizando. Após esta etapa, cada uma das atividades que compõem o processo podem ser codificadas, dando funcionalidade às mesmas. === Exemplo === No nosso exemplo, vamos desenvolver esta etapa na seguinte ordem: 1. Criar o Processo; 1. Criar as Atividades / Transições / Perfis; 1. Mapear os Perfis. ==== Criar o processo ==== Na interface de Administração de [wiki:WF/Processos Processos], preenchemos: Nome do processo: Solicitações Descrição: Processo de gerenciamento de solicitações Para os outros campos, utilizam-se os valores padrões. Clicamos no botão "criar". ==== Criar as atividades / Transições / Perfis ==== Selecione a opção "Atividades". Quando o processo é criado, duas atividades são criadas com ele: a atividade do tipo start e de nome "start" e a atividade do tipo end e de nome "end". Selecionamos a atividade "start" e, mudamos / preenchemos os seguintes campos: {{{ Nome: Compor Solicitação Descrição: Atividade para o solicitante compor uma solicitação Interativa: marcar opção Roteamento Automático: marcar opção '''Adicionar perfil''' Nome: solicitante Descrição: autorizados a compor solicitações }}} Clicamos em "salvar". Selecionamos a atividade "end" e, mudamos / preenchemos os seguintes campos: {{{ Nome: Informar Resultado Descrição: Atividade para informar o solicitante sobre sua solicitação Interativa: marcar opção Roteamento Automático: marcar opção '''Usar perfis existentes''' Selecionar "solicitante" Clicamos em "salvar". Clicamos em "novo". Preenchemos os seguintes campos: {{{ Nome: Executar Descrição: Atividade para o técnico executar uma solicitação Tipo: activity Interativa: marcar opção Roteamento Automático: marcar opção '''Adicionar Transições''' : Adicionar transições para: "Informar Resultado" '''Adicionar perfil''' : Nome: tecnico : Descrição: autorizados a executar solicitações Clicamos em "salvar". Clicamos em "novo". Preenchemos os seguintes campos: Nome: Avaliar Descrição: Atividade para o distribuidor avaliar uma solicitação Tipo: switch Interativa: marcar opção Roteamento Automático: marcar opção '''Adicionar Transições''' : Adicionar transições de: "Compor Solicitação" : Adicionar transições para: "Executar" e "Informar Resultado" '''Adicionar perfil''' : Nome: distribuidor : Descrição: autorizados a avaliar solicitações Clicamos em "salvar". ==== Mapear os Perfis ==== Clicamos em "Perfis" Na área "Mapear usuários/grupos a perfis", selecionamos um dos perfis (no lado direito) e adicionamos os usuários que pertencem a este perfil. Depois, clicamos em "Mapear". Para finalizar, basta repetir este mesmo passo para os outros dois perfis. ---- == Implementação == Nesta etapa é feita a codificação das atividades que foram criadas na etapa anterior.Será utilizada a arquitetura [http://pt.wikipedia.org/wiki/MVCMVC] (''Model-View-Controller''). Consulte o documento [wiki:WF/MetodologiadeDesenvolvimento Metodologia de Desenvolvimento] para saber mais detalhes de como a arquitetura MVC está implementada no WorkflowdoExpresso. === Exemplo === Insiraoscódigos,listadosabaixo,nosrespectivosarquivos.Utilize,paraisso,oeditordecódigosPhpquejávemembutidonoWorkflow.(Vejaodocumento[wiki:WF_Ediçãodecódigo)] . ==== Atividades ==== '''Avaliar.php''' {{{ run($_REQUEST['action']); ?> }}} '''Compor_Solicitao.php''' {{{ run($_REQUEST['action']); ?> }}} '''Executar.php''' {{{ run($_REQUEST['action']); ?> }}} '''Informar_Resultado.php''' {{{ run($_REQUEST['action']); ?> }}} ==== Templates ==== '''templates/Avaliar.tpl''' {{{ {include file="info_solicitacao.tpl"}
}}} '''templates/Compor_Solicitao.tpl''' {{{
}}} '''templates/Executar.tpl''' {{{ {include file="info_solicitacao.tpl"}
Procedimento Executado:

}}} '''templates/Informar_Resultado.tpl''' {{{ {include file="info_solicitacao.tpl"}
Mensagem {$mensagem|nl2br}
}}} '''templates/info_solicitacao.tpl''' Por padrão, o Workflow cria um arquivo tpl para cada atividade interativa do processo. O arquivo info_solicitacao.tpl não corresponde a uma atividade, mas sim a um trecho de código que será incluído em outros arquivos tpl. Por isso, não estará na lista de arquivos já existentes, e deverá ser criado através da interface de código, aba templates, da seguinte maneira: 1 - Clique no botão 'Novo template'; 2 - Escolha a opção 'em_branco.tpl'; 3 - Informe o nome do arquivo e clique em OK 4 - Inclua o código abaixo {{{
Solicitante {$solicitante_desc}
Data {$data}
Título {$titulo}
Descrição {$descricao|nl2br}
}}} ==== Includes ==== Os próximos arquivos devem ser incluídos de forma semelhante como foi feito para o arquivo info_solicitação.tpl anteriormente, só que desta vez será usada a aba includes, da interface de código. Para cada arquivo a ser incluído, execute: 1 - Clique no botão 'Novo Include'; 2 - Escolha a opção 'em_branco.php'; 3 - Informe o nome do arquivo e clique em OK 4 - Inclua o código correspondente '''class.avaliar.controller.inc.php''' {{{ model->defaultAction(); $this->loadViewVars(); $this->showForm($this->AVALIAR); } function aprovar() { $this->model->aprovarAction(); } function rejeitar() { $this->model->rejeitarAction(); } function run($action) { $this->dispatch($action); } } ?> }}} '''class.avaliar.model.inc.php''' {{{ updateAttributes(); $this->addViewVar('titulo', $this->_titulo); $this->addViewVar('descricao', $this->_descricao); $this->addViewVar('data', $this->_data); $this->addViewVar('solicitante_desc', $this->_solicitante_desc); return true; } function aprovarAction() { $this->instance->setNextActivity('Executar'); $this->commitInstance(); return true; } function rejeitarAction() { $this->updateAttributes(); $this->instance->setNextActivity('Informar Resultado'); $this->instance->setNextUser($this->_solicitante); /* devolve a instância para o solicitante */ $this->_mensagem = "Sua solicitação foi rejeitada"; $this->updateInstance(); $this->commitInstance(); return true; } } ?> }}} '''class.compor.solicitacao.controller.inc.php''' {{{ model->defaultAction(); $this->loadViewVars(); $this->showForm($this->COMPOR_SOLICITACAO); } function enviar() { $this->model->enviarAction(); $this->loadViewVars(); } function run($action) { $this->dispatch($action); } } ?> }}} '''class.compor.solicitacao.model.inc.php''' {{{ _titulo = $form['titulo']; else $msgerro[] = 'É necessário fornecer um título'; if (isset($form['descricao']) && !empty($form['descricao'])) $this->_descricao = $form['descricao']; else $msgerro[] = 'É necessário fornecer uma descrição'; return $msgerro; } function enviarAction() { /* se não houve erros */ if (count($this->activity->error = $this->inputValidate($this->request)) == 0) { $this->_solicitante = $this->getWfProperty('wf_user_id'); $this->_solicitante_desc = $this->getWfProperty('wf_user_cnname'); $this->_data = date('d/m/Y H\hi'); $this->updateInstance(); $this->commitInstance(); return true; } else { $this->addViewVar('titulo', $this->_titulo); $this->addViewVar('descricao', $this->_descricao); return false; } } } ?> }}} '''class.controller.inc.php''' {{{ super(&$model , &$env); } } ?> }}} '''class.executar.controller.inc.php''' {{{ model->defaultAction(); $this->loadViewVars(); $this->showForm($this->EXECUTAR); } function finalizar() { $this->model->finalizarAction(); } function run($action) { $this->dispatch($action); } } ?> }}} '''class.executar.model.inc.php''' {{{ updateAttributes(); $this->addViewVar('titulo', $this->_titulo); $this->addViewVar('descricao', $this->_descricao); $this->addViewVar('data', $this->_data); $this->addViewVar('solicitante_desc', $this->_solicitante_desc); return true; } function finalizarAction() { $this->updateAttributes(); $this->_mensagem = "Sua solicitação foi atendida pelo técnico " . $this->getWfProperty('wf_user_cnname') . ".\nProcedimento executado:\n" . $this->request['procedimento']; $this->updateInstance(); $this->instance->setNextUser($this->_solicitante); /* devolve a instância para o solicitante */ $this->commitInstance(); return true; } } ?> }}} '''class.informar.resultado.controller.inc.php''' {{{ model->defaultAction(); $this->loadViewVars(); $this->showForm($this->INFORMAR_RESULTADO); } function encerrar() { $this->model->encerrarAction(); } function run($action) { $this->dispatch($action); } } ?> }}} '''class.informar.resultado.model.inc.php''' {{{ updateAttributes(); $this->addViewVar('titulo', $this->_titulo); $this->addViewVar('descricao', $this->_descricao); $this->addViewVar('data', $this->_data); $this->addViewVar('solicitante_desc', $this->_solicitante_desc); $this->addViewVar('mensagem', $this->_mensagem); return true; } function encerrarAction() { $this->commitInstance(); return true; } } ?> }}} '''class.model.inc.php''' {{{ super(&$env); } } ?> }}} '''shared.php''' {{{ }}} ==== Finalização ==== Para finalizar o processo,é necessário compilá-lo e ativá-lo.Para isto,acessamos a interface de Administração de [wiki:WF/Processos Processos] ,abrimos o nosso processo e clicamos em "Compilação" e depoi sem "ativar".Uma vez feito isso,o processo estará disponível aquem tem direito(os que estão nos perfis do processo). Para colocar um ícone que representa o processo, basta inserir uma imagem de 32x32 pixels de nome "icon.png" no diretório resources do processo.