Repository: urlaubsverwaltung/urlaubsverwaltung (java)

Issue:
Krankmeldungen fehlerhaft, wenn am 24.12. bzw. 31.12. eine halbe Krankmeldung eingereicht wurde und Arbeitsdauer der Tage halbtags ist
Wenn eine Krankmeldung am 24.12. oder am 31.12. halbtägig beantragt wurde, dann halbieren wir den halben Tag erneut. Dies bedeutet, dass jede Person, welche am 24.12. bzw. am 31.12. einen halben Krankheitstag hat, je einen viertel Tag in der Statistik zurückbekommt.

Diese fehlerhafte Berechnung ist nicht nur in den Statistiken unter "Krankmeldung" zu sehen, sondern auch in der Übersicht unter Krankmeldungen.

Siehe dazu auch #5068

https://github.com/user-attachments/assets/1fb90924-21a2-49c9-8a0f-d8660f7f0ca0

<!--

Yay, thanks for your contribution. Your awesome 🥰

Please check the issue tracker first. Maybe someone else has reported the same ugly bug.
Or just file an issue, I'm just a hint not your boss.

Please fill the sections below and delete everything you don't consider valuable currently.

-->

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
 - OS: [e.g. iOS]
 - Browser [e.g. chrome, safari]
 - Version [e.g. 22]

**Smartphone (please complete the following information):**
 - Device: [e.g. iPhone6]
 - OS: [e.g. iOS8.1]
 - Browser [e.g. stock browser, safari]
 - Version [e.g. 22]

**Additional context**
Add any other context about the problem here.


Pull request description:
sick note: do not reduce half day on christmas eve and new years eve
closes #5088 

<!--

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/sicknote/sicknote/SickNote.java b/src/main/java/org/synyx/urlaubsverwaltung/sicknote/sicknote/SickNote.java
index a35281ad6..bc713b4eb 100644
--- a/src/main/java/org/synyx/urlaubsverwaltung/sicknote/sicknote/SickNote.java
+++ b/src/main/java/org/synyx/urlaubsverwaltung/sicknote/sicknote/SickNote.java
@@ -139,7 +139,8 @@ public class SickNote {
         BigDecimal workingTimeSum = BigDecimal.ZERO;
         for (LocalDate localDate : dateRange) {
             final BigDecimal workingTime = workingTimeCalendar.workingTime(localDate).orElse(BigDecimal.ZERO);
-            if (dayLength.isHalfDay()) {
+            final WorkingTimeCalendar.WorkingDayInformation workingDayInformation = workingTimeCalendar.workingDays().get(dateRange.startDate());
+            if (dayLength.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/sicknote/sicknote/SickNoteTest.java b/src/test/java/org/synyx/urlaubsverwaltung/sicknote/sicknote/SickNoteTest.java
index a3efde544..fac242638 100644
--- a/src/test/java/org/synyx/urlaubsverwaltung/sicknote/sicknote/SickNoteTest.java
+++ b/src/test/java/org/synyx/urlaubsverwaltung/sicknote/sicknote/SickNoteTest.java
@@ -23,6 +23,8 @@ import static java.time.Month.JUNE;
 import static java.time.ZoneOffset.UTC;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.synyx.urlaubsverwaltung.period.DayLength.FULL;
+import static org.synyx.urlaubsverwaltung.period.DayLength.MORNING;
+import static org.synyx.urlaubsverwaltung.workingtime.WorkingTimeCalendar.WorkingDayInformation.WorkingTimeCalendarEntryType.PUBLIC_HOLIDAY;
 import static org.synyx.urlaubsverwaltung.workingtime.WorkingTimeCalendar.WorkingDayInformation.WorkingTimeCalendarEntryType.WORKDAY;
 
 class SickNoteTest {
@@ -33,7 +35,7 @@ class SickNoteTest {
         final Map<LocalDate, WorkingDayInformation> workingTimes = buildWorkingTimeByDate(
             LocalDate.of(2022, JUNE, 1),
             LocalDate.of(2022, JUNE, 30),
-            (date) -> new WorkingDayInformation(FULL, WORKDAY, WORKDAY)
+            date -> new WorkingDayInformation(FULL, WORKDAY, WORKDAY)
         );
         final WorkingTimeCalendar workingTimeCalendar = new WorkingTimeCalendar(workingTimes);
 
@@ -56,7 +58,7 @@ class SickNoteTest {
         final Map<LocalDate, WorkingDayInformation> workingTimes = buildWorkingTimeByDate(
             LocalDate.of(2022, JUNE, 1),
             LocalDate.of(2022, JUNE, 30),
-            (date) -> new WorkingDayInformation(FULL, WORKDAY, WORKDAY)
+            date -> new WorkingDayInformation(FULL, WORKDAY, WORKDAY)
         );
         final WorkingTimeCalendar workingTimeCalendar = new WorkingTimeCalendar(workingTimes);
 
@@ -72,6 +74,29 @@ class SickNoteTest {
         assertThat(actual).isEqualTo(BigDecimal.valueOf(0.5));
     }
 
+    @ParameterizedTest
+    @EnumSource(value = DayLength.class, names = {"MORNING", "NOON"})
+    void ensureWorkingTimeForHalfDaySickNoteAtHalfPublicHoliday(DayLength givenDayLength) {
+
+        final LocalDate christmas = LocalDate.of(2022, DECEMBER, 24);
+        final Map<LocalDate, WorkingDayInformation> workingTimes = buildWorkingTimeByDate(
+            christmas,
+            christmas,
+            date -> new WorkingDayInformation(MORNING, WORKDAY, PUBLIC_HOLIDAY)
+        );
+        final WorkingTimeCalendar workingTimeCalendar = new WorkingTimeCalendar(workingTimes);
+
+        final SickNote sickNote = SickNote.builder()
+            .dayLength(givenDayLength)
+            .startDate(christmas)
+            .endDate(christmas)
+            .workingTimeCalendar(workingTimeCalendar)
+            .build();
+
+        final BigDecimal actual = sickNote.getWorkDays(christmas, christmas);
+        assertThat(actual).isEqualTo(BigDecimal.valueOf(0.5));
+    }
+
     @Test
     void ensureGetWorkDaysWhenDateRangeIsAfterAubDate() {
 
@@ -104,7 +129,7 @@ class SickNoteTest {
         final Map<LocalDate, WorkingDayInformation> workingTimes = buildWorkingTimeByDate(
             LocalDate.of(2022, JUNE, 1),
             LocalDate.of(2022, JUNE, 30),
-            (date) -> new WorkingDayInformation(FULL, WORKDAY, WORKDAY)
+            date -> new WorkingDayInformation(FULL, WORKDAY, WORKDAY)
         );
         final WorkingTimeCalendar workingTimeCalendar = new WorkingTimeCalendar(workingTimes);
 
@@ -129,7 +154,7 @@ class SickNoteTest {
         final Map<LocalDate, WorkingDayInformation> workingTimes = buildWorkingTimeByDate(
             LocalDate.of(2022, JUNE, 1),
             LocalDate.of(2022, JUNE, 30),
-            (date) -> new WorkingDayInformation(FULL, WORKDAY, WORKDAY)
+            date -> new WorkingDayInformation(FULL, WORKDAY, WORKDAY)
         );
         final WorkingTimeCalendar workingTimeCalendar = new WorkingTimeCalendar(workingTimes);
 
@@ -279,7 +304,7 @@ class SickNoteTest {
         final Map<LocalDate, WorkingDayInformation> workingTimes = buildWorkingTimeByDate(
             LocalDate.of(2022, JANUARY, 1),
             LocalDate.of(2022, DECEMBER, 31),
-            (date) -> new WorkingDayInformation(FULL, WORKDAY, WORKDAY)
+            date -> new WorkingDayInformation(FULL, WORKDAY, WORKDAY)
         );
         final WorkingTimeCalendar workingTimeCalendar = new WorkingTimeCalendar(workingTimes);