basic overtime calculation corrections; needs slots
This commit is contained in:
15
build.gradle
15
build.gradle
@ -7,7 +7,7 @@ plugins {
|
||||
apply plugin: 'io.spring.dependency-management'
|
||||
|
||||
group = 'de.jottyfan'
|
||||
version = '1.4.2'
|
||||
version = '1.4.3'
|
||||
|
||||
description = """timetrack"""
|
||||
|
||||
@ -23,9 +23,11 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.apache.logging.log4j:log4j-api:2.20.0'
|
||||
implementation 'org.apache.logging.log4j:log4j-core:2.20.0'
|
||||
implementation 'org.apache.logging.log4j:log4j-to-slf4j:2.20.0'
|
||||
implementation 'de.jottyfan:timetrackjooq:20240103d'
|
||||
|
||||
implementation 'org.apache.logging.log4j:log4j-api:latest.release'
|
||||
implementation 'org.apache.logging.log4j:log4j-core:latest.release'
|
||||
implementation 'org.apache.logging.log4j:log4j-to-slf4j:latest.release'
|
||||
|
||||
implementation 'org.webjars:bootstrap:5.3.1'
|
||||
implementation 'org.webjars:font-awesome:6.4.2'
|
||||
@ -35,7 +37,7 @@ dependencies {
|
||||
implementation 'org.webjars:jquery-ui:1.13.2'
|
||||
implementation 'org.webjars:fullcalendar:5.11.3'
|
||||
|
||||
implementation 'com.google.code.gson:gson:2.10.1';
|
||||
implementation 'com.google.code.gson:gson:latest.release';
|
||||
|
||||
implementation 'org.webjars.bowergithub.datatables:datatables:1.10.21'
|
||||
|
||||
@ -48,9 +50,8 @@ dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
implementation 'org.springframework.boot:spring-boot-devtools'
|
||||
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
|
||||
implementation 'de.jottyfan:timetrackjooq:0.1.3'
|
||||
|
||||
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:3.2.1'
|
||||
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:latest.release'
|
||||
|
||||
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
||||
runtimeOnly 'org.postgresql:postgresql'
|
||||
|
@ -8,13 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.SessionAttributes;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import de.jottyfan.timetrack.component.OAuth2Provider;
|
||||
import de.jottyfan.timetrack.modules.CommonController;
|
||||
import de.jottyfan.timetrack.modules.done.model.DoneModel;
|
||||
@ -46,17 +40,18 @@ public class DoneController extends CommonController {
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@RequestMapping(value = "/done/list")
|
||||
@GetMapping("/done/list")
|
||||
public String getList(Model model, @ModelAttribute("doneModel") DoneModel doneModel) {
|
||||
String username = provider.getName();
|
||||
Duration maxWorkTime = Duration.ofHours(8); // TODO: to the configuration file
|
||||
LocalDate day = doneModel.getDay();
|
||||
List<DoneBean> list = doneService.getList(day, username);
|
||||
List<DoneBean> week = doneService.getWeek(day, username);
|
||||
SummaryBean bean = new SummaryBean(list, day, maxWorkTime);
|
||||
SummaryBean sumBean = new SummaryBean(list, day, maxWorkTime);
|
||||
SummaryBean weekBean = new SummaryBean(week, day, maxWorkTime);
|
||||
model.addAttribute("doneList", list);
|
||||
model.addAttribute("sum", bean);
|
||||
model.addAttribute("sum", sumBean);
|
||||
model.addAttribute("daysum", doneService.getDaysum(day, username));
|
||||
model.addAttribute("schedule", weekBean.toJson());
|
||||
model.addAttribute("recentList", doneService.getListRecent(username, 10));
|
||||
model.addAttribute("projectList", doneService.getProjects(false));
|
||||
@ -75,7 +70,7 @@ public class DoneController extends CommonController {
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@RequestMapping(value = "/done/add/{day}", method = RequestMethod.GET)
|
||||
@GetMapping("/done/add/{day}")
|
||||
public String toAdd(@PathVariable @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate day, Model model) {
|
||||
DoneBean bean = new DoneBean();
|
||||
bean.setLocalDate(day);
|
||||
@ -122,7 +117,7 @@ public class DoneController extends CommonController {
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@RequestMapping(value = "/done/upsert", method = RequestMethod.POST)
|
||||
@PostMapping("/done/upsert")
|
||||
public String doUpsert(Model model, @ModelAttribute DoneBean bean) {
|
||||
String username = provider.getName();
|
||||
Integer amount = doneService.doUpsert(bean, username);
|
||||
@ -130,7 +125,7 @@ public class DoneController extends CommonController {
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@RequestMapping(value = "/done/addrecent/{id}", method = RequestMethod.GET)
|
||||
@GetMapping("/done/addrecent/{id}")
|
||||
public String addRecent(Model model, @PathVariable Integer id) {
|
||||
String username = provider.getName();
|
||||
DoneBean bean = doneService.getBean(id);
|
||||
@ -139,7 +134,7 @@ public class DoneController extends CommonController {
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@RequestMapping(value = "/done/list/previousday", method = RequestMethod.GET)
|
||||
@GetMapping("/done/list/previousday")
|
||||
public String previousDay(Model model, @ModelAttribute("doneModel") DoneModel doneModel) {
|
||||
LocalDate day = doneModel.getDay();
|
||||
doneModel.setDay(day.minusDays(1));
|
||||
@ -147,7 +142,7 @@ public class DoneController extends CommonController {
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@RequestMapping(value = "/done/list/nextday", method = RequestMethod.GET)
|
||||
@GetMapping("/done/list/nextday")
|
||||
public String nextDay(Model model, @ModelAttribute("doneModel") DoneModel doneModel) {
|
||||
LocalDate day = doneModel.getDay();
|
||||
doneModel.setDay(day.plusDays(1));
|
||||
|
@ -0,0 +1,72 @@
|
||||
package de.jottyfan.timetrack.modules.done;
|
||||
|
||||
import static de.jottyfan.timetrack.db.done.Tables.V_CURRENT_OVERTIME;
|
||||
import static de.jottyfan.timetrack.db.done.Tables.V_DAY;
|
||||
import static de.jottyfan.timetrack.db.profile.Tables.T_LOGIN;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Record6;
|
||||
import org.jooq.SelectConditionStep;
|
||||
import org.jooq.impl.DSL;
|
||||
import org.jooq.types.YearToSecond;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import de.jottyfan.timetrack.modules.done.model.DaysumBean;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jotty
|
||||
*
|
||||
*/
|
||||
@Repository
|
||||
public class DoneRepository {
|
||||
private static final Logger LOGGER = LogManager.getLogger(DoneRepository.class);
|
||||
|
||||
@Autowired
|
||||
private DSLContext jooq;
|
||||
|
||||
public DaysumBean getDaysum(LocalDate day, String login) {
|
||||
Field<LocalTime> WORKTIME = DSL.field("worktime", LocalTime.class);
|
||||
Field<LocalTime> BREAKTIME = DSL.field("breaktime", LocalTime.class);
|
||||
|
||||
SelectConditionStep<Record6<LocalTime, LocalTime, LocalTime, LocalTime, YearToSecond, LocalTime>> sql = jooq
|
||||
// @formatter:off
|
||||
.select(V_DAY.STARTTIME,
|
||||
V_DAY.ENDTIME,
|
||||
V_DAY.WORKTIME.cast(LocalTime.class).as(WORKTIME),
|
||||
V_DAY.BREAKTIME.cast(LocalTime.class).as(BREAKTIME),
|
||||
V_DAY.DAY_OVERTIME,
|
||||
V_CURRENT_OVERTIME.OVERTIME.plus(DSL.coalesce(V_DAY.DAY_OVERTIME, YearToSecond.valueOf(0))).as(V_CURRENT_OVERTIME.OVERTIME))
|
||||
.from(V_DAY)
|
||||
.innerJoin(T_LOGIN).on(T_LOGIN.PK.eq(V_DAY.FK_LOGIN))
|
||||
.leftJoin(V_CURRENT_OVERTIME).on(V_CURRENT_OVERTIME.FK_LOGIN.eq(V_DAY.FK_LOGIN))
|
||||
.where(V_DAY.DAY.eq(day))
|
||||
.and(T_LOGIN.LOGIN.eq(login));
|
||||
// @formatter:on
|
||||
LOGGER.trace(sql);
|
||||
Record6<LocalTime, LocalTime, LocalTime, LocalTime, YearToSecond, LocalTime> r = sql.fetchOne();
|
||||
if (r == null) {
|
||||
return null;
|
||||
} else {
|
||||
DaysumBean bean = new DaysumBean();
|
||||
bean.setDaytimeFrom(r.get(V_DAY.STARTTIME));
|
||||
bean.setDaytimeUntil(r.get(V_DAY.ENDTIME));
|
||||
bean.setDayworktime(r.get(WORKTIME));
|
||||
bean.setBreaks(r.get(BREAKTIME));
|
||||
YearToSecond dayOvertime = r.get(V_DAY.DAY_OVERTIME);
|
||||
Duration dayOvertimeDuration = dayOvertime == null ? null : dayOvertime.toDuration();
|
||||
String dayOvertimeString = dayOvertimeDuration == null ? null : String.format("%3d:%2d", dayOvertimeDuration.toHours(), Math.abs(dayOvertimeDuration.toMinutes() % 60));
|
||||
bean.setDayOvertime(dayOvertimeString == null ? "?" : dayOvertimeString);
|
||||
bean.setTotalOvertime(r.get(V_CURRENT_OVERTIME.OVERTIME));
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ 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;
|
||||
import de.jottyfan.timetrack.db.done.tables.records.VProjectRecord;
|
||||
import de.jottyfan.timetrack.modules.done.model.DaysumBean;
|
||||
import de.jottyfan.timetrack.modules.done.model.FavoriteBean;
|
||||
import de.jottyfan.timetrack.modules.note.NoteService;
|
||||
|
||||
@ -35,6 +36,9 @@ public class DoneService {
|
||||
|
||||
@Autowired
|
||||
private TimeService timeService;
|
||||
|
||||
@Autowired
|
||||
private DoneRepository repository;
|
||||
|
||||
@Autowired
|
||||
private DSLContext dsl;
|
||||
@ -226,4 +230,8 @@ public class DoneService {
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
public DaysumBean getDaysum(LocalDate day, String login) {
|
||||
return repository.getDaysum(day, login);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,105 @@
|
||||
package de.jottyfan.timetrack.modules.done.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalTime;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jotty
|
||||
*
|
||||
*/
|
||||
public class DaysumBean implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private LocalTime daytimeFrom;
|
||||
private LocalTime daytimeUntil;
|
||||
private LocalTime dayworktime;
|
||||
private LocalTime breaks;
|
||||
private String dayOvertime;
|
||||
private LocalTime totalOvertime;
|
||||
|
||||
/**
|
||||
* @return the daytimeFrom
|
||||
*/
|
||||
public LocalTime getDaytimeFrom() {
|
||||
return daytimeFrom;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param daytimeFrom the daytimeFrom to set
|
||||
*/
|
||||
public void setDaytimeFrom(LocalTime daytimeFrom) {
|
||||
this.daytimeFrom = daytimeFrom;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the daytimeUntil
|
||||
*/
|
||||
public LocalTime getDaytimeUntil() {
|
||||
return daytimeUntil;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param daytimeUntil the daytimeUntil to set
|
||||
*/
|
||||
public void setDaytimeUntil(LocalTime daytimeUntil) {
|
||||
this.daytimeUntil = daytimeUntil;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the dayworktime
|
||||
*/
|
||||
public LocalTime getDayworktime() {
|
||||
return dayworktime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dayworktime the dayworktime to set
|
||||
*/
|
||||
public void setDayworktime(LocalTime dayworktime) {
|
||||
this.dayworktime = dayworktime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the breaks
|
||||
*/
|
||||
public LocalTime getBreaks() {
|
||||
return breaks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param breaks the breaks to set
|
||||
*/
|
||||
public void setBreaks(LocalTime breaks) {
|
||||
this.breaks = breaks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the dayOvertime
|
||||
*/
|
||||
public String getDayOvertime() {
|
||||
return dayOvertime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dayOvertime the dayOvertime to set
|
||||
*/
|
||||
public void setDayOvertime(String dayOvertime) {
|
||||
this.dayOvertime = dayOvertime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the totalovertime
|
||||
*/
|
||||
public LocalTime getTotalOvertime() {
|
||||
return totalOvertime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param totalovertime the totalovertime to set
|
||||
*/
|
||||
public void setTotalOvertime(LocalTime totalOvertime) {
|
||||
this.totalOvertime = totalOvertime;
|
||||
}
|
||||
|
||||
}
|
@ -99,13 +99,13 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>Zusammenfassung</td>
|
||||
<td>Start: <span class="emphgreen" th:text="${sum.start}"></span></td>
|
||||
<td>Ende: <span class="emphgreen" th:text="${sum.end}"></span></td>
|
||||
<td>Arbeitszeit total: <span class="emphblue" th:text="${sum.total}"></span></td>
|
||||
<td>Pausezeit total: <span class="emphorange" th:text="${sum.pause}"></span></td>
|
||||
<td colspan="2">Überstunden: <span class="emphred" th:text="${sum.overdue}"></span></td>
|
||||
<tr th:if="${daysum}">
|
||||
<td>Start: <span class="emphgreen" th:text="${#temporals.format(daysum.daytimeFrom, 'HH:mm')}" th:if="${daysum.daytimeFrom}"></span></td>
|
||||
<td>Ende: <span class="emphgreen" th:text="${#temporals.format(daysum.daytimeUntil, 'HH:mm')}" th:if="${daysum.daytimeUntil}"></span></td>
|
||||
<td>Arbeitszeit total: <span class="emphblue" th:text="${#temporals.format(daysum.dayworktime, 'HH:mm')}" th:if="${daysum.dayworktime}"></span></td>
|
||||
<td>Pausezeit total: <span class="emphorange" th:text="${#temporals.format(daysum.breaks, 'HH:mm')}" th:if="${daysum.breaks}"></span></td>
|
||||
<td>Überstunden heute: <span class="emphred" th:text="${daysum.dayOvertime}"></span></td>
|
||||
<td colspan="2">Überstunden total: <span class="emphred" th:text="${#temporals.format(daysum.totalOvertime, 'HH:mm')}" th:if="${daysum.totalOvertime}"></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
|
Reference in New Issue
Block a user