Repository: urlaubsverwaltung/urlaubsverwaltung
Pull request #4743 (2024-06-21 08:01:05)

Hide submitted sick notes on application overview
if submission by user is not enabled

#4731

<!--

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/application/application/ApplicationForLeaveViewController.java b/src/main/java/org/synyx/urlaubsverwaltung/application/application/ApplicationForLeaveViewController.java
index 292ba7efe..8722e0672 100644
--- a/src/main/java/org/synyx/urlaubsverwaltung/application/application/ApplicationForLeaveViewController.java
+++ b/src/main/java/org/synyx/urlaubsverwaltung/application/application/ApplicationForLeaveViewController.java
@@ -12,6 +12,8 @@ import org.synyx.urlaubsverwaltung.department.DepartmentService;
 import org.synyx.urlaubsverwaltung.period.DayLength;
 import org.synyx.urlaubsverwaltung.person.Person;
 import org.synyx.urlaubsverwaltung.person.PersonService;
+import org.synyx.urlaubsverwaltung.settings.SettingsService;
+import org.synyx.urlaubsverwaltung.sicknote.settings.SickNoteSettings;
 import org.synyx.urlaubsverwaltung.sicknote.sicknote.SickNoteService;
 import org.synyx.urlaubsverwaltung.sicknote.sicknote.SickNoteStatus;
 import org.synyx.urlaubsverwaltung.util.DurationFormatter;
@@ -56,18 +58,20 @@ class ApplicationForLeaveViewController implements HasLaunchpad {
     private final WorkDaysCountService workDaysCountService;
     private final DepartmentService departmentService;
     private final PersonService personService;
+    private final SettingsService settingsService;
     private final Clock clock;
     private final MessageSource messageSource;
 
     @Autowired
     ApplicationForLeaveViewController(ApplicationService applicationService, SickNoteService sickNoteService, WorkDaysCountService workDaysCountService,
-                                      DepartmentService departmentService, PersonService personService, Clock clock,
+                                      DepartmentService departmentService, PersonService personService, SettingsService settingsService, Clock clock,
                                       MessageSource messageSource) {
         this.applicationService = applicationService;
         this.sickNoteService = sickNoteService;
         this.workDaysCountService = workDaysCountService;
         this.departmentService = departmentService;
         this.personService = personService;
+        this.settingsService = settingsService;
         this.clock = clock;
         this.messageSource = messageSource;
     }
@@ -100,13 +104,16 @@ class ApplicationForLeaveViewController implements HasLaunchpad {
     }
 
     private void prepareApplicationModels(Model model, Locale locale) {
+
+        final SickNoteSettings sickNoteSettings = settingsService.getSettings().getSickNoteSettings();
+
         final Person signedInUser = personService.getSignedInUser();
         model.addAttribute("signedInUser", signedInUser);
 
-        model.addAttribute("canAccessApplicationStatistics", signedInUser.hasRole(OFFICE) || signedInUser.hasRole(BOSS) || signedInUser.hasRole(DEPARTMENT_HEAD) || signedInUser.hasRole(SECOND_STAGE_AUTHORITY));
-        model.addAttribute("canAccessCancellationRequests", signedInUser.hasRole(OFFICE) || (signedInUser.hasRole(APPLICATION_CANCELLATION_REQUESTED) && (signedInUser.hasRole(BOSS) || signedInUser.hasRole(DEPARTMENT_HEAD) || signedInUser.hasRole(SECOND_STAGE_AUTHORITY))));
-        model.addAttribute("canAccessOtherApplications", signedInUser.hasRole(OFFICE) || signedInUser.hasRole(BOSS) || signedInUser.hasRole(DEPARTMENT_HEAD) || signedInUser.hasRole(SECOND_STAGE_AUTHORITY));
-        model.addAttribute("canAccessSickNoteSubmissions", signedInUser.hasRole(OFFICE) || (signedInUser.hasRole(SICK_NOTE_EDIT) && (signedInUser.hasRole(BOSS) || signedInUser.hasRole(DEPARTMENT_HEAD) || signedInUser.hasRole(SECOND_STAGE_AUTHORITY))));
+        model.addAttribute("canAccessApplicationStatistics", isAllowedToAccessApplicationStatistics(signedInUser));
+        model.addAttribute("canAccessCancellationRequests", isAllowedToAccessCancellationRequest(signedInUser));
+        model.addAttribute("canAccessOtherApplications", isAllowedToAccessOtherApplications(signedInUser));
+        model.addAttribute("canAccessSickNoteSubmissions", sickNoteSettings.getUserIsAllowedToSubmitSickNotes() && isAllowedToAccessSickNoteSubmissions(signedInUser));
 
         final List<Person> membersAsDepartmentHead = signedInUser.hasRole(DEPARTMENT_HEAD) ? departmentService.getMembersForDepartmentHead(signedInUser) : List.of();
         final List<Person> membersAsSecondStageAuthority = signedInUser.hasRole(SECOND_STAGE_AUTHORITY) ? departmentService.getMembersForSecondStageAuthority(signedInUser) : List.of();
@@ -133,6 +140,24 @@ class ApplicationForLeaveViewController implements HasLaunchpad {
         model.addAttribute("applications_holiday_replacements", replacements);
     }
 
+    private static boolean isAllowedToAccessApplicationStatistics(Person signedInUser) {
+        return signedInUser.hasAnyRole(OFFICE, BOSS, DEPARTMENT_HEAD, SECOND_STAGE_AUTHORITY);
+    }
+
+    private static boolean isAllowedToAccessCancellationRequest(Person signedInUser) {
+        return signedInUser.hasRole(OFFICE)
+            || (signedInUser.hasRole(APPLICATION_CANCELLATION_REQUESTED) && (signedInUser.hasAnyRole(BOSS, DEPARTMENT_HEAD, SECOND_STAGE_AUTHORITY)));
+    }
+
+    private static boolean isAllowedToAccessOtherApplications(Person signedInUser) {
+        return signedInUser.hasAnyRole(OFFICE, BOSS, DEPARTMENT_HEAD, SECOND_STAGE_AUTHORITY);
+    }
+
+    private static boolean isAllowedToAccessSickNoteSubmissions(Person signedInUser) {
+        return signedInUser.hasRole(OFFICE)
+            || (signedInUser.hasRole(SICK_NOTE_EDIT) && (signedInUser.hasAnyRole(BOSS, DEPARTMENT_HEAD, SECOND_STAGE_AUTHORITY)));
+    }
+
     private List<ApplicationForLeaveDto> mapToApplicationForLeaveDtoList(List<ApplicationForLeave> applications, Person signedInUser, List<Person> membersAsDepartmentHead,
                                                                          List<Person> membersAsSecondStageAuthority, Locale locale) {
 


Test patch:
diff --git a/src/test/java/org/synyx/urlaubsverwaltung/application/application/ApplicationForLeaveViewControllerTest.java b/src/test/java/org/synyx/urlaubsverwaltung/application/application/ApplicationForLeaveViewControllerTest.java
index bde98ba2c..92158a160 100644
--- a/src/test/java/org/synyx/urlaubsverwaltung/application/application/ApplicationForLeaveViewControllerTest.java
+++ b/src/test/java/org/synyx/urlaubsverwaltung/application/application/ApplicationForLeaveViewControllerTest.java
@@ -17,6 +17,9 @@ import org.synyx.urlaubsverwaltung.application.vacationtype.VacationType;
 import org.synyx.urlaubsverwaltung.department.DepartmentService;
 import org.synyx.urlaubsverwaltung.person.Person;
 import org.synyx.urlaubsverwaltung.person.PersonService;
+import org.synyx.urlaubsverwaltung.settings.Settings;
+import org.synyx.urlaubsverwaltung.settings.SettingsService;
+import org.synyx.urlaubsverwaltung.sicknote.settings.SickNoteSettings;
 import org.synyx.urlaubsverwaltung.sicknote.sicknote.SickNote;
 import org.synyx.urlaubsverwaltung.sicknote.sicknote.SickNoteService;
 import org.synyx.urlaubsverwaltung.sicknote.sicknotetype.SickNoteType;
@@ -79,14 +82,19 @@ class ApplicationForLeaveViewControllerTest {
     @Mock
     private PersonService personService;
     @Mock
+    private SettingsService settingsService;
+    @Mock
     private MessageSource messageSource;
 
     private final Clock clock = Clock.systemUTC();
 
     @BeforeEach
     void setUp() {
+
+        userIsAllowedToSubmitSickNotes(false);
+
         sut = new ApplicationForLeaveViewController(applicationService, sickNoteService, workDaysCountService, departmentService,
-            personService, clock, messageSource);
+            personService, settingsService, clock, messageSource);
     }
 
     @Test
@@ -407,7 +415,7 @@ class ApplicationForLeaveViewControllerTest {
             .andExpect(model().attribute("canAccessApplicationStatistics", is(true)))
             .andExpect(model().attribute("canAccessCancellationRequests", is(true)))
             .andExpect(model().attribute("canAccessOtherApplications", is(true)))
-            .andExpect(model().attribute("canAccessSickNoteSubmissions", is(true)))
+            .andExpect(model().attribute("canAccessSickNoteSubmissions", is(false)))
             .andExpect(model().attribute("userApplications", hasSize(1)))
             .andExpect(model().attribute("userApplications", hasItems(
                 allOf(
@@ -1534,6 +1542,7 @@ class ApplicationForLeaveViewControllerTest {
         when(personService.getActivePersons()).thenReturn(List.of(person));
 
         // other sicknotes
+        userIsAllowedToSubmitSickNotes(true);
         when(sickNoteService.getForStatesAndPerson(List.of(SUBMITTED), List.of(person))).thenReturn(List.of(sickNote));
 
         perform(get(path)).andExpect(status().isOk())
@@ -1589,6 +1598,7 @@ class ApplicationForLeaveViewControllerTest {
         when(departmentService.getMembersForDepartmentHead(departmentHead)).thenReturn(List.of(person));
 
         // other sicknotes
+        userIsAllowedToSubmitSickNotes(true);
         when(sickNoteService.getForStatesAndPerson(List.of(SUBMITTED), List.of(person))).thenReturn(List.of(sickNote));
 
         perform(get("/web/application")).andExpect(status().isOk())
@@ -1644,6 +1654,7 @@ class ApplicationForLeaveViewControllerTest {
         when(departmentService.getMembersForSecondStageAuthority(secondStageAuthority)).thenReturn(List.of(person));
 
         // other sicknotes
+        userIsAllowedToSubmitSickNotes(true);
         when(sickNoteService.getForStatesAndPerson(List.of(SUBMITTED), List.of(person))).thenReturn(List.of(sickNote));
 
         perform(get("/web/application")).andExpect(status().isOk())
@@ -1699,6 +1710,7 @@ class ApplicationForLeaveViewControllerTest {
         when(personService.getActivePersons()).thenReturn(List.of(person, boss));
 
         // other sicknotes
+        userIsAllowedToSubmitSickNotes(true);
         when(sickNoteService.getForStatesAndPerson(List.of(SUBMITTED), List.of(person))).thenReturn(List.of(sickNote));
 
         perform(get("/web/application")).andExpect(status().isOk())
@@ -1741,4 +1753,12 @@ class ApplicationForLeaveViewControllerTest {
     private ResultActions perform(MockHttpServletRequestBuilder builder) throws Exception {
         return standaloneSetup(sut).build().perform(builder);
     }
+
+    private void userIsAllowedToSubmitSickNotes(boolean userIsAllowedToSubmit) {
+        final Settings settings = new Settings();
+        final SickNoteSettings sickNoteSettings = new SickNoteSettings();
+        sickNoteSettings.setUserIsAllowedToSubmitSickNotes(userIsAllowedToSubmit);
+        settings.setSickNoteSettings(sickNoteSettings);
+        when(settingsService.getSettings()).thenReturn(settings);
+    }
 }