Introdução
Nesse vigésimo quarto post vou fazer algumas correções e melhorias na nossa aplicação.
Correção na Execução do BPM
No post anterior eu identifiquei que tinha uma falha, antes de finalizar a execução do fluxo a conta lançada estava aparecendo, isso aconteceu porque eu utilizei o próprio atributo autorizado da entidade LancamentoEntity na resposta de aprovação de cada um dos cargos. Vou corrigir fazendo a seguinte alteração, primeiro criando uma variável transient no LancamentoEntity conforme a seguir:
LancamentoEntity.java:
/* CODIGO ANTERIOR OCULTADO */
@Transient
private transient boolean aprovado;
/* CODIGO OMITIDO */
public boolean isAprovado() {
return aprovado;
}
public void setAprovado(boolean aprovado) {
this.aprovado = aprovado;
}
/* CODIGO POSTERIOR OMITIDO */
E no lancamentoData.xhtml faço a alteração apontando para o atributo acima:
lancamentoData.xhtml:
/* CODIGO ANTERIOR OMITIDO */<h:panelGroup rendered="#{lancamentoDataAction.idDynamicAction eq 'idAvaliarLancamento'}">
<a:outputLabel value="#{e:bundle('label.aprovado')}" for="idLancamentoAprovacao"/>
<br/>
<a:toggleSwitch id="idLancamentoAprovacao"
label="#{e:bundle('label.aprovado')}"
value="#{lancamentoDataAction.entity.aprovado}"/>
</h:panelGroup>/* CODIGO POSTERIOR OMITIDO */
E pra finalizar vou alterar o LancamentoObserver, mudando o evento para Before e setar a variável de aprovação no fluxo conforme o atributo aprovado no lugar de autorizado conforme a seguir:
LancamentoObserver.java:
/* CODIGO ANTERIOR OMITIDO */private void avaliacao(@Observes @JArchEventDynamicBefore("idAvaliarLancamento") LancamentoEntity lancamento,
UserInformation userInformation, TaskService taskService) {
UsuarioEntity usuarioLogado = userInformation.get(UsuarioEntity.class);
String variavelAprovacao;
if (usuarioLogado.getCargo() == CargoType.SUPERVISOR) {
variavelAprovacao = "aprovadoSupervisor";
} else if (usuarioLogado.getCargo() == CargoType.GERENTE) {
variavelAprovacao = "aprovadoGerente";
} else {
variavelAprovacao = "aprovadoDiretor";
}
taskService.complete(lancamento.getTask().get().getId(),
Map.of(variavelAprovacao, lancamento.isAprovado(),
"valorLancamento", lancamento.getValor().doubleValue()));
}/* CODIGO POSTERIOR OMITIDO */
E no bundle:
bundle_pt_BR.properties:
label.aprovado=Aprovado
Após a compilação e execução de uma nova instância no fluxo:
E entrando na tela de lançamento não aparece a conta que está em analise no fluxo:
Filtro Relatório Lançamento
O relatório de lançamento tem um falha, não está filtrando o tipo de lançamento (Pagar / Receber). Vou alterar o filtro do relatório para contemplar o tipo de laçamento e também para filtrar somente os lançamentos autorizados. Vou adicionar no filtro do método selecionaDados():
RelatorioLancamentoAction.java:
/* CODIGO ANTERIOR OMITIDO */private Collection<LancamentoEntity> selecionaDados() {
boolean filtraBanco = !excetoBanco && bancos != null && !bancos.isEmpty();
boolean filtraExcetoBanco = excetoBanco && bancos != null && !bancos.isEmpty();
boolean filtraCentroCusto = !excetoCentroCusto && centroCustos != null && !centroCustos.isEmpty();
boolean filtraExcetoCentroCusto = excetoCentroCusto && centroCustos != null && !centroCustos.isEmpty();
boolean filtraCategoria = !excetoCategoria && categorias != null && !categorias.isEmpty();
boolean filtraExcetoCategoria = excetoCategoria && categorias != null && !categorias.isEmpty();
boolean filtraPessoa = !excetoPessoa && pessoas != null && !pessoas.isEmpty();
boolean filtraExcetoPessoa = excetoPessoa && pessoas != null && !pessoas.isEmpty();
return lancamentoFacade
.clientJpaql()
.where()
.contains(filtraBanco, LancamentoEntity_.banco, bancos)
.and(filtraBanco)
.notContains(filtraExcetoBanco, LancamentoEntity_.banco, bancos)
.and(filtraExcetoBanco)
.contains(filtraCentroCusto, LancamentoEntity_.centroCusto, centroCustos)
.and(filtraCentroCusto)
.notContains(filtraExcetoCentroCusto, LancamentoEntity_.centroCusto, centroCustos)
.and(filtraExcetoCentroCusto)
.contains(filtraCategoria, LancamentoEntity_.categoria, categorias)
.and(filtraCategoria)
.notContains(filtraExcetoCategoria, LancamentoEntity_.categoria, categorias)
.and(filtraExcetoCategoria)
.contains(filtraPessoa, LancamentoEntity_.pessoa, pessoas)
.and(filtraPessoa)
.notContains(filtraExcetoPessoa, LancamentoEntity_.pessoa, pessoas)
.and(filtraExcetoPessoa)
.greaterOrEqualsThan(vencimentoInicio != null, LancamentoEntity_.vencimento, vencimentoInicio)
.and(vencimentoInicio != null)
.lessOrEqualsThan(vencimentoFim != null, LancamentoEntity_.vencimento, vencimentoFim)
.and(vencimentoFim != null)
.equalsTo(LancamentoEntity_.tipoLancamento, tipoLancamento)
.and()
.equalsTo(LancamentoEntity_.autorizado, true)
.collect()
.list();
}/* CODIGO POSTERIOR OMITIDO */
Agora ao tentar imprimir o relatório:
Filtro Alertas e Mensagens
Os alertas e mensagens gerados também não possuí o filtro de contas autorizadas. Então vou corrigir isso também. Para isso preciso alterar os métodos contaPagarAbertoAte() e contaPagarAbertoEm() do LancamentoFacade adicionado o filtro de autorizado.
LancamentoFacade.java:
LancamentoFacade.java:
/* CODIGO ANTERIOR OMITIDO */
public Collection<LancamentoEntity> contaPagarAbertoAte(LocalDate vencimento) {
return clientJpaql()
.where()
.equalsTo(LancamentoEntity_.aberto, true)
.and()
.equalsTo(LancamentoEntity_.tipoLancamento, TipoLancamentoType.PAGAR)
.and()
.equalsTo(LancamentoEntity_.autorizado, true)
.and()
.lessOrEqualsThan(LancamentoEntity_.vencimento, vencimento)
.collect()
.list();
}
public Collection<LancamentoEntity> contaPagarAbertoEm(LocalDate vencimento) {
return clientJpaql()
.where()
.equalsTo(LancamentoEntity_.aberto, true)
.and()
.equalsTo(LancamentoEntity_.tipoLancamento, TipoLancamentoType.PAGAR)
.and()
.equalsTo(LancamentoEntity_.autorizado, true)
.and()
.equalsTo(LancamentoEntity_.vencimento, vencimento)
.collect()
.list();
}/* CODIGO ANTERIOR OMITIDO */
Alterando Ícones Dashboard
Vou alterar o ícones dos cards dos lançamentos de contas pagar e receber para ficar com uma aparência melhor:
bemVindo.xhtml:
<e:dashboardUnity icon="fa fa-coins fa-5x"
classMinHeight="h100"
styleIcon="color: orange"
title="#{bemVindoAction.quantidadeContaPagar}"
labelButtonLink="#{e:bundle('label.acessar')}"
link="../lancamento/lancamentoList.jsf?tipo=PAGAR"
descriptionLink="#{e:bundle('message.acessarPagina')}"/>
<e:dashboardUnity icon="fa fa-hand-holding-usd fa-5x"
classMinHeight="h100"
styleIcon="color: red"
title="#{bemVindoAction.quantidadeContaPago}"
labelButtonLink="#{e:bundle('label.acessar')}"
link="../lancamento/lancamentoList.jsf?tipo=PAGAR"
descriptionLink="#{e:bundle('message.acessarPagina')}"/>
<e:dashboardUnity icon="fa fa-donate fa-5x"
classMinHeight="h100"
styleIcon="color: blue"
title="#{bemVindoAction.quantidadeContaReceber}"
labelButtonLink="#{e:bundle('label.acessar')}"
link="../lancamento/lancamentoList.jsf?tipo=RECECER"
descriptionLink="#{e:bundle('message.acessarPagina')}"/>
<e:dashboardUnity icon="fa fa-comments-dollar fa-5x"
classMinHeight="h100"
styleIcon="color: green"
title="#{bemVindoAction.quantidadeContaRecebido}"
labelButtonLink="#{e:bundle('label.acessar')}"
link="../lancamento/lancamentoList.jsf?tipo=RECEBER"
descriptionLink="#{e:bundle('message.acessarPagina')}"/>
Agora a aparência ficou como:

Alterando Tempo Sessão
Atualmente a aplicação está com o tempo de 5 minutos para usuários Administrador, Operador e Supervisor e 1 minuto para usuários Gerente e Diretor. Vou alterar para 30 minutos e 10 minutos. Alterando primeiro o web.xml do contas-web:
web.xml:
<session-config>
<session-timeout>30</session-timeout>
</session-config>
E no LoginObserver ajusto para 10 minutos se cargos igual Gerente ou Diretor:
public class LoginObserver {
private void login(@Observes @JArchEventLoginAfter UsuarioEntity usuario, AlertaFacade alertaFacade, MensagemFacade mensagemFacade) {
alertaFacade.atualizaAlertaSessao();
mensagemFacade.atualizaMensagemSessao();
if (usuario.getCargo().equals(CargoType.DIRETOR) || usuario.getCargo().equals(CargoType.GERENTE)) {
JsfUtils.getSession().setMaxInactiveInterval(600);
}
}
}
Constant
Uma boa prática é definir String literal como variável do tipo final, principalmente aquelas que são utilizadas mais de uma vez. Por exemplo, no BPM defini o id do fluxo como process-avaliacao-conta. Essa mesma String é utilizada em mais de um lugar, dentro do LancamentoObserver e no AutorizacaoLancamentoListTaskAction. Então vou criar uma classe Constant dentro do pacote raiz no contas-client, somente para armazenar essas essas constants.
Constant.java:
public final class Constant {public static final String PROCESS_AVALIACAO_CONTA = "process-avaliacao-conta";private Constant() {
}
}
E substituo em todos os lugares que faziam referência conforme a seguir:
LancamentoObserver.java:
runtimeService
.createProcessInstanceByKey(Constant.PROCESS_AVALIACAO_CONTA)
.businessKey(lancamento.getId().toString())
.setVariable("descricao", lancamento.getDescricao())
.setVariable("valor", lancamento.getValor().doubleValue())
.setVariable("vencimento", lancamento.getVencimento())
.execute();
AutorizacaoLancamentoListTaskAction:
TaskQuery taskQuery = processEngine
.getTaskService()
.createTaskQuery()
.processDefinitionKey(Constant.PROCESS_AVALIACAO_CONTA)
.active()
.initializeFormKeys()
.withCandidateGroups()
.taskCandidateGroup(usuarioLogado.getCargo().name())
.includeAssignedTasks();
Fica como dica sempre adotar esse mesmo procedimento para quaisquer String literais com mais de uma ocorrência.
Cargo Usuário
Pra finalizar vou adicionar 5 métodos no CargoType, assim não precisarei mais fazer essas comparações de getCargo() com o Enumerado. Vou criar os métodos isOperador(), isSupervisor(), isGerente(), isDiretor() e isAdministrador() no CargoType. Segue a implementação:
CargoType.java:
/* CODIGO ANTERIOR OMITIDO */
public boolean isOperador() {
return this == OPERADOR;
}
public boolean isSupervisor() {
return this == SUPERVISOR;
}
public boolean isGerente() {
return this == GERENTE;
}
public boolean isDiretor() {
return this == DIRETOR;
}
public boolean isAdministrador() {
return this == ADMINISTRADOR;
}/* CODIGO POSTERIOR OMITIDO */
Agora é só substituir em todos os fontes que faziam a comparação.
Nesse post fiz algumas correções e melhorias na aplicação. Nos próximos posts vou adicionar mais recursos do BPM.
Nenhum comentário:
Postar um comentário