Skip to content
Snippets Groups Projects
Commit e32f457a authored by BEAUVAIS ANTOINE's avatar BEAUVAIS ANTOINE
Browse files

Added simple stock manipulation through transaction.

parent 9c701b4c
Branches
1 merge request!2Merge new API transaction handling into 'master'.
Showing
with 263 additions and 7 deletions
......@@ -33,7 +33,7 @@ public class DatabaseSystem {
DatabaseSystem.instance = new DatabaseSQLiteImpl();
if(DatabaseSystem.instance == null)
throw new DatabaseConnectionException();
throw new DatabaseConnectionException("Failed to create DB.");
return DatabaseSystem.instance;
}
......
......@@ -53,4 +53,19 @@ public class ApiErrorHandler {
HttpStatus.BAD_REQUEST);
}
/**
* Handler for HTTP 404 Not Found.
* @param ex the thrown Exception.
* @param request the HTTP Servlet request.
* @param response the HTTP Servlet response.
* @return the response to the client.
*/
@ExceptionHandler(ApiResourceNotFoundException.class)
public ResponseEntity<Object> handleResourceNotFound(Exception ex,
HttpServletRequest request, HttpServletResponse response)
{
return new ResponseEntity<>(new ErrorMessage(ex.getMessage()),
HttpStatus.NOT_FOUND);
}
}
/*
* CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL-B
* https://cecill.info/licences/Licence_CeCILL-B_V1-fr.html
*/
package fr.unistra.sil.erp.back.controller.api;
/**
* API Exception for HTTP 404 Not Found.
*
* If a resource requested by the user does not exist, this exception
* is thrown and handled through ApiErrorHandler.class.
*
* @see ApiErrorHandler
*
* @author BEAUVAIS ANTOINE
*/
public class ApiResourceNotFoundException extends Exception {
/**
* Class constructor.
* @param errMsg the error message.
*/
public ApiResourceNotFoundException(String errMsg)
{
super(errMsg);
}
}
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
* CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL-B
* https://cecill.info/licences/Licence_CeCILL-B_V1-fr.html
*/
package fr.unistra.sil.erp.back.controller.api;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import static fr.unistra.sil.erp.back.Config.MAPPING_SUBTRANSAC;
import fr.unistra.sil.erp.back.DatabaseSystem;
import fr.unistra.sil.erp.back.controller.ISubmitTransactionController;
import fr.unistra.sil.erp.back.db.DatabaseConnectionException;
import fr.unistra.sil.erp.back.db.DatabaseInterface;
import fr.unistra.sil.erp.back.db.DatabaseResourceNotFoundException;
import fr.unistra.sil.erp.back.db.DatabaseUpdateException;
import fr.unistra.sil.erp.back.model.Stock;
import fr.unistra.sil.erp.back.model.Transaction;
import java.io.IOException;
import java.util.logging.Level;
......@@ -35,11 +41,15 @@ public class ApiSubmitTransactionController
* @param response the HTTP Servlet Response provided by Spring.
* @return the response for the user.
* @throws ApiBadRequestException if the query failed.
* @throws ApiServerErrorException Server error.
* @throws ApiResourceNotFoundException Stock not found.
*/
@RequestMapping(value=MAPPING_SUBTRANSAC, method = RequestMethod.POST)
@Override
public ResponseEntity<Object> submitTransaction(HttpServletRequest request,
HttpServletResponse response) throws ApiBadRequestException
HttpServletResponse response)
throws ApiBadRequestException, ApiServerErrorException,
ApiResourceNotFoundException
{
Gson gson = new Gson();
String body;
......@@ -70,9 +80,34 @@ public class ApiSubmitTransactionController
if(!t.checkIfValid())
throw new ApiBadRequestException("Invalid JSON schema.");
System.out.println("Transaction : " + t.getItem() +
t.getType() + " " + t.getAmount());
DatabaseInterface db;
Stock s;
try {
db = DatabaseSystem.getInstance();
s = db.getStockForItem(t.getItem());
if(s == null)
throw new ApiServerErrorException("Database failure.");
int newQuantity = s.getQuantity() + t.getQuantity();
if(newQuantity < 0)
newQuantity = 0;
db.updateStock(s.getId(), newQuantity);
} catch (DatabaseConnectionException ex) {
Logger.getLogger(ApiSubmitTransactionController.class.getName())
.log(Level.SEVERE, ex.getMessage(), ex);
throw new ApiServerErrorException("Database failure.");
} catch (DatabaseResourceNotFoundException ex) {
//Logger.getLogger(ApiSubmitTransactionController.class.getName())
// .log(Level.SEVERE, null, ex);
throw new ApiResourceNotFoundException("No stock found for item " +
t.getItem());
} catch (DatabaseUpdateException ex) {
Logger.getLogger(ApiSubmitTransactionController.class.getName())
.log(Level.SEVERE, ex.getMessage(), ex);
throw new ApiServerErrorException("Database update failure.");
}
return new ResponseEntity<>(t, HttpStatus.CREATED);
}
......
......@@ -16,4 +16,13 @@ package fr.unistra.sil.erp.back.db;
*/
public class DatabaseConnectionException extends Exception {
/**
* Class constructor.
* @param errMsg the error message.
*/
public DatabaseConnectionException(String errMsg)
{
super(errMsg);
}
}
......@@ -46,4 +46,22 @@ public interface DatabaseInterface {
*/
public List<Stock> getStocks();
/**
* Returns the stock entry of an item.
* @param id the item's ID.
* @return the stock line.
* @throws DatabaseResourceNotFoundException when the query fails.
*/
public Stock getStockForItem(int itemId)
throws DatabaseResourceNotFoundException;
/**
* Updates the specified stock's quantity.
* @param id the stock entry's ID.
* @param quantity the new quantity.
* @throws DatabaseUpdateException when the query fails.
*/
public void updateStock(int id, int quantity)
throws DatabaseConnectionException, DatabaseUpdateException;
}
/*
* CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL-B
* https://cecill.info/licences/Licence_CeCILL-B_V1-fr.html
*/
package fr.unistra.sil.erp.back.db;
/**
* Exception for non-existent database resources.
*
* If the information requested in a database doesn't exist, this Exception
* is thrown.
*
* @author BEAUVAIS ANTOINE
*/
public class DatabaseResourceNotFoundException extends Exception {
/**
* Class constructor.
* @param errMsg the error message.
*/
public DatabaseResourceNotFoundException(String errMsg)
{
super(errMsg);
}
}
......@@ -60,6 +60,12 @@ public class DatabaseSQLiteImpl implements DatabaseInterface {
"i.name AS name, s.quantity AS quantity FROM stocks s " +
"INNER JOIN items i ON s.item = i.ref";
private static final String SQL_GETSTOCKFORITEM = SQL_GETSTOCKS +
" WHERE item = ?";
private static final String SQL_UPDATESTOCK =
"UPDATE stocks SET quantity = ? WHERE item = ?";
/**
* SQL Connection object.
*/
......@@ -177,6 +183,7 @@ public class DatabaseSQLiteImpl implements DatabaseInterface {
} catch (SQLException ex) {
Logger.getLogger(DatabaseSQLiteImpl.class.getName()).log(
Level.SEVERE, "Failed to parse results.", ex);
return null;
}
return res;
......@@ -235,5 +242,96 @@ public class DatabaseSQLiteImpl implements DatabaseInterface {
return res;
}
/**
* Returns the stock entry for the specified item.
* @param itemId the item's ID.
* @return the Stock entry.
* @throws DatabaseResourceNotFoundException if the stock doesn't exist.
*/
@Override
public Stock getStockForItem(int itemId)
throws DatabaseResourceNotFoundException {
PreparedStatement ps;
try {
ps = this.conn.prepareStatement(SQL_GETSTOCKFORITEM);
} catch (SQLException ex) {
Logger.getLogger(DatabaseSQLiteImpl.class.getName()).log(
Level.SEVERE, "Failed to connect to database.", ex);
return null;
}
try {
ps.setInt(1, itemId);
} catch (SQLException ex) {
Logger.getLogger(DatabaseSQLiteImpl.class.getName()).log(
Level.SEVERE, "Failed to set query parameter.", ex);
return null;
}
ResultSet rs;
try {
rs = ps.executeQuery();
} catch (SQLException ex) {
Logger.getLogger(DatabaseSQLiteImpl.class.getName()).log(
Level.SEVERE, "Failed to fetch stock for item " +
itemId, ex);
return null;
}
Stock s;
try {
if(rs.next())
s = new Stock(rs.getInt("id"), rs.getInt("item"),
rs.getString("name"),
rs.getInt("quantity"));
else
throw new DatabaseResourceNotFoundException("Stock not found.");
} catch (SQLException ex) {
Logger.getLogger(DatabaseSQLiteImpl.class.getName()).log(
Level.SEVERE, "Failed to parse results.", ex);
return null;
}
return s;
}
/**
* Updates the specified stock entry with the new quantity.
* @param id the stock's ID.
* @param quantity the associated quantity.
* @throws DatabaseConnectionException when the connection to the DB fails.
* @throws DatabaseUpdateException when the update fails.
*/
@Override
public void updateStock(int id, int quantity)
throws DatabaseConnectionException, DatabaseUpdateException {
PreparedStatement ps;
try {
ps = this.conn.prepareStatement(SQL_UPDATESTOCK);
} catch (SQLException ex) {
Logger.getLogger(DatabaseSQLiteImpl.class.getName()).log(
Level.SEVERE, "Failed to connect to database.", ex);
throw new DatabaseConnectionException("Failed to connect to DB.");
}
try {
ps.setInt(1, quantity);
ps.setInt(2, id);
} catch (SQLException ex) {
Logger.getLogger(DatabaseSQLiteImpl.class.getName()).log(
Level.SEVERE, "Failed to set query parameter.", ex);
throw new DatabaseUpdateException("Failed to set query params.");
}
try {
ps.execute();
} catch (SQLException ex) {
Logger.getLogger(DatabaseSQLiteImpl.class.getName())
.log(Level.SEVERE, "Failed to execute query.", ex);
throw new DatabaseUpdateException("Failed to execute query.");
}
}
}
/*
* CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL-B
* https://cecill.info/licences/Licence_CeCILL-B_V1-fr.html
*/
package fr.unistra.sil.erp.back.db;
/**
* Exception for database update failures.
*
* When a database system fails to update specific rows
* from the database, then it throws this Exception so
* the application can handle it.
*
* @author BEAUVAIS ANTOINE
*/
public class DatabaseUpdateException extends Exception {
/**
* Class constructor.
* @param errMsg the error message.
*/
public DatabaseUpdateException(String errMsg)
{
super(errMsg);
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment