Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/storetimeinminutes #53

Merged
merged 33 commits into from
Feb 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
25264f8
#40 dailyWorkingTime -> dailyWorkingTimeMinutes
KlausRicharz Feb 25, 2022
2f8de05
Fix date validation
KlausRicharz Feb 25, 2022
67bf327
#40 overtimeStatic -> overtimeStaticMinutes
KlausRicharz Feb 25, 2022
234d5bf
Fix handling of X-Forwarded headers send by reverse proxies
KlausRicharz Feb 25, 2022
e2ba311
#40 overtimeStatic -> overtimeStaticMinutes
KlausRicharz Feb 25, 2022
f980289
#40 suborder debithours -> debitMinutes
KlausRicharz Feb 25, 2022
75c8530
Revert unintended change
KlausRicharz Feb 26, 2022
2e4f436
#40 Overtime time -> timeMinutes
KlausRicharz Feb 26, 2022
3cda0dc
Fix JPA auditing
KlausRicharz Feb 26, 2022
5c269b2
Fix JPA auditing
KlausRicharz Feb 26, 2022
6bb9b92
#40 Employeeorder debithours -> debitMinutes
KlausRicharz Feb 26, 2022
2ca0244
#40 Remove costs column from Timereport in database migration script …
KlausRicharz Feb 26, 2022
de32d95
#40 Introduce Duration in employeecontract
KlausRicharz Feb 26, 2022
8871880
#40 Introduce DurationUtils and correct packages of unit tests
KlausRicharz Feb 26, 2022
e4260d9
Improve hibernate annotation processing
KlausRicharz Feb 26, 2022
9e4a625
Improve git properties generation
KlausRicharz Feb 26, 2022
4121fc0
#40 Use Duration for Overtime#timeMinutes
KlausRicharz Feb 26, 2022
8ec10f7
Fix lombok annotation processing
KlausRicharz Feb 26, 2022
d8dd39a
Fix lombok annotations
KlausRicharz Feb 26, 2022
b704024
#40 Use Duration for Overtime#timeMinutes
KlausRicharz Feb 26, 2022
0e725ef
#40 Add changeset to set 0 to NULL debisMinutes columns
KlausRicharz Feb 26, 2022
5b5426d
#40 Customerorder, Suborder, Employeeorder debitMinutes -> Duration
KlausRicharz Feb 26, 2022
211856f
Fix wrong date validation - messed up true/false
KlausRicharz Feb 26, 2022
7e55f69
Fix tests for DurationUtils
KlausRicharz Feb 26, 2022
95839b7
#40 Employeecontract dailyWorkingTimeMinutes, overtimeStaticMinutes -…
KlausRicharz Feb 27, 2022
6201b06
#40 Improve naming of getter / setter of Employeecontract
KlausRicharz Feb 27, 2022
bf15133
#40 Improve naming of getter / setter of Employeeorder, Customerorder…
KlausRicharz Feb 27, 2022
a991643
Fix wrong action path
KlausRicharz Feb 27, 2022
4080cbd
Fix resetting boolean form values. Checkboxes do not transmit uncheck…
KlausRicharz Feb 27, 2022
ec8f7e2
Fix formatting of employeecontract.dailyWorkingTime
KlausRicharz Feb 27, 2022
2de2734
Fix formatting of SuborderViewDecorator.duration
KlausRicharz Feb 27, 2022
d5f1fbd
Fix Duration comparison
KlausRicharz Feb 27, 2022
c968ae5
Fix handling of null values in DurationMinutesConverter
KlausRicharz Feb 27, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<configuration>
<offline>true</offline>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
Expand Down
32 changes: 13 additions & 19 deletions src/main/java/org/tb/auth/AfterLogin.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import static org.tb.common.util.TimeFormatUtils.timeFormatMinutes;
import static org.tb.common.util.UrlUtils.absoluteUrl;

import java.time.Duration;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -16,7 +17,6 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.struts.util.MessageResources;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.tb.common.GlobalConstants;
import org.tb.common.Warning;
Expand All @@ -35,7 +35,7 @@

@Component
@Slf4j
@RequiredArgsConstructor(onConstructor_ = { @Autowired})
@RequiredArgsConstructor
public class AfterLogin {

private final TimereportHelper timereportHelper;
Expand Down Expand Up @@ -210,25 +210,19 @@ private void addWarnings(Employeecontract employeecontract, MessageResources res
}

public void handleOvertime(Employeecontract employeecontract, HttpSession session) {
double overtimeStatic = employeecontract.getOvertimeStatic();
int otStaticMinutes = (int) (overtimeStatic * 60);
Duration overtimeStatic = employeecontract.getOvertimeStatic();
long otStaticMinutes = overtimeStatic.toMinutes();

int overtime;
if (employeecontract.getUseOvertimeOld() != null && !employeecontract.getUseOvertimeOld()) {
//use new overtime computation with static + dynamic overtime
//need the LocalDate from the day after reportAcceptanceDate, so the latter is not used twice in overtime computation:
LocalDate dynamicDate;
if (employeecontract.getReportAcceptanceDate() == null || employeecontract.getReportAcceptanceDate().equals(employeecontract.getValidFrom())) {
dynamicDate = employeecontract.getValidFrom();
} else {
dynamicDate = addDays(employeecontract.getReportAcceptanceDate(), 1);
}
int overtimeDynamic = timereportHelper.calculateOvertime(dynamicDate, today(), employeecontract, true);
overtime = otStaticMinutes + overtimeDynamic;
// if after SALAT-Release 1.83, no Release was accepted yet, use old overtime computation
//use new overtime computation with static + dynamic overtime
//need the LocalDate from the day after reportAcceptanceDate, so the latter is not used twice in overtime computation:
LocalDate dynamicDate;
if (employeecontract.getReportAcceptanceDate() == null || employeecontract.getReportAcceptanceDate().equals(employeecontract.getValidFrom())) {
dynamicDate = employeecontract.getValidFrom();
} else {
overtime = timereportHelper.calculateOvertimeTotal(employeecontract);
dynamicDate = addDays(employeecontract.getReportAcceptanceDate(), 1);
}
long overtimeDynamic = timereportHelper.calculateOvertime(dynamicDate, today(), employeecontract, true);
long overtime = otStaticMinutes + overtimeDynamic;

boolean overtimeIsNegative = overtime < 0;

Expand All @@ -249,7 +243,7 @@ public void handleOvertime(Employeecontract employeecontract, HttpSession sessio
if (validUntil != null && validUntil.isBefore(currentDate) && !validUntil.isBefore(start)) {
currentDate = validUntil;
}
int monthlyOvertime = 0;
long monthlyOvertime = 0;
if (!(validUntil != null && validUntil.isBefore(start) || validFrom.isAfter(currentDate))) {
monthlyOvertime = timereportHelper.calculateOvertime(start, currentDate, employeecontract, false);
}
Expand Down
7 changes: 3 additions & 4 deletions src/main/java/org/tb/auth/LoginEmployeeAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,9 @@ private void generateEmployeeOrders(LocalDate today, Employeecontract employeeco
}
if (suborder.getCustomerorder().getSign().equals(GlobalConstants.CUSTOMERORDER_SIGN_VACATION)
&& !suborder.getSign().equalsIgnoreCase(GlobalConstants.SUBORDER_SIGN_OVERTIME_COMPENSATION)) {
employeeorder.setDebithours(employeecontract
.getDailyWorkingTime()
* employeecontract
.getVacationEntitlement());
// TODO reduce VacationEntitlement if contract is not running the whole year
var vacationBudget = employeecontract.getDailyWorkingTime().multipliedBy(employeecontract.getVacationEntitlement());
employeeorder.setDebithours(vacationBudget);
employeeorder.setDebithoursunit(GlobalConstants.DEBITHOURS_UNIT_TOTALTIME);
} else {
// not decided yet
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/org/tb/common/AuditedEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.time.LocalDateTime;
import java.util.Objects;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
Expand All @@ -14,6 +15,7 @@
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.domain.Persistable;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

/**
* Contains information about creation edits made to database columns common to
Expand All @@ -24,6 +26,7 @@
@Getter
@Setter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
abstract public class AuditedEntity implements Persistable<Long> {

@Id
Expand Down
6 changes: 0 additions & 6 deletions src/main/java/org/tb/common/DataValidation.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,6 @@ public static void isTrue(boolean expression, ErrorCode errorCode) {
}
}

public static void isInRange(double value, double min, double max, ErrorCode errorCode) {
if(value < min || value > max) {
throw new InvalidDataException(errorCode);
}
}

public static void lengthIsInRange(String value, int min, int max, ErrorCode errorCode) {
if(value == null || value.length() < min || value.length() > max) {
throw new InvalidDataException(errorCode);
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/org/tb/common/DurationMinutesConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.tb.common;

import java.time.Duration;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

@Converter
public class DurationMinutesConverter implements AttributeConverter<Duration, Integer> {

@Override
public Integer convertToDatabaseColumn(Duration duration) {
if(duration == null) return null;
return (int) duration.toMinutes();
}

@Override
public Duration convertToEntityAttribute(Integer minutes) {
if(minutes == null) return null;
return Duration.ofMinutes(minutes);
}

}
6 changes: 1 addition & 5 deletions src/main/java/org/tb/common/GlobalConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ public class GlobalConstants {

public static final int STARTING_YEAR = 2007;

public static final double MAX_HOURS_PER_DAY = 10.0;

public static final double MAX_DEBITHOURS = 10000.0;
public static final double MAX_OVERTIME = 10000.0;
public static final double MIN_OVERTIME = -10000.0;
public static final int MAX_HOURS_PER_DAY = 10;

public static final int COMMENT_MAX_LENGTH = 32000;

Expand Down
31 changes: 31 additions & 0 deletions src/main/java/org/tb/common/jsptags/FormatDurationTag.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.tb.common.jsptags;

import java.io.IOException;
import java.time.Duration;
import java.time.LocalDate;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
import lombok.Setter;
import org.tb.common.util.DurationUtils;

@Setter
public class FormatDurationTag extends TagSupport {

private Duration value;

@Override
public int doStartTag() throws JspException {
if(value != null) {
JspWriter out = pageContext.getOut();
try {
out.print(DurationUtils.format(value));
return super.doStartTag();
} catch (IOException e) {
throw new JspException(e);
}
}
return SKIP_BODY;
}

}
21 changes: 0 additions & 21 deletions src/main/java/org/tb/common/util/DateUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import static org.tb.common.GlobalConstants.DEFAULT_DATE_FORMAT;
import static org.tb.common.GlobalConstants.DEFAULT_LOCALE;
import static org.tb.common.GlobalConstants.DEFAULT_TIMEZONE_ID;
import static org.tb.common.GlobalConstants.MINUTES_PER_HOUR;
import static org.tb.common.GlobalConstants.STARTING_YEAR;

import java.text.ParseException;
Expand Down Expand Up @@ -304,26 +303,6 @@ public static int getLastDayOfMonth(LocalDate date) {
return date.getMonthValue();
}

/**
* calculates worktime from begin/end times in a form
*
* @return double - decimal hours
*/
public static double calculateTime(int hrbegin, int minbegin, int hrend, int minend) {
double worktime;

int hours = hrend - hrbegin;
int minutes = minend - minbegin;

if (minutes < 0) {
hours -= 1;
minutes += MINUTES_PER_HOUR;
}
worktime = hours * 1. + minutes / 60.;

return worktime;
}

/**
* Takes a LocalDate and a number of days. Changes the LocalDate by adding (amount is positive) or subtracting (amount is negative)
* the number of days to it. For example, you have some LocalDate and need the next day: input parameters are (date, 1).
Expand Down
124 changes: 124 additions & 0 deletions src/main/java/org/tb/common/util/DurationUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package org.tb.common.util;

import static java.lang.Math.abs;
import static org.tb.common.GlobalConstants.MINUTES_PER_HOUR;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import lombok.experimental.UtilityClass;

@UtilityClass
public class DurationUtils {

public static String format(Duration duration) {
if(duration == null) {
return "";
}
if(duration.isZero()) {
return "0:00";
}
StringBuilder sb = new StringBuilder();
if(duration.isNegative()) {
sb.append('-');
}
sb.append(abs(duration.toHours())).append(':');
sb.append(String.format("%02d", abs(duration.toMinutesPart())));
return sb.toString();
}

public static Duration parseDuration(String value) {
if(value == null || value.trim().isEmpty()) {
return Duration.ZERO;
}
boolean negative = value.startsWith("-");
if(negative) {
value = value.substring(1);
}
int minutes = 0;
if(value.contains(":")) {
String[] split = value.split(":");
if(!split[0].isEmpty()) {
minutes = Integer.parseInt(split[0]) * MINUTES_PER_HOUR;
}
if(split.length > 1 && !split[1].isEmpty()) {
minutes += Integer.parseInt(split[1]);
}
} else {
minutes = Integer.parseInt(value) * MINUTES_PER_HOUR;
}
if(negative) {
minutes = minutes * -1;
}

return Duration.ofMinutes(minutes);
}

public static boolean validateDuration(String value) {
if(value == null || value.trim().isEmpty()) {
return true;
}
// cut leading minues
if(value.startsWith("-")) {
value = value.substring(1);
}
try {
// check if hours:minutes
if(value.contains(":")) {
String[] split = value.split(":");
if(split.length > 2) {
return false;
}
if(!split[0].isEmpty()) {
int hours = Integer.parseInt(split[0]);
// negative value is not allowed. Minues sign must be present at the very start of the value, which was already cut
if(hours < 0) {
return false;
}
}
if(split.length == 2 && !split[1].isEmpty()) {
int minutes = Integer.parseInt(split[1]);
// negative value is not allowed. Minues sign must be present at the very start of the value, which was already cut
if(minutes < 0) {
return false;
}
// minutes may be no more than 59
if(minutes > 59) {
return false;
}
}
// check hours only as no ":" in value
} else {
int hours = Integer.parseInt(value);
// negative value is not allowed. Minues sign must be present at the very start of the value, which was already cut
if(hours < 0) {
return false;
}
}
return true;
} catch (NumberFormatException e) {
return false;
}
}

public static String decimalFormat(Duration duration) {
if(duration == null) {
return "";
}
if(duration.isZero()) {
return "0,00";
}
StringBuilder sb = new StringBuilder();
if(duration.isNegative()) {
sb.append('-');
}
sb.append(abs(duration.toHours())).append(',');
int minutesDecimal = BigDecimal.valueOf(duration.toMinutesPart())
.multiply(BigDecimal.valueOf(100))
.divide(BigDecimal.valueOf(MINUTES_PER_HOUR), RoundingMode.HALF_UP)
.intValueExact();
sb.append(String.format("%02d", abs(minutesDecimal)));
return sb.toString();
}

}
6 changes: 4 additions & 2 deletions src/main/java/org/tb/common/util/ExcelArchivierer.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import static org.tb.common.GlobalConstants.DEFAULT_TIMEZONE_ID;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
Expand Down Expand Up @@ -148,7 +150,7 @@ private static Workbook createInvoiceExcel(ShowInvoiceForm showInvoiceForm, Http
// ab hier ggf. Timereports ausgeben
List<InvoiceTimereportHelper> invoiceTimereportViewHelpers = invoiceSuborderViewHelper.getInvoiceTimereportViewHelperList();
if (request.getSession().getAttribute("timereportsbox") != null && ((Boolean) request.getSession().getAttribute("timereportsbox"))
&& invoiceTimereportViewHelpers.size() > 0) {
&& !invoiceTimereportViewHelpers.isEmpty()) {
for (InvoiceTimereportHelper invoiceTimereportViewHelper : invoiceTimereportViewHelpers) {
if (invoiceTimereportViewHelper.isVisible()) {
rowIndex = addTimereportDataRow(workbook, rowIndex, invoiceTimereportViewHelper, request, factory);
Expand Down Expand Up @@ -258,7 +260,7 @@ private static int addSuborderDataRow(Workbook workbook, int rowIndex, InvoiceSu
if (request.getSession().getAttribute("targethoursbox") != null && ((Boolean) request.getSession().getAttribute("targethoursbox"))) {
cell = row.createCell(colIndex, Cell.CELL_TYPE_NUMERIC);
if (invoiceSuborderViewHelper.getDebithours() != null) {
cell.setCellValue(invoiceSuborderViewHelper.getDebithours() / 24);
cell.setCellValue((double) invoiceSuborderViewHelper.getDebithours().toMinutes() / 24);
} else {
cell.setCellValue(0L);
}
Expand Down
Loading