From 3b0f488df62d96df0dacf248623edecf8e4b3b78 Mon Sep 17 00:00:00 2001 From: Benjamin Seber Date: Mon, 1 May 2023 15:43:39 +0200 Subject: [PATCH] add user context to ReportDay --- .../zeiterfassung/report/ReportDay.java | 53 ++++++++- .../report/ReportServicePermissionAware.java | 4 +- .../report/ReportServiceRaw.java | 111 ++++++++++++------ .../timeentry/TimeEntryService.java | 9 +- .../timeentry/TimeEntryServiceImpl.java | 32 ++++- .../usermanagement/UserManagementService.java | 3 +- .../UserManagementServiceImpl.java | 2 +- .../report/ReportCsvServiceTest.java | 13 +- .../zeiterfassung/report/ReportDayTest.java | 3 +- .../zeiterfassung/report/ReportMonthTest.java | 69 ++++++----- .../ReportServicePermissionAwareTest.java | 100 ++++++++-------- .../report/ReportServiceRawTest.java | 22 ++-- .../zeiterfassung/report/ReportWeekTest.java | 39 +++--- .../timeentry/TimeEntryServiceImplTest.java | 46 ++++++-- 14 files changed, 325 insertions(+), 181 deletions(-) diff --git a/src/main/java/de/focusshift/zeiterfassung/report/ReportDay.java b/src/main/java/de/focusshift/zeiterfassung/report/ReportDay.java index 9a927ad67..641fb5d69 100644 --- a/src/main/java/de/focusshift/zeiterfassung/report/ReportDay.java +++ b/src/main/java/de/focusshift/zeiterfassung/report/ReportDay.java @@ -2,19 +2,68 @@ import de.focusshift.zeiterfassung.timeentry.PlannedWorkingHours; import de.focusshift.zeiterfassung.timeentry.WorkDuration; +import de.focusshift.zeiterfassung.usermanagement.UserLocalId; import java.time.Duration; import java.time.LocalDate; +import java.util.Collection; import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.stream.Stream; -record ReportDay(LocalDate date, PlannedWorkingHours plannedWorkingHours, List reportDayEntries) { +record ReportDay( + LocalDate date, + Map plannedWorkingHoursByUser, + Map> reportDayEntriesByUser +) { + + public List reportDayEntries() { + return reportDayEntriesByUser.values().stream().flatMap(Collection::stream).toList(); + } + + public PlannedWorkingHours plannedWorkingHours() { + return plannedWorkingHoursByUser.values().stream().reduce(PlannedWorkingHours.ZERO, PlannedWorkingHours::plus); + } + + public PlannedWorkingHours plannedWorkingHoursByUser(UserLocalId userLocalId) { + return findValueByFirstKeyMatch(plannedWorkingHoursByUser, userLocalId::equals).orElse(PlannedWorkingHours.ZERO); + } public WorkDuration workDuration() { - final Duration duration = reportDayEntries.stream() + + final Stream allReportDayEntries = reportDayEntriesByUser.values() + .stream() + .flatMap(Collection::stream); + + return calculateWorkDurationFrom(allReportDayEntries); + } + + public WorkDuration workDurationByUser(UserLocalId userLocalId) { + return workDurationByUserPredicate(userLocalId::equals); + } + + private WorkDuration workDurationByUserPredicate(Predicate predicate) { + final List reportDayEntries = findValueByFirstKeyMatch(reportDayEntriesByUser, predicate).orElse(List.of()); + return calculateWorkDurationFrom(reportDayEntries.stream()); + } + + private WorkDuration calculateWorkDurationFrom(Stream reportDayEntries) { + + final Duration duration = reportDayEntries .map(ReportDayEntry::workDuration) .map(WorkDuration::value) .reduce(Duration.ZERO, Duration::plus); return new WorkDuration(duration); } + + private Optional findValueByFirstKeyMatch(Map map, Predicate predicate) { + return map.entrySet() + .stream() + .filter(entry -> predicate.test(entry.getKey())) + .findFirst() + .map(Map.Entry::getValue); + } } diff --git a/src/main/java/de/focusshift/zeiterfassung/report/ReportServicePermissionAware.java b/src/main/java/de/focusshift/zeiterfassung/report/ReportServicePermissionAware.java index dc8e5abaa..4e627c55d 100644 --- a/src/main/java/de/focusshift/zeiterfassung/report/ReportServicePermissionAware.java +++ b/src/main/java/de/focusshift/zeiterfassung/report/ReportServicePermissionAware.java @@ -1,6 +1,5 @@ package de.focusshift.zeiterfassung.report; -import de.focusshift.zeiterfassung.timeentry.PlannedWorkingHours; import de.focusshift.zeiterfassung.user.UserDateService; import de.focusshift.zeiterfassung.user.UserId; import de.focusshift.zeiterfassung.usermanagement.UserLocalId; @@ -11,6 +10,7 @@ import java.time.YearMonth; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.stream.IntStream; import static java.time.temporal.ChronoUnit.MONTHS; @@ -111,7 +111,7 @@ private ReportWeek emptyReportWeek(Year year, int week) { private ReportWeek emptyReportWeek(LocalDate startOfWeekDate) { final List reportDays = IntStream.rangeClosed(0, 6) - .mapToObj(daysToAdd -> new ReportDay(startOfWeekDate.plusDays(daysToAdd), PlannedWorkingHours.ZERO, List.of())) + .mapToObj(daysToAdd -> new ReportDay(startOfWeekDate.plusDays(daysToAdd), Map.of(), Map.of())) .toList(); return new ReportWeek(startOfWeekDate, reportDays); diff --git a/src/main/java/de/focusshift/zeiterfassung/report/ReportServiceRaw.java b/src/main/java/de/focusshift/zeiterfassung/report/ReportServiceRaw.java index f69ddb58f..08b5b64f1 100644 --- a/src/main/java/de/focusshift/zeiterfassung/report/ReportServiceRaw.java +++ b/src/main/java/de/focusshift/zeiterfassung/report/ReportServiceRaw.java @@ -20,16 +20,15 @@ import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Function; import java.util.stream.IntStream; -import java.util.stream.Stream; import static java.lang.invoke.MethodHandles.lookup; import static java.time.temporal.ChronoUnit.MONTHS; -import static java.util.Collections.emptyList; import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Collectors.toMap; @@ -60,9 +59,11 @@ ReportWeek getReportWeek(Year year, int week, UserId userId) { final User user = userManagementService.findUserById(userId) .orElseThrow(() -> new IllegalStateException("could not find user id=%s".formatted(userId))); + final UserLocalId userLocalId = user.localId(); + return createReportWeek(year, week, - period -> timeEntryService.getEntries(period.from(), period.toExclusive(), userId), - period -> workingTimeCalendarService.getWorkingTimes(period.from(), period.toExclusive(), List.of(user.localId()))); + period -> Map.of(userLocalId, timeEntryService.getEntries(period.from(), period.toExclusive(), userId)), + period -> workingTimeCalendarService.getWorkingTimes(period.from(), period.toExclusive(), List.of(userLocalId))); } ReportWeek getReportWeek(Year year, int week, List userLocalIds) { @@ -82,8 +83,10 @@ ReportMonth getReportMonth(YearMonth yearMonth, UserId userId) { final User user = userManagementService.findUserById(userId) .orElseThrow(() -> new IllegalStateException("could not find user id=%s".formatted(userId))); + final UserLocalId userLocalId = user.localId(); + return createReportMonth(yearMonth, - period -> timeEntryService.getEntries(period.from(), period.toExclusive(), userId), + period -> timeEntryService.getEntriesByUserLocalIds(period.from(), period.toExclusive(), List.of(userLocalId)), period -> workingTimeCalendarService.getWorkingTimes(period.from(), period.toExclusive(), List.of(user.localId()))); } @@ -100,50 +103,61 @@ ReportMonth getReportMonthForAllUsers(YearMonth yearMonth) { } private ReportWeek createReportWeek(Year year, int week, - Function> timeEntriesProvider, + Function>> timeEntriesProvider, Function> workingTimeCalendarProvider) { final LocalDate firstDateOfWeek = userDateService.firstDayOfWeek(year, week); final Period period = new Period(firstDateOfWeek, firstDateOfWeek.plusWeeks(1)); - final List timeEntries = timeEntriesProvider.apply(period); - final Map userById = userByIdForTimeEntries(timeEntries); + final Map> timeEntries = timeEntriesProvider.apply(period); + final Map userById = userByIdForTimeEntries(timeEntries.values().stream().flatMap(Collection::stream).toList()); - final Collection workingTimeCalendars = workingTimeCalendarProvider.apply(period).values(); - final Function plannedWorkingTimeByDate = plannedWorkingTimeForDate(workingTimeCalendars); + final Map workingTimeCalendars = workingTimeCalendarProvider.apply(period); + final Function> plannedWorkingTimeByDate = plannedWorkingTimeForDate(workingTimeCalendars); return reportWeek(firstDateOfWeek, timeEntries, userById, plannedWorkingTimeByDate); } private ReportMonth createReportMonth(YearMonth yearMonth, - Function> timeEntriesProvider, + Function>> timeEntriesProvider, Function> workingTimeCalendarProvider) { final LocalDate firstOfMonth = LocalDate.of(yearMonth.getYear(), yearMonth.getMonthValue(), 1); final Period period = new Period(firstOfMonth, firstOfMonth.plusMonths(1)); - final List timeEntries = timeEntriesProvider.apply(period); - final Map userById = userByIdForTimeEntries(timeEntries); + final Map> timeEntriesByUserId = timeEntriesProvider.apply(period); + final Map userById = userByIdForTimeEntries(timeEntriesByUserId.values().stream().flatMap(Collection::stream).toList()); - final Collection workingTimeCalendars = workingTimeCalendarProvider.apply(period).values(); - final Function plannedWorkingTimeForDate = plannedWorkingTimeForDate(workingTimeCalendars); + final Map workingTimeCalendars = workingTimeCalendarProvider.apply(period); + final Function> plannedWorkingTimeForDate = plannedWorkingTimeForDate(workingTimeCalendars); - List weeks = getStartOfWeekDatesForMonth(yearMonth) + final List weeks = getStartOfWeekDatesForMonth(yearMonth) .stream() - .map(startOfWeekDate -> reportWeek(startOfWeekDate, timeEntries, userById, plannedWorkingTimeForDate)) + .map(startOfWeekDate -> + reportWeek( + startOfWeekDate, + timeEntriesByUserId, + userById, + plannedWorkingTimeForDate + ) + ) .toList(); return new ReportMonth(yearMonth, weeks); } - private Function plannedWorkingTimeForDate(Collection workingTimeCalendars) { - return date -> workingTimeCalendars.stream() - .map(cal -> cal.plannedWorkingHours(date)) - .filter(Optional::isPresent) - .map(Optional::get) - .reduce(PlannedWorkingHours.ZERO, PlannedWorkingHours::plus); + private Function> plannedWorkingTimeForDate(Map workingTimeCalendars) { + return date -> + workingTimeCalendars.entrySet() + .stream() + .collect( + toMap( + Map.Entry::getKey, + entry -> entry.getValue().plannedWorkingHours(date).orElse(PlannedWorkingHours.ZERO) + ) + ); } private Map userByIdForTimeEntries(List timeEntries) { @@ -153,19 +167,42 @@ private Map userByIdForTimeEntries(List timeEntries) { .collect(toMap(User::id, Function.identity())); } - private ReportWeek reportWeek(LocalDate startOfWeekDate, List timeEntries, Map userById, - Function plannedWorkingHoursProvider) { + private ReportWeek reportWeek(LocalDate startOfWeekDate, + Map> timeEntriesByUserLocalId, + Map userById, + Function> plannedWorkingHoursProvider) { - final Map> reportDayEntriesByDate = timeEntries - .stream() - .flatMap(timeEntry -> timeEntryToReportDayEntries(timeEntry, userById::get)) - .collect(groupingBy(reportDayEntry -> reportDayEntry.start().toLocalDate())); + final Map>> reportEntriesByDate = new HashMap<>(); + for (Map.Entry> entry : timeEntriesByUserLocalId.entrySet()) { + + final UserLocalId userLocalId = entry.getKey(); + + final Map> collect = entry.getValue() + .stream() + .map(t -> timeEntryToReportDayEntry(t, userById::get)) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(groupingBy(report -> report.start().toLocalDate())); + + for (Map.Entry> localDateListEntry : collect.entrySet()) { + reportEntriesByDate.compute(localDateListEntry.getKey(), (localDate, userLocalIdListMap) -> { + final Map> map = userLocalIdListMap == null ? new HashMap<>() : userLocalIdListMap; + map.put(userLocalId, collect.get(localDate)); + return map; + }); + } + } - final Function> resolveReportDayEntries = - (LocalDate date) -> reportDayEntriesByDate.getOrDefault(date, emptyList()); + final Function>> resolveReportDayEntries = + (LocalDate date) -> reportEntriesByDate.getOrDefault(date, Map.of()); final List reportDays = IntStream.rangeClosed(0, 6) - .mapToObj(daysToAdd -> toReportDay(startOfWeekDate.plusDays(daysToAdd), plannedWorkingHoursProvider, resolveReportDayEntries)) + .mapToObj(daysToAdd -> + toReportDay( + startOfWeekDate.plusDays(daysToAdd), + plannedWorkingHoursProvider, + resolveReportDayEntries + )) .toList(); return new ReportWeek(startOfWeekDate, reportDays); @@ -185,7 +222,7 @@ private List getStartOfWeekDatesForMonth(YearMonth yearMonth) { return startOfWeekDates; } - private static Stream timeEntryToReportDayEntries(TimeEntry timeEntry, Function userProvider) { + private static Optional timeEntryToReportDayEntry(TimeEntry timeEntry, Function userProvider) { final String comment = timeEntry.comment(); final ZonedDateTime startDateTime = timeEntry.start(); @@ -194,16 +231,16 @@ private static Stream timeEntryToReportDayEntries(TimeEntry time final User user = userProvider.apply(timeEntry.userId()); if (user == null) { LOG.info("could not find user with id={} for timeEntry={} while generating report.", timeEntry.userId(), timeEntry.id()); - return Stream.empty(); + return Optional.empty(); } final ReportDayEntry first = new ReportDayEntry(user, comment, startDateTime, endDateTime, timeEntry.isBreak()); - return Stream.of(first); + return Optional.of(first); } private static ReportDay toReportDay(LocalDate date, - Function plannedWorkingHoursProvider, - Function> resolveReportDayEntries) { + Function> plannedWorkingHoursProvider, + Function>> resolveReportDayEntries) { return new ReportDay(date, plannedWorkingHoursProvider.apply(date), resolveReportDayEntries.apply(date)); } diff --git a/src/main/java/de/focusshift/zeiterfassung/timeentry/TimeEntryService.java b/src/main/java/de/focusshift/zeiterfassung/timeentry/TimeEntryService.java index 82f85ab72..c1faa838f 100644 --- a/src/main/java/de/focusshift/zeiterfassung/timeentry/TimeEntryService.java +++ b/src/main/java/de/focusshift/zeiterfassung/timeentry/TimeEntryService.java @@ -8,6 +8,7 @@ import java.time.LocalDate; import java.time.ZonedDateTime; import java.util.List; +import java.util.Map; import java.util.Optional; public interface TimeEntryService { @@ -37,9 +38,9 @@ public interface TimeEntryService { * @param from first date of interval * @param toExclusive last date (exclusive) of interval * - * @return unsorted list of {@linkplain TimeEntry}s. + * @return unsorted list of {@linkplain TimeEntry}s grouped by user */ - List getEntriesForAllUsers(LocalDate from, LocalDate toExclusive); + Map> getEntriesForAllUsers(LocalDate from, LocalDate toExclusive); /** * {@linkplain TimeEntry}s for all given users and interval. @@ -48,9 +49,9 @@ public interface TimeEntryService { * @param toExclusive last date (exclusive) of interval * @param userLocalIds {@linkplain UserLocalId}s of desired users * - * @return unsorted list of {@linkplain TimeEntry}s. + * @return unsorted list of {@linkplain TimeEntry}s grouped by user */ - List getEntriesByUserLocalIds(LocalDate from, LocalDate toExclusive, List userLocalIds); + Map> getEntriesByUserLocalIds(LocalDate from, LocalDate toExclusive, List userLocalIds); /** * {@linkplain TimeEntryWeekPage}s for the given user and week of year with sorted {@linkplain TimeEntry}s diff --git a/src/main/java/de/focusshift/zeiterfassung/timeentry/TimeEntryServiceImpl.java b/src/main/java/de/focusshift/zeiterfassung/timeentry/TimeEntryServiceImpl.java index e06c8aaa6..afa7605af 100644 --- a/src/main/java/de/focusshift/zeiterfassung/timeentry/TimeEntryServiceImpl.java +++ b/src/main/java/de/focusshift/zeiterfassung/timeentry/TimeEntryServiceImpl.java @@ -27,7 +27,9 @@ import static java.time.temporal.ChronoUnit.MINUTES; import static java.time.temporal.ChronoUnit.SECONDS; import static java.util.Comparator.comparing; +import static java.util.function.Function.identity; import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.toMap; @Service class TimeEntryServiceImpl implements TimeEntryService { @@ -73,36 +75,54 @@ public List getEntries(LocalDate from, LocalDate toExclusive, UserId } @Override - public List getEntriesForAllUsers(LocalDate from, LocalDate toExclusive) { + public Map> getEntriesForAllUsers(LocalDate from, LocalDate toExclusive) { final Instant fromInstant = toInstant(from); final Instant toInstant = toInstant(toExclusive); - return timeEntryRepository.findAllByStartGreaterThanEqualAndStartLessThan(fromInstant, toInstant) + final Map> timeEntriesByUserId = timeEntryRepository.findAllByStartGreaterThanEqualAndStartLessThan(fromInstant, toInstant) .stream() .map(TimeEntryServiceImpl::toTimeEntry) - .toList(); + .collect(groupingBy(TimeEntry::userId)); + + final Map userById = userManagementService.findAllUsersByIds(timeEntriesByUserId.keySet()) + .stream() + .collect(toMap(User::id, identity())); + + return timeEntriesByUserId.entrySet() + .stream() + .collect( + toMap( + entry -> userById.get(entry.getKey()).localId(), + Map.Entry::getValue + ) + ); } @Override - public List getEntriesByUserLocalIds(LocalDate from, LocalDate toExclusive, List userLocalIds) { + public Map> getEntriesByUserLocalIds(LocalDate from, LocalDate toExclusive, List userLocalIds) { final Instant fromInstant = toInstant(from); final Instant toInstant = toInstant(toExclusive); - final List userIdValues = userManagementService.findAllUsersByLocalIds(userLocalIds) + final List users = userManagementService.findAllUsersByLocalIds(userLocalIds); + + final List userIdValues = users .stream() .map(User::id) .map(UserId::value) .toList(); + final Map userLocalIdById = users.stream().collect(toMap(User::id, User::localId)); + final List result = timeEntryRepository .findAllByOwnerIsInAndStartGreaterThanEqualAndStartLessThan(userIdValues, fromInstant, toInstant); return result .stream() .map(TimeEntryServiceImpl::toTimeEntry) - .toList(); + // TODO add empty list entry for users without time entries + .collect(groupingBy(timeEntry -> userLocalIdById.get(timeEntry.userId()))); } @Override diff --git a/src/main/java/de/focusshift/zeiterfassung/usermanagement/UserManagementService.java b/src/main/java/de/focusshift/zeiterfassung/usermanagement/UserManagementService.java index c7e7e3622..6f6d62caf 100644 --- a/src/main/java/de/focusshift/zeiterfassung/usermanagement/UserManagementService.java +++ b/src/main/java/de/focusshift/zeiterfassung/usermanagement/UserManagementService.java @@ -2,6 +2,7 @@ import de.focusshift.zeiterfassung.user.UserId; +import java.util.Collection; import java.util.List; import java.util.Optional; @@ -15,7 +16,7 @@ public interface UserManagementService { List findAllUsers(String query); - List findAllUsersByIds(List ids); + List findAllUsersByIds(Collection ids); List findAllUsersByLocalIds(List localIds); } diff --git a/src/main/java/de/focusshift/zeiterfassung/usermanagement/UserManagementServiceImpl.java b/src/main/java/de/focusshift/zeiterfassung/usermanagement/UserManagementServiceImpl.java index 3f128dff4..44aa232c5 100644 --- a/src/main/java/de/focusshift/zeiterfassung/usermanagement/UserManagementServiceImpl.java +++ b/src/main/java/de/focusshift/zeiterfassung/usermanagement/UserManagementServiceImpl.java @@ -39,7 +39,7 @@ public List findAllUsers(String query) { } @Override - public List findAllUsersByIds(List userIds) { + public List findAllUsersByIds(Collection userIds) { return mapToUser(tenantUserService.findAllUsersById(userIds)); } diff --git a/src/test/java/de/focusshift/zeiterfassung/report/ReportCsvServiceTest.java b/src/test/java/de/focusshift/zeiterfassung/report/ReportCsvServiceTest.java index 3ca18158c..4af293134 100644 --- a/src/test/java/de/focusshift/zeiterfassung/report/ReportCsvServiceTest.java +++ b/src/test/java/de/focusshift/zeiterfassung/report/ReportCsvServiceTest.java @@ -25,6 +25,7 @@ import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; @@ -87,7 +88,7 @@ void ensureWeekReportCsvRoundsWorkedHoursToTwoDigit() { final ZonedDateTime from = ZonedDateTime.of(LocalDateTime.of(2021, 1, 4, 10, 0), ZONE_ID_BERLIN); final ZonedDateTime to = ZonedDateTime.of(LocalDateTime.of(2021, 1, 4, 10, 30), ZONE_ID_BERLIN); final ReportDayEntry reportDayEntry = new ReportDayEntry(batman, "hard work", from, to, false); - final ReportDay reportDay = new ReportDay(LocalDate.of(2021, 1, 4), PlannedWorkingHours.EIGHT, List.of(reportDayEntry)); + final ReportDay reportDay = new ReportDay(LocalDate.of(2021, 1, 4), Map.of(batman.localId(), PlannedWorkingHours.EIGHT), Map.of(batman.localId(), List.of(reportDayEntry))); when(reportService.getReportWeek(Year.of(2021), 1, new UserId("batman"))) .thenReturn(new ReportWeek(LocalDate.of(2020, 12, 28), List.of(reportDay))); @@ -117,13 +118,13 @@ void ensureWeekReportCsvContainsSummarizedInfoPerDay() { final ZonedDateTime d1_2_From = ZonedDateTime.of(LocalDateTime.of(2021, 1, 4, 14, 0), ZONE_ID_BERLIN); final ZonedDateTime d1_2_To = ZonedDateTime.of(LocalDateTime.of(2021, 1, 4, 15, 0), ZONE_ID_BERLIN); final ReportDayEntry d1_2_ReportDayEntry = new ReportDayEntry(batman, "hard work", d1_2_From, d1_2_To, false); - final ReportDay reportDayOne = new ReportDay(LocalDate.of(2021, 1, 4), PlannedWorkingHours.EIGHT, List.of(d1_1_ReportDayEntry, d1_2_ReportDayEntry)); + final ReportDay reportDayOne = new ReportDay(LocalDate.of(2021, 1, 4), Map.of(batman.localId(), PlannedWorkingHours.EIGHT), Map.of(batman.localId(), List.of(d1_1_ReportDayEntry, d1_2_ReportDayEntry))); // day two final ZonedDateTime d2_1_From = ZonedDateTime.of(LocalDateTime.of(2021, 1, 5, 9, 0), ZONE_ID_BERLIN); final ZonedDateTime d2_1_To = ZonedDateTime.of(LocalDateTime.of(2021, 1, 5, 17, 0), ZONE_ID_BERLIN); final ReportDayEntry d2_1_ReportDayEntry = new ReportDayEntry(batman, "hard work", d2_1_From, d2_1_To, false); - final ReportDay reportDayTwo = new ReportDay(LocalDate.of(2021, 1, 5), PlannedWorkingHours.EIGHT, List.of(d2_1_ReportDayEntry)); + final ReportDay reportDayTwo = new ReportDay(LocalDate.of(2021, 1, 5), Map.of(batman.localId(), PlannedWorkingHours.EIGHT), Map.of(batman.localId(), List.of(d2_1_ReportDayEntry))); when(reportService.getReportWeek(Year.of(2021), 1, new UserId("batman"))) @@ -172,7 +173,7 @@ void ensureMonthReportCsvRoundsWorkedHoursToTwoDigit() { final ZonedDateTime from = ZonedDateTime.of(LocalDateTime.of(2021, 1, 4, 10, 0), ZONE_ID_BERLIN); final ZonedDateTime to = ZonedDateTime.of(LocalDateTime.of(2021, 1, 4, 10, 30), ZONE_ID_BERLIN); final ReportDayEntry reportDayEntry = new ReportDayEntry(batman, "hard work", from, to, false); - final ReportDay reportDay = new ReportDay(LocalDate.of(2021, 1, 4), PlannedWorkingHours.EIGHT, List.of(reportDayEntry)); + final ReportDay reportDay = new ReportDay(LocalDate.of(2021, 1, 4), Map.of(batman.localId(), PlannedWorkingHours.EIGHT), Map.of(batman.localId(), List.of(reportDayEntry))); final ReportWeek firstWeek = new ReportWeek(LocalDate.of(2020, 12, 28), List.of(reportDay)); final ReportWeek secondWeek = new ReportWeek(LocalDate.of(2021, 1, 4), List.of()); @@ -208,13 +209,13 @@ void ensureMonthReportCsvContainsSummarizedInfoPerDay() { final ZonedDateTime d1_2_From = ZonedDateTime.of(LocalDateTime.of(2021, 1, 4, 14, 0), ZONE_ID_BERLIN); final ZonedDateTime d1_2_To = ZonedDateTime.of(LocalDateTime.of(2021, 1, 4, 15, 0), ZONE_ID_BERLIN); final ReportDayEntry d1_2_ReportDayEntry = new ReportDayEntry(batman, "hard work", d1_2_From, d1_2_To, false); - final ReportDay w1_reportDay = new ReportDay(LocalDate.of(2021, 1, 4), PlannedWorkingHours.EIGHT, List.of(d1_1_ReportDayEntry, d1_2_ReportDayEntry)); + final ReportDay w1_reportDay = new ReportDay(LocalDate.of(2021, 1, 4), Map.of(batman.localId(), PlannedWorkingHours.EIGHT), Map.of(batman.localId(), List.of(d1_1_ReportDayEntry, d1_2_ReportDayEntry))); // week two, day one final ZonedDateTime d2_1_From = ZonedDateTime.of(LocalDateTime.of(2021, 1, 5, 9, 0), ZONE_ID_BERLIN); final ZonedDateTime d2_1_To = ZonedDateTime.of(LocalDateTime.of(2021, 1, 5, 17, 0), ZONE_ID_BERLIN); final ReportDayEntry d2_1_ReportDayEntry = new ReportDayEntry(batman, "hard work", d2_1_From, d2_1_To, false); - final ReportDay w2_reportDay = new ReportDay(LocalDate.of(2021, 1, 5), PlannedWorkingHours.EIGHT, List.of(d2_1_ReportDayEntry)); + final ReportDay w2_reportDay = new ReportDay(LocalDate.of(2021, 1, 5), Map.of(batman.localId(), PlannedWorkingHours.EIGHT), Map.of(batman.localId(), List.of(d2_1_ReportDayEntry))); final ReportWeek firstWeek = new ReportWeek(LocalDate.of(2020, 12, 28), List.of(w1_reportDay)); final ReportWeek secondWeek = new ReportWeek(LocalDate.of(2021, 1, 4), List.of(w2_reportDay)); diff --git a/src/test/java/de/focusshift/zeiterfassung/report/ReportDayTest.java b/src/test/java/de/focusshift/zeiterfassung/report/ReportDayTest.java index 686449bce..e89d33140 100644 --- a/src/test/java/de/focusshift/zeiterfassung/report/ReportDayTest.java +++ b/src/test/java/de/focusshift/zeiterfassung/report/ReportDayTest.java @@ -13,6 +13,7 @@ import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.List; +import java.util.Map; import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; @@ -30,7 +31,7 @@ void ensureToRemoveBreaks() { final ZonedDateTime to = dateTime(2021, 1, 4, 2, 0); final ReportDayEntry reportDayEntry = new ReportDayEntry(batman, "hard work", from, to, true); - final ReportDay reportDay = new ReportDay(LocalDate.of(2021, 1, 4), PlannedWorkingHours.EIGHT, List.of(reportDayEntry)); + final ReportDay reportDay = new ReportDay(LocalDate.of(2021, 1, 4), Map.of(batman.localId(), PlannedWorkingHours.EIGHT), Map.of(batman.localId(), List.of(reportDayEntry))); assertThat(reportDay.workDuration().value()).isEqualTo(Duration.ZERO); } diff --git a/src/test/java/de/focusshift/zeiterfassung/report/ReportMonthTest.java b/src/test/java/de/focusshift/zeiterfassung/report/ReportMonthTest.java index 6bee52b86..3c57fd345 100644 --- a/src/test/java/de/focusshift/zeiterfassung/report/ReportMonthTest.java +++ b/src/test/java/de/focusshift/zeiterfassung/report/ReportMonthTest.java @@ -15,6 +15,7 @@ import java.time.YearMonth; import java.time.ZonedDateTime; import java.util.List; +import java.util.Map; import java.util.Set; import static java.time.ZoneOffset.UTC; @@ -52,22 +53,24 @@ private ReportWeek firstWeekFebruary2023(User user, LocalDate firstDateOfWeek, L final LocalDate saturday = firstDateOfWeek.plusDays(5); final LocalDate sunday = firstDateOfWeek.plusDays(6); + final UserLocalId userLocalId = user.localId(); + return new ReportWeek(firstDateOfWeek, List.of( // january - new ReportDay(firstDateOfWeek, PlannedWorkingHours.ZERO, List.of()), - new ReportDay(tuesday, PlannedWorkingHours.ZERO, List.of()), + new ReportDay(firstDateOfWeek, Map.of(userLocalId, PlannedWorkingHours.ZERO), Map.of(userLocalId, List.of())), + new ReportDay(tuesday, Map.of(userLocalId, PlannedWorkingHours.ZERO), Map.of(userLocalId, List.of())), // february - new ReportDay(wednesday, PlannedWorkingHours.EIGHT, List.of( + new ReportDay(wednesday, Map.of(userLocalId, PlannedWorkingHours.EIGHT), Map.of(userLocalId, List.of( new ReportDayEntry(user, "", ZonedDateTime.of(LocalDateTime.of(wednesday, timeStart), UTC), ZonedDateTime.of(LocalDateTime.of(wednesday, timeEnd), UTC), false) - )), - new ReportDay(thursday, PlannedWorkingHours.EIGHT, List.of( + ))), + new ReportDay(thursday, Map.of(userLocalId, PlannedWorkingHours.EIGHT), Map.of(userLocalId, List.of( new ReportDayEntry(user, "", ZonedDateTime.of(LocalDateTime.of(thursday, timeStart), UTC), ZonedDateTime.of(LocalDateTime.of(thursday, timeEnd), UTC), false) - )), - new ReportDay(friday, PlannedWorkingHours.EIGHT, List.of( + ))), + new ReportDay(friday, Map.of(userLocalId, PlannedWorkingHours.EIGHT), Map.of(userLocalId, List.of( new ReportDayEntry(user, "", ZonedDateTime.of(LocalDateTime.of(friday, timeStart), UTC), ZonedDateTime.of(LocalDateTime.of(friday, timeEnd), UTC), false) - )), - new ReportDay(saturday, PlannedWorkingHours.EIGHT, List.of()), - new ReportDay(sunday, PlannedWorkingHours.EIGHT, List.of()) + ))), + new ReportDay(saturday, Map.of(userLocalId, PlannedWorkingHours.EIGHT), Map.of(userLocalId, List.of())), + new ReportDay(sunday, Map.of(userLocalId, PlannedWorkingHours.EIGHT), Map.of(userLocalId, List.of())) )); } @@ -80,24 +83,26 @@ private ReportWeek nthWeekFebruary2023(User user, LocalDate firstDateOfWeek, Loc final LocalDate saturday = firstDateOfWeek.plusDays(5); final LocalDate sunday = firstDateOfWeek.plusDays(6); + final UserLocalId userLocalId = user.localId(); + return new ReportWeek(firstDateOfWeek, List.of( - new ReportDay(firstDateOfWeek, PlannedWorkingHours.EIGHT, List.of( + new ReportDay(firstDateOfWeek, Map.of(userLocalId, PlannedWorkingHours.EIGHT), Map.of(userLocalId, List.of( new ReportDayEntry(user, "", ZonedDateTime.of(LocalDateTime.of(firstDateOfWeek, timeStart), UTC), ZonedDateTime.of(LocalDateTime.of(firstDateOfWeek, timeEnd), UTC), false) - )), - new ReportDay(tuesday, PlannedWorkingHours.EIGHT, List.of( + ))), + new ReportDay(tuesday, Map.of(userLocalId, PlannedWorkingHours.EIGHT), Map.of(userLocalId, List.of( new ReportDayEntry(user, "", ZonedDateTime.of(LocalDateTime.of(tuesday, timeStart), UTC), ZonedDateTime.of(LocalDateTime.of(tuesday, timeEnd), UTC), false) - )), - new ReportDay(wednesday, PlannedWorkingHours.EIGHT, List.of( + ))), + new ReportDay(wednesday, Map.of(userLocalId, PlannedWorkingHours.EIGHT), Map.of(userLocalId, List.of( new ReportDayEntry(user, "", ZonedDateTime.of(LocalDateTime.of(wednesday, timeStart), UTC), ZonedDateTime.of(LocalDateTime.of(wednesday, timeEnd), UTC), false) - )), - new ReportDay(thursday, PlannedWorkingHours.EIGHT, List.of( + ))), + new ReportDay(thursday, Map.of(userLocalId, PlannedWorkingHours.EIGHT), Map.of(userLocalId, List.of( new ReportDayEntry(user, "", ZonedDateTime.of(LocalDateTime.of(thursday, timeStart), UTC), ZonedDateTime.of(LocalDateTime.of(thursday, timeEnd), UTC), false) - )), - new ReportDay(friday, PlannedWorkingHours.EIGHT, List.of( + ))), + new ReportDay(friday, Map.of(userLocalId, PlannedWorkingHours.EIGHT), Map.of(userLocalId, List.of( new ReportDayEntry(user, "", ZonedDateTime.of(LocalDateTime.of(friday, timeStart), UTC), ZonedDateTime.of(LocalDateTime.of(friday, timeEnd), UTC), false) - )), - new ReportDay(saturday, PlannedWorkingHours.ZERO, List.of()), - new ReportDay(sunday, PlannedWorkingHours.ZERO, List.of()) + ))), + new ReportDay(saturday, Map.of(userLocalId, PlannedWorkingHours.ZERO), Map.of(userLocalId, List.of())), + new ReportDay(sunday, Map.of(userLocalId, PlannedWorkingHours.ZERO), Map.of(userLocalId, List.of())) )); } @@ -110,20 +115,22 @@ private ReportWeek lastWeekOfFebruary2023(User user, LocalDate firstDateOfWeek, final LocalDate saturday = firstDateOfWeek.plusDays(5); final LocalDate sunday = firstDateOfWeek.plusDays(6); + final UserLocalId userLocalId = user.localId(); + return new ReportWeek(firstDateOfWeek, List.of( // february - new ReportDay(firstDateOfWeek, PlannedWorkingHours.EIGHT, List.of( + new ReportDay(firstDateOfWeek, Map.of(userLocalId, PlannedWorkingHours.EIGHT), Map.of(userLocalId, List.of( new ReportDayEntry(user, "", ZonedDateTime.of(LocalDateTime.of(wednesday, timeStart), UTC), ZonedDateTime.of(LocalDateTime.of(wednesday, timeEnd), UTC), false) - )), - new ReportDay(tuesday, PlannedWorkingHours.EIGHT, List.of( + ))), + new ReportDay(tuesday, Map.of(userLocalId, PlannedWorkingHours.EIGHT), Map.of(userLocalId, List.of( new ReportDayEntry(user, "", ZonedDateTime.of(LocalDateTime.of(wednesday, timeStart), UTC), ZonedDateTime.of(LocalDateTime.of(wednesday, timeEnd), UTC), false) - )), + ))), // march - new ReportDay(wednesday, PlannedWorkingHours.ZERO, List.of()), - new ReportDay(thursday, PlannedWorkingHours.ZERO, List.of()), - new ReportDay(friday, PlannedWorkingHours.ZERO, List.of()), - new ReportDay(saturday, PlannedWorkingHours.ZERO, List.of()), - new ReportDay(sunday, PlannedWorkingHours.ZERO, List.of()) + new ReportDay(wednesday, Map.of(userLocalId, PlannedWorkingHours.ZERO), Map.of(userLocalId, List.of())), + new ReportDay(thursday, Map.of(userLocalId, PlannedWorkingHours.ZERO), Map.of(userLocalId, List.of())), + new ReportDay(friday, Map.of(userLocalId, PlannedWorkingHours.ZERO), Map.of(userLocalId, List.of())), + new ReportDay(saturday, Map.of(userLocalId, PlannedWorkingHours.ZERO), Map.of(userLocalId, List.of())), + new ReportDay(sunday, Map.of(userLocalId, PlannedWorkingHours.ZERO), Map.of(userLocalId, List.of())) )); } } diff --git a/src/test/java/de/focusshift/zeiterfassung/report/ReportServicePermissionAwareTest.java b/src/test/java/de/focusshift/zeiterfassung/report/ReportServicePermissionAwareTest.java index e863193ef..8ef927340 100644 --- a/src/test/java/de/focusshift/zeiterfassung/report/ReportServicePermissionAwareTest.java +++ b/src/test/java/de/focusshift/zeiterfassung/report/ReportServicePermissionAwareTest.java @@ -1,6 +1,5 @@ package de.focusshift.zeiterfassung.report; -import de.focusshift.zeiterfassung.timeentry.PlannedWorkingHours; import de.focusshift.zeiterfassung.user.UserDateService; import de.focusshift.zeiterfassung.usermanagement.UserLocalId; import org.junit.jupiter.api.BeforeEach; @@ -13,6 +12,7 @@ import java.time.Year; import java.time.YearMonth; import java.util.List; +import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; @@ -37,10 +37,9 @@ void setUp() { @Test void getReportWeekForMultipleUsersWhenCurrentUserHasNoPermissionForAnyGivenOne() { - final List userIds = List.of( - new UserLocalId(1L), - new UserLocalId(2L) - ); + final UserLocalId localId_1 = new UserLocalId(1L); + final UserLocalId localId_2 = new UserLocalId(2L); + final List userIds = List.of(localId_1, localId_2); when(reportPermissionService.filterUserLocalIdsByCurrentUserHasPermissionFor(userIds)).thenReturn(List.of()); @@ -52,23 +51,22 @@ void getReportWeekForMultipleUsersWhenCurrentUserHasNoPermissionForAnyGivenOne() assertThat(actual).isNotNull(); assertThat(actual.firstDateOfWeek()).isEqualTo(LocalDate.of(2023, 2, 13)); assertThat(actual.reportDays()).containsExactly( - new ReportDay(LocalDate.of(2023, 2, 13), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 14), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 15), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 16), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 17), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 18), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 19), PlannedWorkingHours.ZERO, List.of()) + new ReportDay(LocalDate.of(2023, 2, 13), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 14), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 15), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 16), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 17), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 18), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 19), Map.of(), Map.of()) ); } @Test void getReportMonthForMultipleUsersWhenCurrentUserHasNoPermissionForAnyGivenOne() { - final List userIds = List.of( - new UserLocalId(1L), - new UserLocalId(2L) - ); + final UserLocalId localId_1 = new UserLocalId(1L); + final UserLocalId localId_2 = new UserLocalId(2L); + final List userIds = List.of(localId_1, localId_2); when(reportPermissionService.filterUserLocalIdsByCurrentUserHasPermissionFor(userIds)) .thenReturn(List.of()); @@ -85,65 +83,65 @@ void getReportMonthForMultipleUsersWhenCurrentUserHasNoPermissionForAnyGivenOne( assertThat(actual.weeks().get(0)).satisfies(week -> { assertThat(week.firstDateOfWeek()).isEqualTo(LocalDate.of(2023, 1, 30)); assertThat(week.reportDays()).containsExactly( - new ReportDay(LocalDate.of(2023, 1, 30), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 1, 31), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 1), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 2), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 3), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 4), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 5), PlannedWorkingHours.ZERO, List.of()) + new ReportDay(LocalDate.of(2023, 1, 30), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 1, 31), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 1), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 2), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 3), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 4), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 5), Map.of(), Map.of()) ); }); assertThat(actual.weeks().get(1)).satisfies(week -> { assertThat(week.firstDateOfWeek()).isEqualTo(LocalDate.of(2023, 2, 6)); assertThat(week.reportDays()).containsExactly( - new ReportDay(LocalDate.of(2023, 2, 6), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 7), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 8), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 9), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 10), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 11), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 12), PlannedWorkingHours.ZERO, List.of()) + new ReportDay(LocalDate.of(2023, 2, 6), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 7), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 8), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 9), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 10), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 11), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 12), Map.of(), Map.of()) ); }); assertThat(actual.weeks().get(2)).satisfies(week -> { assertThat(week.firstDateOfWeek()).isEqualTo(LocalDate.of(2023, 2, 13)); assertThat(week.reportDays()).containsExactly( - new ReportDay(LocalDate.of(2023, 2, 13), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 14), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 15), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 16), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 17), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 18), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 19), PlannedWorkingHours.ZERO, List.of()) + new ReportDay(LocalDate.of(2023, 2, 13), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 14), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 15), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 16), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 17), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 18), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 19), Map.of(), Map.of()) ); }); assertThat(actual.weeks().get(3)).satisfies(week -> { assertThat(week.firstDateOfWeek()).isEqualTo(LocalDate.of(2023, 2, 20)); assertThat(week.reportDays()).containsExactly( - new ReportDay(LocalDate.of(2023, 2, 20), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 21), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 22), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 23), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 24), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 25), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 26), PlannedWorkingHours.ZERO, List.of()) + new ReportDay(LocalDate.of(2023, 2, 20), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 21), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 22), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 23), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 24), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 25), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 26), Map.of(), Map.of()) ); }); assertThat(actual.weeks().get(4)).satisfies(week -> { assertThat(week.firstDateOfWeek()).isEqualTo(LocalDate.of(2023, 2, 27)); assertThat(week.reportDays()).containsExactly( - new ReportDay(LocalDate.of(2023, 2, 27), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 28), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 3, 1), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 3, 2), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 3, 3), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 3, 4), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 3, 5), PlannedWorkingHours.ZERO, List.of()) + new ReportDay(LocalDate.of(2023, 2, 27), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 2, 28), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 3, 1), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 3, 2), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 3, 3), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 3, 4), Map.of(), Map.of()), + new ReportDay(LocalDate.of(2023, 3, 5), Map.of(), Map.of()) ); }); } diff --git a/src/test/java/de/focusshift/zeiterfassung/report/ReportServiceRawTest.java b/src/test/java/de/focusshift/zeiterfassung/report/ReportServiceRawTest.java index 0d37a64b3..ec025dff4 100644 --- a/src/test/java/de/focusshift/zeiterfassung/report/ReportServiceRawTest.java +++ b/src/test/java/de/focusshift/zeiterfassung/report/ReportServiceRawTest.java @@ -24,6 +24,7 @@ import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; @@ -207,14 +208,15 @@ void ensureReportWeekWithTimeEntryTouchingNextDayIsReportedForStartingDate() { void ensureReportMonthFirstDayOfEveryWeekIsMonday() { final UserId userId = new UserId("batman"); - final User user = new User(userId, new UserLocalId(1L), "givenName", "familyName", new EMailAddress(""), Set.of()); + final UserLocalId localId = new UserLocalId(1L); + final User user = new User(userId, localId, "givenName", "familyName", new EMailAddress(""), Set.of()); when(userManagementService.findUserById(userId)).thenReturn(Optional.of(user)); when(userDateService.localDateToFirstDateOfWeek(LocalDate.of(2021, 1, 1))) .thenReturn(LocalDate.of(2020, 12, 28)); - when(timeEntryService.getEntries(LocalDate.of(2021, 1, 1), LocalDate.of(2021, 2, 1), userId)) - .thenReturn(List.of()); + when(timeEntryService.getEntriesByUserLocalIds(LocalDate.of(2021, 1, 1), LocalDate.of(2021, 2, 1), List.of(localId))) + .thenReturn(Map.of()); final ReportMonth actualReportMonth = sut.getReportMonth(YearMonth.of(2021, 1), userId); @@ -229,14 +231,15 @@ void ensureReportMonthFirstDayOfEveryWeekIsMonday() { void ensureReportMonthDecemberWithoutTimeEntries() { final UserId userId = new UserId("batman"); - final User user = new User(userId, new UserLocalId(1L), "givenName", "familyName", new EMailAddress(""), Set.of()); + final UserLocalId localId = new UserLocalId(1L); + final User user = new User(userId, localId, "givenName", "familyName", new EMailAddress(""), Set.of()); when(userManagementService.findUserById(userId)).thenReturn(Optional.of(user)); when(userDateService.localDateToFirstDateOfWeek(LocalDate.of(2021, 12, 1))) .thenReturn(LocalDate.of(2021, 11, 29)); - when(timeEntryService.getEntries(LocalDate.of(2021, 12, 1), LocalDate.of(2022, 1, 1), userId)) - .thenReturn(List.of()); + when(timeEntryService.getEntriesByUserLocalIds(LocalDate.of(2021, 12, 1), LocalDate.of(2022, 1, 1), List.of(localId))) + .thenReturn(Map.of()); final ReportMonth actualReportMonth = sut.getReportMonth(YearMonth.of(2021, 12), userId); @@ -257,7 +260,8 @@ void ensureReportMonthDecemberWithoutTimeEntries() { void ensureReportMonthDecemberWithOneTimeEntryAWeek() { final UserId userId = new UserId("batman"); - final User user = new User(userId, new UserLocalId(1L), "givenName", "familyName", new EMailAddress(""), Set.of()); + final UserLocalId localId = new UserLocalId(1L); + final User user = new User(userId, localId, "givenName", "familyName", new EMailAddress(""), Set.of()); when(userManagementService.findUserById(userId)).thenReturn(Optional.of(user)); final ZonedDateTime w1_d1_From = dateTime(2021, 1, 4, 1, 0); @@ -291,8 +295,8 @@ void ensureReportMonthDecemberWithOneTimeEntryAWeek() { when(userDateService.localDateToFirstDateOfWeek(LocalDate.of(2021, 1, 1))) .thenReturn(LocalDate.of(2020, 12, 28)); - when(timeEntryService.getEntries(LocalDate.of(2021, 1, 1), LocalDate.of(2021, 2, 1), userId)) - .thenReturn(List.of(w1_d1_TimeEntry, w1_d2_TimeEntry, w2_d1_TimeEntry, w2_d2_TimeEntry, w3_d1_TimeEntry, w3_d2_TimeEntry, w4_d1_TimeEntry, w4_d2_TimeEntry)); + when(timeEntryService.getEntriesByUserLocalIds(LocalDate.of(2021, 1, 1), LocalDate.of(2021, 2, 1), List.of(localId))) + .thenReturn(Map.of(localId, List.of(w1_d1_TimeEntry, w1_d2_TimeEntry, w2_d1_TimeEntry, w2_d2_TimeEntry, w3_d1_TimeEntry, w3_d2_TimeEntry, w4_d1_TimeEntry, w4_d2_TimeEntry))); when(userManagementService.findAllUsersByIds(List.of(userId))).thenReturn(List.of(user)); diff --git a/src/test/java/de/focusshift/zeiterfassung/report/ReportWeekTest.java b/src/test/java/de/focusshift/zeiterfassung/report/ReportWeekTest.java index 0402dbac0..6f37691cf 100644 --- a/src/test/java/de/focusshift/zeiterfassung/report/ReportWeekTest.java +++ b/src/test/java/de/focusshift/zeiterfassung/report/ReportWeekTest.java @@ -14,6 +14,7 @@ import java.time.LocalTime; import java.time.ZonedDateTime; import java.util.List; +import java.util.Map; import java.util.Set; import static java.time.ZoneOffset.UTC; @@ -30,13 +31,15 @@ void ensureAverageDayWorkDurationIsEmptyWhenNoReportDays() { @Test void ensureAverageDayWorkDurationIsEmptyWhenAllReportDaysHasNotPlannedWorkingHours() { + final UserLocalId userLocalId = new UserLocalId(1L); + final ReportWeek sut = new ReportWeek(LocalDate.of(2023, 2, 13), List.of( - new ReportDay(LocalDate.of(2023, 2, 13), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 14), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 15), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 16), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 17), PlannedWorkingHours.ZERO, List.of()), - new ReportDay(LocalDate.of(2023, 2, 18), PlannedWorkingHours.ZERO, List.of()) + new ReportDay(LocalDate.of(2023, 2, 13), Map.of(userLocalId, PlannedWorkingHours.ZERO), Map.of(userLocalId, List.of())), + new ReportDay(LocalDate.of(2023, 2, 14), Map.of(userLocalId, PlannedWorkingHours.ZERO), Map.of(userLocalId, List.of())), + new ReportDay(LocalDate.of(2023, 2, 15), Map.of(userLocalId, PlannedWorkingHours.ZERO), Map.of(userLocalId, List.of())), + new ReportDay(LocalDate.of(2023, 2, 16), Map.of(userLocalId, PlannedWorkingHours.ZERO), Map.of(userLocalId, List.of())), + new ReportDay(LocalDate.of(2023, 2, 17), Map.of(userLocalId, PlannedWorkingHours.ZERO), Map.of(userLocalId, List.of())), + new ReportDay(LocalDate.of(2023, 2, 18), Map.of(userLocalId, PlannedWorkingHours.ZERO), Map.of(userLocalId, List.of())) )); assertThat(sut.averageDayWorkDuration()).isEqualTo(WorkDuration.ZERO); @@ -59,23 +62,23 @@ void ensureAverageDayWorkDuration() { final LocalDate sunday = monday.plusDays(6); final ReportWeek sut = new ReportWeek(monday, List.of( - new ReportDay(monday, PlannedWorkingHours.EIGHT, List.of( + new ReportDay(monday, Map.of(user.localId(), PlannedWorkingHours.EIGHT), Map.of(user.localId(), List.of( new ReportDayEntry(user, "", ZonedDateTime.of(LocalDateTime.of(monday, timeStart), UTC), ZonedDateTime.of(LocalDateTime.of(monday, timeEnd), UTC), false) - )), - new ReportDay(tuesday, PlannedWorkingHours.EIGHT, List.of( + ))), + new ReportDay(tuesday, Map.of(user.localId(), PlannedWorkingHours.EIGHT), Map.of(user.localId(), List.of( new ReportDayEntry(user, "", ZonedDateTime.of(LocalDateTime.of(tuesday, timeStart), UTC), ZonedDateTime.of(LocalDateTime.of(tuesday, timeEnd), UTC), false) - )), - new ReportDay(wednesday, PlannedWorkingHours.EIGHT, List.of( + ))), + new ReportDay(wednesday, Map.of(user.localId(), PlannedWorkingHours.EIGHT), Map.of(user.localId(), List.of( new ReportDayEntry(user, "", ZonedDateTime.of(LocalDateTime.of(wednesday, timeStart), UTC), ZonedDateTime.of(LocalDateTime.of(wednesday, timeEnd), UTC), false) - )), - new ReportDay(thursday, PlannedWorkingHours.EIGHT, List.of( + ))), + new ReportDay(thursday, Map.of(user.localId(), PlannedWorkingHours.EIGHT), Map.of(user.localId(), List.of( new ReportDayEntry(user, "", ZonedDateTime.of(LocalDateTime.of(thursday, timeStart), UTC), ZonedDateTime.of(LocalDateTime.of(thursday, timeEnd), UTC), false) - )), - new ReportDay(friday, PlannedWorkingHours.EIGHT, List.of( + ))), + new ReportDay(friday, Map.of(user.localId(), PlannedWorkingHours.EIGHT), Map.of(user.localId(), List.of( new ReportDayEntry(user, "", ZonedDateTime.of(LocalDateTime.of(friday, timeStart), UTC), ZonedDateTime.of(LocalDateTime.of(friday, timeEnd), UTC), false) - )), - new ReportDay(saturday, PlannedWorkingHours.ZERO, List.of()), - new ReportDay(sunday, PlannedWorkingHours.ZERO, List.of()) + ))), + new ReportDay(saturday, Map.of(user.localId(), PlannedWorkingHours.ZERO), Map.of(user.localId(), List.of())), + new ReportDay(sunday, Map.of(user.localId(), PlannedWorkingHours.ZERO), Map.of(user.localId(), List.of())) )); final WorkDuration actual = sut.averageDayWorkDuration(); diff --git a/src/test/java/de/focusshift/zeiterfassung/timeentry/TimeEntryServiceImplTest.java b/src/test/java/de/focusshift/zeiterfassung/timeentry/TimeEntryServiceImplTest.java index db06d2091..8db02afd6 100644 --- a/src/test/java/de/focusshift/zeiterfassung/timeentry/TimeEntryServiceImplTest.java +++ b/src/test/java/de/focusshift/zeiterfassung/timeentry/TimeEntryServiceImplTest.java @@ -772,7 +772,15 @@ void ensureGetEntriesForAllUsers() { when(timeEntryRepository.findAllByStartGreaterThanEqualAndStartLessThan(from.atStartOfDay(UTC).toInstant(), toExclusive.atStartOfDay(UTC).toInstant())) .thenReturn(List.of(timeEntryEntity, timeEntryBreakEntity)); - final List actual = sut.getEntriesForAllUsers(from, toExclusive); + final UserLocalId batmanLocalId = new UserLocalId(1L); + final UserLocalId pinguinLocalId = new UserLocalId(2L); + final User batman = new User(new UserId("batman"), batmanLocalId, "Bruce", "Wayne", new EMailAddress("batman@example.org"), Set.of()); + final User pinguin = new User(new UserId("pinguin"), pinguinLocalId, "ping", "uin", new EMailAddress("pinguin@example.org"), Set.of()); + + when(userManagementService.findAllUsersByIds(Set.of(new UserId("batman"), new UserId("pinguin")))) + .thenReturn(List.of(batman, pinguin)); + + final Map> actual = sut.getEntriesForAllUsers(from, toExclusive); final ZonedDateTime expectedStart = ZonedDateTime.of(entryStart, ZONE_ID_UTC); final ZonedDateTime expectedEnd = ZonedDateTime.of(entryEnd, ZONE_ID_UTC); @@ -780,10 +788,17 @@ void ensureGetEntriesForAllUsers() { final ZonedDateTime expectedBreakStart = ZonedDateTime.of(entryBreakStart, ZONE_ID_UTC); final ZonedDateTime expectedBreakEnd = ZonedDateTime.of(entryBreakEnd, ZONE_ID_UTC); - assertThat(actual).containsExactly( - new TimeEntry(new TimeEntryId(1L), new UserId("batman"), "hard work", expectedStart, expectedEnd, false), - new TimeEntry(new TimeEntryId(2L), new UserId("pinguin"), "deserved break", expectedBreakStart, expectedBreakEnd, true) - ); + assertThat(actual).hasSize(2); + assertThat(actual).hasEntrySatisfying(batmanLocalId, timeEntries -> { + assertThat(timeEntries).containsExactly( + new TimeEntry(new TimeEntryId(1L), new UserId("batman"), "hard work", expectedStart, expectedEnd, false) + ); + }); + assertThat(actual).hasEntrySatisfying(pinguinLocalId, timeEntries -> { + assertThat(timeEntries).containsExactly( + new TimeEntry(new TimeEntryId(2L), new UserId("pinguin"), "deserved break", expectedBreakStart, expectedBreakEnd, true) + ); + }); } @Test @@ -802,16 +817,16 @@ void ensureGetEntriesByUserLocalIds() { final LocalDateTime entryStart = LocalDateTime.of(from, LocalTime.of(10, 0, 0)); final LocalDateTime entryEnd = LocalDateTime.of(toExclusive, LocalTime.of(12, 0, 0)); - final TimeEntryEntity timeEntryEntity = new TimeEntryEntity(1L, "batman", "hard work", entryStart.toInstant(UTC), ZONE_ID_UTC, entryEnd.toInstant(UTC), ZONE_ID_UTC, now, false); + final TimeEntryEntity timeEntryEntity = new TimeEntryEntity(1L, "uuid-1", "hard work", entryStart.toInstant(UTC), ZONE_ID_UTC, entryEnd.toInstant(UTC), ZONE_ID_UTC, now, false); final LocalDateTime entryBreakStart = LocalDateTime.of(from, LocalTime.of(12, 0, 0)); final LocalDateTime entryBreakEnd = LocalDateTime.of(toExclusive, LocalTime.of(13, 0, 0)); - final TimeEntryEntity timeEntryBreakEntity = new TimeEntryEntity(2L, "robin", "deserved break", entryBreakStart.toInstant(UTC), ZONE_ID_UTC, entryBreakEnd.toInstant(UTC), ZONE_ID_UTC, now, true); + final TimeEntryEntity timeEntryBreakEntity = new TimeEntryEntity(2L, "uuid-2", "deserved break", entryBreakStart.toInstant(UTC), ZONE_ID_UTC, entryBreakEnd.toInstant(UTC), ZONE_ID_UTC, now, true); when(timeEntryRepository.findAllByOwnerIsInAndStartGreaterThanEqualAndStartLessThan(List.of("uuid-1", "uuid-2"), from.atStartOfDay(UTC).toInstant(), toExclusive.atStartOfDay(UTC).toInstant())) .thenReturn(List.of(timeEntryEntity, timeEntryBreakEntity)); - final List actual = sut.getEntriesByUserLocalIds(from, toExclusive, List.of(batmanLocalId, robinLocalId)); + final Map> actual = sut.getEntriesByUserLocalIds(from, toExclusive, List.of(batmanLocalId, robinLocalId)); final ZonedDateTime expectedStart = ZonedDateTime.of(entryStart, ZONE_ID_UTC); final ZonedDateTime expectedEnd = ZonedDateTime.of(entryEnd, ZONE_ID_UTC); @@ -819,10 +834,17 @@ void ensureGetEntriesByUserLocalIds() { final ZonedDateTime expectedBreakStart = ZonedDateTime.of(entryBreakStart, ZONE_ID_UTC); final ZonedDateTime expectedBreakEnd = ZonedDateTime.of(entryBreakEnd, ZONE_ID_UTC); - assertThat(actual).containsExactly( - new TimeEntry(new TimeEntryId(1L), new UserId("batman"), "hard work", expectedStart, expectedEnd, false), - new TimeEntry(new TimeEntryId(2L), new UserId("robin"), "deserved break", expectedBreakStart, expectedBreakEnd, true) - ); + assertThat(actual).hasSize(2); + assertThat(actual).hasEntrySatisfying(batmanLocalId, timeEntries -> { + assertThat(timeEntries).containsExactly( + new TimeEntry(new TimeEntryId(1L), new UserId("uuid-1"), "hard work", expectedStart, expectedEnd, false) + ); + }); + assertThat(actual).hasEntrySatisfying(robinLocalId, timeEntries -> { + assertThat(timeEntries).containsExactly( + new TimeEntry(new TimeEntryId(2L), new UserId("uuid-2"), "deserved break", expectedBreakStart, expectedBreakEnd, true) + ); + }); } @Test