Merge branch 'SPM-22'
This commit is contained in:
commit
f8c1eb9362
28
README.md
Normal file
28
README.md
Normal file
@ -0,0 +1,28 @@
|
||||
![BauDas Logo](https://services.joethei.xyz/images/bauDas.png)
|
||||
#Kundenkarten Verwaltung
|
||||
|
||||
[![Build Status](https://teamcity.joethei.xyz/app/rest/builds/buildType:(id:Studium_Programmierung_Softwareprojektmanagement_SpmProd)/statusIcon)](https://tcstatus.joethei.space/dashboard/spm)
|
||||
[![Quality Gate](https://sonarqube.joethei.xyz/api/project_badges/measure?project=Studium_Programmierung_Softwareprojektmanagement&metric=alert_status)
|
||||
![Code Coverage](https://sonarqube.joethei.xyz/api/project_badges/measure?project=Studium_Programmierung_Softwareprojektmanagement&metric=coverage)](https://sonarqube.joethei.xyz/dashboard?id=Studium_Programmierung_Softwareprojektmanagement)
|
||||
|
||||
## Requirements
|
||||
|
||||
- Java 8
|
||||
- Maven 3
|
||||
- Tomcat 9
|
||||
|
||||
## Development Setup
|
||||
|
||||
- clone this repository
|
||||
- import it into your preferred editor
|
||||
- start the server with maven goal ````tomcat7:run````
|
||||
- change stuff
|
||||
- restart the server if needed
|
||||
|
||||
|
||||
## TODO: better Name for this
|
||||
- clone this repository
|
||||
- run maven goal ````package````
|
||||
- war can be found in target folder
|
||||
|
||||
© 2019 Ihni GmbH
|
30
pom.xml
30
pom.xml
@ -16,8 +16,10 @@
|
||||
<java.version>1.8</java.version>
|
||||
<checkstyle_file>checkstyle.xml</checkstyle_file>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<jacoco.dataFile>${project.build.directory}/jacoco.exec</jacoco.dataFile>
|
||||
</properties>
|
||||
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<name>Johannes Theiner</name>
|
||||
@ -213,6 +215,34 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.8.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-prepare-agent</id>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>default-report</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>default-check</id>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -0,0 +1,58 @@
|
||||
package de.hsel.spm.baudas.web;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import de.hsel.spm.baudas.analysis.TopFlopArticle;
|
||||
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.*;
|
||||
|
||||
/**
|
||||
* @author Johannes Theiner
|
||||
* @version 0.1
|
||||
* @since 0.1
|
||||
**/
|
||||
|
||||
@WebServlet("/top_flop")
|
||||
public class TopFlopArticleDiagram extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 6567531464214L;
|
||||
|
||||
@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();
|
||||
|
||||
Gson gson = new Gson();
|
||||
|
||||
UUID uuid = UUID.fromString(req.getParameter("id"));
|
||||
File file = Data.get(uuid);
|
||||
|
||||
TopFlopArticle articles = new TopFlopArticle(file);
|
||||
Map<String, Integer> map = articles.getResult();
|
||||
|
||||
Map<String, List<String>> result = new HashMap<>();
|
||||
|
||||
List<String> labels = new ArrayList<>();
|
||||
List<String> data = new ArrayList<>();
|
||||
|
||||
for(Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
labels.add(entry.getKey());
|
||||
data.add(entry.getValue().toString());
|
||||
}
|
||||
|
||||
result.put("labels", labels);
|
||||
result.put("data", data);
|
||||
|
||||
out.print(gson.toJson(result));
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
{
|
||||
"labels": [
|
||||
"Insgesamt",
|
||||
"Gruppe 1",
|
||||
"Gruppe 2",
|
||||
"Gruppe 3"
|
||||
],
|
||||
"data1": [
|
||||
50,
|
||||
10,
|
||||
20,
|
||||
30
|
||||
],
|
||||
"data2": [
|
||||
30,
|
||||
5,
|
||||
20,
|
||||
5
|
||||
],
|
||||
"data3": [
|
||||
80,
|
||||
20,
|
||||
30,
|
||||
30
|
||||
]
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"labels": [
|
||||
"8-9",
|
||||
"9-10",
|
||||
"10-11",
|
||||
"11-12",
|
||||
"12-13",
|
||||
"13-14"
|
||||
],
|
||||
"data1": [
|
||||
12,
|
||||
19,
|
||||
3,
|
||||
5,
|
||||
2,
|
||||
3
|
||||
]
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
{
|
||||
"labels": [
|
||||
"Gruppe 1",
|
||||
"Gruppe 2",
|
||||
"Gruppe 3"
|
||||
],
|
||||
"data1": [
|
||||
2055,
|
||||
816,
|
||||
953
|
||||
]
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
{
|
||||
"labels": [
|
||||
"Insgesamt",
|
||||
"Gruppe 1",
|
||||
"Gruppe 2",
|
||||
"Gruppe 3"
|
||||
],
|
||||
"label1": "Gartengeräte",
|
||||
"data1": [
|
||||
150,
|
||||
50,
|
||||
50,
|
||||
50
|
||||
],
|
||||
"label2": "Eisenwaren",
|
||||
"data2": [
|
||||
120,
|
||||
10,
|
||||
80,
|
||||
30
|
||||
],
|
||||
"label3": "Baumaterialien",
|
||||
"data3": [
|
||||
200,
|
||||
102,
|
||||
53,
|
||||
45
|
||||
]
|
||||
|
||||
}
|
@ -7,17 +7,18 @@
|
||||
<!--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://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>
|
||||
|
||||
<script src="js/cache.js"></script>
|
||||
|
||||
<script src="js/week_overview.js"></script>
|
||||
<script src="js/shopping_times.js"></script>
|
||||
<%--<script src="js/sold_articles.js"></script>
|
||||
<script src="js/top_articles.js"></script>
|
||||
<script src="js/flop_articles.js"></script>--%>
|
||||
<script src="js/top_flop.js"></script>
|
||||
|
||||
<%--<script src="js/sold_articles.js"></script>--%>
|
||||
|
||||
|
||||
<!--Ende Skriptbereich-->
|
||||
</body>
|
||||
|
@ -65,18 +65,6 @@
|
||||
<li>
|
||||
<div class="divider"></div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="input-field container">
|
||||
<label>Gruppenauswahl</label>
|
||||
<br>
|
||||
<select>
|
||||
<option value="0">alle</option>
|
||||
<option value="1">Gruppe 1</option>
|
||||
<option value="2">Gruppe 2</option>
|
||||
<option value="3">Gruppe 3</option>
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="input-field container">
|
||||
<label for="dataset">Datensatzauswahl</label>
|
||||
@ -106,7 +94,6 @@
|
||||
<div class="col s12 offset-s6">
|
||||
<button class="btn blue-grey waves-effect waves-light" type="submit" name="action">Hochladen<i class="material-icons right">file_upload</i></button>
|
||||
</div>
|
||||
</button>
|
||||
</li>
|
||||
</form>
|
||||
</ul>
|
@ -11,12 +11,9 @@
|
||||
<div class="col s12 m12">
|
||||
<div id="overview" class="card white">
|
||||
<div class="center">
|
||||
<span class="card-title center">Übersicht</span>
|
||||
</div>
|
||||
<div class="card-action center">
|
||||
<a href="#">Tagesübersicht</a>
|
||||
<a href="#">Wochenübersicht</a>
|
||||
<span class="card-title center">Wochenübersicht</span>
|
||||
</div>
|
||||
|
||||
<div class="card-content">
|
||||
<div>
|
||||
<canvas id="overview_chart" width="1000" height="400"></canvas>
|
||||
@ -52,60 +49,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Verkaufte Artikel-->
|
||||
<div class="col s12 m6">
|
||||
<div id="sold_articles" class="card white">
|
||||
<div class="card-content">
|
||||
<div class="center">
|
||||
<span class="card-title center">Verkaufte Artikel</span>
|
||||
</div>
|
||||
<div class="center">
|
||||
<div class="input-field col s12">
|
||||
<select>
|
||||
<option value="0">Artikel 1</option>
|
||||
<option value="1">Artikel 2</option>
|
||||
<option value="2">Artikel 3</option>
|
||||
</select>
|
||||
<label>Artikel</label>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<canvas id="sold_articles_cake" width="1000" height="400"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Top Artikel-->
|
||||
<div class="col s12 m6">
|
||||
<!--Verkaufszahlen-->
|
||||
<div class="col s12 m12">
|
||||
<div id="top_articles" class="card white">
|
||||
<div class="center">
|
||||
<span class="card-title center">Top Artikel</span>
|
||||
</div>
|
||||
<div class="card-action center">
|
||||
<a href="#">Umsatz</a>
|
||||
<a href="#">Stückzahl</a>
|
||||
<span class="card-title center">Verkaufszahlen</span>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div>
|
||||
<canvas id="top_articles_chart" width="1000" height="400"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--Flop Artikel-->
|
||||
<div class="col s12 m6">
|
||||
<div id="flop_articles" class="card white">
|
||||
<div class="center">
|
||||
<span class="card-title center">Flop Artikel</span>
|
||||
</div>
|
||||
<div class="card-action center">
|
||||
<a href="#">Umsatz</a>
|
||||
<a href="#">Stückzahl</a>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div>
|
||||
<canvas id="flop_articles_chart" width="1000" height="400"></canvas>
|
||||
<canvas id="top_flop_chart" width="1000" height="400"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -20,20 +20,25 @@ function updateCache() {
|
||||
let dataset = $('#dataset');
|
||||
let selected = $('#dataset :selected');
|
||||
if (typeof selected !== 'undefined' && selected.index() !== -1) {
|
||||
updateWeekOverviewChart(selected.val());
|
||||
updateShoppingTimesChart(selected.val());
|
||||
updateAll(selected.val());
|
||||
} else {
|
||||
//requesting files, getting values from html does not work...
|
||||
//if no selection is provided, select newest file
|
||||
request('files').then(results => {
|
||||
let uuid = results[results.length - 1].uuid;
|
||||
dataset.val(uuid);
|
||||
updateWeekOverviewChart(uuid);
|
||||
updateShoppingTimesChart(uuid);
|
||||
updateAll(uuid);
|
||||
dataset.formSelect();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function updateAll(uuid) {
|
||||
updateWeekOverviewChart(uuid);
|
||||
updateShoppingTimesChart(uuid);
|
||||
updateTopFlopChart(uuid);
|
||||
//add new charts here.
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,47 +0,0 @@
|
||||
$.ajax({
|
||||
url: 'data/flop_articles.json',
|
||||
dataType: 'json'
|
||||
}).done(function (results) {
|
||||
new Chart(document.getElementById("flop_articles_chart"), {
|
||||
type: 'horizontalBar',
|
||||
data: {
|
||||
labels: results.labels,
|
||||
datasets: [{
|
||||
label: 'Holz',
|
||||
backgroundColor: 'rgba(244, 177, 131, 1)',
|
||||
stack: 'Stack 0',
|
||||
data: results.data1
|
||||
}, {
|
||||
label: 'Eisenwaren',
|
||||
backgroundColor: 'rgba(255, 217, 102, 1)',
|
||||
stack: 'Stack 1',
|
||||
data: results.data2
|
||||
}, {
|
||||
label: 'Baumaterialien',
|
||||
backgroundColor: 'rgba(196, 209, 142, 1)',
|
||||
stack: 'Stack 2',
|
||||
data: results.data3
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
title: {
|
||||
display: false,
|
||||
text: 'Flop Artikel'
|
||||
},
|
||||
legend: {
|
||||
position: 'bottom',
|
||||
},
|
||||
scales: {
|
||||
yAxes: [{
|
||||
gridLines: {
|
||||
display: false
|
||||
},
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
@ -1,38 +0,0 @@
|
||||
$.ajax({
|
||||
url: 'data/sold_articles.json',
|
||||
dataType: 'json'
|
||||
}).done(function (results) {
|
||||
new Chart(document.getElementById("sold_articles_cake"), {
|
||||
type: 'pie',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: results.data1,
|
||||
backgroundColor: [
|
||||
'rgba(237, 125, 49, 0.9)',
|
||||
'rgba(255, 192, 0, 0.9)',
|
||||
'rgba(112, 173, 71, 0.9)',
|
||||
],
|
||||
label: 'Dataset 1'
|
||||
}],
|
||||
labels: results.labels
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
title: {
|
||||
display: false,
|
||||
text: 'Verkaufte Artikel',
|
||||
},
|
||||
tooltips: {
|
||||
mode: 'index',
|
||||
intersect: false,
|
||||
},
|
||||
hover: {
|
||||
mode: 'nearest',
|
||||
intersect: true
|
||||
},
|
||||
legend: {
|
||||
position: 'bottom'
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
@ -1,47 +0,0 @@
|
||||
$.ajax({
|
||||
url: 'data/top_articles.json',
|
||||
dataType: 'json'
|
||||
}).done(function (results) {
|
||||
new Chart(document.getElementById("top_articles_chart"), {
|
||||
type: 'horizontalBar',
|
||||
data: {
|
||||
labels: results.labels,
|
||||
datasets: [{
|
||||
label: results.label1,
|
||||
backgroundColor: 'rgba(244, 177, 131, 1)',
|
||||
stack: 'Stack 0',
|
||||
data: results.data1
|
||||
}, {
|
||||
label: results.label2,
|
||||
backgroundColor: 'rgba(255, 217, 102, 1)',
|
||||
stack: 'Stack 1',
|
||||
data: results.data2
|
||||
}, {
|
||||
label: results.label3,
|
||||
backgroundColor: 'rgba(196, 209, 142, 1)',
|
||||
stack: 'Stack 2',
|
||||
data: results.data3
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
title: {
|
||||
display: false,
|
||||
text: 'Top Artikel'
|
||||
},
|
||||
legend: {
|
||||
position: 'bottom',
|
||||
},
|
||||
scales: {
|
||||
yAxes: [{
|
||||
gridLines: {
|
||||
display: false
|
||||
},
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
56
src/main/webapp/js/top_flop.js
Normal file
56
src/main/webapp/js/top_flop.js
Normal file
@ -0,0 +1,56 @@
|
||||
let top_flop_result;
|
||||
|
||||
|
||||
let top_flop = new Chart($("#top_flop_chart"), {
|
||||
type: 'horizontalBar',
|
||||
data: {
|
||||
labels: [],
|
||||
datasets: [{
|
||||
data: [],
|
||||
backgroundColor: [],
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
title: {
|
||||
display: false,
|
||||
text: 'Top Flop Artikel'
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
scales: {
|
||||
yAxes: [{
|
||||
gridLines: {
|
||||
display: false
|
||||
},
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function updateTopFlopChart(id) {
|
||||
if (typeof id !== 'undefined') {
|
||||
request('top_flop', id).then(function (data) {
|
||||
top_flop_result = data;
|
||||
updateTopFlop();
|
||||
});
|
||||
} else request('top_flop').then(function (data) {
|
||||
top_flop_result = data;
|
||||
updateTopFlop();
|
||||
});
|
||||
}
|
||||
|
||||
function updateTopFlop() {
|
||||
top_flop.data.labels = top_flop_result.labels;
|
||||
top_flop.data.datasets[0].data = top_flop_result.data;
|
||||
let seq = palette('mpn65', 15);
|
||||
for (let i = 0; i < 15; i++) {
|
||||
top_flop.data.datasets[0].backgroundColor[i] = "#" + seq[i];
|
||||
}
|
||||
top_flop.update();
|
||||
|
||||
}
|
@ -30,7 +30,7 @@ class WeekOverviewTest {
|
||||
|
||||
AtomicReference<Map<String, Map.Entry<Double, Integer>>> result = new AtomicReference<>();
|
||||
|
||||
assertTimeout(Duration.ofMillis(1), () -> result.set(overview.getResult()));
|
||||
assertTimeout(Duration.ofMillis(5), () -> result.set(overview.getResult()));
|
||||
|
||||
|
||||
assertEquals(2477, result.get().get("Montag").getKey());
|
||||
@ -57,7 +57,7 @@ class WeekOverviewTest {
|
||||
|
||||
AtomicReference<Map<String, Map.Entry<Double, Integer>>> result = new AtomicReference<>();
|
||||
|
||||
assertTimeout(Duration.ofMillis(3), () -> result.set(overview.getResult()));
|
||||
assertTimeout(Duration.ofMillis(7), () -> result.set(overview.getResult()));
|
||||
|
||||
|
||||
assertEquals(26273, result.get().get("Montag").getKey());
|
||||
@ -84,7 +84,7 @@ class WeekOverviewTest {
|
||||
|
||||
AtomicReference<Map<String, Map.Entry<Double, Integer>>> result = new AtomicReference<>();
|
||||
|
||||
assertTimeout(Duration.ofMillis(30), () -> result.set(overview.getResult()));
|
||||
assertTimeout(Duration.ofMillis(60), () -> result.set(overview.getResult()));
|
||||
|
||||
|
||||
assertEquals(295688, result.get().get("Montag").getKey());
|
||||
|
Loading…
Reference in New Issue
Block a user