20
20
import java .time .ZonedDateTime ;
21
21
import java .util .ArrayList ;
22
22
import java .util .Collection ;
23
+ import java .util .HashMap ;
23
24
import java .util .List ;
24
25
import java .util .Map ;
25
26
import java .util .Optional ;
26
27
import java .util .function .Function ;
27
28
import java .util .stream .IntStream ;
28
- import java .util .stream .Stream ;
29
29
30
30
import static java .lang .invoke .MethodHandles .lookup ;
31
31
import static java .time .temporal .ChronoUnit .MONTHS ;
32
- import static java .util .Collections .emptyList ;
33
32
import static java .util .stream .Collectors .groupingBy ;
34
33
import static java .util .stream .Collectors .toMap ;
35
34
@@ -60,9 +59,11 @@ ReportWeek getReportWeek(Year year, int week, UserId userId) {
60
59
final User user = userManagementService .findUserById (userId )
61
60
.orElseThrow (() -> new IllegalStateException ("could not find user id=%s" .formatted (userId )));
62
61
62
+ final UserLocalId userLocalId = user .localId ();
63
+
63
64
return createReportWeek (year , week ,
64
- period -> timeEntryService .getEntries (period .from (), period .toExclusive (), userId ),
65
- period -> workingTimeCalendarService .getWorkingTimes (period .from (), period .toExclusive (), List .of (user . localId () )));
65
+ period -> Map . of ( userLocalId , timeEntryService .getEntries (period .from (), period .toExclusive (), userId ) ),
66
+ period -> workingTimeCalendarService .getWorkingTimes (period .from (), period .toExclusive (), List .of (userLocalId )));
66
67
}
67
68
68
69
ReportWeek getReportWeek (Year year , int week , List <UserLocalId > userLocalIds ) {
@@ -82,8 +83,10 @@ ReportMonth getReportMonth(YearMonth yearMonth, UserId userId) {
82
83
final User user = userManagementService .findUserById (userId )
83
84
.orElseThrow (() -> new IllegalStateException ("could not find user id=%s" .formatted (userId )));
84
85
86
+ final UserLocalId userLocalId = user .localId ();
87
+
85
88
return createReportMonth (yearMonth ,
86
- period -> timeEntryService .getEntries (period .from (), period .toExclusive (), userId ),
89
+ period -> timeEntryService .getEntriesByUserLocalIds (period .from (), period .toExclusive (), List . of ( userLocalId ) ),
87
90
period -> workingTimeCalendarService .getWorkingTimes (period .from (), period .toExclusive (), List .of (user .localId ())));
88
91
}
89
92
@@ -100,50 +103,61 @@ ReportMonth getReportMonthForAllUsers(YearMonth yearMonth) {
100
103
}
101
104
102
105
private ReportWeek createReportWeek (Year year , int week ,
103
- Function <Period , List <TimeEntry >> timeEntriesProvider ,
106
+ Function <Period , Map < UserLocalId , List <TimeEntry > >> timeEntriesProvider ,
104
107
Function <Period , Map <UserLocalId , WorkingTimeCalendar >> workingTimeCalendarProvider ) {
105
108
106
109
final LocalDate firstDateOfWeek = userDateService .firstDayOfWeek (year , week );
107
110
108
111
final Period period = new Period (firstDateOfWeek , firstDateOfWeek .plusWeeks (1 ));
109
112
110
- final List <TimeEntry > timeEntries = timeEntriesProvider .apply (period );
111
- final Map <UserId , User > userById = userByIdForTimeEntries (timeEntries );
113
+ final Map < UserLocalId , List <TimeEntry > > timeEntries = timeEntriesProvider .apply (period );
114
+ final Map <UserId , User > userById = userByIdForTimeEntries (timeEntries . values (). stream (). flatMap ( Collection :: stream ). toList () );
112
115
113
- final Collection < WorkingTimeCalendar > workingTimeCalendars = workingTimeCalendarProvider .apply (period ). values ( );
114
- final Function <LocalDate , PlannedWorkingHours > plannedWorkingTimeByDate = plannedWorkingTimeForDate (workingTimeCalendars );
116
+ final Map < UserLocalId , WorkingTimeCalendar > workingTimeCalendars = workingTimeCalendarProvider .apply (period );
117
+ final Function <LocalDate , Map < UserLocalId , PlannedWorkingHours > > plannedWorkingTimeByDate = plannedWorkingTimeForDate (workingTimeCalendars );
115
118
116
119
return reportWeek (firstDateOfWeek , timeEntries , userById , plannedWorkingTimeByDate );
117
120
}
118
121
119
122
private ReportMonth createReportMonth (YearMonth yearMonth ,
120
- Function <Period , List <TimeEntry >> timeEntriesProvider ,
123
+ Function <Period , Map < UserLocalId , List <TimeEntry > >> timeEntriesProvider ,
121
124
Function <Period , Map <UserLocalId , WorkingTimeCalendar >> workingTimeCalendarProvider ) {
122
125
123
126
final LocalDate firstOfMonth = LocalDate .of (yearMonth .getYear (), yearMonth .getMonthValue (), 1 );
124
127
125
128
final Period period = new Period (firstOfMonth , firstOfMonth .plusMonths (1 ));
126
129
127
- final List <TimeEntry > timeEntries = timeEntriesProvider .apply (period );
128
- final Map <UserId , User > userById = userByIdForTimeEntries (timeEntries );
130
+ final Map < UserLocalId , List <TimeEntry >> timeEntriesByUserId = timeEntriesProvider .apply (period );
131
+ final Map <UserId , User > userById = userByIdForTimeEntries (timeEntriesByUserId . values (). stream (). flatMap ( Collection :: stream ). toList () );
129
132
130
- final Collection < WorkingTimeCalendar > workingTimeCalendars = workingTimeCalendarProvider .apply (period ). values ( );
131
- final Function <LocalDate , PlannedWorkingHours > plannedWorkingTimeForDate = plannedWorkingTimeForDate (workingTimeCalendars );
133
+ final Map < UserLocalId , WorkingTimeCalendar > workingTimeCalendars = workingTimeCalendarProvider .apply (period );
134
+ final Function <LocalDate , Map < UserLocalId , PlannedWorkingHours > > plannedWorkingTimeForDate = plannedWorkingTimeForDate (workingTimeCalendars );
132
135
133
- List <ReportWeek > weeks = getStartOfWeekDatesForMonth (yearMonth )
136
+ final List <ReportWeek > weeks = getStartOfWeekDatesForMonth (yearMonth )
134
137
.stream ()
135
- .map (startOfWeekDate -> reportWeek (startOfWeekDate , timeEntries , userById , plannedWorkingTimeForDate ))
138
+ .map (startOfWeekDate ->
139
+ reportWeek (
140
+ startOfWeekDate ,
141
+ timeEntriesByUserId ,
142
+ userById ,
143
+ plannedWorkingTimeForDate
144
+ )
145
+ )
136
146
.toList ();
137
147
138
148
return new ReportMonth (yearMonth , weeks );
139
149
}
140
150
141
- private Function <LocalDate , PlannedWorkingHours > plannedWorkingTimeForDate (Collection <WorkingTimeCalendar > workingTimeCalendars ) {
142
- return date -> workingTimeCalendars .stream ()
143
- .map (cal -> cal .plannedWorkingHours (date ))
144
- .filter (Optional ::isPresent )
145
- .map (Optional ::get )
146
- .reduce (PlannedWorkingHours .ZERO , PlannedWorkingHours ::plus );
151
+ private Function <LocalDate , Map <UserLocalId , PlannedWorkingHours >> plannedWorkingTimeForDate (Map <UserLocalId , WorkingTimeCalendar > workingTimeCalendars ) {
152
+ return date ->
153
+ workingTimeCalendars .entrySet ()
154
+ .stream ()
155
+ .collect (
156
+ toMap (
157
+ Map .Entry ::getKey ,
158
+ entry -> entry .getValue ().plannedWorkingHours (date ).orElse (PlannedWorkingHours .ZERO )
159
+ )
160
+ );
147
161
}
148
162
149
163
private Map <UserId , User > userByIdForTimeEntries (List <TimeEntry > timeEntries ) {
@@ -153,19 +167,42 @@ private Map<UserId, User> userByIdForTimeEntries(List<TimeEntry> timeEntries) {
153
167
.collect (toMap (User ::id , Function .identity ()));
154
168
}
155
169
156
- private ReportWeek reportWeek (LocalDate startOfWeekDate , List <TimeEntry > timeEntries , Map <UserId , User > userById ,
157
- Function <LocalDate , PlannedWorkingHours > plannedWorkingHoursProvider ) {
170
+ private ReportWeek reportWeek (LocalDate startOfWeekDate ,
171
+ Map <UserLocalId , List <TimeEntry >> timeEntriesByUserLocalId ,
172
+ Map <UserId , User > userById ,
173
+ Function <LocalDate , Map <UserLocalId , PlannedWorkingHours >> plannedWorkingHoursProvider ) {
158
174
159
- final Map <LocalDate , List <ReportDayEntry >> reportDayEntriesByDate = timeEntries
160
- .stream ()
161
- .flatMap (timeEntry -> timeEntryToReportDayEntries (timeEntry , userById ::get ))
162
- .collect (groupingBy (reportDayEntry -> reportDayEntry .start ().toLocalDate ()));
175
+ final Map <LocalDate , Map <UserLocalId , List <ReportDayEntry >>> reportEntriesByDate = new HashMap <>();
176
+ for (Map .Entry <UserLocalId , List <TimeEntry >> entry : timeEntriesByUserLocalId .entrySet ()) {
177
+
178
+ final UserLocalId userLocalId = entry .getKey ();
179
+
180
+ final Map <LocalDate , List <ReportDayEntry >> collect = entry .getValue ()
181
+ .stream ()
182
+ .map (t -> timeEntryToReportDayEntry (t , userById ::get ))
183
+ .filter (Optional ::isPresent )
184
+ .map (Optional ::get )
185
+ .collect (groupingBy (report -> report .start ().toLocalDate ()));
186
+
187
+ for (Map .Entry <LocalDate , List <ReportDayEntry >> localDateListEntry : collect .entrySet ()) {
188
+ reportEntriesByDate .compute (localDateListEntry .getKey (), (localDate , userLocalIdListMap ) -> {
189
+ final Map <UserLocalId , List <ReportDayEntry >> map = userLocalIdListMap == null ? new HashMap <>() : userLocalIdListMap ;
190
+ map .put (userLocalId , collect .get (localDate ));
191
+ return map ;
192
+ });
193
+ }
194
+ }
163
195
164
- final Function <LocalDate , List <ReportDayEntry >> resolveReportDayEntries =
165
- (LocalDate date ) -> reportDayEntriesByDate .getOrDefault (date , emptyList ());
196
+ final Function <LocalDate , Map < UserLocalId , List <ReportDayEntry > >> resolveReportDayEntries =
197
+ (LocalDate date ) -> reportEntriesByDate .getOrDefault (date , Map . of ());
166
198
167
199
final List <ReportDay > reportDays = IntStream .rangeClosed (0 , 6 )
168
- .mapToObj (daysToAdd -> toReportDay (startOfWeekDate .plusDays (daysToAdd ), plannedWorkingHoursProvider , resolveReportDayEntries ))
200
+ .mapToObj (daysToAdd ->
201
+ toReportDay (
202
+ startOfWeekDate .plusDays (daysToAdd ),
203
+ plannedWorkingHoursProvider ,
204
+ resolveReportDayEntries
205
+ ))
169
206
.toList ();
170
207
171
208
return new ReportWeek (startOfWeekDate , reportDays );
@@ -185,7 +222,7 @@ private List<LocalDate> getStartOfWeekDatesForMonth(YearMonth yearMonth) {
185
222
return startOfWeekDates ;
186
223
}
187
224
188
- private static Stream <ReportDayEntry > timeEntryToReportDayEntries (TimeEntry timeEntry , Function <UserId , User > userProvider ) {
225
+ private static Optional <ReportDayEntry > timeEntryToReportDayEntry (TimeEntry timeEntry , Function <UserId , User > userProvider ) {
189
226
190
227
final String comment = timeEntry .comment ();
191
228
final ZonedDateTime startDateTime = timeEntry .start ();
@@ -194,16 +231,16 @@ private static Stream<ReportDayEntry> timeEntryToReportDayEntries(TimeEntry time
194
231
final User user = userProvider .apply (timeEntry .userId ());
195
232
if (user == null ) {
196
233
LOG .info ("could not find user with id={} for timeEntry={} while generating report." , timeEntry .userId (), timeEntry .id ());
197
- return Stream .empty ();
234
+ return Optional .empty ();
198
235
}
199
236
200
237
final ReportDayEntry first = new ReportDayEntry (user , comment , startDateTime , endDateTime , timeEntry .isBreak ());
201
- return Stream .of (first );
238
+ return Optional .of (first );
202
239
}
203
240
204
241
private static ReportDay toReportDay (LocalDate date ,
205
- Function <LocalDate , PlannedWorkingHours > plannedWorkingHoursProvider ,
206
- Function <LocalDate , List <ReportDayEntry >> resolveReportDayEntries ) {
242
+ Function <LocalDate , Map < UserLocalId , PlannedWorkingHours > > plannedWorkingHoursProvider ,
243
+ Function <LocalDate , Map < UserLocalId , List <ReportDayEntry > >> resolveReportDayEntries ) {
207
244
208
245
return new ReportDay (date , plannedWorkingHoursProvider .apply (date ), resolveReportDayEntries .apply (date ));
209
246
}
0 commit comments