191 lines
7.4 KiB
Java
191 lines
7.4 KiB
Java
package com.andreicerbu;
|
|
|
|
import com.andreicerbu.exceptions.*;
|
|
import com.andreicerbu.items.database.TableDeposit;
|
|
import com.andreicerbu.json.JsonFields;
|
|
import org.json.JSONArray;
|
|
import org.json.JSONObject;
|
|
|
|
import java.sql.*;
|
|
import java.util.*;
|
|
|
|
import static com.andreicerbu.json.JsonFields.listOfDeposits;
|
|
|
|
public class Algorithm {
|
|
JSONObject order = null;
|
|
Integer id_user = null;
|
|
String name = null;
|
|
Float lat_coord = null;
|
|
Float long_coord = null;
|
|
|
|
JSONObject routeJson = null;
|
|
JSONObject destination = null;
|
|
JSONArray deposits = null;
|
|
|
|
List<TableDeposit> listOfDeposits = new ArrayList<>();
|
|
Map<Integer, String> mapProductIdToName = new HashMap<>();
|
|
|
|
public Algorithm(JSONObject order) throws SQLException, ProductUnavailableAnymoreException {
|
|
this.order = new JSONObject(order.toString());
|
|
this.id_user = this.order.getInt(JsonFields.id_user);
|
|
this.order.remove(JsonFields.id_user);
|
|
|
|
run();
|
|
}
|
|
|
|
private void getUserInformation(Connection conn) throws SQLException{
|
|
PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?");
|
|
pstmt.setInt(1, id_user);
|
|
|
|
ResultSet resultSet = pstmt.executeQuery();
|
|
resultSet.next();
|
|
|
|
name = resultSet.getString("username");
|
|
lat_coord = resultSet.getFloat(JsonFields.lat_coord);
|
|
long_coord = resultSet.getFloat(JsonFields.long_coord);
|
|
|
|
destination = new JSONObject();
|
|
destination.put(JsonFields.id_user, id_user);
|
|
destination.put(JsonFields.name, name);
|
|
destination.put(JsonFields.lat_coord, lat_coord);
|
|
destination.put(JsonFields.long_coord, long_coord);
|
|
}
|
|
|
|
private void getDeposits(Connection conn) throws SQLException{
|
|
PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM deposits");
|
|
ResultSet resultSet = pstmt.executeQuery();
|
|
|
|
while(resultSet.next()){
|
|
listOfDeposits.add(new TableDeposit(
|
|
resultSet.getInt("id"), resultSet.getString("name"),
|
|
resultSet.getFloat("lat_coord"), resultSet.getFloat("long_coord")
|
|
));
|
|
}
|
|
|
|
listOfDeposits.sort(new Comparator<TableDeposit>() {
|
|
@Override
|
|
public int compare(TableDeposit d1, TableDeposit d2) {
|
|
return (int) (findDistanceBetweenCoord(d2.getLat_coord(), d2.getLong_coord(), lat_coord, long_coord) -
|
|
findDistanceBetweenCoord(d1.getLat_coord(), d1.getLong_coord(), lat_coord, long_coord));
|
|
}
|
|
});
|
|
}
|
|
|
|
private float findDistanceBetweenCoord(Float x1, Float y1, Float x2, Float y2){
|
|
return (float) Math.sqrt(
|
|
Math.pow((x2 - x1), 2) + Math.pow((y2 - y1), 2)
|
|
);
|
|
}
|
|
|
|
private void getProductNames(Connection conn) throws SQLException {
|
|
JSONArray products = new JSONArray(order.get(JsonFields.listOfProducts).toString());
|
|
Statement stmt = conn.createStatement();
|
|
ResultSet resultSet = stmt.executeQuery("SELECT id, name FROM products");
|
|
|
|
while (resultSet.next()) {
|
|
int id_product = resultSet.getInt("id");
|
|
String name = resultSet.getString("name");
|
|
|
|
for (int index = 0; index < products.length(); index++) {
|
|
JSONObject item = products.getJSONObject(index);
|
|
|
|
if(id_product == item.getInt(JsonFields.id_product)){
|
|
mapProductIdToName.put(id_product, name);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void createRoute(Connection conn) throws SQLException, ProductUnavailableAnymoreException {
|
|
deposits = new JSONArray();
|
|
JSONArray products = new JSONArray(order.get(JsonFields.listOfProducts).toString());
|
|
|
|
PreparedStatement pstmt;
|
|
for(TableDeposit deposit : listOfDeposits){//we take each deposit
|
|
JSONObject depositJSON = new JSONObject(createDepositJSONForRoute(deposit).toString());
|
|
JSONArray listOfProductsJSON = depositJSON.getJSONArray(JsonFields.listOfProducts);
|
|
|
|
pstmt = conn.prepareStatement("SELECT * FROM prod_in_depo WHERE id_deposit = ?");
|
|
pstmt.setInt(1, deposit.getId_deposit());
|
|
ResultSet resultSet = pstmt.executeQuery();//we take all the products that exists in a deposit
|
|
|
|
while(resultSet.next()){
|
|
int id_product = resultSet.getInt("id_product");
|
|
int quantity = resultSet.getInt("quantity");
|
|
String name = mapProductIdToName.get(id_product);
|
|
|
|
for(int index = 0; index < products.length(); index++){//iterate through our order
|
|
JSONObject item = products.getJSONObject(index);
|
|
JSONObject itemForList = new JSONObject();
|
|
|
|
if(item.getInt(JsonFields.id_product) == id_product){
|
|
itemForList.put(JsonFields.id_product, id_product);
|
|
itemForList.put(JsonFields.name, name);
|
|
int newQuantity = item.getInt(JsonFields.quantity) - quantity;
|
|
|
|
if(newQuantity > 0){
|
|
item.put(JsonFields.quantity, newQuantity);
|
|
itemForList.put(JsonFields.quantity, quantity);
|
|
}else{
|
|
itemForList.put(JsonFields.quantity, item.getInt(JsonFields.quantity));
|
|
products.remove(index);
|
|
}
|
|
|
|
listOfProductsJSON.put(itemForList);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!depositJSON.getJSONArray(JsonFields.listOfProducts).isEmpty()) {
|
|
deposits.put(depositJSON);
|
|
}
|
|
|
|
if(products.isEmpty()){
|
|
return;
|
|
}
|
|
}
|
|
|
|
if(!products.isEmpty()){
|
|
throw new ProductUnavailableAnymoreException("One of the chosen products is not available anymore");
|
|
}
|
|
}
|
|
|
|
private JSONObject createDepositJSONForRoute(TableDeposit deposit){
|
|
JSONObject depositJSON = new JSONObject();
|
|
|
|
depositJSON.put(JsonFields.id_deposit, deposit.getId_deposit());
|
|
depositJSON.put(JsonFields.name, deposit.getName());
|
|
depositJSON.put(JsonFields.lat_coord, deposit.getLat_coord());
|
|
depositJSON.put(JsonFields.long_coord, deposit.getLong_coord());
|
|
depositJSON.put(JsonFields.listOfProducts, new JSONArray());
|
|
depositJSON.put(JsonFields.distance, findDistanceBetweenCoord(lat_coord, long_coord, deposit.getLat_coord(), deposit.getLong_coord()));
|
|
|
|
return depositJSON;
|
|
}
|
|
|
|
|
|
private void createJsonRoute(){
|
|
routeJson = new JSONObject();
|
|
|
|
routeJson.put(JsonFields.destination, destination);
|
|
routeJson.put(JsonFields.listOfDeposits, deposits);
|
|
routeJson.put(JsonFields.listOfProducts, order.getJSONArray(JsonFields.listOfProducts));
|
|
}
|
|
|
|
private synchronized void run() throws SQLException, ProductUnavailableAnymoreException{
|
|
Connection conn = Database.getConnection();
|
|
|
|
getUserInformation(conn);
|
|
getDeposits(conn);
|
|
getProductNames(conn);
|
|
|
|
createRoute(conn);
|
|
createJsonRoute();
|
|
}
|
|
|
|
public JSONObject getRouteJson() {
|
|
return routeJson;
|
|
}
|
|
}
|