Repository: urlaubsverwaltung/urlaubsverwaltung
Pull request #5075 (2025-01-13 10:15:29)

Absence statistic: Check if workingDays and workingDayInformation are not null
<!--

Thanks for contributing to the Urlaubsverwaltung.
Please review the following notes before submitting you pull request.

Please look for other issues or pull requests which already work on this topic. Is somebody already on it? Do you need to synchronize?

# Security Vulnerabilities

🛑 STOP! 🛑 If your contribution fixes a security vulnerability, please do not submit it.
Instead, please open a report of a security vulnerability via
[Report a security vulnerability](https://github.com/urlaubsverwaltung/urlaubsverwaltung/security/advisories/new)


# Describing Your Changes

If, having reviewed the notes above, you're ready to submit your pull request, please
provide a brief description of the proposed changes.

If they:
 🐞 fix a bug, please describe the broken behaviour and how the changes fix it.
    Please label with 'type: bug' and 'status: new'
    
 🎁 make an enhancement, please describe the new functionality and why you believe it's useful.
    Please label with 'type: enhancement' and 'status: new'
 
If your pull request relates to any existing issues,
please reference them by using the issue number prefixed with #.

-->



Patch:
diff --git a/src/main/java/org/synyx/urlaubsverwaltung/account/VacationDaysService.java b/src/main/java/org/synyx/urlaubsverwaltung/account/VacationDaysService.java
index 3250bf05b..f20bb5904 100644
--- a/src/main/java/org/synyx/urlaubsverwaltung/account/VacationDaysService.java
+++ b/src/main/java/org/synyx/urlaubsverwaltung/account/VacationDaysService.java
@@ -227,7 +227,7 @@ public class VacationDaysService {
         final WorkingTimeCalendar.WorkingDayInformation workingDayInformation = workingTimeCalendar.workingDays().get(application.getStartDate());
 
         final UsedVacationDaysDateRange dateRangeUsedVacationDays;
-        if (application.getDayLength().isHalfDay() && !workingDayInformation.hasHalfDayPublicHoliday()) {
+        if (application.getDayLength().isHalfDay() && workingDayInformation != null && !workingDayInformation.hasHalfDayPublicHoliday()) {
             // halfDay application is only possible for one localDate.
             // so we can safely divide the calculated workDays by 2.
             dateRangeUsedVacationDays = new UsedVacationDaysDateRange(divideBy2(dateRangeWorkDaysCountBeforeExpiryDate), divideBy2(dateRangeWorkDaysCountAfterExpiryDate));
@@ -247,7 +247,7 @@ public class VacationDaysService {
         }
 
         final UsedVacationDaysYear yearUsedVacationDays;
-        if (application.getDayLength().isHalfDay() && !workingDayInformation.hasHalfDayPublicHoliday()) {
+        if (application.getDayLength().isHalfDay() && workingDayInformation != null && !workingDayInformation.hasHalfDayPublicHoliday()) {
             // halfDay application is only possible for one localDate.
             // so we can safely divide the calculated workDays by 2.
             yearUsedVacationDays = new UsedVacationDaysYear(divideBy2(yearWorkDaysCountBeforeExpiry), divideBy2(yearWorkDaysCountAfterExpiry));
diff --git a/src/main/java/org/synyx/urlaubsverwaltung/workingtime/WorkingTimeCalendar.java b/src/main/java/org/synyx/urlaubsverwaltung/workingtime/WorkingTimeCalendar.java
index 61612e9d6..abcf072bc 100644
--- a/src/main/java/org/synyx/urlaubsverwaltung/workingtime/WorkingTimeCalendar.java
+++ b/src/main/java/org/synyx/urlaubsverwaltung/workingtime/WorkingTimeCalendar.java
@@ -79,8 +79,8 @@ public record WorkingTimeCalendar(Map<LocalDate, WorkingDayInformation> workingD
             BigDecimal workingTimeSum = BigDecimal.ZERO;
             for (LocalDate localDate : overlap.get()) {
                 final BigDecimal workingTime = workingTime(localDate).orElse(BigDecimal.ZERO);
-                final boolean hasHalfDayPublicHoliday = this.workingDays().get(application.getStartDate()).hasHalfDayPublicHoliday();
-                if (application.getDayLength().isHalfDay() && !hasHalfDayPublicHoliday) {
+                final WorkingDayInformation workingDayInformation = this.workingDays().get(application.getStartDate());
+                if (application.getDayLength().isHalfDay() && workingDayInformation != null && !workingDayInformation.hasHalfDayPublicHoliday()) {
                     workingTimeSum = workingTimeSum.add(workingTime.divide(BigDecimal.valueOf(2), 1, RoundingMode.CEILING));
                 } else {
                     workingTimeSum = workingTimeSum.add(workingTime);


Test patch:
diff --git a/src/test/java/org/synyx/urlaubsverwaltung/workingtime/WorkingTimeCalendarTest.java b/src/test/java/org/synyx/urlaubsverwaltung/workingtime/WorkingTimeCalendarTest.java
index 13a337876..fe00dd75b 100644
--- a/src/test/java/org/synyx/urlaubsverwaltung/workingtime/WorkingTimeCalendarTest.java
+++ b/src/test/java/org/synyx/urlaubsverwaltung/workingtime/WorkingTimeCalendarTest.java
@@ -264,6 +264,24 @@ class WorkingTimeCalendarTest {
             assertThat(actual).isEqualTo(BigDecimal.valueOf(2));
         }
 
+        @Test
+        void ensureWorkingTimeForApplicationWithoutWorkingDayInformation() {
+
+            final LocalDate applicationDate = LocalDate.of(2023, 3, 31);
+            final DateRange aprilDateRange = new DateRange(LocalDate.of(2023, 3, 1), LocalDate.of(2023, 4, 30));
+
+            final WorkingTimeCalendar sut = new WorkingTimeCalendar(Map.of());
+
+            final Application application = new Application();
+            application.setStartDate(applicationDate);
+            application.setEndDate(applicationDate);
+            application.setDayLength(MORNING);
+
+            final BigDecimal actual = sut.workingTimeInDateRage(application, aprilDateRange);
+
+            assertThat(actual).isEqualTo(BigDecimal.ZERO);
+        }
+
         @ParameterizedTest
         @EnumSource(value = DayLength.class, names = {"MORNING", "NOON"})
         void ensureWorkingTimeForHalfDayApplicationAtHalfPublicHoliday(DayLength dayLength) {