Práctica Java - Gestión de stocks con acceso a base de datos

medio El objetivo de esta práctica es realizar un proyecto con SpringBoot desde cero y orientado por fases para trabajar primero con test unitarios, y terminar creando una aplicación web completa con conexión a SQL con Java Persisten Api más HTML dinámico con Thymeleaf.

Objetivos del ejercicio

Crear una aplicación web de cero con:

Crear una aplicación web que consista en:


Requisitos del proyecto

A continuación se describen las funcionalidades y requisitos que debe respetar el progrador a la hora de realizar la implementación

Perfiles de usuario:

Requisitos funcionales

Modelo de datos

Las siguentes entidades de información deben estar alojadas en el package com.arteco.curso.java.tienda.model:

Diseño técnico

Interfaces principales

ShopEnvironment
Es la clase que servirá de punto de entrada para construir una nueva tienda. Simplemente contendrá un elemento que devuelva la tienda asociada. Cada vez que se cree un SH se creará una nueva tienda.

La interfaz debe estar alojada en el paquete: com.arteco.curso.java.tienda.business
public interface ShopEnvironment {
    Shop getShop();
}
Shop
Debe ser otra interfaz, que nos permitirá realizar todas las operaciones tanto del gestor como del mangaer sobre ella. Por tanto deberá contener todos los métodos necesarios según los requisitos funcionales. Cada uno de esos métodos deberán ser evaluado desde los tests.

La interfaz debe estar alojada en el paquete: com.arteco.curso.java.tienda.business

Los comentarios que describen los métodos deben adaptarse a Javadoc siguiendo la guía Javadoc
public interface Shop {

    // Añade tantos items item al stock como indique quantity.
    // Cantidad debe ser mayor que 0, si no se ignora la operación
    void addItemToStock(Item item, int quantity);

    // Elimina items del stock, tantos como pueda, cantidad debe ser mayor que 0,
    // devuelve el número de elementos que ha podido borrar.
    // si la cantidad no es mayor que 0 se ignora la operación
    int removeItemFromStock(Long itemId, int quantity);

    // Devuelve el item o null si no ha podido encontrarlo en el stock
    Item getItem(Long id);

    // Elimina todos los items del stock, independientemente de cuantos haya
    // si no se encuentra el item se ignora la operación
    void deleteItem(Long id);

    // Permite modificar el item que previamente ha estado alojado en el stock
    // si no se encuentra el item por su Id se ignora la operación
    void saveItem(Item item);

    // Devuelve la suma de todos los items del stock teniendo en cuenta sus cantidades
    int countStock();

    // Permite buscar items, obteniendo su stock de la tienda dado ninguno o alguno
    // de los filtros que se indiquen por parámetros. Cualquier valor del filtro
    // debe poder ser null. Si todo es null devuelve el stock completo de la tienda.
    List<StockItem> getItems(ItemFilters filter);

    // Se crea un nuevo cliente, dado un nombre, que permitirá crear un carrito
    // traspasar elementos del stock al carrito. La compra puede terminar en
    // cofirmación o en rollback devolviendo el stock del carrito a la tienda
    Customer newCustomer(String name);

    // Crea un carrito, gestionado por la tienda, devolviendo el identificador de este
    // De esta manera la gestión del carrito estará encapsulada por la tienda
    String newCarry(Long customerId);

    // Traspasa un item con sus cantidades del stock de la tienda al stock del carrito
    // si no hay suficientes elementos la operación no se realiza para ningún item
    // si el carrito o el item no se encuentra, devuelve falso sin realizar la operación
    void addItemToCarry(String carryId, Long itemId, Integer quantity);

    // Devuelve un item con sus cantidades del stock del carrito al stock de la tienda
    void removeItemFromCarry(String carryId, Long itemId, Integer quantity);

    // Finaliza un carrito devolviendo todo su stock a la tienda
    void cancelCarry(String carryId);

    // Cuenta el stock de elementos que hay en el carrito
    int countCarryStock(String carryId);
}

Implementación 1 – En memoria

Dada que la tienda (Shop) es una interfaz, se creará una primera implementación de la interfaz en forma de una clase que gestione el stock y los carritos en memoria usando colecciones de Java como listas (java.util.List) o mapas (java.util.Map).

Las clases necesarias deben estar alojadas en el paquete com.arteco.curso.java.tienda.business.inmemmory

Implementación 2 – En base de datos

Dada que la tienda es una interfaz, se creará una segunda implementación tras finalizar los tests unitarios que comprueben todos los métodos de la interfaz Shop en forma de una clase que gestione el stock y los carritos en base de datos usando una base de datos embebida en la propia aplicación como HSQLDB.

Las clases necesarias deben estar alojadas en el paquete com.arteco.curso.java.tienda.business.jdbc

Primeros test unitarios

Para validar que las implementaciones son correctas el sistema deberá superar con éxito el test expuesto a continuación. Ambas implementaciones deben cumplir todos los casos exitosamente. Esta clase debe estar ubicada bajo el directorio de src/test/java y con package com.arteco.curso.java.tienda.business

Ver código fuente del anexo Tienda Online - Tests.java e incorporar al proyecto bajo el nombre ShopInMemmoryTests.java. Se deberá creare una segunda clase de test destinado a probar los mismos métodos pero para la implementación de JDBC. Se debe evitar la duplicidad de código fuente en los tests aprovechando herencia o clases útiles comparitdas.


Metodología de desarrollo

Fase 1 – Creación de proyecto e implementación en memoria

Fase 2 – Implementación en base de datos

Fase 3 – Creación de interfície de usuario web

Anexo 1 – Spring Properties para HSQLDB

Para configurar la conexión con base de datos debemos añadir a application.properties los siguientes valores:

spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
spring.datasource.url=jdbc:hsqldb:mem:testdb;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=create

Anexo 2 – Test unitarios