diff --git a/.classpath b/.classpath
index 6d924d7..bfdccfd 100644
--- a/.classpath
+++ b/.classpath
@@ -6,6 +6,13 @@
+
+
+
+
+
+
+
diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component
index 0d9c0d3..9542a85 100644
--- a/.settings/org.eclipse.wst.common.component
+++ b/.settings/org.eclipse.wst.common.component
@@ -1,37 +1,48 @@
-
+
+
-
+
+
-
+
+
-
+
+
-
+
+
-
+
+
-
+
+
-
+
+
-
+
+
+
-
+
+
diff --git a/build.gradle b/build.gradle
index c7399a4..6aeb5ce 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ plugins {
}
group = 'de.jottyfan'
-version = '1.2.3'
+version = '1.2.4'
sourceCompatibility = '11'
ext['spring-framework.version'] = '5.3.18'
@@ -51,6 +51,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
+ implementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
implementation 'de.jottyfan:timetrackjooq:0.1.1'
diff --git a/src/main/java/de/jottyfan/timetrack/help/LocalDateHelper.java b/src/main/java/de/jottyfan/timetrack/help/LocalDateHelper.java
new file mode 100644
index 0000000..028e428
--- /dev/null
+++ b/src/main/java/de/jottyfan/timetrack/help/LocalDateHelper.java
@@ -0,0 +1,28 @@
+package de.jottyfan.timetrack.help;
+
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+
+/**
+ *
+ * @author henkej
+ *
+ */
+public class LocalDateHelper {
+
+ /**
+ * find the day of the week in relation to day
+ *
+ * @param day the day to start the search from
+ * @param dayOfWeek the day of the week that is wanted
+ * @param backwards if true, search before day, if false, search after day
+ * @return the found date
+ */
+ public static final LocalDate seekDay(LocalDate day, DayOfWeek dayOfWeek, boolean backwards) {
+ LocalDate found = day;
+ while (!found.getDayOfWeek().equals(dayOfWeek)) {
+ found = backwards ? found.minusDays(1) : found.plusDays(1);
+ }
+ return found;
+ }
+}
diff --git a/src/main/java/de/jottyfan/timetrack/spring/done/DoneBean.java b/src/main/java/de/jottyfan/timetrack/spring/done/DoneBean.java
index 51d40cd..09cbae4 100644
--- a/src/main/java/de/jottyfan/timetrack/spring/done/DoneBean.java
+++ b/src/main/java/de/jottyfan/timetrack/spring/done/DoneBean.java
@@ -76,7 +76,8 @@ public class DoneBean implements Serializable, Comparable {
public final String toJson() {
StringBuilder buf = new StringBuilder("{");
- buf.append("\"from\": ").append(nullable(timeFrom, "HH:mm"));
+ buf.append("\"daySlot\": ").append(day == null ? "null" : day.getDayOfWeek().getValue());
+ buf.append(", \"from\": ").append(nullable(timeFrom, "HH:mm"));
buf.append(", \"until\": ").append(nullable(timeUntil, "HH:mm"));
buf.append(", \"billing\": ").append(nullable(billing, null));
buf.append("}");
diff --git a/src/main/java/de/jottyfan/timetrack/spring/done/DoneController.java b/src/main/java/de/jottyfan/timetrack/spring/done/DoneController.java
index 61879ac..75e7584 100644
--- a/src/main/java/de/jottyfan/timetrack/spring/done/DoneController.java
+++ b/src/main/java/de/jottyfan/timetrack/spring/done/DoneController.java
@@ -45,11 +45,13 @@ public class DoneController {
Duration maxWorkTime = Duration.ofHours(8); // TODO: to the configuration file
LocalDate day = doneModel.getDay();
List list = doneService.getList(day, username);
+ List week = doneService.getWeek(day, username);
SummaryBean bean = new SummaryBean(list, day, maxWorkTime);
+ SummaryBean weekBean = new SummaryBean(week, day, maxWorkTime);
model.addAttribute("doneList", list);
model.addAttribute("doneModel", doneModel);
model.addAttribute("sum", bean);
- model.addAttribute("schedule", bean.toJson()); // TODO: add the other days of that week
+ model.addAttribute("schedule", weekBean.toJson());
model.addAttribute("projectList", doneService.getProjects(false));
model.addAttribute("moduleList", doneService.getModules(false));
model.addAttribute("jobList", doneService.getJobs(false));
diff --git a/src/main/java/de/jottyfan/timetrack/spring/done/IDoneService.java b/src/main/java/de/jottyfan/timetrack/spring/done/IDoneService.java
index ea62db0..86c39f6 100644
--- a/src/main/java/de/jottyfan/timetrack/spring/done/IDoneService.java
+++ b/src/main/java/de/jottyfan/timetrack/spring/done/IDoneService.java
@@ -5,7 +5,6 @@ import java.util.List;
import javax.servlet.http.HttpServletRequest;
-import de.jottyfan.timetrack.db.done.tables.records.TProjectRecord;
import de.jottyfan.timetrack.db.done.tables.records.VBillingRecord;
import de.jottyfan.timetrack.db.done.tables.records.VJobRecord;
import de.jottyfan.timetrack.db.done.tables.records.VModuleRecord;
@@ -18,20 +17,13 @@ import de.jottyfan.timetrack.db.done.tables.records.VProjectRecord;
*/
public interface IDoneService {
public List getList(LocalDate day, String username);
-
+ public List getWeek(LocalDate day, String username);
public DoneBean getBean(Integer id);
-
public String getCurrentUser(HttpServletRequest request);
-
public List getProjects(boolean includeNull);
-
public List getModules(boolean includeNull);
-
public List getJobs(boolean includeNull);
-
public List getBillings(boolean includeNull);
-
public Integer doUpsert(DoneBean bean, String username);
-
public Integer doDelete(Integer id);
}
diff --git a/src/main/java/de/jottyfan/timetrack/spring/done/SummaryBean.java b/src/main/java/de/jottyfan/timetrack/spring/done/SummaryBean.java
index f7e8fda..0ab1011 100644
--- a/src/main/java/de/jottyfan/timetrack/spring/done/SummaryBean.java
+++ b/src/main/java/de/jottyfan/timetrack/spring/done/SummaryBean.java
@@ -4,7 +4,6 @@ import java.io.Serializable;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
import java.util.List;
/**
@@ -19,17 +18,23 @@ public class SummaryBean implements Serializable {
private final LocalDate day;
private final List list;
+ /**
+ * @param list the list of beans
+ * @param day the day that this selection refers to; might be the day
+ * of the week for weekly sets
+ * @param maxDayWorktime the maximum work time of a day
+ */
public SummaryBean(List list, LocalDate day, Duration maxDayWorktime) {
this.list = list;
this.day = day;
this.maxDayWorktime = maxDayWorktime;
}
-
+
public String toJson() {
StringBuilder buf = new StringBuilder("{");
- buf.append("\"maxDayWorktime\": \"").append(String.format("%02d:%02d", maxDayWorktime.toHoursPart(), maxDayWorktime.toMinutesPart()));
- buf.append("\", \"daySlot\": ").append(day == null ? "null" : day.getDayOfWeek().getValue());
- buf.append(", \"schedule\": [");
+ buf.append("\"maxDayWorktime\": \"")
+ .append(String.format("%02d:%02d", maxDayWorktime.toHoursPart(), maxDayWorktime.toMinutesPart()));
+ buf.append("\", \"schedule\": [");
boolean first = true;
for (DoneBean bean : list) {
if (!first) {
@@ -67,7 +72,7 @@ public class SummaryBean implements Serializable {
int minutesPercent = Float.valueOf((5f / 3f) * minutes).intValue();
return String.format("%d,%d h", duration.toHoursPart(), minutesPercent);
}
-
+
/**
* @return the start
*/
diff --git a/src/main/java/de/jottyfan/timetrack/spring/done/impl/DoneGateway.java b/src/main/java/de/jottyfan/timetrack/spring/done/impl/DoneGateway.java
index f491989..ae3f1d8 100644
--- a/src/main/java/de/jottyfan/timetrack/spring/done/impl/DoneGateway.java
+++ b/src/main/java/de/jottyfan/timetrack/spring/done/impl/DoneGateway.java
@@ -8,6 +8,7 @@ import static de.jottyfan.timetrack.db.done.Tables.V_PROJECT;
import static de.jottyfan.timetrack.db.profile.Tables.T_LOGIN;
import java.sql.SQLException;
+import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
@@ -34,6 +35,7 @@ import de.jottyfan.timetrack.db.done.tables.records.VJobRecord;
import de.jottyfan.timetrack.db.done.tables.records.VModuleRecord;
import de.jottyfan.timetrack.db.done.tables.records.VProjectRecord;
import de.jottyfan.timetrack.db.profile.tables.records.TLoginRecord;
+import de.jottyfan.timetrack.help.LocalDateHelper;
import de.jottyfan.timetrack.spring.done.DoneBean;
/**
@@ -216,19 +218,19 @@ public class DoneGateway {
}
/**
- * get list of entries of day
+ * get list of entries of interval
*
- * @param day the day
+ * @param start the lower limit
+ * @param end the upper limit
+ * @param userId the id of the user
*
* @return a list (an empty one at least)
* @throws SQLException
* @throws ClassNotFoundException
* @throws DataAccessException
*/
- public List getAllOfDay(LocalDate day, Integer userId)
+ private List getAllOfInterval(LocalDateTime start, LocalDateTime end, Integer userId)
throws DataAccessException, ClassNotFoundException, SQLException {
- LocalDateTime dayStart = day.atStartOfDay();
- LocalDateTime dayEnd = day.atTime(23, 59, 59);
SelectConditionStep> sql = getJooq()
// @formatter:off
.select(T_DONE.PK,
@@ -239,8 +241,8 @@ public class DoneGateway {
T_DONE.FK_JOB,
T_DONE.FK_BILLING)
.from(T_DONE)
- .where(T_DONE.TIME_FROM.between(dayStart, dayEnd).or(T_DONE.TIME_FROM.isNull()))
- .and(T_DONE.TIME_UNTIL.between(dayStart, dayEnd).or(T_DONE.TIME_UNTIL.isNull()))
+ .where(T_DONE.TIME_FROM.between(start, end).or(T_DONE.TIME_FROM.isNull()))
+ .and(T_DONE.TIME_UNTIL.between(start, end).or(T_DONE.TIME_UNTIL.isNull()))
.and(T_DONE.FK_LOGIN.eq(userId == null ? -999999 : userId));
// @formatter:on
LOGGER.debug("{}", sql.toString());
@@ -265,6 +267,40 @@ public class DoneGateway {
return list;
}
+ /**
+ * get list of entries of day
+ *
+ * @param day the day
+ *
+ * @return a list (an empty one at least)
+ * @throws SQLException
+ * @throws ClassNotFoundException
+ * @throws DataAccessException
+ */
+ public List getAllOfDay(LocalDate day, Integer userId)
+ throws DataAccessException, ClassNotFoundException, SQLException {
+ LocalDateTime dayStart = day.atStartOfDay();
+ LocalDateTime dayEnd = day.atTime(23, 59, 59);
+ return getAllOfInterval(dayStart, dayEnd, userId);
+ }
+
+ /**
+ * get all entries of the week where day belongs to
+ *
+ * @param day the day that the week refers to
+ * @param userId the id of the user
+ * @return a list of done beans; an empty one at least
+ * @throws SQLException
+ * @throws ClassNotFoundException
+ * @throws DataAccessException
+ */
+ public List getAllOfWeek(LocalDate day, Integer userId)
+ throws DataAccessException, ClassNotFoundException, SQLException {
+ LocalDate sunday = LocalDateHelper.seekDay(day, DayOfWeek.SUNDAY, true);
+ LocalDate saturday = LocalDateHelper.seekDay(day, DayOfWeek.SATURDAY, false);
+ return getAllOfInterval(sunday.atStartOfDay(), saturday.atTime(23, 59, 59), userId);
+ }
+
/**
* delete an entry from the database
*
diff --git a/src/main/java/de/jottyfan/timetrack/spring/done/impl/DoneService.java b/src/main/java/de/jottyfan/timetrack/spring/done/impl/DoneService.java
index 07ae0b8..f4c5cb9 100644
--- a/src/main/java/de/jottyfan/timetrack/spring/done/impl/DoneService.java
+++ b/src/main/java/de/jottyfan/timetrack/spring/done/impl/DoneService.java
@@ -57,6 +57,22 @@ public class DoneService implements IDoneService {
}
}
+ @Override
+ public List getWeek(LocalDate day, String username) {
+ try {
+ DoneGateway gw = new DoneGateway(dsl);
+ Integer userId = gw.getUserId(username);
+ if (userId == null) {
+ LOGGER.warn("userId of user {} is null", username);
+ }
+ return gw.getAllOfWeek(day, userId);
+ } catch (Exception e) {
+ LOGGER.error(e);
+ return new ArrayList<>();
+ }
+ }
+
+
@Override
public DoneBean getBean(Integer id) {
try {
diff --git a/src/main/resources/static/js/schedule.js b/src/main/resources/static/js/schedule.js
index 4aad292..6c1ebdf 100644
--- a/src/main/resources/static/js/schedule.js
+++ b/src/main/resources/static/js/schedule.js
@@ -17,16 +17,32 @@ class Schedule {
drawBackgroundDay = function(ctx, width, height, offsetx) {
var hourHeight = parseInt(height / 24);
+ var fs = ["#eeeeee", "#bbbbbb", "#eeeeee", "#bbbbbb", "#eeeeee", "#bbbbbb",
+ "#faf0fa", "#d9cbd9", "#faf0fa", "#9acbd9", "#cdf0fa", "#9acbd9",
+ "#cdf0fa", "#9acbd9", "#cdf0fa", "#d9cbd9", "#faf0fa", "#d9cbd9",
+ "#faf0fa", "#d9cbd9", "#eeeeee", "#bbbbbb", "#eeeeee", "#bbbbbb"];
for (var i = 0; i < 24; i++) {
var x = parseInt(offsetx);
var y = parseInt(i * hourHeight);
var w = parseInt(width);
var h = parseInt(hourHeight);
- ctx.fillStyle = (i > 8 & i <= 17) ? (i % 2 ? "#cdf0fa" : "#9acbd9") : (i % 2 ? "#faf0fa" : "#d9cbd9");
+ ctx.fillStyle = fs[i];
ctx.fillRect(x, y, w, h);
}
+ ctx.lineWidth = 1;
ctx.strokeStyle = "white";
ctx.strokeRect(offsetx, 0, width, height);
+ ctx.strokeStyle = "black";
+ ctx.lineWidth = 2;
+ ctx.moveTo(parseInt(offsetx), parseInt(hourHeight * 6));
+ ctx.lineTo(parseInt(offsetx + width), parseInt(hourHeight * 6));
+ ctx.stroke();
+ ctx.moveTo(parseInt(offsetx), parseInt(hourHeight * 12));
+ ctx.lineTo(parseInt(offsetx + width), parseInt(hourHeight * 12));
+ ctx.stroke();
+ ctx.moveTo(parseInt(offsetx), parseInt(hourHeight * 18));
+ ctx.lineTo(parseInt(offsetx + width), parseInt(hourHeight * 18));
+ ctx.stroke();
}
drawBackgroundWeek = function(ctx, width, height) {
diff --git a/src/main/resources/templates/done/list.html b/src/main/resources/templates/done/list.html
index 02a16c2..1e9284f 100644
--- a/src/main/resources/templates/done/list.html
+++ b/src/main/resources/templates/done/list.html
@@ -191,7 +191,6 @@
var ctx = $("#scheduleCanvas")[0].getContext("2d");
var currentDayRecords = JSON.parse('[(${schedule})]');
var scheduleRecords = currentDayRecords.schedule;
- var daySlot = currentDayRecords.daySlot;
for (var i = 0; i < scheduleRecords.length; i++) {
var r = scheduleRecords[i];
var cssClass = r.billing;
@@ -206,7 +205,7 @@
color = "#00aa00";
}
/* daySlot 7 = sunday, but this should be slot 0 */
- schedule.drawSlot(ctx, daySlot > 6 ? 0 : daySlot, r.from, r.until, "black", color);
+ schedule.drawSlot(ctx, r.daySlot > 6 ? 0 : r.daySlot, r.from, r.until, "black", color);
}
var localeUrl = '[[@{/js/dataTables/de.json}]]';
$("#project_table").DataTable({
diff --git a/src/test/java/de/jottyfan/timetrack/help/TestLocalDateHelper.java b/src/test/java/de/jottyfan/timetrack/help/TestLocalDateHelper.java
new file mode 100644
index 0000000..2e25e27
--- /dev/null
+++ b/src/test/java/de/jottyfan/timetrack/help/TestLocalDateHelper.java
@@ -0,0 +1,26 @@
+package de.jottyfan.timetrack.help;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ *
+ * @author henkej
+ *
+ */
+public class TestLocalDateHelper {
+ @Test
+ public void testFindWeekDays() {
+ assertEquals(20, LocalDateHelper.seekDay(LocalDate.of(2022, 2, 23), DayOfWeek.SUNDAY, true).getDayOfMonth());
+ assertEquals(26, LocalDateHelper.seekDay(LocalDate.of(2022, 2, 23), DayOfWeek.SATURDAY, false).getDayOfMonth());
+ assertEquals(13, LocalDateHelper.seekDay(LocalDate.of(2022, 2, 19), DayOfWeek.SUNDAY, true).getDayOfMonth());
+ assertEquals(19, LocalDateHelper.seekDay(LocalDate.of(2022, 2, 19), DayOfWeek.SATURDAY, false).getDayOfMonth());
+ assertEquals("26.12.2021", LocalDateHelper.seekDay(LocalDate.of(2022, 1, 1), DayOfWeek.SUNDAY, true).format(DateTimeFormatter.ofPattern("dd.MM.yyyy")));
+ assertEquals("02.01.2022", LocalDateHelper.seekDay(LocalDate.of(2021, 12, 31), DayOfWeek.SUNDAY, false).format(DateTimeFormatter.ofPattern("dd.MM.yyyy")));
+ }
+}