sábado, 27 de junho de 2020

Contas Pagar/Receber - Parte VIII - Ações Dinâmicas

Introdução
Nesse oitavo post vou mostrar como criar ações dinâmicas para efetuar o pagamento da conta. As ações dinâmicas podem ser criadas com as seguintes anotações: @JArchDynamicDirectAction, @JArchDynamicShowDataAction e @JArchDynamicDownlod. Para mostrar o uso dessas ações vou fazer um exemplo com cada uma delas. Vou mostrar também um exemplo do evento @JArchEventCreateEntity.

@JArchEventCreateEntity
Essa evento é disparado sempre que uma instância da entidade for criada através do botão incluir da tela de lista. Vou usar esse evento para preencher o atributo aberto do lançamento para true (indicando que a conta está em aberto), segue a codificação desse evento:
LancamentoObserver.java:

private void criacaoLancamento(@Observes @JArchEventCreateEntity LancamentoEntity lancamento) {
lancamento.setAberto(true);
}


@JArchDynamicDirectAction
Essa anotação vai gerar uma ação dinâmica que será executado na tela de lista sem mostrar a tela de dados. Essa anotação é utilizado direto em um método da action de Lista, esse método tem que retornar void e receber como parâmetro a Entity ou List (esse será mostrado num post futuro). Vamos criar uma ação dinâmica para efetuar a baixa de uma conta, conforme código abaixo:
LancamentoListAction.java:

@JArchDynamicDirectAction(id = "idBaixarLancamento", labelMenu = "label.baixar", headerConfirmation = "message.baixarConta", messageConfirmation = "message.confirmarBaixaDessaConta")
public void baixaConta(LancamentoEntity lancamento) {
getFacade().baixaConta(lancamento);
}

No exemplo anterior foi utilizado a anotação para criar a ação dinâmica de baixar, configurando o headerMessage e messageConfirmation. Na implementação desse método foi efetuado a chamada do método baixaConta da fachada, conforme código:
LancamentoFacade.java:

public class LancamentoFacade extends CrudFacade<LancamentoEntity, ILancamentoManager> {

public void baixaConta(LancamentoEntity lancamento) {
lancamento.setAberto(false);
change(lancamento);
}
}
bundle_pt_BR.properties:
message.baixarConta=Baixa Conta
message.confirmarBaixaDessaConta=Confirmar baixa dessa conta ?
Segue o resultado dessa configuração:



@JArchDynamicShowDataAction
Essa anotação vai gerar uma ação dinâmica que será executado na tela de lista e vai entrar na tela de dados. Essa anotação é utilizado direto na classe da action de lista. Na anotação será configurado qual método será chamado dentro da tela de dados quando clicar no botão da ação. O método configurado na anotação deve ser void sem parametro. Vamos criar uma ação dinâmica desse tipo para cancelar a baixa de uma conta, conforme código abaixo:
LancamentoListAction.java:

@JArchDynamicShowDataAction(id = "idCancelarBaixaLancamento", labelMenu = "label.cancelarBaixa", labelButton = "label.cancelarBaixa", nameMethodDataAction = "cancelaBaixaLancamento", confirmation = true, headerConfirmation = "message.cancelarBaixa", messageConfirmation = "message.confirmarCancelamentoBaixaDessaConta")
@JArchViewScoped
public class LancamentoListAction extends CrudListAction<LancamentoEntity, LancamentoFacade> {

Acima foi definido a ação dinâmica que será concluído através do método cancelaBaixaLancamento da action de dados.
LancamentoDataAction.java:

public void cancelaBaixaLancamento() {
getFacade().cancelaBaixaLancamento(getEntity());
}

LancamentoFacade.java:

public void cancelaBaixaLancamento(LancamentoEntity lancamento) {
lancamento.setAberto(true);
change(lancamento);
}
bundle_pt_BR.properties:
label.cancelarBaixa=Cancelar Baixa
message.cancelarBaixa=Cancelar Baixa
message.confirmarCancelamentoBaixaDessaConta=Confirmar cancelamento de baixa dessa conta ?
Segue o resultado dessa configuração:




@JArchDynamicDownload
Essa anotação vai gerar uma ação dinâmica pra efetuar um download, que será executado na tela de lista. Essa anotação é utilizado direto no método na classe da action de lista. O método configurado na anotação deve retornar um StremeadContent e receber como parametro a entidade ou um list. Vou criar uma ação dinâmica desse tipo para fazer o download do comprovante da baixa de uma conta:
LancamentoListAction.java:

@JArchDynamicDownload(id = "idDownloadComprovanteBaixa", labelMenu = "label.comprovanteBaixa")
public StreamedContent downloadComprovanteBaixa(LancamentoEntity lancamento) {
return getFacade().downloadComprovanteBaixa(lancamento);
}

LancamentoFacade.java:

public StreamedContent downloadComprovanteBaixa(LancamentoEntity lancamento) {
Document document = new Document();
try {
File file = File.createTempFile("comprovante", ".pdf");
FileOutputStream fileOutputStream = new FileOutputStream(file);
PdfWriter.getInstance(document, fileOutputStream);
document.open();
document.add(new Paragraph("Comprovante de Pagamento Conta " + lancamento.getTipoLancamento().getDescription()));
document.add(new Paragraph("Codigo......: " + lancamento.getCodigo()));
document.add(new Paragraph("Descrição...: " + lancamento.getDescricao()));
document.add(new Paragraph("Banco.......: " + lancamento.getBanco().getCodigo() + " - " + lancamento.getBanco().getNome()));
document.add(new Paragraph("Centro Custo: " + lancamento.getCentroCusto().getCodigo() + " - " + lancamento.getCentroCusto().getDescricao()));
document.add(new Paragraph("Categoria...: " + lancamento.getCategoria().getCodigo() + " - " + lancamento.getCategoria().getDescricao()));
document.add(new Paragraph("Pessoa......: " + CpfCnpjUtils.formataCpfCnpj(lancamento.getPessoa().getCpfCnpj()) + " - " + lancamento.getPessoa().getNome()));
document.add(new Paragraph("Vencimento..: " + DateUtils.formatddMMyyyy(lancamento.getVencimento())));
document.add(new Paragraph("Valor.......: " + NumberUtils.formatMoney(lancamento.getValor())));
document.add(new Paragraph("Código de autenticação: " + Md5Utils.generate(NumberUtils.formatZeroLeft(lancamento.getId(), 10))));
document.close();
return new DefaultStreamedContent(new FileInputStream(file), FileType.PDF.getContentType(), "comprovante.pdf");
} catch(DocumentException | IOException ioe) {
throw new ValidationException("Erro na geração do comprovante...");
} finally {
document.close();
}
}
bundle_pt_BR.properties:

label.comprovanteBaixa=Comprovante Baixa

Segue o resultado dessa configuração:


Melhorias
As ações dinâmicas acima estão funcionando perfeitamente, mas preciso fazer algumas melhorias. A primeira melhoria que vou fazer e colocar que a ação dinâmica de Baixar vai ficar sempre antes da ação dinâmica Cancelar Baixa e depois a ação de Comprovante Baixa no menu. Para isso basta somente preencher o atributo order das anotações:

LancamentoListAction.java:

@JArchDynamicDirectAction(id = "idBaixarLancamento", labelMenu = "label.baixar", headerConfirmation = "message.baixarConta", messageConfirmation = "message.confirmarBaixaDessaConta", order = 1)
public void baixaConta(LancamentoEntity lancamento) {
getFacade().baixaConta(lancamento);
}


@JArchDynamicShowDataAction(id = "idCancelarBaixaLancamento", labelMenu = "label.cancelarBaixa", labelButton = "label.cancelarBaixa",
nameMethodDataAction = "cancelaBaixaLancamento", confirmation = true, headerConfirmation = "message.cancelarBaixa", messageConfirmation = "message.confirmarCancelamentoBaixaDessaConta", order = 2)
@JArchViewScoped
public class LancamentoListAction extends CrudListAction<LancamentoEntity, LancamentoFacade> {


@JArchDynamicDownload(id = "idDownloadComprovanteBaixa", labelMenu = "label.comprovanteBaixa", order = 3)
public StreamedContent downloadComprovanteBaixa(LancamentoEntity lancamento) {
return getFacade().downloadComprovanteBaixa(lancamento);
}

O resultado dessa alteração acima:

Agora a segunda melhoria é somente habilitar a ação de Baixar caso a conta esteja em aberto. Para isso basta configurar o atributo elDisabled da anotação:
LancamentoListAction.java:

@JArchDynamicDirectAction(id = "idBaixarLancamento", labelMenu = "label.baixar", headerConfirmation = "message.baixarConta", messageConfirmation = "message.confirmarBaixaDessaConta", order = 1, elDisabled = "#{(l -> not l.aberto)(lancamento)}" )
public void baixaConta(LancamentoEntity lancamento) {
getFacade().baixaConta(lancamento);
}

A terceira melhoria é somente habilitar a ação de Cancelar Baixa caso a conta esteja baixado. Para isso basta configurar o atributo elDisabled da anotação:
LancamentoListAction.java:

@JArchDynamicShowDataAction(id = "idCancelarBaixaLancamento", labelMenu = "label.cancelarBaixa", labelButton = "label.cancelarBaixa", nameMethodDataAction = "cancelaBaixaLancamento", confirmation = true, headerConfirmation = "message.cancelarBaixa", messageConfirmation = "message.confirmarCancelamentoBaixaDessaConta", order = 2, elDisabled = "#{(l -> l.aberto)(lancamento)}")
@JArchViewScoped
public class LancamentoListAction extends CrudListAction<LancamentoEntity, LancamentoFacade> {

A quarta melhoria é somente habilitar a ação de Comprovante Baixa caso a conta esteja baixado. Para isso basta configurar o atributo elDisabled da anotação:
LancamentoListAction.java:

@JArchDynamicDownload(id = "idDownloadComprovanteBaixa", labelMenu = "label.comprovanteBaixa", order = 3,
elDisabled = "#{(l -> l.aberto)(lancamento)}")
public StreamedContent downloadComprovanteBaixa(LancamentoEntity lancamento) {
return getFacade().downloadComprovanteBaixa(lancamento);
}

Para os 3 itens anteriores falta somente configurar a variável lancamento no componente e:divListDatatable no atributo varRowDataTable da tela de lista, conforme exemplo:
lancamentoList.xhtml:

<e:divListDatatable id="listEntityDataTableLancamento"
title="#{e:bundle('label.lista')} - #{lancamentoListAction.tipoLancamento.description}"
actionList="#{lancamentoListAction}" showColumnsTotalizer="true" varRowDataTable="lancamento" />

Após essas configurações o resultado será esse:

Repare que os itens Cancelar Baixa e Comprovante Baixa estão desabilitados porque a conta não está baixada. Efetuando a baixa dessa conta temos:

Após a baixa as ações de Cancelar Baixa e Comprovante Baixa foram ativadas e a de Baixar ficou desabilitado.

Pra finalizar as melhorias vamos somente adicionar a coluna aberto no grid de pesquisa:
package-info.java

@JArchColumnDataTable(clazzEntity = LancamentoEntity.class, attribute ="aberto", title = "label.aberto", width = 60, type = FieldType.BOOLEAN)

E agora temos a seguinte lista de lançamento com a coluna aberto:

Conclusão
Nesse post mostrei como utilizar as ações dinâmicas, e como podemos desabilita-las de acordo com uma expressão. Demonstrei o uso e utilidade dos 3 tipos de anotações dinâmicas. No próximo post vou explorar ainda mais recursos do JARCH. 

Segue o link dessa video aula: https://youtu.be/e4k3OhQ28Qc

Até mais,


Nenhum comentário:

Postar um comentário

Versão 23.3.0-Final

      Introdução Nesse post vou mostrar as principais novidades da versão 23.3.0, algumas correções e pequenas alterações. Alterações Além d...