Implement per-month employee working hours

Closes #76
This commit is contained in:
Simon Bruder 2023-12-05 15:21:22 +01:00 committed by Denis Natusch
parent cc05fb2e2e
commit 56f212396b
No known key found for this signature in database
GPG key ID: 5E57BD8EDACFA985
7 changed files with 66 additions and 10 deletions

View file

@ -25,7 +25,14 @@ package catering.order {
class CustomOrder {
- start : LocalDateTime
- finish : LocalDateTime
+ getDurationInSeconds(start:LocalDateTime,finish:LocalDateTime): long
+ getDurationInHours(start:LocalDateTime,finish:LocalDateTime): long
+ min(a:LocalDateTime,b:LocalDateTime): LocalDateTime
+ max(b:LocalDateTime,b:LocalDateTime): LocalDateTime
+ getDurationInSecondsDuringMonth(month:YearMonth): long
}
CustomOrder ..> time.LocalDateTime
CustomOrder ..> time.YearMonth
enum EventType {
EVENT_CATERING
@ -71,6 +78,7 @@ OrderController .....> catering.orderCatalog.OrderCatalogEntry
package time {
class LocalDateTime
class DateTimeFormatter
class YearMonth
}
@enduml

BIN
src/main/asciidoc/models/design/order.svg (Stored with Git LFS)

Binary file not shown.

View file

@ -47,8 +47,8 @@ package catering.staff {
class StaffController {
+ StaffController(staffRepository: StaffRepository)
+ getStaff(model: Model): String
+ getStaff(model: Model, form: StaffForm): String
+ getStaff(model: Model, month:Optional<YearMonth>): String
+ getStaff(model: Model, form: StaffForm, month:Optional<YearMonth>): String
+ removeEmployee(employee: Employee, model: Model): String
+ addEmployee(form:StaffForm, result:Errors, model: Model): String
+ editEmployee(employee: Employee, model Model): String
@ -70,6 +70,7 @@ package catering.staff {
+ findAll(): Streamable<Employee>
+ delete(id: Long): void
+ getAvailableStaffByJob(job: JobType, start:LocalDateTime, finish:LocalDateTime): Set<Employee>
+ getWorkingHourseByemployee(e: Employee,month: YearMonth): double
}
StaffManagement --> StaffRepository : -staffRepository
StaffManagement --> OrderManagement : -orderManagement

View file

@ -11,6 +11,7 @@ import org.springframework.data.annotation.Id;
import javax.money.MonetaryAmount;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.HashSet;
import java.util.Set;
@ -40,12 +41,37 @@ public class CustomOrder extends Order {
public CustomOrder() { }
private long getDurationInSeconds(LocalDateTime start, LocalDateTime finish) {
if (start.compareTo(finish) > 0) {
return 0;
}
return Duration.between(start, finish).getSeconds();
}
/**
* Helper function to get the amount of hours in between start and finish (analogous to CustomCart)
* @return hours between start and finish
*/
private long getDurationInHours(LocalDateTime start, LocalDateTime finish) {
return getDurationInSeconds(start, finish) / 3600;
}
public long getDurationInHours() {
return Duration.between(start, finish).getSeconds() / 3600;
return getDurationInHours(start, finish);
}
private static LocalDateTime min(LocalDateTime a, LocalDateTime b) {
return (a.compareTo(b)) < 0 ? a : b;
}
private static LocalDateTime max(LocalDateTime a, LocalDateTime b) {
return (a.compareTo(b)) > 0 ? a : b;
}
public long getDurationInSecondsDuringMonth(YearMonth month) {
LocalDateTime startInMonth = max(this.start, month.atDay(1).atStartOfDay());
LocalDateTime finishInMonth = min(this.finish, month.plusMonths(1).atDay(1).atStartOfDay());
return getDurationInSeconds(startInMonth, finishInMonth);
}
/**

View file

@ -2,6 +2,9 @@ package catering.staff;
import static org.salespointframework.core.Currencies.EURO;
import java.time.YearMonth;
import java.util.Optional;
import org.javamoney.moneta.Money;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
@ -26,13 +29,15 @@ public class StaffController {
@GetMapping("/staff")
@PreAuthorize("hasRole('ADMIN')")
public String getStaff(Model model) {
return getStaff(model, new StaffForm());
public String getStaff(Model model, @RequestParam Optional<YearMonth> month) {
return getStaff(model, new StaffForm(), month.orElseGet(YearMonth::now));
}
public String getStaff(Model model, @Valid StaffForm form) {
public String getStaff(Model model, @Valid StaffForm form, YearMonth month) {
model.addAttribute("staff", staffManagement.findAll());
model.addAttribute("form", form);
model.addAttribute("month", month);
model.addAttribute("management", staffManagement);
return "staff";
}
@ -41,7 +46,7 @@ public class StaffController {
public String addEmployee(@Valid @ModelAttribute("form") StaffForm form, Errors result, Model model) {
form.validate(result);
if (result.hasErrors()) {
return getStaff(model, form);
return getStaff(model, form, YearMonth.now());
}
staffManagement.save(new Employee(form.getName(), form.getJob(), Money.of(form.getWage(), EURO)));
return "redirect:/staff";

View file

@ -1,6 +1,7 @@
package catering.staff;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
@ -104,4 +105,10 @@ public class StaffManagement {
.collect(Collectors.toSet());
}
public double getWorkingHoursByEmployee(Employee e, YearMonth month) {
return orderManagement.findAll(Pageable.unpaged()).stream()
.filter(order -> order.getStaff().contains(e))
.map(order -> order.getDurationInSecondsDuringMonth(month))
.collect(Collectors.summingDouble(seconds -> (double) seconds / 3600));
}
}

View file

@ -10,11 +10,19 @@
<div layout:fragment="content">
<div>
<h2>Mitarbeiterdetails</h2>
<form th:action="@{/staff}" method="get">
<div class="mb-3">
<label for="month">Monat:</label>
<input type="month" name="month" id="month" th:value="${month}" required>
</div>
<button class="btn btn-primary" type="submit">Zeitangabe aktualisieren</button>
</form>
<table class="table">
<tr>
<th>Name</th>
<th>Beruf</th>
<th>Lohn</th>
<th>Arbeitszeit</th>
<th></th>
<th></th>
</tr>
@ -23,6 +31,7 @@
<td th:text="${employee.name}">Max</td>
<td th:text="${employee.job}">Koch</td>
<td th:text="${employee.wage}"></td>
<td th:with="month=${month}" th:text="${management.getWorkingHoursByEmployee(employee, month)}"></td>
<td>
<a th:href="@{'/staff/edit/' + ${employee.id}}"
><button class="btn btn-warning">Bearbeiten</button></a