From b0a59f7995c559904c88256f9ddcc468dbe4f401 Mon Sep 17 00:00:00 2001
From: Gaydamakha <mikhail.gaydamakha@etu.unistra.fr>
Date: Thu, 16 Dec 2021 22:24:11 +0100
Subject: [PATCH] :recycle: add Category inside Item object and add Item inside
 Stock object

---
 build.gradle                                  |  3 +-
 .../api/ApiPostCategoryController.java        |  9 +-
 .../controller/api/ApiPostItemController.java |  2 +-
 .../fr/unistra/sil/erp/back/model/Item.java   | 91 ++++++-------------
 .../fr/unistra/sil/erp/back/model/Stock.java  | 43 ++-------
 .../repository/ICategoriesRepository.java     |  6 +-
 .../erp/back/repository/IItemsRepository.java |  5 -
 .../category/SqliteCategoryRepository.java    | 87 +++++++++---------
 .../item/SqliteItemsRepository.java           | 72 +++++++--------
 .../stock/SqliteStocksRepository.java         | 36 +++++---
 .../back/service/CantStoreItemException.java  |  3 +
 .../erp/back/service/StoreItemService.java    | 30 +++---
 .../erp/back/service/UpdateStockService.java  | 12 +--
 13 files changed, 168 insertions(+), 231 deletions(-)

diff --git a/build.gradle b/build.gradle
index c19a7a3..c7c53eb 100644
--- a/build.gradle
+++ b/build.gradle
@@ -11,7 +11,7 @@ tasks {
 
 group = 'fr.unistra.sil'
 version = '0.0.1-SNAPSHOT'
-sourceCompatibility = '1.8'
+sourceCompatibility = "1.9"
 
 repositories {
 	mavenCentral()
@@ -40,3 +40,4 @@ javadoc {
 test {
 	useJUnitPlatform()
 }
+targetCompatibility = JavaVersion.VERSION_1_9
diff --git a/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiPostCategoryController.java b/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiPostCategoryController.java
index e50a21d..1226cd4 100644
--- a/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiPostCategoryController.java
+++ b/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiPostCategoryController.java
@@ -33,7 +33,7 @@ public class ApiPostCategoryController {
     /**
      * Category repository.
      */
-    private ICategoriesRepository repository;
+    private final ICategoriesRepository repository;
 
     /**
      * Constructor.
@@ -83,9 +83,9 @@ public class ApiPostCategoryController {
         if(c.getName() == null || c.getName().equals("")) {
             throw new ApiBadRequestException("Missing category name.");
         }
-        
+
         try {
-            this.repository.createCategory(c);
+            c = this.repository.createCategory(c);
         } catch (DatabaseConnectionException ex) {
             Logger.getLogger(ApiPostCategoryController.class.getName()).log(Level.SEVERE, null, ex);
             throw new ApiServerErrorException("Database connection failure.");
@@ -94,7 +94,6 @@ public class ApiPostCategoryController {
             throw new ApiServerErrorException("Database update failure.");
         }
         
-        return new ResponseEntity<>(this.repository.getLatestCategory(),
-                HttpStatus.CREATED);
+        return new ResponseEntity<>(c, HttpStatus.CREATED);
     }
 }
diff --git a/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiPostItemController.java b/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiPostItemController.java
index 309ddb6..27b04ef 100644
--- a/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiPostItemController.java
+++ b/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiPostItemController.java
@@ -44,7 +44,7 @@ public class ApiPostItemController {
     @PostMapping(MAPPING_ITEMS)
     public ResponseEntity<Item> postItem(
             @Validated @RequestBody PostItemDTO requestBody
-    ) throws ApiServerErrorException {
+    ) throws ApiServerErrorException, ApiResourceNotFoundException {
         Item item;
         try {
             item = service.store(new StoreItemRequest(
diff --git a/src/main/java/fr/unistra/sil/erp/back/model/Item.java b/src/main/java/fr/unistra/sil/erp/back/model/Item.java
index 61eaaf7..e61222c 100644
--- a/src/main/java/fr/unistra/sil/erp/back/model/Item.java
+++ b/src/main/java/fr/unistra/sil/erp/back/model/Item.java
@@ -21,128 +21,91 @@ import java.math.BigDecimal;
  * @author BEAUVAIS ANTOINE
  */
 public class Item {
-    
+
     /**
      * The product's reference number.
      */
     private final Integer id;
-    
+
     /**
      * The product's name.
      */
     private final String name;
-    
+
     /**
      * The product's regular price.
      */
     private final BigDecimal price;
-    
+
     /**
      * The product's price for subscribers.
      */
     @JsonProperty("subscriber_price")
     private final BigDecimal subscriberPrice;
-    
-    /**
-     * This product's category identifier.
-     */
-    private final int category;
 
-    /**
-       Category name for JSON response.
-     */
-    private String categoryName;
-    
-    /**
-     * Class constructor.
-     * @param id Item ID.
-     * @param name Item name.
-     * @param price Item price.
-     * @param subscriberPrice The item's price.
-     * @param category Item category.
-     */
-    public Item(Integer id, String name, BigDecimal price,
-                BigDecimal subscriberPrice, int category)
-    {
-        this.id = id;
-        this.name = name;
-        this.price = price;
-        this.subscriberPrice = subscriberPrice;
-        this.category = category;
-        this.categoryName = null;
-    }
+    private final Category category;
 
     /**
      * Class constructor.
-     * @param id Item ID.
-     * @param name Item name.
-     * @param price Item price.
+     *
+     * @param id              Item ID.
+     * @param name            Item name.
+     * @param price           Item price.
      * @param subscriberPrice The item's price.
-     * @param category Item category.
-     * @param categoryName Item category name for JSON.
+     * @param category        Item category.
      */
     public Item(Integer id, String name, BigDecimal price,
-                BigDecimal subscriberPrice, int category, String categoryName)
-    {
+                BigDecimal subscriberPrice, Category category) {
         this.id = id;
         this.name = name;
         this.price = price;
         this.subscriberPrice = subscriberPrice;
         this.category = category;
-        this.categoryName = categoryName;
     }
-    
+
     /**
      * Returns the current item's reference number.
+     *
      * @return the reference number.
      */
-    public Integer getId()
-    {
+    public Integer getId() {
         return this.id;
     }
-    
+
     /**
      * Returns the current item's name.
+     *
      * @return the name.
      */
-    public String getName()
-    {
+    public String getName() {
         return this.name;
     }
-    
+
     /**
      * Returns the current item's price.
+     *
      * @return the price.
      */
-    public BigDecimal getPrice()
-    {
+    public BigDecimal getPrice() {
         return this.price;
     }
-    
+
     /**
      * Returns the current item's price for subscribers.
+     *
      * @return the price for subscribers.
      */
-    public BigDecimal getSubscriberPrice()
-    {
+    public BigDecimal getSubscriberPrice() {
         return this.subscriberPrice;
     }
-    
+
     /**
      * Returns the current item's category identifier.
+     *
      * @return the category identifier.
      */
-    public int getCategory()
-    {
+    public Category getCategory() {
         return this.category;
     }
 
-    /**
-     * Returns the category name.
-     * @return the category name.
-     */
-    public String getCategoryName()
-    {
-        return this.categoryName;
-    }
-}
+}
\ No newline at end of file
diff --git a/src/main/java/fr/unistra/sil/erp/back/model/Stock.java b/src/main/java/fr/unistra/sil/erp/back/model/Stock.java
index ff3ed1f..a03795a 100644
--- a/src/main/java/fr/unistra/sil/erp/back/model/Stock.java
+++ b/src/main/java/fr/unistra/sil/erp/back/model/Stock.java
@@ -4,8 +4,6 @@
  */
 package fr.unistra.sil.erp.back.model;
 
-import com.fasterxml.jackson.annotation.JsonProperty;
-
 /**
  * Representation of a stock entry.
  * 
@@ -21,19 +19,9 @@ public class Stock {
      * The stock entry's ID.
      */
     private final int id;
-    
-    /**
-     * The stock's item ID.
-     */
-    @JsonProperty("item_id")
-    private final int itemId;
-    
-    /**
-     * The stock's item name.
-     */
-    @JsonProperty("item_name")
-    private final String itemName;
-    
+
+    private final Item item;
+
     /**
      * The quantity for the item.
      */
@@ -42,15 +30,13 @@ public class Stock {
     /**
      * Class constructor.
      * @param id the Stock's ID.
-     * @param itemId the item's ID.
-     * @param itemName the item's name.
+     * @param item the Stock's item
      * @param quantity the quantity.
      */
-    public Stock(int id, int itemId, String itemName, int quantity)
+    public Stock(int id, Item item, int quantity)
     {
         this.id = id;
-        this.itemId = itemId;
-        this.itemName = itemName;
+        this.item = item;
         this.quantity = quantity;
     }
     
@@ -62,25 +48,16 @@ public class Stock {
     {
         return this.id;
     }
-    
+
     /**
      * Returns the item's ID.
      * @return the item's ID.
      */
-    public int getItemId()
+    public Item getItem()
     {
-        return this.itemId;
+        return this.item;
     }
-    
-    /**
-     * Returns the item's name.
-     * @return the item's name.
-     */
-    public String getItemName()
-    {
-        return this.itemName;
-    }
-    
+
     /**
      * Returns the quantity for the item.
      * @return the quantity.
diff --git a/src/main/java/fr/unistra/sil/erp/back/repository/ICategoriesRepository.java b/src/main/java/fr/unistra/sil/erp/back/repository/ICategoriesRepository.java
index 6fbef24..6ec8efe 100644
--- a/src/main/java/fr/unistra/sil/erp/back/repository/ICategoriesRepository.java
+++ b/src/main/java/fr/unistra/sil/erp/back/repository/ICategoriesRepository.java
@@ -16,13 +16,13 @@ public interface ICategoriesRepository {
      * @return the list of categories, or null if an error occurred.
      */
     List<Category> getCategories();
-    
+
     /**
      * Retrieves the category with the highest ID.
      * @return the category.
      */
-    Category getLatestCategory();
-    
+    Category getCategory(int id) throws DatabaseResourceNotFoundException;
+
     /**
      * Creates a new category in the database.
      * 
diff --git a/src/main/java/fr/unistra/sil/erp/back/repository/IItemsRepository.java b/src/main/java/fr/unistra/sil/erp/back/repository/IItemsRepository.java
index c775a4c..3f63c4a 100644
--- a/src/main/java/fr/unistra/sil/erp/back/repository/IItemsRepository.java
+++ b/src/main/java/fr/unistra/sil/erp/back/repository/IItemsRepository.java
@@ -36,10 +36,5 @@ public interface IItemsRepository {
      */
     Item store(Item item);
 
-    /**
-     *
-     * @param id
-     * @return
-     */
     Item findById(int id);
 }
diff --git a/src/main/java/fr/unistra/sil/erp/back/repository/category/SqliteCategoryRepository.java b/src/main/java/fr/unistra/sil/erp/back/repository/category/SqliteCategoryRepository.java
index c67219b..d72c11a 100644
--- a/src/main/java/fr/unistra/sil/erp/back/repository/category/SqliteCategoryRepository.java
+++ b/src/main/java/fr/unistra/sil/erp/back/repository/category/SqliteCategoryRepository.java
@@ -1,11 +1,7 @@
 package fr.unistra.sil.erp.back.repository.category;
 
 import fr.unistra.sil.erp.back.model.Category;
-import fr.unistra.sil.erp.back.repository.DatabaseConnectionException;
-import fr.unistra.sil.erp.back.repository.DatabaseResourceNotFoundException;
-import fr.unistra.sil.erp.back.repository.DatabaseUpdateException;
-import fr.unistra.sil.erp.back.repository.ICategoriesRepository;
-import fr.unistra.sil.erp.back.repository.SqliteRepository;
+import fr.unistra.sil.erp.back.repository.*;
 import org.springframework.stereotype.Repository;
 
 import java.sql.Connection;
@@ -24,27 +20,35 @@ import java.util.logging.Logger;
 @Repository
 public class SqliteCategoryRepository extends SqliteRepository implements ICategoriesRepository {
 
+    public static String columns() {
+        List<String> columns = List.of(
+                "categories.id AS category_id",
+                "categories.name AS category_name"
+        );
+        return String.join(", ", columns);
+    }
+
+    public static Category fromDb(ResultSet rs) throws SQLException {
+        return new Category(rs.getInt("category_id"), rs.getString("category_name"));
+    }
+
     /**
      * Query used to retrieve all categories stored in the database.
      */
     private static final String SQL_GETCATEGORIES =
-            "SELECT id, name FROM categories";
-    
-    /**
-     * Query used to retrieve one category stored in the database.
-     */
-    private static final String SQL_GETCATEGORY =
-            "SELECT id, name FROM categories WHERE id = ?";
-    
-    private static final String SQL_GETLASTCATEGORY =
-            "SELECT MAX(id), name FROM categories";
-    
+            "SELECT " + columns() + " FROM categories";
+
+    private static final String SQL_GET_CATEGORY = SQL_GETCATEGORIES + " WHERE id = ?";
+
     /**
      * Query used to create a new category.
      */
     private static final String SQL_CREATECATEGORY =
             "INSERT INTO categories (name) VALUES (?)";
 
+    private static final String SQL_GETLASTCATEGORY =
+            "SELECT MAX(id) as max_id, name FROM categories";
+
     /**
      *
      * @param conn
@@ -62,7 +66,7 @@ public class SqliteCategoryRepository extends SqliteRepository implements ICateg
         List<Category> res = new ArrayList<>();
         try {
             while (rs.next()) {
-                Category c = new Category(rs.getInt("id"), rs.getString("name"));
+                Category c = fromDb(rs);
                 res.add(c);
             }
         } catch (SQLException ex) {
@@ -84,7 +88,7 @@ public class SqliteCategoryRepository extends SqliteRepository implements ICateg
     {
         PreparedStatement ps;
         try {
-            ps = this.conn.prepareStatement(SQL_GETCATEGORY);
+            ps = this.conn.prepareStatement(SQL_GET_CATEGORY);
         } catch (SQLException ex) {
             Logger.getLogger(this.getClass().getName()).log(
                     Level.SEVERE, "Failed to connect to database.", ex);
@@ -112,7 +116,7 @@ public class SqliteCategoryRepository extends SqliteRepository implements ICateg
         Category c;
         try {
             if (rs.next())
-                c = new Category(rs.getInt("id"), rs.getString("name"));
+                c = fromDb(rs);
             else
                 throw new DatabaseResourceNotFoundException("Stock not found.");
         } catch (SQLException ex) {
@@ -123,32 +127,7 @@ public class SqliteCategoryRepository extends SqliteRepository implements ICateg
 
         return c;
     }
-    
-    /**
-     * Retrieves the latest category.
-     * @return 
-     */
-    @Override
-    public Category getLatestCategory()
-    {
-        ResultSet rs = this.query(SQL_GETCATEGORIES);
-        if (rs == null)
-            return null;
 
-        Category c = null;
-        try {
-            while (rs.next()) {
-                c = new Category(rs.getInt("id"), rs.getString("name"));
-            }
-        } catch (SQLException ex) {
-            Logger.getLogger(this.getClass().getName()).log(
-                    Level.SEVERE, "Failed to fetch results.", ex);
-            return null;
-        }
-
-        return c;
-    }
-    
     @Override
     public Category createCategory(Category c)
             throws DatabaseConnectionException, DatabaseUpdateException
@@ -177,7 +156,23 @@ public class SqliteCategoryRepository extends SqliteRepository implements ICateg
                     .log(Level.SEVERE, "Failed to execute query.", ex);
             throw new DatabaseUpdateException("Failed to execute query.");
         }
-        
-        return c;
+
+        int id;
+        ResultSet rs;
+        try {
+            ps = this.conn.prepareStatement(SQL_GETLASTCATEGORY);
+            rs = ps.executeQuery();
+        } catch (SQLException ex) {
+            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Failed to find item id: " + ex.getMessage());
+            return null;
+        }
+        try {
+            id = rs.getInt("max_id");
+        } catch (SQLException ex) {
+            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Failed to parse item id: " + ex.getMessage());
+            return null;
+        }
+
+        return new Category(id, c.getName());
     }
 }
diff --git a/src/main/java/fr/unistra/sil/erp/back/repository/item/SqliteItemsRepository.java b/src/main/java/fr/unistra/sil/erp/back/repository/item/SqliteItemsRepository.java
index ac415e9..8bad9c3 100644
--- a/src/main/java/fr/unistra/sil/erp/back/repository/item/SqliteItemsRepository.java
+++ b/src/main/java/fr/unistra/sil/erp/back/repository/item/SqliteItemsRepository.java
@@ -1,9 +1,9 @@
 package fr.unistra.sil.erp.back.repository.item;
 
 import fr.unistra.sil.erp.back.model.Item;
-import fr.unistra.sil.erp.back.model.Stock;
 import fr.unistra.sil.erp.back.repository.IItemsRepository;
 import fr.unistra.sil.erp.back.repository.SqliteRepository;
+import fr.unistra.sil.erp.back.repository.category.SqliteCategoryRepository;
 import org.springframework.stereotype.Repository;
 
 import java.sql.*;
@@ -13,36 +13,50 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 /**
- *
  * @author antoine.beauvais
  */
 @Repository
 public class SqliteItemsRepository extends SqliteRepository implements IItemsRepository {
 
-    /**
-     * Query used to select all items stored in the database.
-     */
-    private static final String SQL_GETALLITEMS =
-            "SELECT id, name, price, subscriberPrice, category FROM items";
+    public static String columns() {
+        List<String> columns = List.of(
+                "items.id AS item_id",
+                "items.name AS item_name",
+                "items.price AS item_price",
+                "items.subscriberPrice AS item_subscriber_price",
+                "items.category AS item_category"
+        );
+        return String.join(", ", columns) + ", " + SqliteCategoryRepository.columns();
+    }
+
+    public static Item fromDb(ResultSet rs) throws SQLException {
+        return new Item(rs.getInt("item_id"),
+                rs.getString("item_name"),
+                rs.getBigDecimal("item_price"),
+                rs.getBigDecimal("item_subscriber_price"),
+                SqliteCategoryRepository.fromDb(rs)
+        );
+    }
 
     /**
      * Query used to find an item by id
      */
-    private static final String SQL_GET_ITEM = "SELECT * FROM items WHERE id = ?";
+    private static final String SQL_GET_ITEM = "SELECT " + columns() + " FROM items WHERE id = ?";
+
+    private static final String SQL_GETITEMSWITHCATEGORY =
+            "SELECT " + columns() + " FROM items INNER JOIN categories ON items.category = categories.id";
 
     /**
      * Query used to get all items stored in the database from a specific
      * category.
      */
-    private static final String SQL_GETITEMSFROMCATEGORY = SQL_GETALLITEMS +
-            " WHERE category = ?";
+    private static final String SQL_GETITEMSFROMCATEGORY = SQL_GETITEMSWITHCATEGORY +
+            " WHERE categories.id = ?";
 
-    private static final String SQL_GETITEMSWITHCATEGORY =
-        "SELECT i.id, i.name, i.price, i.subscriberPrice, i.category, c.name AS cName"
-        + " FROM items i LEFT JOIN categories c ON i.category = c.id";
 
     /**
      * Class constructor.
+     *
      * @param conn
      */
     public SqliteItemsRepository(Connection conn) {
@@ -52,17 +66,14 @@ public class SqliteItemsRepository extends SqliteRepository implements IItemsRep
 
     @Override
     public List<Item> getAllItems() {
-        ResultSet rs = query(SQL_GETALLITEMS);
+        ResultSet rs = query(SQL_GETITEMSWITHCATEGORY);
         if (rs == null)
             return null;
 
         List<Item> res = new ArrayList<>();
         try {
             while (rs.next()) {
-                Item item = new Item(rs.getInt("id"), rs.getString("name"),
-                        rs.getBigDecimal("price"),
-                        rs.getBigDecimal("subscriberPrice"),
-                        rs.getInt("category"));
+                Item item = fromDb(rs);
                 res.add(item);
             }
         } catch (SQLException ex) {
@@ -77,16 +88,15 @@ public class SqliteItemsRepository extends SqliteRepository implements IItemsRep
     @Override
     public List<Item> getAllItemsWithCategory() {
         ResultSet rs = query(SQL_GETITEMSWITHCATEGORY);
+        Logger.getLogger(this.getClass().getName()).log(
+                Level.SEVERE, SQL_GETITEMSWITHCATEGORY);
         if (rs == null)
             return null;
 
         List<Item> res = new ArrayList<>();
         try {
             while (rs.next()) {
-                Item item = new Item(rs.getInt("id"), rs.getString("name"),
-                        rs.getBigDecimal("price"),
-                        rs.getBigDecimal("subscriberPrice"),
-                        rs.getInt("category"), rs.getString("cName"));
+                Item item = fromDb(rs);
                 res.add(item);
             }
         } catch (SQLException ex) {
@@ -99,7 +109,6 @@ public class SqliteItemsRepository extends SqliteRepository implements IItemsRep
     }
 
 
-
     @Override
     public List<Item> getItemsFromCategory(int category) {
         PreparedStatement ps;
@@ -133,10 +142,7 @@ public class SqliteItemsRepository extends SqliteRepository implements IItemsRep
         List<Item> res = new ArrayList<>();
         try {
             while (rs.next()) {
-                Item item = new Item(rs.getInt("id"), rs.getString("name"),
-                        rs.getBigDecimal("price"),
-                        rs.getBigDecimal("subscriberPrice"),
-                        rs.getInt("category"));
+                Item item = fromDb(rs);
                 res.add(item);
             }
         } catch (SQLException ex) {
@@ -149,7 +155,6 @@ public class SqliteItemsRepository extends SqliteRepository implements IItemsRep
     }
 
     /**
-     *
      * @param item
      * @return
      */
@@ -162,7 +167,7 @@ public class SqliteItemsRepository extends SqliteRepository implements IItemsRep
             ps.setString(1, item.getName());
             ps.setBigDecimal(2, item.getPrice());
             ps.setBigDecimal(3, item.getSubscriberPrice());
-            ps.setInt(4, item.getCategory());
+            ps.setInt(4, item.getCategory().getId());
         } catch (SQLException ex) {
             Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Failed to connect to database.", ex);
             return null;
@@ -199,7 +204,6 @@ public class SqliteItemsRepository extends SqliteRepository implements IItemsRep
     }
 
     /**
-     *
      * @param id
      * @return
      */
@@ -230,13 +234,7 @@ public class SqliteItemsRepository extends SqliteRepository implements IItemsRep
         Item item;
         try {
             if (rs.next())
-                item = new Item(
-                        rs.getInt("id"),
-                        rs.getString("name"),
-                        rs.getBigDecimal("price"),
-                        rs.getBigDecimal("subscriberPrice"),
-                        rs.getInt("category")
-                );
+                item = fromDb(rs);
             else
                 return null;
         } catch (SQLException ex) {
diff --git a/src/main/java/fr/unistra/sil/erp/back/repository/stock/SqliteStocksRepository.java b/src/main/java/fr/unistra/sil/erp/back/repository/stock/SqliteStocksRepository.java
index 69a4924..a7648c6 100644
--- a/src/main/java/fr/unistra/sil/erp/back/repository/stock/SqliteStocksRepository.java
+++ b/src/main/java/fr/unistra/sil/erp/back/repository/stock/SqliteStocksRepository.java
@@ -1,11 +1,11 @@
 package fr.unistra.sil.erp.back.repository.stock;
 
 import fr.unistra.sil.erp.back.repository.DatabaseConnectionException;
-import fr.unistra.sil.erp.back.repository.DatabaseResourceNotFoundException;
 import fr.unistra.sil.erp.back.repository.DatabaseUpdateException;
 import fr.unistra.sil.erp.back.model.Stock;
 import fr.unistra.sil.erp.back.repository.IStocksRepository;
 import fr.unistra.sil.erp.back.repository.SqliteRepository;
+import fr.unistra.sil.erp.back.repository.item.SqliteItemsRepository;
 import org.springframework.stereotype.Repository;
 
 import java.sql.Connection;
@@ -18,28 +18,37 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 /**
- *
  * @author antoine.beauvais
  */
 @Repository
 public class SqliteStocksRepository extends SqliteRepository implements IStocksRepository {
 
+    public static String columns() {
+        List<String> columns = List.of(
+                "stocks.id AS stock_id",
+                "stocks.item AS stock_item",
+                "stocks.quantity AS stock_quantity"
+        );
+        return String.join(", ", columns) + ", " + SqliteItemsRepository.columns();
+    }
+
+    public static Stock fromDb(ResultSet rs) throws SQLException {
+        return new Stock(rs.getInt("stock_id"), SqliteItemsRepository.fromDb(rs), rs.getInt("stock_quantity"));
+    }
+
     /**
      * Query used to fetch all stocks stored in the database.
      */
     private static final String SQL_GETSTOCKS =
-            "SELECT s.id AS id, s.item AS item, " +
-                    "i.name AS name, s.quantity AS quantity FROM stocks s " +
-                    "INNER JOIN items i ON s.item = i.id";
+            "SELECT " + columns() + " FROM stocks INNER JOIN items ON stocks.item = items.id INNER JOIN categories on items.category = categories.id";
 
-    private static final String SQL_GETSTOCKFORITEM = SQL_GETSTOCKS +
-            " WHERE item = ?";
+    private static final String SQL_GETSTOCKFORITEM = SQL_GETSTOCKS + " WHERE item = ?";
 
-    private static final String SQL_UPDATESTOCK =
-            "UPDATE stocks SET quantity = ? WHERE item = ?";
+    private static final String SQL_UPDATESTOCK = "UPDATE stocks SET quantity = ? WHERE item = ?";
 
     /**
      * Class constructor.
+     *
      * @param conn
      */
     public SqliteStocksRepository(Connection conn) {
@@ -60,9 +69,7 @@ public class SqliteStocksRepository extends SqliteRepository implements IStocksR
         List<Stock> res = new ArrayList<>();
         try {
             while (rs.next()) {
-                Stock s = new Stock(rs.getInt("id"),
-                        rs.getInt("item"), rs.getString("name"),
-                        rs.getInt("quantity"));
+                Stock s = fromDb(rs);
                 res.add(s);
             }
         } catch (SQLException ex) {
@@ -112,9 +119,7 @@ public class SqliteStocksRepository extends SqliteRepository implements IStocksR
         Stock s;
         try {
             if (rs.next())
-                s = new Stock(rs.getInt("id"), rs.getInt("item"),
-                        rs.getString("name"),
-                        rs.getInt("quantity"));
+                s = fromDb(rs);
             else
                 return null;
         } catch (SQLException ex) {
@@ -128,6 +133,7 @@ public class SqliteStocksRepository extends SqliteRepository implements IStocksR
 
     /**
      * Updates the specified stock entry with the new quantity.
+     *
      * @param stock
      * @throws fr.unistra.sil.erp.back.repository.DatabaseConnectionException
      * @throws fr.unistra.sil.erp.back.repository.DatabaseUpdateException
diff --git a/src/main/java/fr/unistra/sil/erp/back/service/CantStoreItemException.java b/src/main/java/fr/unistra/sil/erp/back/service/CantStoreItemException.java
index 37bef11..cd14457 100644
--- a/src/main/java/fr/unistra/sil/erp/back/service/CantStoreItemException.java
+++ b/src/main/java/fr/unistra/sil/erp/back/service/CantStoreItemException.java
@@ -6,4 +6,7 @@ package fr.unistra.sil.erp.back.service;
  */
 public class CantStoreItemException extends Exception
 {
+    public CantStoreItemException(String message) {
+        super(message);
+    }
 }
diff --git a/src/main/java/fr/unistra/sil/erp/back/service/StoreItemService.java b/src/main/java/fr/unistra/sil/erp/back/service/StoreItemService.java
index 2cb2dde..ed4b8ae 100644
--- a/src/main/java/fr/unistra/sil/erp/back/service/StoreItemService.java
+++ b/src/main/java/fr/unistra/sil/erp/back/service/StoreItemService.java
@@ -1,6 +1,10 @@
 package fr.unistra.sil.erp.back.service;
 
+import fr.unistra.sil.erp.back.controller.api.ApiResourceNotFoundException;
+import fr.unistra.sil.erp.back.model.Category;
 import fr.unistra.sil.erp.back.model.Item;
+import fr.unistra.sil.erp.back.repository.DatabaseResourceNotFoundException;
+import fr.unistra.sil.erp.back.repository.ICategoriesRepository;
 import fr.unistra.sil.erp.back.repository.IItemsRepository;
 import org.springframework.stereotype.Service;
 
@@ -10,14 +14,12 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class StoreItemService {
-    private final IItemsRepository repository;
+    private final ICategoriesRepository categoriesRepository;
+    private final IItemsRepository itemsRepository;
 
-    /**
-     *
-     * @param repository
-     */
-    public StoreItemService(IItemsRepository repository) {
-        this.repository = repository;
+    public StoreItemService( ICategoriesRepository categoriesRepository, IItemsRepository itemsRepository) {
+        this.categoriesRepository = categoriesRepository;
+        this.itemsRepository = itemsRepository;
     }
 
     /**
@@ -26,16 +28,22 @@ public class StoreItemService {
      * @return
      * @throws CantStoreItemException
      */
-    public Item store(StoreItemRequest request) throws CantStoreItemException {
-        Item stored = repository.store(new Item(
+    public Item store(StoreItemRequest request) throws CantStoreItemException, ApiResourceNotFoundException {
+        Category category;
+        try {
+            category = categoriesRepository.getCategory(request.getCategory());
+        } catch (DatabaseResourceNotFoundException e) {
+            throw new ApiResourceNotFoundException("Category not found");
+        }
+        Item stored = itemsRepository.store(new Item(
                 null,
                 request.getName(),
                 request.getPrice(),
                 request.getSubscriberPrice(),
-                request.getCategory()
+                category
         ));
         if (stored == null) {
-            throw new CantStoreItemException();
+            throw new CantStoreItemException("Can't store item");
         }
         return stored;
     }
diff --git a/src/main/java/fr/unistra/sil/erp/back/service/UpdateStockService.java b/src/main/java/fr/unistra/sil/erp/back/service/UpdateStockService.java
index 66c7f29..e8c20e7 100644
--- a/src/main/java/fr/unistra/sil/erp/back/service/UpdateStockService.java
+++ b/src/main/java/fr/unistra/sil/erp/back/service/UpdateStockService.java
@@ -1,6 +1,5 @@
 package fr.unistra.sil.erp.back.service;
 
-import fr.unistra.sil.erp.back.model.Item;
 import fr.unistra.sil.erp.back.model.RegistryEntry;
 import fr.unistra.sil.erp.back.model.Stock;
 import fr.unistra.sil.erp.back.repository.*;
@@ -16,18 +15,15 @@ import java.util.Date;
 @Service
 public class UpdateStockService {
     private final IStocksRepository stocksRepository;
-    private final IItemsRepository itemsRepository;
     private final IRegistryRepository registryRepository;
 
     /**
      *
      * @param repository
-     * @param itemsRepository
      * @param registryRepository
      */
-    public UpdateStockService(IStocksRepository repository, IItemsRepository itemsRepository, IRegistryRepository registryRepository) {
+    public UpdateStockService(IStocksRepository repository, IRegistryRepository registryRepository) {
         this.stocksRepository = repository;
-        this.itemsRepository = itemsRepository;
         this.registryRepository = registryRepository;
     }
 
@@ -52,11 +48,7 @@ public class UpdateStockService {
         } catch (DatabaseConnectionException | DatabaseUpdateException e) {
             throw new CantUpdateStockException("Internal error");
         }
-        Item item = itemsRepository.findById(stock.getItemId());
-        if (item == null) {
-            throw new CantUpdateStockException("Item not found");
-        }
-        BigDecimal totalPrice = item.getPrice().multiply(BigDecimal.valueOf(Math.abs(request.getQuantity())));
+        BigDecimal totalPrice = stock.getItem().getPrice().multiply(BigDecimal.valueOf(Math.abs(request.getQuantity())));
         RegistryEntry entry = new RegistryEntry(
                 null,
                 request.getQuantity() > 0 ? 1 : 3,
-- 
GitLab