Merge branch 'SPM-22'

This commit is contained in:
Johannes Theiner 2019-05-23 15:35:28 +02:00
commit f8c1eb9362
16 changed files with 195 additions and 296 deletions

28
README.md Normal file
View 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
View File

@ -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>

View File

@ -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));
}
}

View File

@ -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
]
}

View File

@ -1,18 +0,0 @@
{
"labels": [
"8-9",
"9-10",
"10-11",
"11-12",
"12-13",
"13-14"
],
"data1": [
12,
19,
3,
5,
2,
3
]
}

View File

@ -1,12 +0,0 @@
{
"labels": [
"Gruppe 1",
"Gruppe 2",
"Gruppe 3"
],
"data1": [
2055,
816,
953
]
}

View File

@ -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
]
}

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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.
}
/**

View File

@ -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
}
}]
}
}
});
});

View File

@ -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'
}
}
});
});

View File

@ -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
}
}]
}
}
});
});

View 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();
}

View File

@ -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());