From 311adbc84f031abda212c67757e1f0804f05da2a Mon Sep 17 00:00:00 2001 From: schluebbo Date: Mon, 3 Feb 2025 16:36:46 +0100 Subject: [PATCH 01/13] fix: Restrict bundle publishing to admins - Force `isPublished = false` for non-admins in `editBundle()` - Hide "Release" checkbox in UI for non-admins --- src/main/java/de/imi/mopat/controller/BundleController.java | 5 +++++ src/main/webapp/WEB-INF/bundle/edit.html | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/de/imi/mopat/controller/BundleController.java b/src/main/java/de/imi/mopat/controller/BundleController.java index 6aa36ab7..89147e0f 100644 --- a/src/main/java/de/imi/mopat/controller/BundleController.java +++ b/src/main/java/de/imi/mopat/controller/BundleController.java @@ -31,6 +31,7 @@ import de.imi.mopat.model.dto.QuestionnaireDTO; import de.imi.mopat.model.user.AclObjectIdentity; import de.imi.mopat.model.user.User; +import de.imi.mopat.model.user.UserRole; import de.imi.mopat.validator.BundleDTOValidator; import java.util.ArrayList; @@ -221,6 +222,10 @@ public String editBundle(@RequestParam final String action, return "redirect:/bundle/fill?id=" + bundleDTO.getId(); } + if (!authService.hasExactRole(UserRole.ROLE_ADMIN)){ + bundleDTO.setIsPublished(false); + } + // Check if one of the welcome texts has only one newline and // change it to an empty string SortedMap tempLocalizedWelcomeText = bundleDTO.getLocalizedWelcomeText(); diff --git a/src/main/webapp/WEB-INF/bundle/edit.html b/src/main/webapp/WEB-INF/bundle/edit.html index 77f14ee3..3c75d345 100644 --- a/src/main/webapp/WEB-INF/bundle/edit.html +++ b/src/main/webapp/WEB-INF/bundle/edit.html @@ -134,7 +134,7 @@ > -
+

") || entry.getValue().equals("
")) { - entry.setValue(""); - } - } - bundleDTO.setLocalizedWelcomeText(tempLocalizedWelcomeText); - - // Check if one of the final texts has only one newline and - // change it to an empty string - SortedMap tempLocalizedFinalText = bundleDTO.getLocalizedFinalText(); - for (SortedMap.Entry entry : tempLocalizedFinalText.entrySet()) { - if (entry.getValue().equals("


") || entry.getValue().equals("
")) { - entry.setValue(""); - } - } - bundleDTO.setLocalizedFinalText(tempLocalizedFinalText); + bundleService.prepareBundleForEdit(bundleDTO); List availableQuestionnaireDTOs = getAvailableQuestionnaires(null); List assignedBundleQuestionnaireDTOs = new ArrayList<>( @@ -253,14 +235,7 @@ public String editBundle(@RequestParam final String action, // bundleDTO are detained for (QuestionnaireDTO questionnaireDTO : new ArrayList<>(availableQuestionnaireDTOs)) { for (BundleQuestionnaireDTO bundleQuestionnaireDTO : assignedBundleQuestionnaireDTOs) { - if (bundleQuestionnaireDTO.getQuestionnaireDTO() == null - || bundleQuestionnaireDTO.getQuestionnaireDTO().getId() == null) { - // Delete empty entries - bundleDTO.getBundleQuestionnaireDTOs().remove(bundleQuestionnaireDTO); - // If this available questionnaire is in the assigned - // questionnaire list as well, - // remove it from the available list - } else if (questionnaireDTO.getId().longValue() + if (questionnaireDTO.getId().longValue() == bundleQuestionnaireDTO.getQuestionnaireDTO().getId().longValue()) { // Remove this questionnaire from the list with available // questionnaires diff --git a/src/main/java/de/imi/mopat/helper/controller/BundleService.java b/src/main/java/de/imi/mopat/helper/controller/BundleService.java index fc66ba7c..494d6a71 100644 --- a/src/main/java/de/imi/mopat/helper/controller/BundleService.java +++ b/src/main/java/de/imi/mopat/helper/controller/BundleService.java @@ -16,8 +16,10 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.SortedMap; import java.util.stream.Collectors; +import de.imi.mopat.model.user.UserRole; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -39,6 +41,8 @@ public class BundleService { private BundleQuestionnaireDao bundleQuestionnaireDao; @Autowired private QuestionnaireService questionnaireService; + @Autowired + private AuthService authService; /** * Retrieves all available {@link QuestionnaireDTO} objects that are not currently assigned @@ -129,4 +133,30 @@ public Set getUniqueQuestionnaireIds(List bundles) { public boolean isBundleModifiable(BundleDTO bundleDTO) { return bundleDTO.getId() == null || bundleDao.getElementById(bundleDTO.getId()).isModifiable(); } + + public void prepareBundleForEdit(BundleDTO bundleDTO) { + cleanUpTextFields(bundleDTO); + + if (!authService.hasExactRole(UserRole.ROLE_ADMIN)) { + bundleDTO.setIsPublished(false); + } + + removeUnassignedBundleQuestionnaires(bundleDTO); + } + + public void cleanUpTextFields(BundleDTO bundleDTO) { + bundleDTO.setLocalizedWelcomeText(cleanUpLocalizedText(bundleDTO.getLocalizedWelcomeText())); + bundleDTO.setLocalizedFinalText(cleanUpLocalizedText(bundleDTO.getLocalizedFinalText())); + } + + private SortedMap cleanUpLocalizedText(SortedMap textMap) { + textMap.replaceAll((key, value) -> ("


".equals(value) || "
".equals(value)) ? "" : value); + return textMap; + } + + private void removeUnassignedBundleQuestionnaires(BundleDTO bundleDTO) { + bundleDTO.getBundleQuestionnaireDTOs().removeIf( + bq -> bq.getQuestionnaireDTO() == null || bq.getQuestionnaireDTO().getId() == null + ); + } } From b054b20f055a909ccb7ae168c751a96a081264ce Mon Sep 17 00:00:00 2001 From: schluebbo Date: Thu, 6 Feb 2025 15:03:15 +0100 Subject: [PATCH 05/13] fix: Restore missing hasScores flag after validation error - Ensure `hasScores` is restored in `BundleController` after a validation error - Prevents the score activation button from disappearing in the UI --- src/main/java/de/imi/mopat/controller/BundleController.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/de/imi/mopat/controller/BundleController.java b/src/main/java/de/imi/mopat/controller/BundleController.java index d047853b..6cd6d027 100644 --- a/src/main/java/de/imi/mopat/controller/BundleController.java +++ b/src/main/java/de/imi/mopat/controller/BundleController.java @@ -245,6 +245,8 @@ public String editBundle(@RequestParam final String action, .setExportTemplates(questionnaireDTO.getExportTemplates()); bundleQuestionnaireDTO.getQuestionnaireDTO() .setQuestionnaireGroupDTO(questionnaireDTO.getQuestionnaireGroupDTO()); + bundleQuestionnaireDTO.getQuestionnaireDTO() + .setHasScores(questionnaireDTO.getHasScores()); } } } From d7b7cbbaa09f54abd0eb128f4850279328f2aae7 Mon Sep 17 00:00:00 2001 From: schluebbo Date: Thu, 6 Feb 2025 15:16:38 +0100 Subject: [PATCH 06/13] refactor: Use getAvailableQuestionnaires from BundleService and remove redundant method - Replaced `getAvailableQuestionnaires` in `BundleController` with the existing method from `BundleService` - Adjusted returned list from an immutable to a mutable list for modifications - Removed unused `getAvailableQuestionnaires` method from `BundleController` as it is no longer needed --- .../mopat/controller/BundleController.java | 34 +------------------ .../helper/controller/BundleService.java | 2 +- 2 files changed, 2 insertions(+), 34 deletions(-) diff --git a/src/main/java/de/imi/mopat/controller/BundleController.java b/src/main/java/de/imi/mopat/controller/BundleController.java index 6cd6d027..aad36f2f 100644 --- a/src/main/java/de/imi/mopat/controller/BundleController.java +++ b/src/main/java/de/imi/mopat/controller/BundleController.java @@ -120,38 +120,6 @@ public BundleDTO getBundleDTO(final Long id) { return result; } - /** - * @param id is id of the {@link Bundle Bundle} object - * @return Returns all {@link Questionnaire Questionnaire} objects that are not already present - * in the bundle with the given id. - */ - private List getAvailableQuestionnaires(final Long bundleId) { - // Fetch questionnaires not linked with the given bundle - List availableQuestionnaires = bundleDao.getAvailableQuestionnairesForBundle(bundleId); - - // Collect IDs for fetching scores - Set questionnaireIds = availableQuestionnaires.stream().map(Questionnaire::getId).collect(Collectors.toSet()); - Set questionnairesWithScores = new HashSet<>(); - if (!questionnaireIds.isEmpty()) { - questionnairesWithScores.addAll( - scoreDao.findQuestionnairesWithScores( - new ArrayList<>(questionnaireIds) - ) - ); - } - - // Map to DTO and sort - return availableQuestionnaires.stream() - .filter(q -> !q.getQuestions().isEmpty()) - .map(q -> { - QuestionnaireDTO dto = questionnaireDTOMapper.apply(q); - dto.setHasScores(questionnairesWithScores.contains(q.getId())); - return dto; - }) - .sorted(Comparator.comparing(QuestionnaireDTO::getName, String.CASE_INSENSITIVE_ORDER)) - .collect(Collectors.toList()); - } - /** * Controls the HTTP GET requests for the URL /bundle/list. Shows the list of bundles. * @@ -226,7 +194,7 @@ public String editBundle(@RequestParam final String action, bundleService.prepareBundleForEdit(bundleDTO); - List availableQuestionnaireDTOs = getAvailableQuestionnaires(null); + List availableQuestionnaireDTOs = bundleService.getAvailableQuestionnaires(null); List assignedBundleQuestionnaireDTOs = new ArrayList<>( bundleDTO.getBundleQuestionnaireDTOs()); List questionnaireDTOsToDelete = new ArrayList<>(); diff --git a/src/main/java/de/imi/mopat/helper/controller/BundleService.java b/src/main/java/de/imi/mopat/helper/controller/BundleService.java index 494d6a71..ad3b97de 100644 --- a/src/main/java/de/imi/mopat/helper/controller/BundleService.java +++ b/src/main/java/de/imi/mopat/helper/controller/BundleService.java @@ -74,7 +74,7 @@ public List getAvailableQuestionnaires(final Long bundleId) { Comparator.comparing(QuestionnaireDTO::getQuestionnaireVersionGroupName, String::compareToIgnoreCase) .thenComparing(QuestionnaireDTO::getQuestionnaireVersionGroupId) .thenComparing(QuestionnaireDTO::getVersion)) - .toList(); + .collect(Collectors.toList()); } /** From ab237e0af7efb7ae09244d37ffb93eba3a95d6a4 Mon Sep 17 00:00:00 2001 From: schluebbo Date: Thu, 6 Feb 2025 15:31:33 +0100 Subject: [PATCH 07/13] refactor: Move assigned and available questionnaire synchronization to BundleService - Extracted logic for synchronizing assigned and available questionnaires into `syncAssignedAndAvailableQuestionnaires` in `BundleService` - Ensured `exportTemplates`, `questionnaireGroupDTO`, and `hasScores` are properly updated in assigned questionnaires --- .../mopat/controller/BundleController.java | 30 +--------------- .../helper/controller/BundleService.java | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/main/java/de/imi/mopat/controller/BundleController.java b/src/main/java/de/imi/mopat/controller/BundleController.java index aad36f2f..c7b4fa3f 100644 --- a/src/main/java/de/imi/mopat/controller/BundleController.java +++ b/src/main/java/de/imi/mopat/controller/BundleController.java @@ -195,35 +195,7 @@ public String editBundle(@RequestParam final String action, bundleService.prepareBundleForEdit(bundleDTO); List availableQuestionnaireDTOs = bundleService.getAvailableQuestionnaires(null); - List assignedBundleQuestionnaireDTOs = new ArrayList<>( - bundleDTO.getBundleQuestionnaireDTOs()); - List questionnaireDTOsToDelete = new ArrayList<>(); - - //make sure the changes in the bundleQuestionnaireDTO list of - // bundleDTO are detained - for (QuestionnaireDTO questionnaireDTO : new ArrayList<>(availableQuestionnaireDTOs)) { - for (BundleQuestionnaireDTO bundleQuestionnaireDTO : assignedBundleQuestionnaireDTOs) { - if (questionnaireDTO.getId().longValue() - == bundleQuestionnaireDTO.getQuestionnaireDTO().getId().longValue()) { - // Remove this questionnaire from the list with available - // questionnaires - questionnaireDTOsToDelete.add(questionnaireDTO); - // Set the export templates to the assigned questionnaire - bundleQuestionnaireDTO.getQuestionnaireDTO() - .setExportTemplates(questionnaireDTO.getExportTemplates()); - bundleQuestionnaireDTO.getQuestionnaireDTO() - .setQuestionnaireGroupDTO(questionnaireDTO.getQuestionnaireGroupDTO()); - bundleQuestionnaireDTO.getQuestionnaireDTO() - .setHasScores(questionnaireDTO.getHasScores()); - } - } - } - availableQuestionnaireDTOs.removeAll(questionnaireDTOsToDelete); - - // Sort assigned bundle questionnaires by position - Collections.sort(bundleDTO.getBundleQuestionnaireDTOs(), - (BundleQuestionnaireDTO o1, BundleQuestionnaireDTO o2) -> o1.getPosition() - .compareTo(o2.getPosition())); + bundleService.syncAssignedAndAvailableQuestionnaires(bundleDTO.getBundleQuestionnaireDTOs(), availableQuestionnaireDTOs); // Validate the bundle object bundleDTOValidator.validate(bundleDTO, result); diff --git a/src/main/java/de/imi/mopat/helper/controller/BundleService.java b/src/main/java/de/imi/mopat/helper/controller/BundleService.java index ad3b97de..bc6ab7ba 100644 --- a/src/main/java/de/imi/mopat/helper/controller/BundleService.java +++ b/src/main/java/de/imi/mopat/helper/controller/BundleService.java @@ -9,6 +9,7 @@ import de.imi.mopat.model.BundleQuestionnaire; import de.imi.mopat.model.Questionnaire; import de.imi.mopat.model.dto.BundleDTO; +import de.imi.mopat.model.dto.BundleQuestionnaireDTO; import de.imi.mopat.model.dto.QuestionnaireDTO; import java.util.Comparator; import java.util.HashSet; @@ -17,6 +18,8 @@ import java.util.Optional; import java.util.Set; import java.util.SortedMap; +import java.util.Map; +import java.util.function.Function; import java.util.stream.Collectors; import de.imi.mopat.model.user.UserRole; @@ -159,4 +162,37 @@ private void removeUnassignedBundleQuestionnaires(BundleDTO bundleDTO) { bq -> bq.getQuestionnaireDTO() == null || bq.getQuestionnaireDTO().getId() == null ); } + + public void syncAssignedAndAvailableQuestionnaires(List bundleQuestionnaireDTOS, List availableQuestionnaireDTOs) { + // IDs der bereits zugewiesenen Fragebögen sammeln + Set assignedIds = bundleQuestionnaireDTOS.stream() + .map(BundleQuestionnaireDTO::getQuestionnaireDTO) + .filter(Objects::nonNull) + .map(QuestionnaireDTO::getId) + .collect(Collectors.toSet()); + + List assignedQuestionnaires = availableQuestionnaireDTOs.stream() + .filter(q -> assignedIds.contains(q.getId())) + .toList(); + + availableQuestionnaireDTOs.removeAll(assignedQuestionnaires); + + updateMissingQuestionnaireData(bundleQuestionnaireDTOS, assignedQuestionnaires); + + bundleQuestionnaireDTOS.sort(Comparator.comparing(BundleQuestionnaireDTO::getPosition)); + } + + private void updateMissingQuestionnaireData(List assignedBundleQuestionnaires, List assignedQuestionnaires) { + Map assignedQuestionnaireMap = assignedQuestionnaires.stream() + .collect(Collectors.toMap(QuestionnaireDTO::getId, Function.identity())); + + assignedBundleQuestionnaires.forEach(abq -> { + QuestionnaireDTO assignedQuestionnaire = assignedQuestionnaireMap.get(abq.getQuestionnaireDTO().getId()); + if (assignedQuestionnaire != null) { + abq.getQuestionnaireDTO().setExportTemplates(assignedQuestionnaire.getExportTemplates()); + abq.getQuestionnaireDTO().setQuestionnaireGroupDTO(assignedQuestionnaire.getQuestionnaireGroupDTO()); + abq.getQuestionnaireDTO().setHasScores(assignedQuestionnaire.getHasScores()); + } + }); + } } From 688849b6828ac3bbd101e2a2fee6e62bb3e60441 Mon Sep 17 00:00:00 2001 From: schluebbo Date: Thu, 6 Feb 2025 15:51:53 +0100 Subject: [PATCH 08/13] refactor: Move bundle save and update logic to BundleService - Moved `saveOrUpdateBundle` logic from `BundleController` to `BundleService` - Removed redundant dependencies from `BundleController` that are now handled by `BundleService` --- .../mopat/controller/BundleController.java | 118 +----------------- .../helper/controller/BundleService.java | 112 +++++++++++++++++ 2 files changed, 113 insertions(+), 117 deletions(-) diff --git a/src/main/java/de/imi/mopat/controller/BundleController.java b/src/main/java/de/imi/mopat/controller/BundleController.java index c7b4fa3f..9973bf31 100644 --- a/src/main/java/de/imi/mopat/controller/BundleController.java +++ b/src/main/java/de/imi/mopat/controller/BundleController.java @@ -20,7 +20,6 @@ import de.imi.mopat.model.BundleClinic; import de.imi.mopat.model.BundleQuestionnaire; import de.imi.mopat.model.Clinic; -import de.imi.mopat.model.ExportTemplate; import de.imi.mopat.model.Questionnaire; import de.imi.mopat.model.conditions.Condition; import de.imi.mopat.model.conditions.ConditionTrigger; @@ -29,21 +28,11 @@ import de.imi.mopat.model.dto.BundleDTO; import de.imi.mopat.model.dto.BundleQuestionnaireDTO; import de.imi.mopat.model.dto.QuestionnaireDTO; -import de.imi.mopat.model.user.AclObjectIdentity; -import de.imi.mopat.model.user.User; -import de.imi.mopat.model.user.UserRole; import de.imi.mopat.validator.BundleDTOValidator; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.SortedMap; -import java.util.stream.Collectors; import jakarta.validation.Valid; -import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; @@ -73,8 +62,6 @@ public class BundleController { @Autowired private ScoreDao scoreDao; @Autowired - private ExportTemplateDao exportTemplateDao; - @Autowired private QuestionnaireDao questionnaireDao; @Autowired private BundleDTOValidator bundleDTOValidator; @@ -83,15 +70,9 @@ public class BundleController { @Autowired private BundleService bundleService; @Autowired - private UserService userService; - @Autowired private ClinicService clinicService; @Autowired - private QuestionnaireDTOMapper questionnaireDTOMapper; - @Autowired private BundleDTOMapper bundleDTOMapper; - @Autowired - private AuthService authService; /** * @param id for bundle @@ -188,10 +169,6 @@ public String editBundle(@RequestParam final String action, return "redirect:/bundle/fill?id=" + bundleDTO.getId(); } - if (!authService.hasExactRole(UserRole.ROLE_ADMIN)){ - bundleDTO.setIsPublished(false); - } - bundleService.prepareBundleForEdit(bundleDTO); List availableQuestionnaireDTOs = bundleService.getAvailableQuestionnaires(null); @@ -207,100 +184,7 @@ public String editBundle(@RequestParam final String action, return "bundle/edit"; } - // Set property of the Bundle to current user - User principal = authService.getAuthenticatedUser(); - - Bundle bundle; - if (bundleDTO.getId() != null) { - bundle = bundleDao.getElementById(bundleDTO.getId()); - bundle.setName(bundleDTO.getName()); - bundle.setChangedBy(principal.getId()); - bundle.setDescription(bundleDTO.getDescription()); - bundle.setIsPublished(bundleDTO.getIsPublished()); - bundle.setShowProgressPerBundle(bundleDTO.getShowProgressPerBundle()); - bundle.setDeactivateProgressAndNameDuringSurvey( - bundleDTO.getdeactivateProgressAndNameDuringSurvey()); - } else { - bundle = new Bundle(bundleDTO.getName(), bundleDTO.getDescription(), principal.getId(), - bundleDTO.getIsPublished(), bundleDTO.getShowProgressPerBundle(), - bundleDTO.getdeactivateProgressAndNameDuringSurvey()); - } - bundle.setLocalizedWelcomeText(bundleDTO.getLocalizedWelcomeText()); - bundle.setLocalizedFinalText(bundleDTO.getLocalizedFinalText()); - - if (bundle.getId() == null) { // the bundle is completely new, thus - // no removal of BundleQuestionnaire objects necessary and in the - // end persist (not merge) - bundleDao.merge(bundle); - // Get the current user, which is the owner of the bundle - User currentUser = authService.getAuthenticatedUser(); - // Create a new ACLObjectIdentity for the bundle and save it - AclObjectIdentity bundleObjectIdentity = new AclObjectIdentity(bundle.getId(), - Boolean.TRUE, aclClassDao.getElementByClass(Bundle.class.getName()), currentUser, - null); - aclObjectIdentityDao.persist(bundleObjectIdentity); - } else { - // the bundle is not new, - // thus BundleQuestionnaire objects might have been removed or - // repositioned. - // To avoid complex code, we remove all BundleQuestionnaire - // objects from the bundle and (re-)add them. - // In the end: merge (not persist) (since the bundle already has - // an ID) - for (BundleQuestionnaire toDelete : bundle.getBundleQuestionnaires()) { - HashSet exportTemplates = new HashSet<>( - toDelete.getExportTemplates()); - toDelete.removeExportTemplates(); - for (ExportTemplate exportTemplate : exportTemplates) { - exportTemplateDao.merge(exportTemplate); - } - Questionnaire questionnaire = toDelete.getQuestionnaire(); - questionnaire.removeBundleQuestionnaire(toDelete); - questionnaireDao.merge(questionnaire); - } - bundle.removeAllBundleQuestionnaires(); - bundleDao.merge(bundle); - } - // Save the bundle questionnaire relationships - if (bundleDTO.getBundleQuestionnaireDTOs() != null - && !bundleDTO.getBundleQuestionnaireDTOs().isEmpty()) { - for (BundleQuestionnaireDTO bundleQuestionnaireDTO : bundleDTO.getBundleQuestionnaireDTOs()) { - if (bundleQuestionnaireDTO.getQuestionnaireDTO() == null - || bundleQuestionnaireDTO.getQuestionnaireDTO().getId() == null) { - continue; - } - Questionnaire questionnaire = questionnaireDao.getElementById( - bundleQuestionnaireDTO.getQuestionnaireDTO().getId()); - - if (bundleQuestionnaireDTO.getIsEnabled() == null) { - bundleQuestionnaireDTO.setIsEnabled(false); - } - - if (bundleQuestionnaireDTO.getShowScores() == null) { - bundleQuestionnaireDTO.setShowScores(false); - } - - BundleQuestionnaire bundleQuestionnaire = new BundleQuestionnaire(bundle, - questionnaire, bundleQuestionnaireDTO.getPosition().intValue(), - bundleQuestionnaireDTO.getIsEnabled(), bundleQuestionnaireDTO.getShowScores()); - for (Long id : bundleQuestionnaireDTO.getExportTemplates()) { - ExportTemplate exportTemplate = exportTemplateDao.getElementById(id); - if (exportTemplate != null) { - bundleQuestionnaire.addExportTemplate(exportTemplate); - exportTemplateDao.merge(exportTemplate); - } - } - bundle.addBundleQuestionnaire(bundleQuestionnaire); - questionnaire.addBundleQuestionnaire(bundleQuestionnaire); - questionnaireDao.merge(questionnaire); - } - } - // If the bundle has no questionnaire change isPublished to false - if (Boolean.TRUE.equals(bundle.getIsPublished()) && bundle.getBundleQuestionnaires() - .isEmpty()) { - bundle.setIsPublished(Boolean.FALSE); - } - bundleDao.merge(bundle); + bundleService.saveOrUpdateBundle(bundleDTO); return "redirect:/bundle/list"; } diff --git a/src/main/java/de/imi/mopat/helper/controller/BundleService.java b/src/main/java/de/imi/mopat/helper/controller/BundleService.java index bc6ab7ba..b75eddaa 100644 --- a/src/main/java/de/imi/mopat/helper/controller/BundleService.java +++ b/src/main/java/de/imi/mopat/helper/controller/BundleService.java @@ -1,12 +1,16 @@ package de.imi.mopat.helper.controller; +import de.imi.mopat.dao.user.AclClassDao; +import de.imi.mopat.dao.user.AclObjectIdentityDao; import de.imi.mopat.dao.BundleDao; import de.imi.mopat.dao.BundleQuestionnaireDao; +import de.imi.mopat.dao.ExportTemplateDao; import de.imi.mopat.dao.QuestionnaireDao; import de.imi.mopat.dao.ScoreDao; import de.imi.mopat.helper.model.QuestionnaireDTOMapper; import de.imi.mopat.model.Bundle; import de.imi.mopat.model.BundleQuestionnaire; +import de.imi.mopat.model.ExportTemplate; import de.imi.mopat.model.Questionnaire; import de.imi.mopat.model.dto.BundleDTO; import de.imi.mopat.model.dto.BundleQuestionnaireDTO; @@ -22,6 +26,8 @@ import java.util.function.Function; import java.util.stream.Collectors; +import de.imi.mopat.model.user.AclObjectIdentity; +import de.imi.mopat.model.user.User; import de.imi.mopat.model.user.UserRole; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -46,6 +52,12 @@ public class BundleService { private QuestionnaireService questionnaireService; @Autowired private AuthService authService; + @Autowired + private ExportTemplateDao exportTemplateDao; + @Autowired + private AclClassDao aclClassDao; + @Autowired + private AclObjectIdentityDao aclObjectIdentityDao; /** * Retrieves all available {@link QuestionnaireDTO} objects that are not currently assigned @@ -195,4 +207,104 @@ private void updateMissingQuestionnaireData(List assigne } }); } + + public void saveOrUpdateBundle(BundleDTO bundleDTO) { + if (!authService.hasExactRole(UserRole.ROLE_ADMIN)){ + bundleDTO.setIsPublished(false); + } + // Set property of the Bundle to current user + User principal = authService.getAuthenticatedUser(); + + Bundle bundle; + if (bundleDTO.getId() != null) { + bundle = bundleDao.getElementById(bundleDTO.getId()); + bundle.setName(bundleDTO.getName()); + bundle.setChangedBy(principal.getId()); + bundle.setDescription(bundleDTO.getDescription()); + bundle.setIsPublished(bundleDTO.getIsPublished()); + bundle.setShowProgressPerBundle(bundleDTO.getShowProgressPerBundle()); + bundle.setDeactivateProgressAndNameDuringSurvey( + bundleDTO.getdeactivateProgressAndNameDuringSurvey()); + } else { + bundle = new Bundle(bundleDTO.getName(), bundleDTO.getDescription(), principal.getId(), + bundleDTO.getIsPublished(), bundleDTO.getShowProgressPerBundle(), + bundleDTO.getdeactivateProgressAndNameDuringSurvey()); + } + bundle.setLocalizedWelcomeText(bundleDTO.getLocalizedWelcomeText()); + bundle.setLocalizedFinalText(bundleDTO.getLocalizedFinalText()); + + if (bundle.getId() == null) { // the bundle is completely new, thus + // no removal of BundleQuestionnaire objects necessary and in the + // end persist (not merge) + bundleDao.merge(bundle); + // Get the current user, which is the owner of the bundle + User currentUser = authService.getAuthenticatedUser(); + // Create a new ACLObjectIdentity for the bundle and save it + AclObjectIdentity bundleObjectIdentity = new AclObjectIdentity(bundle.getId(), + Boolean.TRUE, aclClassDao.getElementByClass(Bundle.class.getName()), currentUser, + null); + aclObjectIdentityDao.persist(bundleObjectIdentity); + } else { + // the bundle is not new, + // thus BundleQuestionnaire objects might have been removed or + // repositioned. + // To avoid complex code, we remove all BundleQuestionnaire + // objects from the bundle and (re-)add them. + // In the end: merge (not persist) (since the bundle already has + // an ID) + for (BundleQuestionnaire toDelete : bundle.getBundleQuestionnaires()) { + HashSet exportTemplates = new HashSet<>( + toDelete.getExportTemplates()); + toDelete.removeExportTemplates(); + for (ExportTemplate exportTemplate : exportTemplates) { + exportTemplateDao.merge(exportTemplate); + } + Questionnaire questionnaire = toDelete.getQuestionnaire(); + questionnaire.removeBundleQuestionnaire(toDelete); + questionnaireDao.merge(questionnaire); + } + bundle.removeAllBundleQuestionnaires(); + bundleDao.merge(bundle); + } + // Save the bundle questionnaire relationships + if (bundleDTO.getBundleQuestionnaireDTOs() != null + && !bundleDTO.getBundleQuestionnaireDTOs().isEmpty()) { + for (BundleQuestionnaireDTO bundleQuestionnaireDTO : bundleDTO.getBundleQuestionnaireDTOs()) { + if (bundleQuestionnaireDTO.getQuestionnaireDTO() == null + || bundleQuestionnaireDTO.getQuestionnaireDTO().getId() == null) { + continue; + } + Questionnaire questionnaire = questionnaireDao.getElementById( + bundleQuestionnaireDTO.getQuestionnaireDTO().getId()); + + if (bundleQuestionnaireDTO.getIsEnabled() == null) { + bundleQuestionnaireDTO.setIsEnabled(false); + } + + if (bundleQuestionnaireDTO.getShowScores() == null) { + bundleQuestionnaireDTO.setShowScores(false); + } + + BundleQuestionnaire bundleQuestionnaire = new BundleQuestionnaire(bundle, + questionnaire, bundleQuestionnaireDTO.getPosition().intValue(), + bundleQuestionnaireDTO.getIsEnabled(), bundleQuestionnaireDTO.getShowScores()); + for (Long id : bundleQuestionnaireDTO.getExportTemplates()) { + ExportTemplate exportTemplate = exportTemplateDao.getElementById(id); + if (exportTemplate != null) { + bundleQuestionnaire.addExportTemplate(exportTemplate); + exportTemplateDao.merge(exportTemplate); + } + } + bundle.addBundleQuestionnaire(bundleQuestionnaire); + questionnaire.addBundleQuestionnaire(bundleQuestionnaire); + questionnaireDao.merge(questionnaire); + } + } + // If the bundle has no questionnaire change isPublished to false + if (Boolean.TRUE.equals(bundle.getIsPublished()) && bundle.getBundleQuestionnaires() + .isEmpty()) { + bundle.setIsPublished(Boolean.FALSE); + } + bundleDao.merge(bundle); + } } From 10e6b8b2f85484cd933b5b64df7397be2427d737 Mon Sep 17 00:00:00 2001 From: schluebbo Date: Thu, 6 Feb 2025 16:03:33 +0100 Subject: [PATCH 09/13] refactor: Extract bundle property update logic into separate method - Moved bundle property assignment into a new method `updateBundleProperties` - Simplified bundle initialization by using a conditional expression --- .../helper/controller/BundleService.java | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/src/main/java/de/imi/mopat/helper/controller/BundleService.java b/src/main/java/de/imi/mopat/helper/controller/BundleService.java index b75eddaa..9988f307 100644 --- a/src/main/java/de/imi/mopat/helper/controller/BundleService.java +++ b/src/main/java/de/imi/mopat/helper/controller/BundleService.java @@ -213,32 +213,18 @@ public void saveOrUpdateBundle(BundleDTO bundleDTO) { bundleDTO.setIsPublished(false); } // Set property of the Bundle to current user - User principal = authService.getAuthenticatedUser(); - - Bundle bundle; - if (bundleDTO.getId() != null) { - bundle = bundleDao.getElementById(bundleDTO.getId()); - bundle.setName(bundleDTO.getName()); - bundle.setChangedBy(principal.getId()); - bundle.setDescription(bundleDTO.getDescription()); - bundle.setIsPublished(bundleDTO.getIsPublished()); - bundle.setShowProgressPerBundle(bundleDTO.getShowProgressPerBundle()); - bundle.setDeactivateProgressAndNameDuringSurvey( - bundleDTO.getdeactivateProgressAndNameDuringSurvey()); - } else { - bundle = new Bundle(bundleDTO.getName(), bundleDTO.getDescription(), principal.getId(), - bundleDTO.getIsPublished(), bundleDTO.getShowProgressPerBundle(), - bundleDTO.getdeactivateProgressAndNameDuringSurvey()); - } - bundle.setLocalizedWelcomeText(bundleDTO.getLocalizedWelcomeText()); - bundle.setLocalizedFinalText(bundleDTO.getLocalizedFinalText()); + User currentUser = authService.getAuthenticatedUser(); + + Bundle bundle = (bundleDTO.getId() != null) + ? bundleDao.getElementById(bundleDTO.getId()) + : new Bundle(); + + updateBundleProperties(bundle, bundleDTO, currentUser); if (bundle.getId() == null) { // the bundle is completely new, thus // no removal of BundleQuestionnaire objects necessary and in the // end persist (not merge) bundleDao.merge(bundle); - // Get the current user, which is the owner of the bundle - User currentUser = authService.getAuthenticatedUser(); // Create a new ACLObjectIdentity for the bundle and save it AclObjectIdentity bundleObjectIdentity = new AclObjectIdentity(bundle.getId(), Boolean.TRUE, aclClassDao.getElementByClass(Bundle.class.getName()), currentUser, @@ -307,4 +293,15 @@ public void saveOrUpdateBundle(BundleDTO bundleDTO) { } bundleDao.merge(bundle); } + + private void updateBundleProperties(Bundle bundle, BundleDTO bundleDTO, User principal) { + bundle.setName(bundleDTO.getName()); + bundle.setChangedBy(principal.getId()); + bundle.setDescription(bundleDTO.getDescription()); + bundle.setShowProgressPerBundle(bundleDTO.getShowProgressPerBundle()); + bundle.setDeactivateProgressAndNameDuringSurvey(bundleDTO.getdeactivateProgressAndNameDuringSurvey()); + bundle.setLocalizedWelcomeText(bundleDTO.getLocalizedWelcomeText()); + bundle.setLocalizedFinalText(bundleDTO.getLocalizedFinalText()); + bundle.setIsPublished(bundleDTO.getIsPublished()); + } } From 7e2e5c05c3c57c9f9051c0d85954b87d5fadee21 Mon Sep 17 00:00:00 2001 From: schluebbo Date: Thu, 6 Feb 2025 16:08:29 +0100 Subject: [PATCH 10/13] refactor: Extract ACL entry creation and cleanup logic into methods - Moved ACL entry creation to `createAclEntry` for better code organization - Extracted bundle questionnaire cleanup logic into `cleanupRemovedBundleQuestionnaires` --- .../helper/controller/BundleService.java | 57 ++++++++++--------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/src/main/java/de/imi/mopat/helper/controller/BundleService.java b/src/main/java/de/imi/mopat/helper/controller/BundleService.java index 9988f307..1248feaa 100644 --- a/src/main/java/de/imi/mopat/helper/controller/BundleService.java +++ b/src/main/java/de/imi/mopat/helper/controller/BundleService.java @@ -221,36 +221,11 @@ public void saveOrUpdateBundle(BundleDTO bundleDTO) { updateBundleProperties(bundle, bundleDTO, currentUser); - if (bundle.getId() == null) { // the bundle is completely new, thus - // no removal of BundleQuestionnaire objects necessary and in the - // end persist (not merge) + if (bundle.getId() == null) { bundleDao.merge(bundle); - // Create a new ACLObjectIdentity for the bundle and save it - AclObjectIdentity bundleObjectIdentity = new AclObjectIdentity(bundle.getId(), - Boolean.TRUE, aclClassDao.getElementByClass(Bundle.class.getName()), currentUser, - null); - aclObjectIdentityDao.persist(bundleObjectIdentity); + createAclEntry(bundle, currentUser); } else { - // the bundle is not new, - // thus BundleQuestionnaire objects might have been removed or - // repositioned. - // To avoid complex code, we remove all BundleQuestionnaire - // objects from the bundle and (re-)add them. - // In the end: merge (not persist) (since the bundle already has - // an ID) - for (BundleQuestionnaire toDelete : bundle.getBundleQuestionnaires()) { - HashSet exportTemplates = new HashSet<>( - toDelete.getExportTemplates()); - toDelete.removeExportTemplates(); - for (ExportTemplate exportTemplate : exportTemplates) { - exportTemplateDao.merge(exportTemplate); - } - Questionnaire questionnaire = toDelete.getQuestionnaire(); - questionnaire.removeBundleQuestionnaire(toDelete); - questionnaireDao.merge(questionnaire); - } - bundle.removeAllBundleQuestionnaires(); - bundleDao.merge(bundle); + cleanupRemovedBundleQuestionnaires(bundle); } // Save the bundle questionnaire relationships if (bundleDTO.getBundleQuestionnaireDTOs() != null @@ -304,4 +279,30 @@ private void updateBundleProperties(Bundle bundle, BundleDTO bundleDTO, User pri bundle.setLocalizedFinalText(bundleDTO.getLocalizedFinalText()); bundle.setIsPublished(bundleDTO.getIsPublished()); } + + private void createAclEntry(Bundle bundle, User currentUser) { + AclObjectIdentity bundleObjectIdentity = new AclObjectIdentity( + bundle.getId(), + Boolean.TRUE, + aclClassDao.getElementByClass(Bundle.class.getName()), + currentUser, + null + ); + aclObjectIdentityDao.persist(bundleObjectIdentity); + } + + private void cleanupRemovedBundleQuestionnaires(Bundle bundle) { + for (BundleQuestionnaire toDelete : bundle.getBundleQuestionnaires()) { + HashSet exportTemplates = new HashSet<>(toDelete.getExportTemplates()); + toDelete.removeExportTemplates(); + for (ExportTemplate exportTemplate : exportTemplates) { + exportTemplateDao.merge(exportTemplate); + } + Questionnaire questionnaire = toDelete.getQuestionnaire(); + questionnaire.removeBundleQuestionnaire(toDelete); + questionnaireDao.merge(questionnaire); + } + bundle.removeAllBundleQuestionnaires(); + bundleDao.merge(bundle); + } } From 1005b94604d49c0387d406d8f484b53cb3df8744 Mon Sep 17 00:00:00 2001 From: schluebbo Date: Thu, 6 Feb 2025 17:00:45 +0100 Subject: [PATCH 11/13] refactor: Extract questionnaire persistence logic into `persistBundleQuestionnaires` - Moved bundle questionnaire persistence into a separate method for better readability. - Simplified `saveOrUpdateBundle` by handling `isPublished` logic separately. --- .../helper/controller/BundleService.java | 91 +++++++++---------- 1 file changed, 42 insertions(+), 49 deletions(-) diff --git a/src/main/java/de/imi/mopat/helper/controller/BundleService.java b/src/main/java/de/imi/mopat/helper/controller/BundleService.java index 1248feaa..9dd04360 100644 --- a/src/main/java/de/imi/mopat/helper/controller/BundleService.java +++ b/src/main/java/de/imi/mopat/helper/controller/BundleService.java @@ -15,14 +15,8 @@ import de.imi.mopat.model.dto.BundleDTO; import de.imi.mopat.model.dto.BundleQuestionnaireDTO; import de.imi.mopat.model.dto.QuestionnaireDTO; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.SortedMap; -import java.util.Map; + +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -209,10 +203,6 @@ private void updateMissingQuestionnaireData(List assigne } public void saveOrUpdateBundle(BundleDTO bundleDTO) { - if (!authService.hasExactRole(UserRole.ROLE_ADMIN)){ - bundleDTO.setIsPublished(false); - } - // Set property of the Bundle to current user User currentUser = authService.getAuthenticatedUser(); Bundle bundle = (bundleDTO.getId() != null) @@ -227,46 +217,49 @@ public void saveOrUpdateBundle(BundleDTO bundleDTO) { } else { cleanupRemovedBundleQuestionnaires(bundle); } - // Save the bundle questionnaire relationships - if (bundleDTO.getBundleQuestionnaireDTOs() != null - && !bundleDTO.getBundleQuestionnaireDTOs().isEmpty()) { - for (BundleQuestionnaireDTO bundleQuestionnaireDTO : bundleDTO.getBundleQuestionnaireDTOs()) { - if (bundleQuestionnaireDTO.getQuestionnaireDTO() == null - || bundleQuestionnaireDTO.getQuestionnaireDTO().getId() == null) { - continue; - } - Questionnaire questionnaire = questionnaireDao.getElementById( - bundleQuestionnaireDTO.getQuestionnaireDTO().getId()); - - if (bundleQuestionnaireDTO.getIsEnabled() == null) { - bundleQuestionnaireDTO.setIsEnabled(false); - } - - if (bundleQuestionnaireDTO.getShowScores() == null) { - bundleQuestionnaireDTO.setShowScores(false); - } - - BundleQuestionnaire bundleQuestionnaire = new BundleQuestionnaire(bundle, - questionnaire, bundleQuestionnaireDTO.getPosition().intValue(), - bundleQuestionnaireDTO.getIsEnabled(), bundleQuestionnaireDTO.getShowScores()); - for (Long id : bundleQuestionnaireDTO.getExportTemplates()) { - ExportTemplate exportTemplate = exportTemplateDao.getElementById(id); - if (exportTemplate != null) { + + persistBundleQuestionnaires(bundleDTO, bundle); + + boolean isNotAdmin = !authService.hasExactRole(UserRole.ROLE_ADMIN); + boolean hasNoQuestionnaires = bundle.getBundleQuestionnaires().isEmpty(); + if (isNotAdmin || hasNoQuestionnaires) { + bundleDTO.setIsPublished(false); + } + + bundleDao.merge(bundle); + } + + private void persistBundleQuestionnaires(BundleDTO bundleDTO, Bundle bundle) { + if (bundleDTO.getBundleQuestionnaireDTOs() == null || bundleDTO.getBundleQuestionnaireDTOs().isEmpty()) { + return; + } + + for (BundleQuestionnaireDTO bundleQuestionnaireDTO : bundleDTO.getBundleQuestionnaireDTOs()) { + if (bundleQuestionnaireDTO.getQuestionnaireDTO() == null || bundleQuestionnaireDTO.getQuestionnaireDTO().getId() == null) { + continue; + } + + Questionnaire questionnaire = questionnaireDao.getElementById(bundleQuestionnaireDTO.getQuestionnaireDTO().getId()); + BundleQuestionnaire bundleQuestionnaire = new BundleQuestionnaire( + bundle, + questionnaire, + bundleQuestionnaireDTO.getPosition().intValue(), + Optional.ofNullable(bundleQuestionnaireDTO.getIsEnabled()).orElse(false), + Optional.ofNullable(bundleQuestionnaireDTO.getShowScores()).orElse(false) + ); + + bundleQuestionnaireDTO.getExportTemplates().stream() + .map(exportTemplateDao::getElementById) + .filter(Objects::nonNull) + .forEach(exportTemplate -> { bundleQuestionnaire.addExportTemplate(exportTemplate); exportTemplateDao.merge(exportTemplate); - } - } - bundle.addBundleQuestionnaire(bundleQuestionnaire); - questionnaire.addBundleQuestionnaire(bundleQuestionnaire); - questionnaireDao.merge(questionnaire); - } - } - // If the bundle has no questionnaire change isPublished to false - if (Boolean.TRUE.equals(bundle.getIsPublished()) && bundle.getBundleQuestionnaires() - .isEmpty()) { - bundle.setIsPublished(Boolean.FALSE); + }); + + bundle.addBundleQuestionnaire(bundleQuestionnaire); + questionnaire.addBundleQuestionnaire(bundleQuestionnaire); + questionnaireDao.merge(questionnaire); } - bundleDao.merge(bundle); } private void updateBundleProperties(Bundle bundle, BundleDTO bundleDTO, User principal) { From b540c7cb11b6b5927bb731af2ddb475cc1666786 Mon Sep 17 00:00:00 2001 From: schluebbo Date: Thu, 6 Feb 2025 17:09:44 +0100 Subject: [PATCH 12/13] refactor: Move `getBundleDTO` from `BundleController` to `BundleService` - Extracted `getBundleDTO` from `BundleController` to `BundleService`. --- .../mopat/controller/BundleController.java | 31 +----------------- .../helper/controller/BundleService.java | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/main/java/de/imi/mopat/controller/BundleController.java b/src/main/java/de/imi/mopat/controller/BundleController.java index 9973bf31..dbbe556a 100644 --- a/src/main/java/de/imi/mopat/controller/BundleController.java +++ b/src/main/java/de/imi/mopat/controller/BundleController.java @@ -71,35 +71,6 @@ public class BundleController { private BundleService bundleService; @Autowired private ClinicService clinicService; - @Autowired - private BundleDTOMapper bundleDTOMapper; - - /** - * @param id for bundle - * @return resulting bundle for id - */ - public BundleDTO getBundleDTO(final Long id) { - BundleDTO result; - BundleDTO bundleDTO; - if (id == null || id <= 0) { - result = new BundleDTO(); - } else { - Bundle bundle = bundleDao.getElementById(id); - if (bundle == null) { - result = new BundleDTO(); - } else { - bundleDTO = bundleDTOMapper.apply(true,bundle); - for (BundleQuestionnaireDTO bundleQuestionnaireDTO - : bundleDTO.getBundleQuestionnaireDTOs()) { - bundleQuestionnaireDTO.getQuestionnaireDTO() - .setHasScores(scoreDao.hasScore(questionnaireDao.getElementById(bundleQuestionnaireDTO.getQuestionnaireDTO() - .getId()))); - } - result = bundleDTO; - } - } - return result; - } /** * Controls the HTTP GET requests for the URL /bundle/list. Shows the list of bundles. @@ -137,7 +108,7 @@ public String listBundles(final Model model) { @PreAuthorize("hasRole('ROLE_EDITOR')") public String fillBundle(@RequestParam(value = "id", required = false) final Long bundleId, final Model model) { - BundleDTO bundleDTO = getBundleDTO(bundleId); + BundleDTO bundleDTO = bundleService.getBundleDTO(bundleId); model.addAttribute("bundleDTO", bundleDTO); model.addAttribute("availableLocales", LocaleHelper.getAvailableLocales()); model.addAttribute("availableQuestionnaireDTOs", bundleService.getAvailableQuestionnaires(bundleId)); diff --git a/src/main/java/de/imi/mopat/helper/controller/BundleService.java b/src/main/java/de/imi/mopat/helper/controller/BundleService.java index 9dd04360..e9e9c260 100644 --- a/src/main/java/de/imi/mopat/helper/controller/BundleService.java +++ b/src/main/java/de/imi/mopat/helper/controller/BundleService.java @@ -7,6 +7,7 @@ import de.imi.mopat.dao.ExportTemplateDao; import de.imi.mopat.dao.QuestionnaireDao; import de.imi.mopat.dao.ScoreDao; +import de.imi.mopat.helper.model.BundleDTOMapper; import de.imi.mopat.helper.model.QuestionnaireDTOMapper; import de.imi.mopat.model.Bundle; import de.imi.mopat.model.BundleQuestionnaire; @@ -52,6 +53,37 @@ public class BundleService { private AclClassDao aclClassDao; @Autowired private AclObjectIdentityDao aclObjectIdentityDao; + @Autowired + private BundleDTOMapper bundleDTOMapper; + + /** + * Retrieves a BundleDTO for the given bundle ID. + * + * @param id The ID of the bundle. + * @return The corresponding BundleDTO or a new instance if the bundle is not found. + */ + public BundleDTO getBundleDTO(final Long id) { + if (id == null || id <= 0) { + return new BundleDTO(); + } + + Bundle bundle = bundleDao.getElementById(id); + if (bundle == null) { + return new BundleDTO(); + } + + BundleDTO bundleDTO = bundleDTOMapper.apply(true, bundle); + + bundleDTO.getBundleQuestionnaireDTOs().forEach(bundleQuestionnaireDTO -> { + QuestionnaireDTO questionnaireDTO = bundleQuestionnaireDTO.getQuestionnaireDTO(); + if (questionnaireDTO != null && questionnaireDTO.getId() != null) { + questionnaireDTO.setHasScores(scoreDao.hasScore(questionnaireDao.getElementById(questionnaireDTO.getId()))); + } + }); + + return bundleDTO; + } + /** * Retrieves all available {@link QuestionnaireDTO} objects that are not currently assigned From f3f9a062f337df315af39e353927697dab687f07 Mon Sep 17 00:00:00 2001 From: schluebbo Date: Thu, 20 Feb 2025 10:13:30 +0100 Subject: [PATCH 13/13] Add JavaDoc for BundleService methods. --- .../helper/controller/BundleService.java | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/main/java/de/imi/mopat/helper/controller/BundleService.java b/src/main/java/de/imi/mopat/helper/controller/BundleService.java index e9e9c260..7b8e47ed 100644 --- a/src/main/java/de/imi/mopat/helper/controller/BundleService.java +++ b/src/main/java/de/imi/mopat/helper/controller/BundleService.java @@ -86,15 +86,11 @@ public BundleDTO getBundleDTO(final Long id) { /** - * Retrieves all available {@link QuestionnaireDTO} objects that are not currently assigned - * to the {@link Bundle} with the given ID. This method filters out any questionnaires that - * have no associated questions and sorts the results first by group name, then by group ID, - * and finally by version. + * Retrieves all questionnaires that are not assigned to the given bundle. + * The list is sorted by group name, group ID, and version. * - * @param bundleId The ID of the {@link Bundle} from which unassigned questionnaires should be retrieved. - * @return A sorted list of {@link QuestionnaireDTO} objects that are not assigned to the specified bundle - * and contain at least one question. If the bundle ID is null or not found, all available questionnaires - * are returned. + * @param bundleId The ID of the bundle. + * @return A sorted list of unassigned questionnaires. */ public List getAvailableQuestionnaires(final Long bundleId) { Optional bundle = findBundleById(bundleId); @@ -175,6 +171,12 @@ public boolean isBundleModifiable(BundleDTO bundleDTO) { return bundleDTO.getId() == null || bundleDao.getElementById(bundleDTO.getId()).isModifiable(); } + /** + * Prepares a bundle for editing by cleaning text fields and ensuring + * that non-admin users cannot publish the bundle. + * + * @param bundleDTO The bundle to prepare. + */ public void prepareBundleForEdit(BundleDTO bundleDTO) { cleanUpTextFields(bundleDTO); @@ -201,8 +203,15 @@ private void removeUnassignedBundleQuestionnaires(BundleDTO bundleDTO) { ); } + /** + * Synchronizes assigned and available questionnaires. + * Ensures that assigned questionnaires are removed from the available list + * and updates missing data (ExportTemplates, QuestionnaireGroup, Scores) for assigned questionnaires. + * + * @param bundleQuestionnaireDTOS The list of assigned questionnaires. + * @param availableQuestionnaireDTOs The list of available questionnaires. + */ public void syncAssignedAndAvailableQuestionnaires(List bundleQuestionnaireDTOS, List availableQuestionnaireDTOs) { - // IDs der bereits zugewiesenen Fragebögen sammeln Set assignedIds = bundleQuestionnaireDTOS.stream() .map(BundleQuestionnaireDTO::getQuestionnaireDTO) .filter(Objects::nonNull) @@ -234,6 +243,12 @@ private void updateMissingQuestionnaireData(List assigne }); } + /** + * Saves or updates the given bundle. + * If the bundle does not exist, it is created. Otherwise, it is updated. + * + * @param bundleDTO The bundle data. + */ public void saveOrUpdateBundle(BundleDTO bundleDTO) { User currentUser = authService.getAuthenticatedUser();