Wednesday, December 17, 2014

Agrupar, Ordenar por Fechas y Totalizar con Java 8

Agrupar, Ordenar por Fechas y Totalizar con Java 8


Tenemos una lista de registros de recibosdetalles.


Deseamos agruparlos por idnivel6 y luego por fecha, y encontrar el total por cada fecha del idnivel6.
Similar a la salida que se muestra a continuacion
ordenar.png


Primero obtenemos los registros
2d.png
filtrados por fecha


  recibosdetallesList = recibosdetallesFacade.findByEntreFechas(desde, hasta);


 /*
                0. elimino los recibosdetalles cuyos recibos fueran anualados
                */
               recibosdetallesList.stream().filter((r) -> (r.getIdrecibo().getAnulado().equals("si"))).forEach((r) -> {
                   recibosdetallesList.remove(r);
               });


//IMPRIMIR LOS DETALLES
 System.out.println("!================= Recibos Detalles =====================!");
               recibosdetallesList.forEach(p
                       -> System.out.println(p.getIdrecibo().getIdrecibo() + " ---> " + p.getIdnivel6().getIdnivel6() + " --> " + p.getFecha()));

/*
                1. Agruparlos por nivel6
                */
               Map<Nivel6, List<Recibosdetalles>> listRecibosdetallesAgrupado = recibosdetallesList
                       .stream()
                       .collect(Collectors.groupingBy(p -> p.getIdnivel6()));


  /*
                2. Recorrer los agrupados por nivel6
                */
               System.out.println("!============== <AGRUPADOS POR NIVEL 6< ==================!");
               listRecibosdetallesAgrupado
                       .forEach((Nivel6 idnivel6, List<Recibosdetalles> p) -> {
                           /*
                            2.1 Imprime cada nivel6 agrupado
                            */
                           System.out.println("====================================================");
                           System.out.println("Nivel6: " + idnivel6.getIdnivel6());


                           /*
                            2.3 Agrupo por fecha                                
                            */
                           Map<Date, List<Recibosdetalles>> listFecha = p
                           .stream()
                           .collect(Collectors.groupingBy(p2 -> p2.getFecha()));


                           /*
                            2.3 Recorro la agrupacion por fecha
                            */
                           listFecha
                           .forEach((Date fecha, List<Recibosdetalles> p3) -> {


                               System.out.println("Fecha: " + fecha);
                               /*
                                2.4 Recorro la lista ordenada y sumo los montos de las fechas
                                */
                               System.out.println(" ---------total: " + totalizarFecha(p3));


                           });


                     

                       });

private Double totalizarFecha(List<Recibosdetalles> p3) { try { Double s = 0.0; s = p3.stream().map((i) -> i.getPago()).reduce(s, (accumulator, _item) -> accumulator + _item); return s; } catch (Exception e) { JSFUtil.addErrorMessage("totalizarFecha() " + e.getLocalizedMessage()); } return 0.0; }

Tuesday, December 16, 2014

Ordenar List y agrupar con Java 8

Ordenar List y agrupar con Java 8


Proyecto: Rigemjsf
Clase: InformeConsolidadoController.java


Queremos un informe agrupado por idnivel5 y totalizar cada idnivel6.




Tenemos un Beans llamado consolidado


@Named
@RequestScoped
public class Consolidado {
private Date fecha;
private String nombre;
private Integer idrecibo;
private Double pago;
private String idnivel6;
private String nombrenivel6;
private String idnivel5;
private String nombrenivel5;









 public String imprimirTodos() {
       try {
           /*
           agruparlo por idnivel6
            */


Map<String, List<Consolidado>> listAgrupado = listConsolidado
                   .stream()
                   .collect(Collectors.groupingBy(p -> p.getIdnivel6()));


           //recorrer el list
           listAgrupado
                   .forEach((String idnivel6, List<Consolidado> p) -> {
                       add(p);
                   });


//Ordenarlo por nivel5


           Collections.sort(listConsolidadoFinal,
                   (Consolidado a, Consolidado b) -> a.getIdnivel5().compareTo(b.getIdnivel6()));
           


         
       } catch (Exception ex) {
           JSFUtil.addErrorMessage("imprimir() " + ex.getLocalizedMessage());
       }
       return null;
   }
   /*
    anade a la lista final la sumatoria
    */
//Aqui totalizamos y agregamos objetos al  nuevo list
     private void add(List<Consolidado> list) {
       try {
           Double s = 0.0;
           s = list.stream().map((i) -> i.getPago()).reduce(s, (accumulator, _item) -> accumulator + _item);
           Consolidado icr = new Consolidado();
           icr = list.get(0);
           icr.setPago(s);
           listConsolidadoFinal.add(icr);
       } catch (Exception e) {
           JSFUtil.addErrorMessage("add() " + e.getLocalizedMessage());
       }


   }


   }

Sunday, December 07, 2014

Libro JEE7 Capítulo 0. Búsquedas

Capítulo 7. Búsquedas
Puedes descargarlo en pdf
https://www.dropbox.com/sh/yzivtufjce1h57g/AAAJzegPVBxFtiqzEOlIAdsoa?dl=0

Encuesta
https://docs.google.com/forms/d/1WG7uzOe17V4u36fC05V3ijYEPZ8fhJD1NPUrkNBS0Jk/alreadyresponded?usp=send_form




Formulario de Búsqueda con DialogFrame


Crearemos un formulario de búsqueda que se podrá invocar desde cualquier formulario o CDI/Beans.


al dar clic en buscar, nos llevará al diálogo para realizar las búsquedas








Para el manejo de registros, a veces no deseamos tener un datatable con todos los registros cargados, si no simplemente un formulario, en el cual podamos realizar búsquedas de manera rápida, cuando lo hacemos por la llave primaria es sencillo ya que solo tendremos un registro, cuando lo hacemos por otros atributos tendremos una lista de registros en los cuales podemos seleccionar uno de ellos, esta lista se mostrará en un dialog, para que el usuario seleccione el registro adecuado.

Crearemos un formulario para realizar búsquedas por cualquier atributo , por palabras exactas o mediante aproximación.


















Pasos:
  1. Editar el CDI Beans EstatusController, inyectar CDI Beans Globales,crear el método init() con la anotación @PostConstructor.


@Inject
   GestorImpresion gestorImpresion;

@PostConstruct
   public void init() {
       //nomnbre de la pagina a retornar
       globales.setUltimapagina("estatusinsert");
      // encontrado = false;
       if (globales.getEstatus().getIdestatus() != "") {
           estatus = globales.getEstatus();
       //    encontrado = true;
       }
   }




  1. Crear CDI EstatusSearchController.java que usaremos para realizar las búsquedas.


  • Desde menú File, seleccione New
  • en Categories, seleccione Java Server Faces
  • en File Types, seleccione JSF ManagedBeans
  • Class Name: EstatusSearchController
  • Package com.avbravo.scrumweb.controlller.net
  • Scope: ViewScoped


import com.avbravo.scrumweb.Estatus;
import com.avbravo.scrumweb.ejb.EstatusFacade;
import com.avbravo.scrumweb.generales.Globales;
import com.avbravo.scrumweb.generales.ResourcesFiles;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;


@Named
@ViewScoped
public class EstatusSearchController implements Serializable{

   @Inject
   EstatusFacade estatusFacade;
   @Inject
   ResourcesFiles rf;
   @Inject
   Globales globales;
   Estatus selected = new Estatus();
   private List<Estatus> filtered;
   List<Estatus> estatusList;

   private String nombreestatus;
   private String idestatus;
   private String esinicial;

   private Boolean usarlike = false;

   public String getIdestatus() {
       return idestatus;
   }

   public void setIdestatus(String idestatus) {
       this.idestatus = idestatus;
   }

   public String getEsinicial() {
       return esinicial;
   }

   public void setEsinicial(String esinicial) {
       this.esinicial = esinicial;
   }

   public List<Estatus> getFiltered() {
       return filtered;
   }

   public void setFiltered(List<Estatus> filtered) {
       this.filtered = filtered;
   }

   /**
    * Creates a new instance of EstatusDataController
    */
   public Estatus getSelected() {
       return selected;
   }

   public void setSelected(Estatus selected) {
       this.selected = selected;
   }

   public EstatusSearchController() {
       estatusList = new ArrayList<>();

   }

   public List<Estatus> getEstatusList() {
       return estatusList;
   }

   public void setEstatusList(List<Estatus> estatusList) {
       this.estatusList = estatusList;
   }

   public String getNombreestatus() {
       return nombreestatus;
   }

   public void setNombreestatus(String nombreestatus) {
       this.nombreestatus = nombreestatus;
   }

   public Boolean getUsarlike() {
       return usarlike;
   }

   public void setUsarlike(Boolean usarlike) {
       this.usarlike = usarlike;
   }

   @PostConstruct
   public void init() {

   }

   public void iniciar() {
       estatusList = estatusFacade.getEstatusList();
   }

   public void iniciar(String value) {
       estatusList = estatusFacade.findByEsinicial(value);
   }

   public String buscar() {
       if (!usarlike) {
           estatusList = estatusFacade.findByEstatus(nombreestatus);
       } else {
           estatusList = estatusFacade.findByEstatusLike(nombreestatus);
       }

       return "";
   }

   public String buscarEsInicial() {

       estatusList = estatusFacade.findByEsinicial(esinicial);
       return "";
   }

   public String buscarIdEstatusList() {

       estatusList = estatusFacade.findByIdEstatusList(idestatus);
       return "";
   }

   public String showAll() {
       estatusList = estatusFacade.findAll();
       return "";
   }

   public String retornar() {
       globales.setEstatus(selected);
       return globales.getUltimapagina();
   }

}



  1. Editar estatusinsert.xml, agregamos un boton para buscar, uno para editar y otro para eliminar, ademas de un diálogo donde se confirmará si se eliminara o no el registro.  

  • Colocar el id=”form” para el form principal
<h:form rendered="#{menuBeans.estatusCrear}" id="form">
  • Indicar el alto y ancho del dialogo
height="175"  width="400"

<p:dialog visible="true" header="#{app['form.estatusnew']}" closable="true"
                                 height="175"  width="400"
        showEffect="clip" hideEffect="fade"   
         widgetVar="estatusinsertDialog">



  • Agregamos panelGroup con el botón buscar en el inputText estatus

  <h:outputLabel value="#{msg.idestatus}" for="idestatus" />
   <h:panelGroup>
             <h:inputText id="idestatus" value="#{estatusController.estatus.idestatus}" title="#{msg.idestatus}" required="true" requiredMessage="#{msg.idestatus} #{app['info.required']}"/>
            <p:commandButton immediate="true"   icon="ui-icon-search"  action="estatussearch"/>
   </h:panelGroup>


  • Agregar los botones de editar , imprimir y eliminar en el <f:facet name="footer">
             <f:facet name="footer">
                      <p:commandButton icon="ui-icon-disk" update="panel,growl"                                                    
rendered="#{menuBeans.estatusCrear}"
                                       action="#{estatusController.save()}"/>
                      <p:commandButton id="button_edit"
                                      update="form,growl"
rendered="#{menuBeans.estatusEditar}"
                                      icon="ui-icon-pencil" action="#{estatusController.edit()}"/>
                       <p:commandButton  id="printButton"
                                      action="#{estatusController.imprimir()}"
                                     icon="ui-icon-print" ajax="false" />
                       <p:commandButton  id="button_delete" update="form,growl" icon="ui-icon-trash"
rendered="#{menuBeans.estatusEliminar}"
                               onclick="PF('confirmationwidgetVar').show();" type="button" />
            </f:facet>










  • Agregar el diálogo para confirmar la eliminación debajo del otro diálogo

<p:dialog id="confirmDialog" modal="false"  header="Delete"  widgetVar="confirmationwidgetVar">
                           <h:panelGrid columns="2">
                               <p:outputLabel value="#{msg.estatus}"/>
                               <p:outputLabel value="#{estatusController.estatus.estatus}"/>

                           </h:panelGrid>

                           <f:facet name="footer">
                               <p:commandButton id="removeButton" value="si"
                                                update="form,growl"
                                                oncomplete="PF('confirmationwidgetVar').hide();"
                                                actionListener="#{estatusController.delete()}" />

                               <p:commandButton id="cancelButton" value="no" onclick="PF('confirmationwidgetVar').hide()" type="button" />
                           </f:facet>
                       </p:dialog>






















  1. Crear la página estatussearch.xhtml, usaremos un diálogo , donde colocaremos inputText para cada atributo y los commandButton para realizar las operaciones de búsqueda, los resultados los mostraremos en un datatable para que se seleccione el registro adecuado.

Ahora creamos un Facelets Template Client
  • Desde menú File, seleccione New
  • en Categories, seleccione Java Server Faces
  • en File Types, seleccione Facelets Template Client
  • En File Name: estatussearch
  • Folder colocamos /page/estatus/
  • Template seleccionamos template.xhtml

Pasos:
  1. Comentamos las opciones del menú
  2. Agregar view,form, growl, messages, y un dialogo global
  3. Agregamos un panelGrid con los atributos que deseamos usar para buscar y un botón al lado de cada uno
  4. Creamos un dataTable que contendrá el resultado de la búsqueda con un botón para seleccionar la fila adecuada. Con dos botones, retornar y mostrar todos.
Agregamos en el    <ui:define name="center">
<f:view>
<h:form id="form" rendered="#{menuBeans.estatusListar}">
<p:messages autoUpdate="true"/>
<p:growl id="growl"/>
<p:dialog  header="search"
                                  closable="true" showEffect="clip"
                                  visible="true"
                                  hideEffect="fade"                                 
                                  height="235"  width="550"
                                  widgetVar="searchDialogWidgetVar">
                           <p:ajax event="close" update="growl"  listener="#{loginBean.irInicio()}"/>  

Colocar un panelGrid colocamos los componentes y los botones de buscar.

<h:panelGrid columns="2">
                               
                               <h:outputLabel value="#{app['form.estatussearch']}" />
                               <h:outputLabel value=""/>
                              
                               <h:outputLabel value="#{msg.idestatus}" for="idestatus" />
                               <h:panelGroup>
                                   <h:inputText id="idestatus" value="#{estatusSearchController.idestatus}" title="Idestatus" />
                                   <p:commandButton  icon="ui-icon-search"  update=":form:datatable" action="#{estatusSearchController.buscarIdEstatusList()}"/>
                               </h:panelGroup>
                               
                               <h:outputLabel value="#{msg.estatus}" for="estatus" />
                               <h:panelGroup>
                                   <h:inputText  id="estatus" value="#{estatusSearchController.nombreestatus}" title="#{msg.estatus}" />

                                   <p:commandButton  icon="ui-icon-search"  update=":form:datatable" action="#{estatusSearchController.buscar()}"/>
                                   <h:outputLabel value="Like"  />
                                   <p:selectBooleanCheckbox   value="#{estatusSearchController.usarlike}" />  
                               </h:panelGroup>

                               <h:outputLabel value="#{msg.esinicial}" for="esinicial" />
                               <h:panelGroup>
                                   
                                   <p:selectOneMenu id="esinicial" value="#{estatusSearchController.esinicial}"
                                                    requiredMessage="#{msg.esinicial} #{app['info.notnull']}">
                                       <f:selectItem itemLabel="#{app['boton.yes']}" itemValue="si" />
                                       <f:selectItem itemLabel="#{app['boton.no']}" itemValue="no" />
                                   </p:selectOneMenu>
                                   <p:commandButton  icon="ui-icon-search"  update=":form:datatable" action="#{estatusSearchController.buscarEsInicial()}"/>
                               </h:panelGroup>
                               <f:facet name="footer">

                               </f:facet>
                           </h:panelGrid>


Agregamos un dataTable basado en estatusSearchController,
  • colocamos dos botones uno para retornar a la página que lo invoco y otro para mostrar todos los registros.
  • Una columna contendrá un botón de selección. Y en el header colocamos el botón de regresar y un botón para mostrar todo.
  • Colocar el id=”datatable”, rows=”7”, utilizar los mensajes de los archivos properties.
  • Colocamos dos botones en el header, retornar y mostrar todo.
  • Cambiar de <h:datatable> y <h:columns> a <p:datatable> y <p:columns>
  <p:dataTable id="datatable" rows="7" value="#{estatusSearchController.estatusList}" var="item">
                               <p:column>
                                   <f:facet name="header">
                                       <h:outputText value="Idestatus"/>
                                   </f:facet>
                                   <h:outputText value="#{item.idestatus}"/>
                               </p:column>
                               <p:column>
                                   <f:facet name="header">
                                       <h:outputText value="Estatus"/>
                                   </f:facet>
                                   <h:outputText value="#{item.estatus}"/>
                               </p:column>
                               <p:column>
                                   <f:facet name="header">
                                       <h:outputText value="Esinicial"/>
                                   </f:facet>
                                   <h:outputText value="#{item.esinicial}"/>
                               </p:column>
                               <p:column >  
             <p:commandButton id="selectButton" update=":form:display"
oncomplete="PF('widgetVarSearch').show()" icon="ui-icon-search" title="View">  
                                       <f:setPropertyActionListener value="#{item}" target="#{estatusSearchController.selected}" />  
             </p:commandButton>  
                               </p:column>
                               <f:facet name="header">
<p:commandButton icon="ui-icon-circle-arrow-w"  action="#{estatusSearchController.retornar()}"/>
<p:commandButton value="All" update ="datatable" action="#{estatusSearchController.showAll()}"/>
                               </f:facet>
                           </p:dataTable>

Cambiamos los textos fijos para usar las etiquetas de los archivos de propiedades.






Agregamos un diálogo debajo del datatable

<p:dialog header="#{app['dialog.search']}" widgetVar="widgetVarSearch" resizable="false" id="searchDialog"  
                                 showEffect="fade" hideEffect="explode"
                                 height="135"  width="250"
                                 modal="false">  

                           <h:panelGrid id="display" columns="2" cellpadding="4" style="margin:0 auto;">  

                               <h:outputLabel value="#{msg.estatus}" for="idestatus" />
                               <h:outputLabel value="#{estatusSearchController.selected.estatus}" />

                               <f:facet name="footer">

                                   <p:commandButton ajax="false"  value="#{app['boton.return']}" action="#{estatusSearchController.retornar()}"/>

                               </f:facet>
                           </h:panelGrid>  

                       </p:dialog>  



Código de estatussearch.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
     xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
     xmlns:h="http://xmlns.jcp.org/jsf/html"
     xmlns:f="http://xmlns.jcp.org/jsf/core"
     xmlns:p="http://primefaces.org/ui">

   <body>

       <ui:composition template="./../../template.xhtml">
           <!--
                       <ui:define name="top">
                           top
                       </ui:define>
           
                       <ui:define name="bottom">
                           bottom
                       </ui:define>
           
                       <ui:define name="left">
                           left
                       </ui:define>
           -->
           <ui:define name="center">
               <f:view>
                   <h:form id="form" rendered="#{menuBeans.estatusListar}">
                       <p:messages autoUpdate="true"/>
                       <p:growl id="growl"/>
                       <p:dialog  header="search"
                                  closable="true" showEffect="clip"
                                  visible="true"
                                  hideEffect="fade"                                 
                                  height="235"  width="550"
                                  widgetVar="searchDialogWidgetVar">
                           <p:ajax event="close" update="growl"  listener="#{loginBean.irInicio()}"/>  

                           <h:panelGrid columns="2">
                               
                               <h:outputLabel value="Search:"  />
                               <h:outputLabel value=""/>
                              
                               <h:outputLabel value="#{msg.idestatus}" for="idestatus" />
                               <h:panelGroup>
                                   <h:inputText id="idestatus" value="#{estatusSearchController.idestatus}" title="Idestatus" />
                                   <p:commandButton  icon="ui-icon-search"  update=":form:datatable" action="#{estatusSearchController.buscarIdEstatusList()}"/>
                               </h:panelGroup>
                               
                               <h:outputLabel value="#{msg.estatus}" for="estatus" />
                               <h:panelGroup>
                                   <h:inputText  id="estatus" value="#{estatusSearchController.nombreestatus}" title="Estatus" />

                                   <p:commandButton  icon="ui-icon-search"  update=":form:datatable" action="#{estatusSearchController.buscar()}"/>
                                   <h:outputLabel value="Like"  />
                                   <p:selectBooleanCheckbox   value="#{estatusSearchController.usarlike}" />  
                               </h:panelGroup>

                               <h:outputLabel value="#{msg.esinicial}" for="esinicial" />
                               <h:panelGroup>
                                   
                                   <p:selectOneMenu id="esinicial" value="#{estatusSearchController.esinicial}"
                                                    requiredMessage="#{msg.esinicial} #{app['info.notnull']}">
                                       <f:selectItem itemLabel="#{app['boton.yes']}" itemValue="si" />
                                       <f:selectItem itemLabel="#{app['boton.no']}" itemValue="no" />
                                   </p:selectOneMenu>
                                   <p:commandButton  icon="ui-icon-search"  update=":form:datatable" action="#{estatusSearchController.buscarEsInicial()}"/>
                               </h:panelGroup>
                               <f:facet name="footer">

                               </f:facet>
                           </h:panelGrid>

                           <p:dataTable id="datatable" rows="7" value="#{estatusSearchController.estatusList}" var="item">
                               <p:column>
                                   <f:facet name="header">
                                       <h:outputText value="Idestatus"/>
                                   </f:facet>
                                   <h:outputText value="#{item.idestatus}"/>
                               </p:column>
                               <p:column>
                                   <f:facet name="header">
                                       <h:outputText value="Estatus"/>
                                   </f:facet>
                                   <h:outputText value="#{item.estatus}"/>
                               </p:column>
                               <p:column>
                                   <f:facet name="header">
                                       <h:outputText value="Esinicial"/>
                                   </f:facet>
                                   <h:outputText value="#{item.esinicial}"/>
                               </p:column>
                               <p:column >  
                                   <p:commandButton id="selectButton" update=":form:display" oncomplete="PF('widgetVarSearch').show()" icon="ui-icon-search" title="View">  
                                       <f:setPropertyActionListener value="#{item}" target="#{estatusSearchController.selected}" />  
                                   </p:commandButton>  
                               </p:column>
                               <f:facet name="header">
                                   <p:commandButton icon="ui-icon-circle-arrow-w"  action="#{estatusSearchController.retornar()}"/>
                                   <p:commandButton value="All" update ="datatable" action="#{estatusSearchController.showAll()}"/>
                               </f:facet>
                           </p:dataTable>



                       </p:dialog>

                       <p:dialog header="#{app['dialog.search']}" widgetVar="widgetVarSearch" resizable="false" id="searchDialog"  
                                 showEffect="fade" hideEffect="explode"
                                 height="135"  width="250"
                                 modal="false">  

                           <h:panelGrid id="display" columns="2" cellpadding="4" style="margin:0 auto;">  

                               <h:outputLabel value="#{msg.estatus}" for="idestatus" />
                               <h:outputLabel value="#{estatusSearchController.selected.estatus}" />

                               <f:facet name="footer">

                                   <p:commandButton ajax="false"  value="#{app['boton.return']}" action="#{estatusSearchController.retornar()}"/>

                               </f:facet>
                           </h:panelGrid>  

                       </p:dialog>  
                   </h:form>
               </f:view>

           </ui:define>

       </ui:composition>

   </body>
</html>