Skip to main content

JmoordbUnit con filtros entre fechas en List embebidos

JmoordbUnit con filtros entre fechas en List<entity> embebidos

Las bases de datos NoSQL, tales como MongoDB nos permiten gran flexibilidad comparados con bases de datos relacionales.





Por ejemplo en una base de datos de facturación de un sistema relacional, tendríamos una tabla de facturas y otra de Pagare, con cientos de registros asociados.

Mediante SQL podemos hacer consultas, en el ejemplo, buscamos en la tabla de pagare todas aquellas facturas con un estatus especifico y con la condición que estos pagares estén entre una fecha de inicio y de fin y que tengan el estatus de cancelado="no".
Usamos un select o un join, en el cual iteramos la consulta sobre dos tablas para obtener los resultados.


Ahora lo vemos desde una perspectiva NoQSL, en el cual podemos almacenar dentro de la colección Factura una lista embebida de Pagare. De manera que al consultar en la colección Factura, automáticamente tendremos acceso a los pagares que se almacenan en la misma colección.




Esquema del Json de Factura

  • Utilizaremos ejbjmoord como APi para comunicarnos con MongoDB.
  • jmoordbUnit para generar los test progresivos (Nos permiten generar ademas del test, una interfaz gráfica con las pruebas).
Pasos:
Creamos dos proyectos en NetBeans IDE
Un proyecto EJB Module llamado storejb


y otro proyecto de tipo Payara Micro Application llamado storetest




Agregar la dependencia de jmoordbunit Dependencias
  <dependency>
            <groupId>com.github.avbravo</groupId>
            <artifactId>jmoordbunit</artifactId>
            <version>0.4.4</version>
        </dependency>

jmoordbUnit genera los archivos de reportes

Clase Factura:



Contiene una Lista embebida de Pagare.
    @Embedded
    List<Pagare> pagare;
 



MOSTRAR TODAS LOS PAGARES


Usamos UnitTest para generar la salida del test.

unitTest.form();
            unitTest.formTitle("Reporte de Todas las facturas con pagare");
            unitTest.panel();
             unitTest.panelAddTableHeader("Pagare", Arrays.asList(new RowView("idfactura"), new RowView("Pagare"), new RowView("Cancelado"),
                    new RowView("Fecha")));
            flist.forEach((f) -> {
                f.getPagare().forEach((p) -> {
                    unitTest.panelAddTableCol(Arrays.asList(new ColView(f.getIdfactura()), new ColView(p.getNumero()),
                            new ColView(p.getCancelado()),
                            new ColView(p.getFechavencimiento())
                    ));
                });

            });
            unitTest.panelAddTableClose();

            unitTest.panelClose();
            unitTest.formClose();

Podemos ver todos los pagares dentro de las facturas y las fechas de vencimiento y el valor de cancelado.


FILTRAR EL LIST<> EMBEBIDO.


Dibujamos las cajas de texto del filtro.
 List<Factura> listFactura = facturaRepository.filters(filter, new Document("idfactura", 1));
            unitTest.assertNotEquals(nameOfMethod(), 0, listFactura.size());

            unitTest.form();
            unitTest.formTitle("Filtro");
            unitTest.panel();

            unitTest.panelAddInputText(Arrays.asList(new InputText("desde", firstDate.toString()),
                    new InputText("hasta", lastDate.toString()), new InputText("cancelado", "no"))
            );

            unitTest.panelClose();
            unitTest.buttonGreen("Filtrar");
            unitTest.formClose();





Aplicamos el filtro generando un Filters para cada posición dentro del List<>

Filtramos cada elemento del List<> embebido indicando la posición dentro del List<>, por ejemplo pagare.0.cancelado, pagare.1.cancelado , y el filtro entre fechas. Utilizamos una función que denominamos functionFilter() que genera un solo Bson  que contiene los filtros para cada posición.

  Integer anio = 2019;
            Integer mes = 4;
            Date firstDate = DateUtil.primerDiaDelMesEnFecha(anio, mes);

            Date lastDate = DateUtil.getDateLastOfMonth(anio, mes);

            Bson filterfactura = Filters.and(Filters.eq("almacen.idalmacen", 6), Filters.or(Filters.eq("estatusfactura.idestatusfactura", 1), Filters.eq("estatusfactura.idestatusfactura", 2), Filters.eq("estatusfactura.idestatusfactura", 6), Filters.eq("estatusfactura.idestatusfactura", 7)));

            Bson filterpagare = functionFilter(0, firstDate,lastDate);
            for (int i = 1; i < 13; i++) {
                Bson f = functionFilter(i, firstDate,lastDate);
                filterpagare = Filters.or(filterpagare, f);
            }   


Bson filter = Filters.and(filterfactura, filterpagare);

Ejecutar el filtro


 List<Factura> listFactura = facturaRepository.filters(filter, new Document("idfactura", 1));


Función que genera el filtro para cada elemento                  


 private Bson functionFilter(Integer i, Date startDate, Date lastDate) {

        Bson filter = Filters.and(
                Filters.gte("pagare." + i + ".fechavencimiento", startDate),
                Filters.lte("pagare." + i + ".fechavencimiento", lastDate),
                Filters.eq("pagare." + i + ".cancelado", "no")
        );
        return filter;
    }


Se realiza el filtro correctamente, mostrando solo la factura 5.


Aplicar un filtro genérico sin indicar la posición dentro del List<>

Cuando usamos este filtro sin especificar la posición dentro del List<>. no funciona el and, se comporta como un or.

 Bson filterfactura = Filters.and(Filters.eq("almacen.idalmacen", 6), Filters.or(Filters.eq("estatusfactura.idestatusfactura", 1), Filters.eq("estatusfactura.idestatusfactura", 2), Filters.eq("estatusfactura.idestatusfactura", 6), Filters.eq("estatusfactura.idestatusfactura", 7)));

       
      
            Bson filterpagare = Filters.and(Filters.eq("pagare.cancelado", "no"),
                    Filters.gte("pagare.fechavencimiento", firstDate),
                    Filters.lte("pagare.fechavencimiento", lastDate)
            );
            Bson filter = Filters.and(filterfactura, filterpagare);


Observen que se genera un listado de todas las facturas que contengan un rango de fecha, pero ignora la condición cancelado = "no"
Aquí falla un filtro de ese tipo dentro de MongoDB, ya que el buscara en la lista cualquier pagare que tenga la condición entre fechas y cualquier pagare que tenga cancelado ="no", sin restringuir que sea el mismo pagare que se este buscando.
Recomendación:
  • Cuando desee hacer filtros dentro de un List<> embebido genere todas las posiciones del list para hacer el filtro.




Comments

Popular posts from this blog

Tutorial básico de aplicaciones Web con NetBeans parte 1

NetBeans ofrece un excelente soporte para el desarrollo de aplicaciones Web, en esta ocasión lo haremos utilizando el Framework Java Server Faces 2.0. En el Menu Seleccionamos Nuevo->Proyecto y luego en Categorias Java Web y en tipo de Proyectos Web  Application indicamos el nombre del proyecto Seleccinamos el servidor Web, usamos GlassFish ya que este soporta EJB3.0 y JSF 2.0 Framework Java Server Faces El IDE genera el esquelto del proyecto Web Pages   almacenamos las paginas .html, xhtml, jsf, los archivos de recursos, los scripts .js, imagenes Source Packages    Son las clases Java  Test Packages    Son las clases que usamos para los Test Libraries     Tenemos las bibliotecas de Java y GlassFish necesarias para ejecutar la aplicación Web. Test Libraries     Están las bibliotecas usadas para los test  Configuration Files    Archivos de configuración de la aplicación. Ejecutamos la...

Incrementar Memoria NetBeans

Algunas veces necesitamos incrementar la memoria para un mejor rendimiento. http://www.netbeans.org/community/releases/55/uml-download.html Este es un ejemplo para UML. Descripción en ingles. Increasing Memory Settings (applicable to all builds) The default memory settings for NetBeans should be increased for UML projects. If you have the available memory, Locate your NetBeans installation directory ($install_dir). This can be found by starting up NetBeans and selecting Help -> About then select the Detail tab. Edit the $install_dir/etc/netbeans.conf file. Find the line defining netbeans_default_options . Increase the maximum memory attribute to -J-Xmx512m. If you experience heap overflows while working with larger files, you should increase this value further.

Cambiando el estado de un checkbox

Cambiando el Estado de un CheckBox Algunas veces deseamos controlar el estado de un checkbox o cambiarlo segùn determinadas condiciones. Pasos: 1. Creamos un proyecto Web. 2. En el diseñador agregamos un checkbox y dos botones. * Dar click derecho en el checkbox y luego seleccionar Add Binding Attribute, para agregar los atributos al checkbox, de manera que los podamos usar en nuestro código. Generando automáticamente private Checkbox checkbox1 = new Checkbox(); public Checkbox getCheckbox1() { return checkbox1; } public void setCheckbox1(Checkbox c) { this.checkbox1 = c; } 3.Damos click derecho en el botón Habilitar, y seleccionamos Edit Action Event Handler. A continuación, agregamos el código: this.checkbox1.setSelected(true);, el método setSelected con valor true, marca el checkbox como seleccionado, y un valor de false, quita la marca. public String button1_action() { // TODO: Process the action. Return value is a navigation // ...