Merge branch 'master' of gitea.joethei.xyz:/Studium/Softwareprojektmanagement into HEAD
This commit is contained in:
commit
e73edbbd21
|
@ -27,14 +27,12 @@ public class ShoppingCart implements Analysis<Map<List<String>, List<String>>> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<List<String>, List<String>> getResult() {
|
public Map<List<String>, List<String>> getResult() {
|
||||||
if(result != null) {
|
if (result != null) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = new HashMap<>();
|
result = new HashMap<>();
|
||||||
|
|
||||||
Apriori model = new Apriori();
|
|
||||||
|
|
||||||
for (int i = 0; i < 11; i++) {
|
for (int i = 0; i < 11; i++) {
|
||||||
instances.deleteAttributeAt(0);
|
instances.deleteAttributeAt(0);
|
||||||
}
|
}
|
||||||
|
@ -60,6 +58,8 @@ public class ShoppingCart implements Analysis<Map<List<String>, List<String>>> {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Apriori model = new Apriori();
|
||||||
|
|
||||||
model.setTreatZeroAsMissing(true);
|
model.setTreatZeroAsMissing(true);
|
||||||
try {
|
try {
|
||||||
model.buildAssociations(instances);
|
model.buildAssociations(instances);
|
||||||
|
@ -67,19 +67,19 @@ public class ShoppingCart implements Analysis<Map<List<String>, List<String>>> {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < model.getAssociationRules().getRules().size();i++){
|
for (int i = 0; i < model.getAssociationRules().getRules().size(); i++) {
|
||||||
AssociationRule rule = model.getAssociationRules().getRules().get(i);
|
AssociationRule rule = model.getAssociationRules().getRules().get(i);
|
||||||
|
|
||||||
List<String> l1 = new ArrayList<>();
|
List<String> l1 = new ArrayList<>();
|
||||||
for(Item item : rule.getPremise()){
|
for (Item item : rule.getPremise()) {
|
||||||
l1.add(item.getAttribute().name());
|
l1.add(item.getAttribute().name());
|
||||||
}
|
}
|
||||||
List<String> l2 = new ArrayList<>();
|
List<String> l2 = new ArrayList<>();
|
||||||
for(Item item : rule.getConsequence()){
|
for (Item item : rule.getConsequence()) {
|
||||||
l2.add(item.getAttribute().name());
|
l2.add(item.getAttribute().name());
|
||||||
}
|
}
|
||||||
|
|
||||||
result.put(l1,l2);
|
result.put(l1, l2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,30 +36,20 @@ public class WeekOverview implements Analysis<Map<String, Map.Entry<Double, Inte
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
result = new HashMap<>();
|
result = new HashMap<>();
|
||||||
int dayIndex = Attribute.SHOPPING_DAY;
|
|
||||||
int amountIndex = Attribute.PURCHASE_AMOUNT;
|
|
||||||
|
|
||||||
int startArticles = Attribute.POWER_TOOLS;
|
|
||||||
int endArticles = Attribute.GARDENING_TOOLS + 1;
|
|
||||||
|
|
||||||
for (int i = 0; i < instances.numInstances(); i++) {
|
for (int i = 0; i < instances.numInstances(); i++) {
|
||||||
Instance instance = instances.get(i);
|
Instance instance = instances.get(i);
|
||||||
double amount = instance.value(amountIndex);
|
double amount = instance.value(Attribute.PURCHASE_AMOUNT);
|
||||||
String day = instance.stringValue(dayIndex);
|
String day = instance.stringValue(Attribute.SHOPPING_DAY);
|
||||||
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
for (int j = startArticles; j < endArticles; j++) {
|
|
||||||
count += (int) instance.value(j);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!result.containsKey(day)) {
|
if (!result.containsKey(day)) {
|
||||||
result.put(day, new AbstractMap.SimpleEntry<>(0.0, 0));
|
result.put(day, new AbstractMap.SimpleEntry<>(0.0, 0));
|
||||||
}
|
}
|
||||||
result.put(day,
|
result.put(day,
|
||||||
new AbstractMap.SimpleEntry<>(
|
new AbstractMap.SimpleEntry<>(
|
||||||
result.get(day).getKey() + amount,
|
result.get(day).getKey() + amount,
|
||||||
result.get(day).getValue() + count
|
result.get(day).getValue() + 1
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
package de.hsel.spm.baudas.web;
|
package de.hsel.spm.baudas.web;
|
||||||
|
|
||||||
import javax.servlet.*;
|
import javax.servlet.Filter;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.FilterConfig;
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
import javax.servlet.annotation.WebFilter;
|
import javax.servlet.annotation.WebFilter;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
@ -14,27 +20,29 @@ import java.io.IOException;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@WebFilter(urlPatterns = {"/*"})
|
@WebFilter(urlPatterns = {"/*"})
|
||||||
public class AuthenticationFilter implements Filter{
|
public class AuthenticationFilter implements Filter {
|
||||||
private ServletContext context;
|
private ServletContext context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by the web container to indicate to a filter that it is being placed into service. This filter manages the authentication.
|
* Called by the web container to indicate to a filter that it is being placed into service. This filter manages the authentication.
|
||||||
* @param fConfig This parameter provides access to everything the code needs to work.
|
*
|
||||||
|
* @param filterConfig This parameter provides access to everything the code needs to work.
|
||||||
* @throws ServletException Defines a general exception a servlet can throw when it encounters difficulty.
|
* @throws ServletException Defines a general exception a servlet can throw when it encounters difficulty.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void init(FilterConfig fConfig) throws ServletException {
|
public void init(FilterConfig filterConfig) throws ServletException {
|
||||||
this.context = fConfig.getServletContext();
|
this.context = filterConfig.getServletContext();
|
||||||
this.context.log("AuthenticationFilter initialized");
|
this.context.log("AuthenticationFilter initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The doFilter method of the Filter is called by the container each time a request/response pair is passed through the chain due to a client request for a resource at the end of the chain.
|
* The doFilter method of the Filter is called by the container each time a request/response pair is passed through the chain due to a client request for a resource at the end of the chain.
|
||||||
* @param request This parameter provides access to everything the code needs to work.
|
*
|
||||||
|
* @param request This parameter provides access to everything the code needs to work.
|
||||||
* @param response This parameter provides access to everything the code needs to issue a response.
|
* @param response This parameter provides access to everything the code needs to issue a response.
|
||||||
* @param chain This parameter allows passing request along the chain of potential handlers until one of them handles the request.
|
* @param chain This parameter allows passing request along the chain of potential handlers until one of them handles the request.
|
||||||
* @throws ServletException Defines a general exception a servlet can throw when it encounters difficulty.
|
* @throws ServletException Defines a general exception a servlet can throw when it encounters difficulty.
|
||||||
* @throws IOException Signals that an I/O exception of some sort has occurred. This class is the general class of exceptions produced by failed or interrupted I/O operations.
|
* @throws IOException Signals that an I/O exception of some sort has occurred. This class is the general class of exceptions produced by failed or interrupted I/O operations.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||||
|
@ -42,7 +50,7 @@ public class AuthenticationFilter implements Filter{
|
||||||
HttpServletResponse res = (HttpServletResponse) response;
|
HttpServletResponse res = (HttpServletResponse) response;
|
||||||
HttpSession session = req.getSession(false);
|
HttpSession session = req.getSession(false);
|
||||||
String url = req.getRequestURI();
|
String url = req.getRequestURI();
|
||||||
if(url.contains("login") || url.contains("logo") || url.contains("js/")){
|
if (url.contains("login") || url.contains("logo") || url.contains("js/")) {
|
||||||
chain.doFilter(request, response);
|
chain.doFilter(request, response);
|
||||||
} else if (session == null || !((boolean) session.getAttribute("authentication"))) { //checking whether the session exists and if authentication succeed
|
} else if (session == null || !((boolean) session.getAttribute("authentication"))) { //checking whether the session exists and if authentication succeed
|
||||||
this.context.log("Unauthorized access request");
|
this.context.log("Unauthorized access request");
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package de.hsel.spm.baudas.web;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import de.hsel.spm.baudas.analysis.Cluster;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* changes data from cluster analysis into a readable format
|
||||||
|
*
|
||||||
|
* @author Julian Hinxlage
|
||||||
|
* @version 0.1
|
||||||
|
* @since 0.1
|
||||||
|
**/
|
||||||
|
@WebServlet("/clusters")
|
||||||
|
public class ClusterDiagram extends HttpServlet {
|
||||||
|
@Override
|
||||||
|
protected void doGet(@NotNull HttpServletRequest req, @NotNull HttpServletResponse resp) throws IOException {
|
||||||
|
req.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||||
|
resp.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||||
|
resp.setContentType("application/json");
|
||||||
|
PrintWriter out = resp.getWriter();
|
||||||
|
|
||||||
|
Map<Integer, Map<String, String>> result = new HashMap<>();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
|
||||||
|
if (req.getParameter("id") == null) {
|
||||||
|
out.print(gson.toJson(result));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UUID uuid = UUID.fromString(req.getParameter("id"));
|
||||||
|
File file = Data.get(uuid);
|
||||||
|
|
||||||
|
Cluster cluster = new Cluster(file);
|
||||||
|
result = cluster.getResult();
|
||||||
|
out.print(gson.toJson(result));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package de.hsel.spm.baudas.web;
|
||||||
|
|
||||||
|
public class Columns {
|
||||||
|
private String col1; //NOPMD
|
||||||
|
private String col2; //NOPMD
|
||||||
|
|
||||||
|
public Columns(String col1, String col2){
|
||||||
|
this.col1 = col1;
|
||||||
|
this.col2 = col2;
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,8 +10,12 @@ import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* manages data about .csv files.
|
* manages data about .csv files.
|
||||||
|
@ -23,7 +27,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
public class Data {
|
public class Data {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private static ConcurrentLinkedQueue<SavedFile> files = new ConcurrentLinkedQueue<>();
|
private static ConcurrentMap<String, List<SavedFile>> files = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,42 +37,55 @@ public class Data {
|
||||||
* @return path to save file to
|
* @return path to save file to
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
static Path add(@NotNull String name) {
|
static Path add(@NotNull String name, @NotNull String session) {
|
||||||
//cleanup old files
|
UUID uuid = UUID.randomUUID();
|
||||||
if (files.isEmpty()) {
|
|
||||||
try {
|
if (!files.containsKey(session))
|
||||||
Files.list(Paths.get("")).forEach(path -> {
|
files.put(session, new ArrayList<>());
|
||||||
if (path.toFile().getName().endsWith(".csv")) {
|
|
||||||
|
if (files.get(session).size() >= 5) {
|
||||||
|
SavedFile file = files.get(session).iterator().next();
|
||||||
|
if (!get(file.getUuid()).delete()) {
|
||||||
|
System.err.println("failed to delete file..." + file);
|
||||||
|
}
|
||||||
|
files.get(session).remove(file);
|
||||||
|
}
|
||||||
|
files.get(session).add(new SavedFile(uuid, name, LocalDateTime.now()));
|
||||||
|
return Paths.get(getFileName(uuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delete all files for session.
|
||||||
|
*
|
||||||
|
* @param session session id
|
||||||
|
*/
|
||||||
|
static void delete(String session) {
|
||||||
|
for (SavedFile file : files.get(session)) {
|
||||||
|
if (!get(file.getUuid()).delete())
|
||||||
|
System.err.println("failed to delete file..." + file);
|
||||||
|
}
|
||||||
|
files.remove(session);
|
||||||
|
|
||||||
|
//deleting all files older than x days.
|
||||||
|
int days = 30;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Files.list(Paths.get("")).forEach(path -> {
|
||||||
|
if (path.toFile().getName().endsWith("*.csv")) {
|
||||||
|
long diff = new Date().getTime() - path.toFile().lastModified();
|
||||||
|
|
||||||
|
if (diff > (long) days * 24 * 60 * 60 * 1000) {
|
||||||
try {
|
try {
|
||||||
Files.delete(path);
|
Files.delete(path);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
} catch (IOException ex) {
|
});
|
||||||
ex.printStackTrace();
|
} catch (IOException ex) {
|
||||||
}
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
Path path;
|
|
||||||
UUID uuid = UUID.randomUUID();
|
|
||||||
|
|
||||||
if (files.size() >= 5) {
|
|
||||||
//remove last and add new one
|
|
||||||
SavedFile file = files.poll();
|
|
||||||
if (!get(file.getUuid()).delete()) {
|
|
||||||
System.out.println("failed to delete file...");
|
|
||||||
}
|
|
||||||
path = Paths.get(getFileName(uuid));
|
|
||||||
files.offer(new SavedFile(uuid, name, LocalDateTime.now()));
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
files.add(new SavedFile(uuid, name, LocalDateTime.now()));
|
|
||||||
path = Paths.get(getFileName(uuid));
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package de.hsel.spm.baudas.web;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* all possible error codes.
|
||||||
|
*
|
||||||
|
* @author Julian Hinxlage
|
||||||
|
* @version 0.1
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum ErrorCode {
|
||||||
|
FILE_NOT_FOUND("Die hochgeladene Datei konnte nicht gefunden werden"),
|
||||||
|
EMPTY_FILE("Die hochgeladene Datei ist leer"),
|
||||||
|
INVALID_FORMAT("Die hochgeladene Datei hat ein falsches Format");
|
||||||
|
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* is there a error code with this name ?.
|
||||||
|
*
|
||||||
|
* @param message string to search for
|
||||||
|
* @return error code exits ?
|
||||||
|
*/
|
||||||
|
public static boolean exists(String message) {
|
||||||
|
for (ErrorCode code : values()) {
|
||||||
|
System.out.println(message + " == " + code.name());
|
||||||
|
if (code.name().equals(message))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,6 @@ public class Files extends HttpServlet {
|
||||||
resp.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
resp.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||||
PrintWriter out = resp.getWriter();
|
PrintWriter out = resp.getWriter();
|
||||||
Gson gson = new Gson();
|
Gson gson = new Gson();
|
||||||
out.print(gson.toJson(Data.getFiles()));
|
out.print(gson.toJson(Data.getFiles().get(req.getSession().getId())));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,10 +23,11 @@ public class LoginServlet extends HttpServlet {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a Servlet that manages the Login and creates Sessions.
|
* This is a Servlet that manages the Login and creates Sessions.
|
||||||
* @param request This parameter provides access to everything the code needs to work.
|
*
|
||||||
|
* @param request This parameter provides access to everything the code needs to work.
|
||||||
* @param response This parameter provides access to everything the code needs to issue a response.
|
* @param response This parameter provides access to everything the code needs to issue a response.
|
||||||
* @throws ServletException Defines a general exception a servlet can throw when it encounters difficulty.
|
* @throws ServletException Defines a general exception a servlet can throw when it encounters difficulty.
|
||||||
* @throws IOException Signals that an I/O exception of some sort has occurred. This class is the general class of exceptions produced by failed or interrupted I/O operations.
|
* @throws IOException Signals that an I/O exception of some sort has occurred. This class is the general class of exceptions produced by failed or interrupted I/O operations.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||||
|
@ -34,7 +35,7 @@ public class LoginServlet extends HttpServlet {
|
||||||
if (this.password.equals(password)) {
|
if (this.password.equals(password)) {
|
||||||
HttpSession newSession = request.getSession(true);
|
HttpSession newSession = request.getSession(true);
|
||||||
newSession.setAttribute("authentication", true);
|
newSession.setAttribute("authentication", true);
|
||||||
newSession.setMaxInactiveInterval(5*60*60); //setting session to expiry in 5 hours
|
newSession.setMaxInactiveInterval(5 * 60 * 60); //setting session to expiry in 5 hours
|
||||||
response.sendRedirect("index.jsp");
|
response.sendRedirect("index.jsp");
|
||||||
} else {
|
} else {
|
||||||
RequestDispatcher rd = getServletContext().getRequestDispatcher("/login.html");
|
RequestDispatcher rd = getServletContext().getRequestDispatcher("/login.html");
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
package de.hsel.spm.baudas.web;
|
package de.hsel.spm.baudas.web;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import javax.servlet.annotation.WebServlet;
|
import javax.servlet.annotation.WebServlet;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Servlet implementation class LogoutServlet.
|
* Servlet implementation class LogoutServlet.
|
||||||
|
@ -19,14 +18,16 @@ public class LogoutServlet extends HttpServlet {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a Servlet that manages the Logout and deletes Sessions.
|
* This is a Servlet that manages the Logout and deletes Sessions.
|
||||||
* @param request This parameter provides access to everything the code needs to work.
|
*
|
||||||
|
* @param request This parameter provides access to everything the code needs to work.
|
||||||
* @param response This parameter provides access to everything the code needs to issue a response.
|
* @param response This parameter provides access to everything the code needs to issue a response.
|
||||||
* @throws IOException Signals that an I/O exception of some sort has occurred. This class is the general class of exceptions produced by failed or interrupted I/O operations.
|
* @throws IOException Signals that an I/O exception of some sort has occurred. This class is the general class of exceptions produced by failed or interrupted I/O operations.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||||
HttpSession session = request.getSession(false);
|
HttpSession session = request.getSession();
|
||||||
if(session != null){
|
if (session != null) {
|
||||||
|
Data.delete(session.getId());
|
||||||
session.invalidate();
|
session.invalidate();
|
||||||
}
|
}
|
||||||
response.sendRedirect(request.getContextPath() + "/");
|
response.sendRedirect(request.getContextPath() + "/");
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package de.hsel.spm.baudas.web;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import de.hsel.spm.baudas.analysis.ShoppingCart;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes data to readable format for table
|
||||||
|
*
|
||||||
|
* @author Karsten Eden
|
||||||
|
* @version 0.1
|
||||||
|
* @since 0.1
|
||||||
|
*/
|
||||||
|
@WebServlet("/shopping_cart")
|
||||||
|
public class ShoppingCartDiagram extends HttpServlet {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 5026732432605473505L;
|
||||||
|
|
||||||
|
protected void doGet(@NotNull HttpServletRequest req, @NotNull HttpServletResponse resp) throws IOException {
|
||||||
|
req.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||||
|
resp.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||||
|
resp.setContentType("application/json");
|
||||||
|
PrintWriter out = resp.getWriter();
|
||||||
|
|
||||||
|
Gson gson = new Gson();
|
||||||
|
List<Columns> colList = new ArrayList<>();
|
||||||
|
|
||||||
|
if (req.getParameter("id") == null) {
|
||||||
|
out.print(gson.toJson(colList));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UUID uuid = UUID.fromString(req.getParameter("id"));
|
||||||
|
File file = Data.get(uuid);
|
||||||
|
|
||||||
|
ShoppingCart cart = new ShoppingCart(file);
|
||||||
|
Map<List<String>, List<String>> result = new HashMap<>();
|
||||||
|
result = cart.getResult();
|
||||||
|
|
||||||
|
List<String> col1 = new ArrayList<>();
|
||||||
|
List<String> col2 = new ArrayList<>();
|
||||||
|
|
||||||
|
for(Map.Entry<List<String>, List<String>> entry : result.entrySet()){
|
||||||
|
col1.add(entry.getKey().toString());
|
||||||
|
col2.add(entry.getValue().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < col1.size(); i++ ){
|
||||||
|
colList.add(new Columns(col1.get(i).replaceAll("\\[", "").replaceAll("\\]", ""), col2.get(i).replaceAll("\\[", "").replaceAll("\\]", "")));
|
||||||
|
}
|
||||||
|
|
||||||
|
out.print(gson.toJson(colList));
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,9 +12,15 @@ import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* top/flop articles list diagram.
|
||||||
|
*
|
||||||
* @author Johannes Theiner
|
* @author Johannes Theiner
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @since 0.1
|
* @since 0.1
|
||||||
|
@ -45,7 +51,7 @@ public class TopFlopArticleDiagram extends HttpServlet {
|
||||||
List<String> labels = new ArrayList<>();
|
List<String> labels = new ArrayList<>();
|
||||||
List<String> data = new ArrayList<>();
|
List<String> data = new ArrayList<>();
|
||||||
|
|
||||||
for(Map.Entry<String, Integer> entry : map.entrySet()) {
|
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||||
labels.add(entry.getKey());
|
labels.add(entry.getKey());
|
||||||
data.add(entry.getValue().toString());
|
data.add(entry.getValue().toString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package de.hsel.spm.baudas.web;
|
package de.hsel.spm.baudas.web;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import weka.core.converters.CSVLoader;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.annotation.MultipartConfig;
|
import javax.servlet.annotation.MultipartConfig;
|
||||||
|
@ -20,7 +21,7 @@ import java.nio.file.StandardCopyOption;
|
||||||
/**
|
/**
|
||||||
* saves uploaded files.
|
* saves uploaded files.
|
||||||
*
|
*
|
||||||
* @author Johannes Theiner
|
* @author Johannes Theiner, Julian Hinxlage
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @since 0.1
|
* @since 0.1
|
||||||
**/
|
**/
|
||||||
|
@ -31,24 +32,71 @@ public class Upload extends HttpServlet {
|
||||||
|
|
||||||
private static final long serialVersionUID = 14144111845151L;
|
private static final long serialVersionUID = 14144111845151L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* let weka check if the format is valid.
|
||||||
|
*
|
||||||
|
* @param stream input stream
|
||||||
|
* @return format valid
|
||||||
|
*/
|
||||||
|
private boolean checkFormat(InputStream stream) {
|
||||||
|
CSVLoader loader = new CSVLoader();
|
||||||
|
try {
|
||||||
|
loader.setSource(stream);
|
||||||
|
return loader.getDataSet() != null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(@NotNull HttpServletRequest req, HttpServletResponse resp)
|
protected void doPost(@NotNull HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
throws ServletException, IOException {
|
|
||||||
req.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
req.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||||
|
|
||||||
Part filePart = req.getPart("file");
|
Part filePart = req.getPart("file");
|
||||||
|
|
||||||
|
if (filePart == null) {
|
||||||
|
resp.sendRedirect("error.jsp?code=" + ErrorCode.FILE_NOT_FOUND);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filePart.getSubmittedFileName() == null) {
|
||||||
|
resp.sendRedirect("error.jsp?code=" + ErrorCode.FILE_NOT_FOUND);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString();
|
String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString();
|
||||||
|
|
||||||
|
if (fileName == null) {
|
||||||
|
resp.sendRedirect("error.jsp?code=" + ErrorCode.FILE_NOT_FOUND);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
InputStream inputStream = filePart.getInputStream();
|
InputStream inputStream = filePart.getInputStream();
|
||||||
|
|
||||||
|
if (inputStream == null) {
|
||||||
|
resp.sendRedirect("error.jsp?code=" + ErrorCode.FILE_NOT_FOUND);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (inputStream.available() == 0) {
|
||||||
|
resp.sendRedirect("error.jsp?code=" + ErrorCode.EMPTY_FILE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Path path = Data.add(fileName);
|
if (!checkFormat(inputStream)) {
|
||||||
|
resp.sendRedirect("error.jsp?code=" + ErrorCode.INVALID_FORMAT);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
inputStream = filePart.getInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
Path path = Data.add(fileName, req.getSession().getId());
|
||||||
if (!Files.exists(path)) {
|
if (!Files.exists(path)) {
|
||||||
Files.createFile(path);
|
Files.createFile(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
Files.copy(inputStream, path, StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(inputStream, path, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
|
||||||
|
|
||||||
resp.sendRedirect("");
|
resp.sendRedirect("");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
<%@include file="head.jsp"%>
|
||||||
|
|
||||||
|
<!--Navbar-->
|
||||||
|
<div class="navbar-fixed">
|
||||||
|
<nav class="nav-extended blue-grey darken-3 white-text row">
|
||||||
|
<a href="#" class="brand-logo hide-on-small-and-down center">BauDas</a>
|
||||||
|
<!--Navbar Items-->
|
||||||
|
<div class="nav-wrapper col 2 right">
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<br>
|
|
@ -0,0 +1,32 @@
|
||||||
|
<%@ page import="de.hsel.spm.baudas.web.ErrorCode" %>
|
||||||
|
<%@ page import="java.nio.charset.StandardCharsets" %>
|
||||||
|
<%@ page import="java.util.List" %>
|
||||||
|
<%@ page import="java.util.Arrays" %>
|
||||||
|
<%@ page import="java.util.ArrayList" %>
|
||||||
|
<%@ page contentType="text/html;charset=UTF-8" %>
|
||||||
|
<%@include file="emptyHeader.jsp"%>
|
||||||
|
<% response.setCharacterEncoding(StandardCharsets.UTF_8.name()); %>
|
||||||
|
<% request.setCharacterEncoding(StandardCharsets.UTF_8.name()); %>
|
||||||
|
|
||||||
|
<%
|
||||||
|
String code = request.getParameter("code");
|
||||||
|
|
||||||
|
if(code != null && ErrorCode.exists(code)){
|
||||||
|
ErrorCode errorCode = ErrorCode.valueOf(code);
|
||||||
|
%>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s4 push-s4">
|
||||||
|
<div class="card-panel red darken-1">
|
||||||
|
<h5 class="white-text center-align">
|
||||||
|
<%= errorCode.getMessage()%>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<%
|
||||||
|
}
|
||||||
|
%>
|
||||||
|
|
||||||
|
|
||||||
|
<%@include file="theming.jsp"%>
|
|
@ -1,24 +1,18 @@
|
||||||
<!--Anfang Skriptbereich-->
|
<!--Anfang Skriptbereich-->
|
||||||
|
|
||||||
<!--Script für Diagramme-->
|
<!--Script für Diagramme-->
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js" integrity="sha256-xKeoJ50pzbUGkpQxDYHD7o7hxe0LaOGeguUidbq6vis=" crossorigin="anonymous"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"
|
||||||
|
integrity="sha256-xKeoJ50pzbUGkpQxDYHD7o7hxe0LaOGeguUidbq6vis=" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
|
|
||||||
<!--Script für Materlialize-->
|
|
||||||
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
|
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
|
||||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
|
<%@include file="theming.jsp"%>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/google-palette@1.1.0/palette.min.js"></script>
|
|
||||||
<script>
|
|
||||||
M.AutoInit();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script src="js/cache.js"></script>
|
<script src="js/cache.js"></script>
|
||||||
<script src="js/week_overview.js"></script>
|
<script src="js/week_overview.js"></script>
|
||||||
<script src="js/shopping_times.js"></script>
|
<script src="js/shopping_times.js"></script>
|
||||||
<script src="js/top_flop.js"></script>
|
<script src="js/top_flop.js"></script>
|
||||||
|
<script src="js/clusters.js"></script>
|
||||||
<%--<script src="js/sold_articles.js"></script>--%>
|
<script src="js/shopping_cart.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<!--Ende Skriptbereich-->
|
<!--Ende Skriptbereich-->
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
<% response.setCharacterEncoding(StandardCharsets.UTF_8.name()); %>
|
||||||
|
<% request.setCharacterEncoding(StandardCharsets.UTF_8.name()); %>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<title>BauDas</title>
|
||||||
|
<!--Import Google Icon Font-->
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
|
<!--Import materialize.css-->
|
||||||
|
<link type="text/css" rel="stylesheet"
|
||||||
|
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"
|
||||||
|
media="screen,projection"/>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.css"
|
||||||
|
integrity="sha256-aa0xaJgmK/X74WM224KMQeNQC2xYKwlAt08oZqjeF0E=" crossorigin="anonymous"/>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=utf-8">
|
||||||
|
|
||||||
|
<!--Let browser know website is optimized for mobile-->
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
|
||||||
|
</head>
|
|
@ -1,12 +1,12 @@
|
||||||
<%@ page import="java.nio.charset.StandardCharsets" %>
|
<%@ page import="java.nio.charset.StandardCharsets" %>
|
||||||
<%@ page contentType="text/html;charset=UTF-8" %>
|
<%@ page contentType="text/html;charset=UTF-8" %>
|
||||||
<%@include file="header.jsp"%>
|
<%@include file="menu.jsp" %>
|
||||||
<% response.setCharacterEncoding(StandardCharsets.UTF_8.name()); %>
|
<% response.setCharacterEncoding(StandardCharsets.UTF_8.name()); %>
|
||||||
<% request.setCharacterEncoding(StandardCharsets.UTF_8.name()); %>
|
<% request.setCharacterEncoding(StandardCharsets.UTF_8.name()); %>
|
||||||
|
|
||||||
<!--Cards-->
|
<!--Cards-->
|
||||||
<!--Analyse-Cards-->
|
<!--Analyse-Cards-->
|
||||||
<div id="analysis" class="row container">
|
<div id="analysis" class="row container black-text">
|
||||||
<!--Übersicht-->
|
<!--Übersicht-->
|
||||||
<div class="col s12 m12">
|
<div class="col s12 m12">
|
||||||
<div id="overview" class="card white">
|
<div id="overview" class="card white">
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div>
|
<div>
|
||||||
<canvas id="overview_chart" width="1000" height="400"></canvas>
|
<canvas class="black-text" id="overview_chart" width="1000" height="400"></canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -63,86 +63,134 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Warenkorbanlyse-->
|
|
||||||
<div id="shopping_card_analysis" class="col s12 m6">
|
|
||||||
<div class="card white">
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="center">
|
|
||||||
<span class="card-title center">Warenkorbanalyse</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>Coming Soon</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--Gruppenübersicht-->
|
<!--Gruppenübersicht-->
|
||||||
<div class="col s12 m6">
|
<div class="col s12 m12">
|
||||||
<div id="group_overview" class="card white">
|
<div id="group_overview" class="card white">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<span class="card-title center">Gruppenübersicht</span>
|
<span class="card-title center">Gruppenübersicht</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p>Coming Soon</p>
|
<table id="cluster_table">
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--Marketing-Cards-->
|
<!--Warenkorbanlyse-->
|
||||||
<div id="marketing" class="row container">
|
<div id="shopping_card_analysis" class="col s12 m12">
|
||||||
|
<div class="card white">
|
||||||
|
<div class="center">
|
||||||
|
<span class="card-title center">Warenkorbanalyse</span>
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<table id="shopping_cart_table">
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="col s12 m6">
|
<!--Marketing-Cards-->
|
||||||
<div id="marketing_tip_1" class="card white">
|
<div id="marketing" class="row container">
|
||||||
<div class="card-content">
|
<div class="row">
|
||||||
<div class="center">
|
<div class="col s12 m6">
|
||||||
<span class="card-title center">Marketingmaßnahme 1</span>
|
<div id="marketing_tip_3" class="card white">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="center">
|
||||||
|
<span class="card-title center">Werbung</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
Werbung dient dazu, auf bestimmte Produkte, Angebote oder den Markt im
|
||||||
|
Allgemeinen aufmerksam zu machen. Sie kann über verschiedene Wege verbreitet
|
||||||
|
werden, etwa das Internet, Zeitungsannoncen oder auch per TV/Radio.
|
||||||
|
Im Gegensatz zu Rabatten (die zeitabhängig am besten funktionieren) ist Werbung
|
||||||
|
stark von der Zielgruppe abhängig. Insbesondere in der Kombination mit anderen
|
||||||
|
Marketingmaßnahmen kann sie so ihre volle Wirkung entfalten.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
Analysen, die für Werbung nützlich sein könnten:
|
||||||
|
Clusteranalyse, Wochenübersicht, Verkaufszahlen
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col s12 m6">
|
||||||
|
<div id="marketing_tip_4" class="card white">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="center">
|
||||||
|
<span class="card-title center">Sortimentsveränderung</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
Gibt es eine Produktgruppe, die sich besonders gut verkauft, so sollte unter
|
||||||
|
Umständen über die Erweiterung des Sortiments innerhalb dieser Gruppe
|
||||||
|
nachgedacht werden.
|
||||||
|
Im Umkehrschluss dazu bietet sich an, schlecht verkaufte Produkte, welche keinen
|
||||||
|
hohen Gewinn abwerfen aus dem täglichen Verkaufsgeschäft wieder zu entfernen.
|
||||||
|
Dies verringert die Bildung von „Ladenhütern“ und schafft Platz für neue, sich
|
||||||
|
besser verkaufende Produkte.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
Analysen, die bei der Sortimentswahl nützlich sein könnten:
|
||||||
|
Verkaufszahlen, Clusterübersicht
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="row">
|
||||||
<p>Coming Soon</p>
|
<div class="col s12 m6">
|
||||||
|
<div id="marketing_tip_1" class="card white">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="center">
|
||||||
|
<span class="card-title center">Rabatt</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
Rabatte können z.B. an Tagen angeboten werden, an denen nur wenige Kunden
|
||||||
|
erscheinen. Dadurch wird einerseits an dieses Tagen oder Uhrzeiten das
|
||||||
|
Kaufverhalten angeregt, als auch der Andrang an anderen reduziert. Dies dient
|
||||||
|
insbesondere der Entzerrung des zeitabhängigen Kaufverhaltens.
|
||||||
|
Des Weiteren können durch Rabatte weniger gut laufende Produkte in den
|
||||||
|
Vordergrund gerückt du vergünstigt angeboten werden.
|
||||||
|
Zusätzlich dazu können sich gut verkaufende Produkte mit einem (vermeintlich)
|
||||||
|
verringerten Preis versehen werden. Dies kann beim Kunden den „inneren
|
||||||
|
Schnäppchenjäger“ wecken und dafür sorgen, dass er sich dieses gute Angebot
|
||||||
|
nicht entgehen lassen kann.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
Analysen, die zur Platzierung von Rabatten nützlich sein können:
|
||||||
|
Wochenübersicht, Einkaufszeiten, Verkaufszahlen
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col s12 m6">
|
||||||
|
<div id="marketing_tip_2" class="card white">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="center">
|
||||||
|
<span class="card-title center">Produktplatzierung </span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
Es gibt bestimmte Produkte, die werden häufig zusammen erworben. Sind diese
|
||||||
|
Produkte quer durch den Laden verstreut, so müssen die Kunden zusätzlich zu
|
||||||
|
ihren Wunschprodukten auch an anderen Auslagen vorbei und die Anzahl an
|
||||||
|
Spontankäufen eben jener weiteren Produkte steigt.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
Analysen, die bei der Produktplatzierung hilfreich sein könnten:
|
||||||
|
Warenkorbsanalyse, Verkaufszahlen
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col s12 m6">
|
|
||||||
<div id="marketing_tip_2" class="card white">
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="center">
|
|
||||||
<span class="card-title center">Marketingmaßnahme 2</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>Coming Soon</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col s12 m6">
|
|
||||||
<div id="marketing_tip_3" class="card white">
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="center">
|
|
||||||
<span class="card-title center">Marketingmaßnahme 3</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>Coming Soon</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col s12 m6">
|
|
||||||
<div id="marketing_tip_4" class="card white">
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="center">
|
|
||||||
<span class="card-title center">Marketingmaßnahme 4</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>Coming Soon</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<%@include file="footer.jsp"%>
|
|
||||||
|
<%@include file="footer.jsp" %>
|
|
@ -1,3 +1,5 @@
|
||||||
|
Chart.defaults.global.defaultFontColor = "black";
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
let dataset = $('#dataset');
|
let dataset = $('#dataset');
|
||||||
request('files').then(results => {
|
request('files').then(results => {
|
||||||
|
@ -33,11 +35,12 @@ function updateCache() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function updateAll(uuid) {
|
function updateAll(uuid) {
|
||||||
updateWeekOverviewChart(uuid);
|
updateWeekOverviewChart(uuid);
|
||||||
updateShoppingTimesChart(uuid);
|
updateShoppingTimesChart(uuid);
|
||||||
updateTopFlopChart(uuid);
|
updateTopFlopChart(uuid);
|
||||||
|
updateClusters(uuid)
|
||||||
|
updateShoppingCartTable(uuid);
|
||||||
//add new charts here.
|
//add new charts here.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
let cluster_result;
|
||||||
|
|
||||||
|
function updateClusters(id) {
|
||||||
|
if(typeof id !== 'undefined') {
|
||||||
|
request('clusters', id).then(function (data) {
|
||||||
|
cluster_result = data;
|
||||||
|
drawClusterTable();
|
||||||
|
});
|
||||||
|
}else request('clusters').then(function(data) {
|
||||||
|
cluster_result = data;
|
||||||
|
drawClusterTable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawClusterTable(){
|
||||||
|
let table = document.getElementById("cluster_table");
|
||||||
|
while(table.hasChildNodes()){
|
||||||
|
table.removeChild(table.firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
let row = $("<thead>");
|
||||||
|
row.append("<tr>");
|
||||||
|
row.append("<td></td>");
|
||||||
|
for (x in cluster_result){
|
||||||
|
if(x == 0){
|
||||||
|
row.append("<td>" + "ø" + "</td>");
|
||||||
|
}else{
|
||||||
|
row.append("<td>" + x + "</td>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
row.append("</tr>");
|
||||||
|
row.append("</thead>");
|
||||||
|
|
||||||
|
|
||||||
|
appendClusterTable(row, "Alter");
|
||||||
|
appendClusterTable(row, "Wohnort");
|
||||||
|
appendClusterTable(row, "Einkaufstag");
|
||||||
|
appendClusterTable(row, "Geschlecht");
|
||||||
|
appendClusterTable(row, "Familienstand");
|
||||||
|
appendClusterTable(row, "Einkaufsuhrzeit");
|
||||||
|
|
||||||
|
|
||||||
|
row.append("</tbody>");
|
||||||
|
$("#cluster_table").append(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendClusterTable(row, attrib){
|
||||||
|
row.append("</tbody>");
|
||||||
|
row.append("<tr>");
|
||||||
|
row.append("<td>" + attrib + "</td>");
|
||||||
|
for (x in cluster_result){
|
||||||
|
row.append($("<td>" + cluster_result[x][attrib] +"</td>"));
|
||||||
|
}
|
||||||
|
row.append("</tr>");
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
let shopping_cart_result;
|
||||||
|
|
||||||
|
function updateShoppingCartTable(id) {
|
||||||
|
if(typeof id !== 'undefined') {
|
||||||
|
request('shopping_cart', id).then(function (data) {
|
||||||
|
shopping_cart_result = data;
|
||||||
|
drawShoppingCartTable();
|
||||||
|
});
|
||||||
|
}else request('shopping_cart_result').then(function(data) {
|
||||||
|
shopping_cart_result = data;
|
||||||
|
drawShoppingCartTable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawShoppingCartTable(){
|
||||||
|
let table = document.getElementById("shopping_cart_table");
|
||||||
|
while(table.hasChildNodes()){
|
||||||
|
table.removeChild(table.firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
let row = $("<thead>");
|
||||||
|
row.append("<tr>");
|
||||||
|
row.append("<th>Artikel</th>");
|
||||||
|
row.append("<th>Wird häufig zusammen gekauft mit</th>")
|
||||||
|
row.append("</tr>");
|
||||||
|
row.append("</thead>");
|
||||||
|
row.append("<tbody>");
|
||||||
|
for (x in shopping_cart_result){
|
||||||
|
row.append("<tr>");
|
||||||
|
row.append("<td>" + shopping_cart_result[x].col1 + "</td>");
|
||||||
|
row.append("<td>" + shopping_cart_result[x].col2 + "</td>");
|
||||||
|
row.append("</tr>");
|
||||||
|
}
|
||||||
|
row.append("</tbody>");
|
||||||
|
$("#shopping_cart_table").append(row);
|
||||||
|
}
|
||||||
|
|
|
@ -5,13 +5,15 @@ let week_overview = new Chart($("#overview_chart"), {
|
||||||
data: {
|
data: {
|
||||||
labels: [0, 0, 0, 0, 0],
|
labels: [0, 0, 0, 0, 0],
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: "Warenanzahl",
|
label: "Kundenanzahl",
|
||||||
|
yAxisID: 'y-axis-1',
|
||||||
data: [0, 0, 0, 0, 0],
|
data: [0, 0, 0, 0, 0],
|
||||||
fill: true,
|
fill: true,
|
||||||
backgroundColor: 'rgba(104, 216, 154, 0.5)',
|
backgroundColor: 'rgba(104, 216, 154, 0.5)',
|
||||||
lineTension: 0
|
lineTension: 0
|
||||||
}, {
|
}, {
|
||||||
label: "Einnahmen in €",
|
label: "Einnahmen in €",
|
||||||
|
yAxisID: 'y-axis-2',
|
||||||
data: [0, 0, 0, 0, 0],
|
data: [0, 0, 0, 0, 0],
|
||||||
fill: true,
|
fill: true,
|
||||||
backgroundColor: 'rgba(113, 114, 231, 1)',
|
backgroundColor: 'rgba(113, 114, 231, 1)',
|
||||||
|
@ -47,9 +49,25 @@ let week_overview = new Chart($("#overview_chart"), {
|
||||||
display: false
|
display: false
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
yAxes: [{
|
yAxes: [
|
||||||
display: true
|
{
|
||||||
}]
|
display: true,
|
||||||
|
position: 'right',
|
||||||
|
id: 'y-axis-1',
|
||||||
|
scaleLabel: {
|
||||||
|
display: true,
|
||||||
|
labelString: 'Kundenanzahl'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
display: true,
|
||||||
|
id: 'y-axis-2',
|
||||||
|
scaleLabel: {
|
||||||
|
display: true,
|
||||||
|
labelString: 'Einnahmen in €'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,26 +1,6 @@
|
||||||
<% response.setCharacterEncoding(StandardCharsets.UTF_8.name()); %>
|
|
||||||
<% request.setCharacterEncoding(StandardCharsets.UTF_8.name()); %>
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="de">
|
|
||||||
<head>
|
|
||||||
<title>BauDas</title>
|
|
||||||
<!--Import Google Icon Font-->
|
|
||||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
|
||||||
<!--Import materialize.css-->
|
|
||||||
<link type="text/css" rel="stylesheet"
|
|
||||||
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"
|
|
||||||
media="screen,projection"/>
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.css"
|
|
||||||
integrity="sha256-aa0xaJgmK/X74WM224KMQeNQC2xYKwlAt08oZqjeF0E=" crossorigin="anonymous"/>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=utf-8">
|
|
||||||
|
|
||||||
<!--Let browser know website is optimized for mobile-->
|
<%@include file="head.jsp"%>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
||||||
|
|
||||||
|
|
||||||
</head>
|
|
||||||
<body class="blue-grey lighten-5">
|
|
||||||
<!--Navbar-->
|
<!--Navbar-->
|
||||||
<div class="navbar-fixed">
|
<div class="navbar-fixed">
|
||||||
<nav class="nav-extended blue-grey darken-3 white-text row">
|
<nav class="nav-extended blue-grey darken-3 white-text row">
|
||||||
|
@ -38,12 +18,12 @@
|
||||||
<ul class="right hide-on-med-and-down">
|
<ul class="right hide-on-med-and-down">
|
||||||
<li><a data-target="slide-out" class="sidenav-trigger show-on-large"><i
|
<li><a data-target="slide-out" class="sidenav-trigger show-on-large"><i
|
||||||
class="material-icons left">menu</i>Menü</a></li><!--Sidenav-->
|
class="material-icons left">menu</i>Menü</a></li><!--Sidenav-->
|
||||||
<li><a href="login.html"><i class="material-icons left">person_outline</i>Logout</a></li><!--Logout-->
|
<li><a href="logout"><i class="material-icons left">person_outline</i>Logout</a></li><!--Logout-->
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="right">
|
<ul class="right">
|
||||||
<li><a href="#" data-target="slide-out" class="sidenav-trigger"><i class="material-icons">menu</i></a>
|
<li><a href="#" data-target="slide-out" class="sidenav-trigger"><i class="material-icons">menu</i></a>
|
||||||
</li><!--Sidenav-->
|
</li><!--Sidenav-->
|
||||||
<li><a href="login.html" class="sidenav-trigger"><i class="material-icons">person_outline</i></a></li>
|
<li><a href="logout" class="sidenav-trigger"><i class="material-icons">person_outline</i></a></li>
|
||||||
<!--Logout-->
|
<!--Logout-->
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/google-palette@1.1.0/palette.min.js"></script>
|
||||||
|
<script>
|
||||||
|
M.AutoInit();
|
||||||
|
</script>
|
|
@ -30,8 +30,7 @@ class WeekOverviewTest {
|
||||||
|
|
||||||
AtomicReference<Map<String, Map.Entry<Double, Integer>>> result = new AtomicReference<>();
|
AtomicReference<Map<String, Map.Entry<Double, Integer>>> result = new AtomicReference<>();
|
||||||
|
|
||||||
assertTimeout(Duration.ofMillis(5), () -> result.set(overview.getResult()));
|
assertTimeout(Duration.ofMillis(15), () -> result.set(overview.getResult()));
|
||||||
|
|
||||||
|
|
||||||
assertEquals(2477, result.get().get("Montag").getKey());
|
assertEquals(2477, result.get().get("Montag").getKey());
|
||||||
assertEquals(3359, result.get().get("Dienstag").getKey());
|
assertEquals(3359, result.get().get("Dienstag").getKey());
|
||||||
|
@ -40,12 +39,12 @@ class WeekOverviewTest {
|
||||||
assertEquals(2399, result.get().get("Freitag").getKey());
|
assertEquals(2399, result.get().get("Freitag").getKey());
|
||||||
assertEquals(18273, result.get().get("Samstag").getKey());
|
assertEquals(18273, result.get().get("Samstag").getKey());
|
||||||
|
|
||||||
assertEquals(3216, result.get().get("Montag").getValue());
|
assertEquals(8, result.get().get("Montag").getValue());
|
||||||
assertEquals(5503, result.get().get("Dienstag").getValue());
|
assertEquals(13, result.get().get("Dienstag").getValue());
|
||||||
assertEquals(1888, result.get().get("Mittwoch").getValue());
|
assertEquals(5, result.get().get("Mittwoch").getValue());
|
||||||
assertEquals(3568, result.get().get("Donnerstag").getValue());
|
assertEquals(9, result.get().get("Donnerstag").getValue());
|
||||||
assertEquals(2953, result.get().get("Freitag").getValue());
|
assertEquals(10, result.get().get("Freitag").getValue());
|
||||||
assertEquals(26243, result.get().get("Samstag").getValue());
|
assertEquals(55, result.get().get("Samstag").getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -57,8 +56,7 @@ class WeekOverviewTest {
|
||||||
|
|
||||||
AtomicReference<Map<String, Map.Entry<Double, Integer>>> result = new AtomicReference<>();
|
AtomicReference<Map<String, Map.Entry<Double, Integer>>> result = new AtomicReference<>();
|
||||||
|
|
||||||
assertTimeout(Duration.ofMillis(7), () -> result.set(overview.getResult()));
|
assertTimeout(Duration.ofMillis(15), () -> result.set(overview.getResult()));
|
||||||
|
|
||||||
|
|
||||||
assertEquals(26273, result.get().get("Montag").getKey());
|
assertEquals(26273, result.get().get("Montag").getKey());
|
||||||
assertEquals(23345, result.get().get("Dienstag").getKey());
|
assertEquals(23345, result.get().get("Dienstag").getKey());
|
||||||
|
@ -67,12 +65,12 @@ class WeekOverviewTest {
|
||||||
assertEquals(26413, result.get().get("Freitag").getKey());
|
assertEquals(26413, result.get().get("Freitag").getKey());
|
||||||
assertEquals(146279, result.get().get("Samstag").getKey());
|
assertEquals(146279, result.get().get("Samstag").getKey());
|
||||||
|
|
||||||
assertEquals(39839, result.get().get("Montag").getValue());
|
assertEquals(108, result.get().get("Montag").getValue());
|
||||||
assertEquals(34992, result.get().get("Dienstag").getValue());
|
assertEquals(93, result.get().get("Dienstag").getValue());
|
||||||
assertEquals(37299, result.get().get("Mittwoch").getValue());
|
assertEquals(89, result.get().get("Mittwoch").getValue());
|
||||||
assertEquals(35005, result.get().get("Donnerstag").getValue());
|
assertEquals(90, result.get().get("Donnerstag").getValue());
|
||||||
assertEquals(38911, result.get().get("Freitag").getValue());
|
assertEquals(110, result.get().get("Freitag").getValue());
|
||||||
assertEquals(214051, result.get().get("Samstag").getValue());
|
assertEquals(510, result.get().get("Samstag").getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -84,8 +82,7 @@ class WeekOverviewTest {
|
||||||
|
|
||||||
AtomicReference<Map<String, Map.Entry<Double, Integer>>> result = new AtomicReference<>();
|
AtomicReference<Map<String, Map.Entry<Double, Integer>>> result = new AtomicReference<>();
|
||||||
|
|
||||||
assertTimeout(Duration.ofMillis(60), () -> result.set(overview.getResult()));
|
assertTimeout(Duration.ofMillis(50), () -> result.set(overview.getResult()));
|
||||||
|
|
||||||
|
|
||||||
assertEquals(295688, result.get().get("Montag").getKey());
|
assertEquals(295688, result.get().get("Montag").getKey());
|
||||||
assertEquals(267269, result.get().get("Dienstag").getKey());
|
assertEquals(267269, result.get().get("Dienstag").getKey());
|
||||||
|
@ -94,11 +91,11 @@ class WeekOverviewTest {
|
||||||
assertEquals(330907, result.get().get("Freitag").getKey());
|
assertEquals(330907, result.get().get("Freitag").getKey());
|
||||||
assertEquals(1410789, result.get().get("Samstag").getKey());
|
assertEquals(1410789, result.get().get("Samstag").getKey());
|
||||||
|
|
||||||
assertEquals(426952, result.get().get("Montag").getValue());
|
assertEquals(1058, result.get().get("Montag").getValue());
|
||||||
assertEquals(379125, result.get().get("Dienstag").getValue());
|
assertEquals(942, result.get().get("Dienstag").getValue());
|
||||||
assertEquals(373891, result.get().get("Mittwoch").getValue());
|
assertEquals(915, result.get().get("Mittwoch").getValue());
|
||||||
assertEquals(356996, result.get().get("Donnerstag").getValue());
|
assertEquals(919, result.get().get("Donnerstag").getValue());
|
||||||
assertEquals(480062, result.get().get("Freitag").getValue());
|
assertEquals(1177, result.get().get("Freitag").getValue());
|
||||||
assertEquals(2015766, result.get().get("Samstag").getValue());
|
assertEquals(4989, result.get().get("Samstag").getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue