From 5117fd0e71258fb29828148f3c1810b4f1d3cc68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Henke?= Date: Fri, 5 Jan 2024 14:58:40 +0100 Subject: [PATCH] preparation for slot dimediff reason --- .../modules/done/DoneController.java | 14 +++++ .../modules/done/DoneRepository.java | 61 +++++++++++++++++- .../timetrack/modules/done/DoneService.java | 18 ++++++ .../modules/done/model/SlotBean.java | 21 ++++++- src/main/resources/static/css/style.css | 8 +++ src/main/resources/templates/done/list.html | 23 ++++++- .../resources/templates/done/slot/item.html | 62 +++++++++++++++---- 7 files changed, 191 insertions(+), 16 deletions(-) diff --git a/src/main/java/de/jottyfan/timetrack/modules/done/DoneController.java b/src/main/java/de/jottyfan/timetrack/modules/done/DoneController.java index 3394b8f..5fbf027 100644 --- a/src/main/java/de/jottyfan/timetrack/modules/done/DoneController.java +++ b/src/main/java/de/jottyfan/timetrack/modules/done/DoneController.java @@ -212,4 +212,18 @@ public class DoneController extends CommonController { model.addAttribute("bean", SlotBean.of(day)); return "/done/slot/item"; } + + @RolesAllowed("timetrack_user") + @PostMapping("/done/slot/upsert") + public String upsertSlot(@ModelAttribute("bean") SlotBean bean, Model model) { + doneService.upsert(bean, provider.getName()); + return "redirect:/done/list"; + } + + @RolesAllowed("timetrack_user") + @GetMapping("/done/slot/{id}/delete") + public String deleteSlot(@PathVariable("id") Integer slotId) { + doneService.delete(slotId, provider.getName()); + return "redirect:/done/list"; + } } diff --git a/src/main/java/de/jottyfan/timetrack/modules/done/DoneRepository.java b/src/main/java/de/jottyfan/timetrack/modules/done/DoneRepository.java index c33253a..5947bd2 100644 --- a/src/main/java/de/jottyfan/timetrack/modules/done/DoneRepository.java +++ b/src/main/java/de/jottyfan/timetrack/modules/done/DoneRepository.java @@ -17,7 +17,9 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jooq.DSLContext; import org.jooq.DatePart; +import org.jooq.DeleteConditionStep; import org.jooq.Field; +import org.jooq.InsertOnDuplicateSetMoreStep; import org.jooq.InsertOnDuplicateStep; import org.jooq.Record1; import org.jooq.Record3; @@ -32,6 +34,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import de.jottyfan.timetrack.db.done.tables.records.TOvertimeRecord; +import de.jottyfan.timetrack.db.done.tables.records.TRequiredWorktimeRecord; import de.jottyfan.timetrack.modules.done.model.DaysumBean; import de.jottyfan.timetrack.modules.done.model.OvertimeBean; import de.jottyfan.timetrack.modules.done.model.SlotBean; @@ -161,6 +164,7 @@ public class DoneRepository { // @formatter:off .select(T_REQUIRED_WORKTIME.PK_REQUIRED_WORKTIME, T_REQUIRED_WORKTIME.DAY, +// T_REQUIRED_WORKTIME.REASON, T_REQUIRED_WORKTIME.REQUIRED_MINUTES) .from(T_REQUIRED_WORKTIME) .innerJoin(T_LOGIN).on(T_LOGIN.PK.eq(T_REQUIRED_WORKTIME.FK_LOGIN)) @@ -177,7 +181,8 @@ public class DoneRepository { LocalDate day = n.get(T_REQUIRED_WORKTIME.DAY); Integer pk = n.get(T_REQUIRED_WORKTIME.PK_REQUIRED_WORKTIME); Integer minutes = n.get(T_REQUIRED_WORKTIME.REQUIRED_MINUTES); - map.put(day, SlotBean.of(pk, day, minutes)); + String reason = null; // n.get(T_REQUIRED_WORKTIME.REASON); + map.put(day, SlotBean.of(pk, day, minutes, reason)); } return map; } @@ -194,6 +199,7 @@ public class DoneRepository { // @formatter:off .select(T_REQUIRED_WORKTIME.PK_REQUIRED_WORKTIME, T_REQUIRED_WORKTIME.DAY, +// T_REQUIRED_WORKTIME.REASON, T_REQUIRED_WORKTIME.REQUIRED_MINUTES) .from(T_REQUIRED_WORKTIME) .innerJoin(T_LOGIN).on(T_LOGIN.PK.eq(T_REQUIRED_WORKTIME.FK_LOGIN)) @@ -204,6 +210,57 @@ public class DoneRepository { Record3 r = sql.fetchOne(); return r == null ? null : SlotBean.of(r.get(T_REQUIRED_WORKTIME.PK_REQUIRED_WORKTIME), r.get(T_REQUIRED_WORKTIME.DAY), - r.get(T_REQUIRED_WORKTIME.REQUIRED_MINUTES)); + r.get(T_REQUIRED_WORKTIME.REQUIRED_MINUTES), null/*r.get(T_REQUIRED_WORKTIME.REASON)*/); + } + + public void addSlot(SlotBean bean, String login) { + InsertOnDuplicateSetMoreStep sql = jooq + // @formatter:off + .insertInto(T_REQUIRED_WORKTIME, + T_REQUIRED_WORKTIME.DAY, + T_REQUIRED_WORKTIME.REQUIRED_MINUTES, +// T_REQUIRED_WORKTIME.REASON, + T_REQUIRED_WORKTIME.FK_LOGIN) + .select(jooq + .select(DSL.val(bean.getDay()), DSL.val(bean.getMinutes()), /* DSL.val(bean.getReason()), */ T_LOGIN.PK) + .from(T_LOGIN) + .where(T_LOGIN.LOGIN.eq(login))) + .onConflict(T_REQUIRED_WORKTIME.FK_LOGIN, T_REQUIRED_WORKTIME.DAY) + .doUpdate() + .set(T_REQUIRED_WORKTIME.REQUIRED_MINUTES, bean.getMinutes()); +// .set(T_REQUIRED_WORKTIME.REASON, bean.getReason()); + // @formatter:off + LOGGER.trace(sql); + sql.execute(); + } + + public void updateSlot(SlotBean bean, String login) { + UpdateConditionStep sql = jooq + // @formatter:off + .update(T_REQUIRED_WORKTIME) + .set(T_REQUIRED_WORKTIME.REQUIRED_MINUTES, bean.getMinutes()) +// .set(T_REQUIRED_WORKTIME.REASON, bean.getReason()) + .where(T_REQUIRED_WORKTIME.PK_REQUIRED_WORKTIME.eq(bean.getId())) + .and(T_REQUIRED_WORKTIME.FK_LOGIN.in(jooq + .select(T_LOGIN.PK) + .from(T_LOGIN) + .where(T_LOGIN.LOGIN.eq(login)))); + // @formatter:on + LOGGER.trace(sql); + sql.execute(); + } + + public void deleteSlot(Integer id, String login) { + DeleteConditionStep sql = jooq + // @formatter:off + .deleteFrom(T_REQUIRED_WORKTIME) + .where(T_REQUIRED_WORKTIME.PK_REQUIRED_WORKTIME.eq(id)) + .and(T_REQUIRED_WORKTIME.FK_LOGIN.in(jooq + .select(T_LOGIN.PK) + .from(T_LOGIN) + .where(T_LOGIN.LOGIN.eq(login)))); + // @formatter:on + LOGGER.trace(sql); + sql.execute(); } } diff --git a/src/main/java/de/jottyfan/timetrack/modules/done/DoneService.java b/src/main/java/de/jottyfan/timetrack/modules/done/DoneService.java index 48590ab..8b53bbe 100644 --- a/src/main/java/de/jottyfan/timetrack/modules/done/DoneService.java +++ b/src/main/java/de/jottyfan/timetrack/modules/done/DoneService.java @@ -287,4 +287,22 @@ public class DoneService { } return list; } + + /** + * upsert the bean + * + * @param bean the bean + * @param username the username + */ + public void upsert(SlotBean bean, String username) { + if (bean.getId() == null) { + repository.addSlot(bean, username); + } else { + repository.updateSlot(bean, username); + } + } + + public void delete(Integer slotId, String username) { + repository.deleteSlot(slotId, username); + } } diff --git a/src/main/java/de/jottyfan/timetrack/modules/done/model/SlotBean.java b/src/main/java/de/jottyfan/timetrack/modules/done/model/SlotBean.java index b2fc0ad..67aa3c5 100644 --- a/src/main/java/de/jottyfan/timetrack/modules/done/model/SlotBean.java +++ b/src/main/java/de/jottyfan/timetrack/modules/done/model/SlotBean.java @@ -3,6 +3,8 @@ package de.jottyfan.timetrack.modules.done.model; import java.io.Serializable; import java.time.LocalDate; +import org.springframework.format.annotation.DateTimeFormat; + /** * * @author jotty @@ -12,14 +14,17 @@ public class SlotBean implements Serializable { private static final long serialVersionUID = 1L; private Integer id; + @DateTimeFormat(pattern="yyyy-MM-dd") private LocalDate day; private Integer minutes; + private String reason; - public static final SlotBean of(Integer id, LocalDate day, Integer minutes) { + public static final SlotBean of(Integer id, LocalDate day, Integer minutes, String reason) { SlotBean bean = new SlotBean(); bean.setId(id); bean.setDay(day); bean.setMinutes(minutes); + bean.setReason(reason); return bean; } @@ -80,4 +85,18 @@ public class SlotBean implements Serializable { public void setId(Integer id) { this.id = id; } + + /** + * @return the reason + */ + public String getReason() { + return reason; + } + + /** + * @param reason the reason to set + */ + public void setReason(String reason) { + this.reason = reason; + } } diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css index ad4bec8..312ffc6 100644 --- a/src/main/resources/static/css/style.css +++ b/src/main/resources/static/css/style.css @@ -449,6 +449,14 @@ body { color: white; } +.slot_reason { + color: #26a269; +} + +[data-bs-theme=dark] .slot_reason { + color: lime; +} + .flex-row-weekday { display: flex; flex-flow: row wrap; diff --git a/src/main/resources/templates/done/list.html b/src/main/resources/templates/done/list.html index 039e91a..e04ed5a 100644 --- a/src/main/resources/templates/done/list.html +++ b/src/main/resources/templates/done/list.html @@ -265,8 +265,27 @@ - -  --:--  +  --:--  + + +
+
+ Legende +
+
+ Üb: Überstunden, Mehrarbeit
+ Ur: Urlaub, Sonderurlaub, Kur
+ gF: gesetzlicher Feiertag
+
+
+ Kr: Arbeits- und Dienstunfähigkeit
+ Gl: Freistellung aus Gleitzeitguthaben
+ Ar: Arbeits- und Dienstbefreiung
+
+
+ mK: "mit Kind krank"
+ Di: Dienstreise, Dienstgänge
diff --git a/src/main/resources/templates/done/slot/item.html b/src/main/resources/templates/done/slot/item.html index 5bc164e..3fab68a 100644 --- a/src/main/resources/templates/done/slot/item.html +++ b/src/main/resources/templates/done/slot/item.html @@ -1,6 +1,5 @@ - + Slot aktualisieren @@ -12,16 +11,57 @@
-
-
ID
-
-
Tag
-
-
vereinbarte Arbeitszeit
-
+
+ +
+
Tag
+
+ +
+
vereinbarte Arbeitszeit in Minuten
+
+ +
+
Abweichungsgrund
+
+ +
+
+
+ +
+
+
+
+
+ + - TODO: Löschen
- TODO: Ersetzen durch Dienstbefreiung, Urlaub, Ausgleichstag/Überstunden, Krankheit oder sonstwas