templateInfoMap) {
if (templateInfoMap != null) {
return templateInfoMap.entrySet().stream()
- .map(e -> TemplateInfoDto.builder().templateId(e.getKey()).name(e.getValue()).build())
- .collect(Collectors.toList());
+ .map(e -> TemplateInfoDto.builder().templateId(e.getKey()).name(e.getValue()).build())
+ .collect(Collectors.toList());
} else {
return List.of();
}
diff --git a/src/main/java/org/highmed/numportal/mapper/UserDetailsMapper.java b/src/main/java/org/highmed/numportal/mapper/UserDetailsMapper.java
index f59aa86a..d313e8f9 100644
--- a/src/main/java/org/highmed/numportal/mapper/UserDetailsMapper.java
+++ b/src/main/java/org/highmed/numportal/mapper/UserDetailsMapper.java
@@ -2,6 +2,7 @@
import org.highmed.numportal.domain.dto.UserDetailsDto;
import org.highmed.numportal.domain.model.admin.UserDetails;
+
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
diff --git a/src/main/java/org/highmed/numportal/properties/ClamAVProperties.java b/src/main/java/org/highmed/numportal/properties/ClamAVProperties.java
index 0baaef44..bd80cc4d 100644
--- a/src/main/java/org/highmed/numportal/properties/ClamAVProperties.java
+++ b/src/main/java/org/highmed/numportal/properties/ClamAVProperties.java
@@ -4,33 +4,34 @@
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
+/**
+ * NOTE # clamd.conf setup
+ * # Close the connection when the data size limit is exceeded.
+ * # The value should match your MTA's limit for a maximum attachment size.
+ * # Default: 100M
+ * #StreamMaxLength 25M
+ *
+ *
+ * TemporaryDirectory
+ */
@Data
@Configuration
@ConfigurationProperties(prefix = "clam-av")
public class ClamAVProperties {
- /**
- * NOTE # clamd.conf setup
- * # Close the connection when the data size limit is exceeded.
- * # The value should match your MTA's limit for a maximum attachment size.
- * # Default: 100M
- * #StreamMaxLength 25M
- *
- * TemporaryDirectory
- */
-
- /**
- * TCPAddr from clamd.conf
- */
- private String host;
-
- /**
- * TCPSocket from clamd.conf
- */
- private int port;
-
- private int readTimeout;
-
- private int connectionTimeout;
+
+ /**
+ * TCPAddr from clamd.conf
+ */
+ private String host;
+
+ /**
+ * TCPSocket from clamd.conf
+ */
+ private int port;
+
+ private int readTimeout;
+
+ private int connectionTimeout;
}
diff --git a/src/main/java/org/highmed/numportal/properties/FeatureProperties.java b/src/main/java/org/highmed/numportal/properties/FeatureProperties.java
new file mode 100644
index 00000000..6ae9470a
--- /dev/null
+++ b/src/main/java/org/highmed/numportal/properties/FeatureProperties.java
@@ -0,0 +1,13 @@
+package org.highmed.numportal.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+
+@Data
+@ConfigurationProperties(prefix = "feature")
+public class FeatureProperties {
+
+ private boolean searchByManager = false;
+
+}
diff --git a/src/main/java/org/highmed/numportal/properties/PseudonymsPsnWorkflowProperties.java b/src/main/java/org/highmed/numportal/properties/PseudonymsPsnWorkflowProperties.java
index b901cfc5..b55509d8 100644
--- a/src/main/java/org/highmed/numportal/properties/PseudonymsPsnWorkflowProperties.java
+++ b/src/main/java/org/highmed/numportal/properties/PseudonymsPsnWorkflowProperties.java
@@ -9,13 +9,13 @@
@ConfigurationProperties(prefix = "requestpsnworkflow.params")
public class PseudonymsPsnWorkflowProperties {
- private String study;
+ private String study;
- private String source;
+ private String source;
- private String target;
+ private String target;
- private String apiKey;
+ private String apiKey;
- private String event;
+ private String event;
}
diff --git a/src/main/java/org/highmed/numportal/service/AqlService.java b/src/main/java/org/highmed/numportal/service/AqlService.java
index e805708b..fdbca8ac 100644
--- a/src/main/java/org/highmed/numportal/service/AqlService.java
+++ b/src/main/java/org/highmed/numportal/service/AqlService.java
@@ -1,14 +1,5 @@
package org.highmed.numportal.service;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
-import org.ehrbase.aqleditor.dto.aql.QueryValidationResponse;
-import org.ehrbase.aqleditor.dto.aql.Result;
-import org.ehrbase.aqleditor.service.AqlEditorAqlService;
-import org.ehrbase.openehr.sdk.aql.parser.AqlParseException;
import org.highmed.numportal.domain.dto.Language;
import org.highmed.numportal.domain.dto.SearchCriteria;
import org.highmed.numportal.domain.dto.SlimAqlDto;
@@ -26,17 +17,48 @@
import org.highmed.numportal.service.exception.ForbiddenException;
import org.highmed.numportal.service.exception.PrivacyException;
import org.highmed.numportal.service.exception.ResourceNotFound;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.ehrbase.aqleditor.dto.aql.QueryValidationResponse;
+import org.ehrbase.aqleditor.dto.aql.Result;
+import org.ehrbase.aqleditor.service.AqlEditorAqlService;
+import org.ehrbase.openehr.sdk.aql.parser.AqlParseException;
import org.springframework.dao.EmptyResultDataAccessException;
-import org.springframework.data.domain.*;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.JpaSort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.OffsetDateTime;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
import java.util.stream.Collectors;
-import static org.highmed.numportal.domain.templates.ExceptionsTemplate.*;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.AQL_EDIT_FOR_AQL_WITH_ID_IS_NOT_ALLOWED_AQL_HAS_DIFFERENT_OWNER;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.AQL_NOT_FOUND;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.CANNOT_ACCESS_THIS_AQL;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.CANNOT_DELETE_AQL;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.CANNOT_FIND_AQL;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.CATEGORY_BY_ID_NOT_FOUND;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.CATEGORY_ID_CANT_BE_NULL;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.CATEGORY_WITH_ID_DOES_NOT_EXIST;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.COULD_NOT_SERIALIZE_AQL_VALIDATION_RESPONSE;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.INVALID_AQL_ID;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.THE_CATEGORY_IS_NOT_EMPTY_CANT_DELETE_IT;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.TOO_FEW_MATCHES_RESULTS_WITHHELD_FOR_PRIVACY_REASONS;
@Slf4j
@Service
@@ -52,7 +74,8 @@ public class AqlService {
private static final String AQL_CATEGORY = "category";
private static final List AQL_CATEGORY_SORT_FIELDS = Arrays.asList("name-de", "name-en");
- private static final List AQL_QUERY_SORT_FIELDS = Arrays.asList(AQL_NAME_GERMAN, AQL_NAME_ENGLISH, AUTHOR_NAME, ORGANIZATION_NAME, AQL_CREATE_DATE, AQL_CATEGORY);
+ private static final List AQL_QUERY_SORT_FIELDS = Arrays.asList(
+ AQL_NAME_GERMAN, AQL_NAME_ENGLISH, AUTHOR_NAME, ORGANIZATION_NAME, AQL_CREATE_DATE, AQL_CATEGORY);
private final AqlRepository aqlRepository;
private final AqlCategoryRepository aqlCategoryRepository;
private final EhrBaseService ehrBaseService;
@@ -64,7 +87,7 @@ public class AqlService {
private final UserService userService;
/**
- * Counts the number of aql queries existing in the platform
+ * Counts the number of aql queries existing in the platform.
*
* @return The number of existing AQL queries in the platform
*/
@@ -77,7 +100,7 @@ public Aql getAqlById(Long id, String loggedInUserId) {
var aql =
aqlRepository.findById(id).orElseThrow(
- () -> new ResourceNotFound(AqlService.class, AQL_NOT_FOUND, String.format(AQL_NOT_FOUND, id)));
+ () -> new ResourceNotFound(AqlService.class, AQL_NOT_FOUND, String.format(AQL_NOT_FOUND, id)));
if (aql.isViewable(loggedInUserId)) {
return aql;
@@ -94,12 +117,12 @@ public List getVisibleAqls(String loggedInUserId) {
public Page getVisibleAqls(String loggedInUserId, Pageable pageable, SearchCriteria searchCriteria) {
UserDetails userDetails = userDetailsService.checkIsUserApproved(loggedInUserId);
- Sort sort = validateAndGetSortForAQLQuery(searchCriteria);
+ Sort sort = validateAndGetSortForAqlQuery(searchCriteria);
Pageable pageRequest;
Page aqlPage;
List aqlQueries;
if (!searchCriteria.isSortByAuthor()) {
- if(AQL_CATEGORY.equals(searchCriteria.getSortBy())) {
+ if (AQL_CATEGORY.equals(searchCriteria.getSortBy())) {
// sort send on page request messes up the generated query for order by and ignores what is inside aql specification
pageRequest = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize());
} else {
@@ -117,22 +140,23 @@ public Page getVisibleAqls(String loggedInUserId, Pageable pageable, Search
}
Language language = Objects.nonNull(searchCriteria.getLanguage()) ? searchCriteria.getLanguage() : Language.de;
AqlSpecification aqlSpecification = AqlSpecification.builder()
- .filter(searchCriteria.getFilter())
- .loggedInUserId(loggedInUserId)
- .loggedInUserOrganizationId((userDetails.getOrganization() != null) ? userDetails.getOrganization().getId() : null)
- .ownersUUID(usersUUID)
- .language(language)
- .sortOrder(sort.getOrderFor(searchCriteria.getSortBy()))
- .build();
+ .filter(searchCriteria.getFilter())
+ .loggedInUserId(loggedInUserId)
+ .loggedInUserOrganizationId(
+ (userDetails.getOrganization() != null) ? userDetails.getOrganization().getId() : null)
+ .ownersUUID(usersUUID)
+ .language(language)
+ .sortOrder(sort.getOrderFor(searchCriteria.getSortBy()))
+ .build();
aqlPage = aqlRepository.findAll(aqlSpecification, pageRequest);
aqlQueries = new ArrayList<>(aqlPage.getContent());
if (searchCriteria.isSortByAuthor()) {
sortAqlQueries(aqlQueries, sort);
aqlQueries = aqlQueries.stream()
- .skip((long) pageable.getPageNumber() * pageable.getPageSize())
- .limit(pageable.getPageSize())
- .collect(Collectors.toList());
+ .skip((long) pageable.getPageNumber() * pageable.getPageSize())
+ .limit(pageable.getPageSize())
+ .collect(Collectors.toList());
}
return new PageImpl<>(aqlQueries, pageable, aqlPage.getTotalElements());
}
@@ -154,13 +178,14 @@ private void sortAqlQueries(List aqlQueries, Sort sort) {
}
}
}
+
public Aql createAql(Aql aql, String loggedInUserId, Long aqlCategoryId) {
var userDetails = userDetailsService.checkIsUserApproved(loggedInUserId);
if (Objects.nonNull(aqlCategoryId)) {
AqlCategory aqlCategory = aqlCategoryRepository.findById(aqlCategoryId).orElseThrow(() ->
- new ResourceNotFound(AqlService.class, CATEGORY_BY_ID_NOT_FOUND,
- String.format(CATEGORY_BY_ID_NOT_FOUND, aqlCategoryId)));
+ new ResourceNotFound(AqlService.class, CATEGORY_BY_ID_NOT_FOUND,
+ String.format(CATEGORY_BY_ID_NOT_FOUND, aqlCategoryId)));
aql.setCategory(aqlCategory);
}
@@ -180,13 +205,13 @@ public Aql updateAql(Aql aql, Long aqlId, String loggedInUserId, Long aqlCategor
.orElseThrow(() -> new ResourceNotFound(AqlService.class, CANNOT_FIND_AQL, String.format(CANNOT_FIND_AQL, aqlId)));
if (Objects.nonNull(aqlCategoryId)) {
AqlCategory aqlCategory = aqlCategoryRepository.findById(aqlCategoryId).orElseThrow(() ->
- new ResourceNotFound(AqlService.class, CATEGORY_BY_ID_NOT_FOUND,
- String.format(CATEGORY_BY_ID_NOT_FOUND, aqlCategoryId)));
+ new ResourceNotFound(AqlService.class, CATEGORY_BY_ID_NOT_FOUND,
+ String.format(CATEGORY_BY_ID_NOT_FOUND, aqlCategoryId)));
aqlToEdit.setCategory(aqlCategory);
}
if (aqlToEdit.hasEmptyOrDifferentOwner(loggedInUserId)) {
- throw new ForbiddenException( AqlService.class, AQL_EDIT_FOR_AQL_WITH_ID_IS_NOT_ALLOWED_AQL_HAS_DIFFERENT_OWNER,
+ throw new ForbiddenException(AqlService.class, AQL_EDIT_FOR_AQL_WITH_ID_IS_NOT_ALLOWED_AQL_HAS_DIFFERENT_OWNER,
String.format(AQL_EDIT_FOR_AQL_WITH_ID_IS_NOT_ALLOWED_AQL_HAS_DIFFERENT_OWNER, aqlId));
}
@@ -225,19 +250,19 @@ public long getAqlSize(SlimAqlDto aql, String userId) {
validateQuery(aql.getQuery());
- Set ehrIds;
+ int numberOfPatients;
try {
- ehrIds =
- ehrBaseService.retrieveEligiblePatientIds(Aql.builder().query(aql.getQuery()).build());
+ numberOfPatients =
+ ehrBaseService.retrieveNumberOfPatients(Aql.builder().query(aql.getQuery()).build());
} catch (AqlParseException e) {
throw new BadRequestException(AqlParseException.class, e.getLocalizedMessage(), e.getMessage());
}
- if (ehrIds.size() < privacyProperties.getMinHits()) {
+ if (numberOfPatients < privacyProperties.getMinHits()) {
log.warn(TOO_FEW_MATCHES_RESULTS_WITHHELD_FOR_PRIVACY_REASONS);
throw new PrivacyException(AqlService.class, TOO_FEW_MATCHES_RESULTS_WITHHELD_FOR_PRIVACY_REASONS);
}
- return ehrIds.size();
+ return numberOfPatients;
}
public List getAqlCategories() {
@@ -281,6 +306,7 @@ public void deleteCategoryById(String loggedInUserId, Long id) {
throw new BadRequestException(AqlService.class, THE_CATEGORY_IS_NOT_EMPTY_CANT_DELETE_IT);
}
}
+
public boolean existsById(Long aqlId) {
return aqlRepository.existsById(aqlId);
}
@@ -300,7 +326,7 @@ private void validateQuery(String query) {
try {
log.error("AQL validation for query '{}' failed: {}", query, response.getMessage());
throw new BadRequestException(QueryValidationResponse.class, COULD_NOT_SERIALIZE_AQL_VALIDATION_RESPONSE,
- String.format(COULD_NOT_SERIALIZE_AQL_VALIDATION_RESPONSE, mapper.writeValueAsString(response)));
+ String.format(COULD_NOT_SERIALIZE_AQL_VALIDATION_RESPONSE, mapper.writeValueAsString(response)));
} catch (JsonProcessingException e) {
log.error(COULD_NOT_SERIALIZE_AQL_VALIDATION_RESPONSE, e);
}
@@ -329,7 +355,7 @@ private Optional validateAndGetSort(SearchCriteria searchCriteria) {
return Optional.of(JpaSort.unsafe(Sort.Direction.ASC, "name->>'de'"));
}
- private Sort validateAndGetSortForAQLQuery(SearchCriteria searchCriteria) {
+ private Sort validateAndGetSortForAqlQuery(SearchCriteria searchCriteria) {
if (searchCriteria.isValid() && StringUtils.isNotEmpty(searchCriteria.getSortBy())) {
if (!AQL_QUERY_SORT_FIELDS.contains(searchCriteria.getSortBy())) {
throw new BadRequestException(AqlService.class, String.format("Invalid %s sortBy field for aql queries", searchCriteria.getSortBy()));
diff --git a/src/main/java/org/highmed/numportal/service/CohortService.java b/src/main/java/org/highmed/numportal/service/CohortService.java
index dbcace65..815b18e4 100644
--- a/src/main/java/org/highmed/numportal/service/CohortService.java
+++ b/src/main/java/org/highmed/numportal/service/CohortService.java
@@ -11,6 +11,17 @@
import org.highmed.numportal.domain.repository.CohortRepository;
import org.highmed.numportal.domain.repository.ProjectRepository;
import org.highmed.numportal.properties.PrivacyProperties;
+import org.highmed.numportal.service.ehrbase.EhrBaseService;
+import org.highmed.numportal.service.exception.BadRequestException;
+import org.highmed.numportal.service.exception.ForbiddenException;
+import org.highmed.numportal.service.exception.PrivacyException;
+import org.highmed.numportal.service.exception.ResourceNotFound;
+import org.highmed.numportal.service.executors.CohortExecutor;
+import org.highmed.numportal.service.policy.EhrPolicy;
+import org.highmed.numportal.service.policy.Policy;
+import org.highmed.numportal.service.policy.ProjectPolicyService;
+import org.highmed.numportal.service.policy.TemplatesPolicy;
+
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
@@ -25,41 +36,36 @@
import org.ehrbase.openehr.sdk.aql.parser.AqlQueryParser;
import org.ehrbase.openehr.sdk.aql.render.AqlRenderer;
import org.ehrbase.openehr.sdk.response.dto.QueryResponseData;
-import org.highmed.numportal.service.ehrbase.EhrBaseService;
-import org.highmed.numportal.service.exception.BadRequestException;
-import org.highmed.numportal.service.exception.ForbiddenException;
-import org.highmed.numportal.service.exception.PrivacyException;
-import org.highmed.numportal.service.exception.ResourceNotFound;
-import org.highmed.numportal.service.executors.CohortExecutor;
-import org.highmed.numportal.service.policy.EhrPolicy;
-import org.highmed.numportal.service.policy.Policy;
-import org.highmed.numportal.service.policy.ProjectPolicyService;
-import org.highmed.numportal.service.policy.TemplatesPolicy;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Service;
-import java.util.*;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
import java.util.stream.Collectors;
-import static org.highmed.numportal.domain.templates.ExceptionsTemplate.*;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.CHANGING_COHORT_ONLY_ALLOWED_BY_THE_OWNER_OF_THE_PROJECT;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.COHORT_CHANGE_ONLY_ALLOWED_ON_PROJECT_STATUS_DRAFT_OR_PENDING;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.COHORT_GROUP_CANNOT_BE_EMPTY;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.COHORT_NOT_FOUND;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.INVALID_AQL_ID;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.INVALID_COHORT_GROUP_AQL_MISSING;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.INVALID_COHORT_GROUP_AQL_MISSING_PARAMETERS;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.INVALID_COHORT_GROUP_CHILDREN_MISSING;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.PROJECT_NOT_FOUND;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.RESULTS_WITHHELD_FOR_PRIVACY_REASONS;
@Slf4j
@Service
@AllArgsConstructor
public class CohortService {
- private final CohortRepository cohortRepository;
- private final CohortExecutor cohortExecutor;
- private final UserDetailsService userDetailsService;
- private final ModelMapper modelMapper;
- private final AqlService aqlService;
- private final ProjectRepository projectRepository;
- private final PrivacyProperties privacyProperties;
- private final ProjectPolicyService policyService;
- private final EhrBaseService ehrBaseService;
- private final ContentService contentService;
- private final TemplateService templateService;
-
public static final String GET_PATIENTS_PER_CLINIC =
"SELECT e/ehr_id/value as patient_id "
+ "FROM EHR e CONTAINS COMPOSITION c "
@@ -74,11 +80,22 @@ public class CohortService {
private static final String AGE_INTERVAL_LABEL = "%d-%d";
private static final int MAX_AGE = 122;
private static final int AGE_INTERVAL = 10;
+ private final CohortRepository cohortRepository;
+ private final CohortExecutor cohortExecutor;
+ private final UserDetailsService userDetailsService;
+ private final ModelMapper modelMapper;
+ private final AqlService aqlService;
+ private final ProjectRepository projectRepository;
+ private final PrivacyProperties privacyProperties;
+ private final ProjectPolicyService policyService;
+ private final EhrBaseService ehrBaseService;
+ private final ContentService contentService;
+ private final TemplateService templateService;
public Cohort getCohort(Long cohortId, String userId) {
userDetailsService.checkIsUserApproved(userId);
return cohortRepository.findById(cohortId).orElseThrow(
- () -> new ResourceNotFound(CohortService.class, COHORT_NOT_FOUND, String.format(COHORT_NOT_FOUND, cohortId)));
+ () -> new ResourceNotFound(CohortService.class, COHORT_NOT_FOUND, String.format(COHORT_NOT_FOUND, cohortId)));
}
public Cohort createCohort(CohortDto cohortDto, String userId) {
@@ -94,11 +111,11 @@ public Cohort createCohort(CohortDto cohortDto, String userId) {
Cohort cohort =
Cohort.builder()
- .name(cohortDto.getName())
- .description(cohortDto.getDescription())
- .project(project)
- .cohortGroup(convertToCohortGroupEntity(cohortDto.getCohortGroup()))
- .build();
+ .name(cohortDto.getName())
+ .description(cohortDto.getDescription())
+ .project(project)
+ .cohortGroup(convertToCohortGroupEntity(cohortDto.getCohortGroup()))
+ .build();
project.setCohort(cohort);
log.info("Cohort created by user {}", userId);
@@ -107,10 +124,10 @@ public Cohort createCohort(CohortDto cohortDto, String userId) {
public Cohort toCohort(CohortDto cohortDto) {
return Cohort.builder()
- .name(cohortDto.getName())
- .description(cohortDto.getDescription())
- .cohortGroup(convertToCohortGroupEntity(cohortDto.getCohortGroup()))
- .build();
+ .name(cohortDto.getName())
+ .description(cohortDto.getDescription())
+ .cohortGroup(convertToCohortGroupEntity(cohortDto.getCohortGroup()))
+ .build();
}
public Set executeCohort(long cohortId, Boolean allowUsageOutsideEu) {
@@ -140,8 +157,8 @@ public Map getSizePerTemplates(
Cohort cohort =
Cohort.builder()
- .cohortGroup(convertToCohortGroupEntity(requestDto.getCohortDto().getCohortGroup()))
- .build();
+ .cohortGroup(convertToCohortGroupEntity(requestDto.getCohortDto().getCohortGroup()))
+ .build();
Set ehrIds = cohortExecutor.execute(cohort, false);
if (ehrIds.size() < privacyProperties.getMinHits()) {
@@ -253,7 +270,7 @@ private void validateCohortParameters(CohortGroupDto cohortGroupDto) {
}
if (CollectionUtils.isNotEmpty(cohortGroupDto.getChildren())) {
cohortGroupDto.getChildren()
- .forEach(this::validateCohortParameters);
+ .forEach(this::validateCohortParameters);
}
}
@@ -269,7 +286,7 @@ private CohortGroup convertToCohortGroupEntity(CohortGroupDto cohortGroupDto) {
if (cohortGroupDto.getQuery() != null && cohortGroupDto.getQuery().getId() != null) {
if (!aqlService.existsById(cohortGroupDto.getQuery().getId())) {
throw new BadRequestException(CohortGroup.class, INVALID_AQL_ID,
- String.format("%s: %s", INVALID_AQL_ID, cohortGroupDto.getQuery().getId()));
+ String.format("%s: %s", INVALID_AQL_ID, cohortGroupDto.getQuery().getId()));
}
} else {
throw new BadRequestException(CohortGroup.class, INVALID_COHORT_GROUP_AQL_MISSING);
@@ -279,14 +296,14 @@ private CohortGroup convertToCohortGroupEntity(CohortGroupDto cohortGroupDto) {
if (cohortGroupDto.isGroup()) {
if (CollectionUtils.isNotEmpty(cohortGroup.getChildren())) {
cohortGroup.setChildren(
- cohortGroupDto.getChildren().stream()
- .map(
- child -> {
- CohortGroup cohortGroupChild = convertToCohortGroupEntity(child);
- cohortGroupChild.setParent(cohortGroup);
- return cohortGroupChild;
- })
- .collect(Collectors.toList()));
+ cohortGroupDto.getChildren().stream()
+ .map(
+ child -> {
+ CohortGroup cohortGroupChild = convertToCohortGroupEntity(child);
+ cohortGroupChild.setParent(cohortGroup);
+ return cohortGroupChild;
+ })
+ .collect(Collectors.toList()));
} else {
throw new BadRequestException(CohortService.class, INVALID_COHORT_GROUP_CHILDREN_MISSING);
}
@@ -348,7 +365,7 @@ private Map getSizesPerHospital(String loggedInUserId, String i
for (String clinic : clinics) {
if (Objects.nonNull(clinic)) {
QueryResponseData queryResponseData =
- ehrBaseService.executePlainQuery(String.format(GET_PATIENTS_PER_CLINIC, clinic, idsString));
+ ehrBaseService.executePlainQuery(String.format(GET_PATIENTS_PER_CLINIC, clinic, idsString));
List> rows = queryResponseData.getRows();
if (rows == null) {
sizes.put(clinic, 0);
diff --git a/src/main/java/org/highmed/numportal/service/CommentService.java b/src/main/java/org/highmed/numportal/service/CommentService.java
index 299ef761..6858647c 100644
--- a/src/main/java/org/highmed/numportal/service/CommentService.java
+++ b/src/main/java/org/highmed/numportal/service/CommentService.java
@@ -4,17 +4,23 @@
import org.highmed.numportal.domain.model.Project;
import org.highmed.numportal.domain.model.admin.UserDetails;
import org.highmed.numportal.domain.repository.CommentRepository;
-import lombok.AllArgsConstructor;
import org.highmed.numportal.service.exception.BadRequestException;
import org.highmed.numportal.service.exception.ForbiddenException;
import org.highmed.numportal.service.exception.ResourceNotFound;
+
+import lombok.AllArgsConstructor;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.stereotype.Service;
import java.time.OffsetDateTime;
import java.util.List;
-import static org.highmed.numportal.domain.templates.ExceptionsTemplate.*;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.CANNOT_DELETE_COMMENT;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.COMMENT_EDIT_FOR_COMMENT_WITH_ID_IS_NOT_ALLOWED_COMMENT_HAS_DIFFERENT_AUTHOR;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.COMMENT_NOT_FOUND;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.INVALID_COMMENT_ID;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.PROJECT_DOES_NOT_EXIST;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.PROJECT_NOT_FOUND;
@Service
@AllArgsConstructor
diff --git a/src/main/java/org/highmed/numportal/service/ContentService.java b/src/main/java/org/highmed/numportal/service/ContentService.java
index d0658135..9969ef2c 100644
--- a/src/main/java/org/highmed/numportal/service/ContentService.java
+++ b/src/main/java/org/highmed/numportal/service/ContentService.java
@@ -1,6 +1,5 @@
package org.highmed.numportal.service;
-import com.fasterxml.jackson.databind.ObjectMapper;
import org.highmed.numportal.domain.dto.CardDto;
import org.highmed.numportal.domain.dto.MetricsDto;
import org.highmed.numportal.domain.dto.NavigationItemDto;
@@ -8,10 +7,12 @@
import org.highmed.numportal.domain.model.Content;
import org.highmed.numportal.domain.model.ContentType;
import org.highmed.numportal.domain.repository.ContentItemRepository;
-import lombok.extern.slf4j.Slf4j;
-import org.ehrbase.openehr.sdk.response.dto.QueryResponseData;
import org.highmed.numportal.service.ehrbase.EhrBaseService;
import org.highmed.numportal.service.exception.SystemException;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.ehrbase.openehr.sdk.response.dto.QueryResponseData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@@ -22,46 +23,38 @@
import java.util.Map;
import java.util.stream.Collectors;
-import static org.highmed.numportal.domain.templates.ExceptionsTemplate.*;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.COULDN_T_PARSE_CARD;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.COULDN_T_PARSE_NAVIGATION_CONTENT;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.COULDN_T_SAVE_CARD;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.COULDN_T_SAVE_NAVIGATION_CONTENT;
@Slf4j
@Service
public class ContentService {
- private final ContentItemRepository contentItemRepository;
-
- private final ObjectMapper mapper;
-
- private final ProjectService projectService;
-
- private final AqlService aqlService;
-
- private final OrganizationService organizationService;
-
- private final EhrBaseService ehrBaseService;
-
- private final UserDetailsService userDetailsService;
-
+ public static final String LIST_CLINICS =
+ "SELECT distinct c/context/health_care_facility/name as health_care_facility FROM EHR e CONTAINS COMPOSITION c";
private static final int PROJECT_COUNT = 5;
-
private static final int SOFA_MIN = 0;
private static final int SOFA_MAX = 24;
private static final int SOFA_INTERVAL_LEN = 5;
-
- public static final String LIST_CLINICS =
- "SELECT distinct c/context/health_care_facility/name as health_care_facility FROM EHR e CONTAINS COMPOSITION c";
-
private static final String GET_CLINIC_SOFA_AVG =
"SELECT avg(r/data[at0001]/events[at0002]/data[at0003]/items[at0041]/value/magnitude) as sofa_avg "
+ "FROM EHR e CONTAINS COMPOSITION c CONTAINS OBSERVATION r[openEHR-EHR-OBSERVATION.sofa_score.v0] "
+ "WHERE c/context/health_care_facility/name = '%s'";
-
private static final String GET_CLINIC_SOFA_COUNT_IN_INTERVAL =
"SELECT count(r/data[at0001]/events[at0002]/data[at0003]/items[at0041]/value/magnitude) as sofa_score "
+ "FROM EHR e CONTAINS COMPOSITION c CONTAINS OBSERVATION r[openEHR-EHR-OBSERVATION.sofa_score.v0] "
+ "WHERE r/data[at0001]/events[at0002]/data[at0003]/items[at0041]/value/magnitude >= %d "
+ "AND r/data[at0001]/events[at0002]/data[at0003]/items[at0041]/value/magnitude <= %d "
+ "AND c/context/health_care_facility/name = '%s'";
+ private final ContentItemRepository contentItemRepository;
+ private final ObjectMapper mapper;
+ private final ProjectService projectService;
+ private final AqlService aqlService;
+ private final OrganizationService organizationService;
+ private final EhrBaseService ehrBaseService;
+ private final UserDetailsService userDetailsService;
@Autowired
public ContentService(
@@ -97,91 +90,92 @@ public List getLatestProjects(List roles) {
*/
public MetricsDto getMetrics() {
return MetricsDto.builder()
- .aqls(aqlService.countAqls())
- .projects(projectService.countProjects())
- .organizations(organizationService.countOrganizations())
- .build();
+ .aqls(aqlService.countAqls())
+ .projects(projectService.countProjects())
+ .organizations(organizationService.countOrganizations())
+ .build();
}
public String getNavigationItems() {
try {
- List contents =
- contentItemRepository.findByType(ContentType.NAVIGATION).orElse(new ArrayList<>());
- if (contents.isEmpty()) {
- return "[]";
- } else {
- return contents.get(0).getContent();
- }
- } catch (Exception e) {
- log.error("Couldn't parse navigation content", e);
- throw new SystemException(ContentService.class, COULDN_T_PARSE_NAVIGATION_CONTENT, String.format(COULDN_T_PARSE_NAVIGATION_CONTENT, e.getMessage()));
+ List contents =
+ contentItemRepository.findByType(ContentType.NAVIGATION).orElse(new ArrayList<>());
+ if (contents.isEmpty()) {
+ return "[]";
+ } else {
+ return contents.get(0).getContent();
}
+ } catch (Exception e) {
+ log.error("Couldn't parse navigation content", e);
+ throw new SystemException(
+ ContentService.class, COULDN_T_PARSE_NAVIGATION_CONTENT, String.format(COULDN_T_PARSE_NAVIGATION_CONTENT, e.getMessage()));
+ }
}
public void setNavigationItems(List navigationItemDtos) {
- try {
- List contents =
- contentItemRepository.findByType(ContentType.NAVIGATION).orElse(new ArrayList<>());
- Content navigation;
- if (contents.isEmpty()) {
- navigation = Content.builder().type(ContentType.NAVIGATION).build();
- } else {
- navigation = contents.get(0);
- }
-
- navigation.setContent(mapper.writeValueAsString(navigationItemDtos));
- contentItemRepository.save(navigation);
+ try {
+ List contents =
+ contentItemRepository.findByType(ContentType.NAVIGATION).orElse(new ArrayList<>());
+ Content navigation;
+ if (contents.isEmpty()) {
+ navigation = Content.builder().type(ContentType.NAVIGATION).build();
+ } else {
+ navigation = contents.get(0);
+ }
+
+ navigation.setContent(mapper.writeValueAsString(navigationItemDtos));
+ contentItemRepository.save(navigation);
} catch (Exception e) {
log.error("Couldn't save navigation content", e);
throw new SystemException(ContentService.class, COULDN_T_SAVE_NAVIGATION_CONTENT,
- String.format(COULDN_T_SAVE_NAVIGATION_CONTENT, e.getMessage()));
+ String.format(COULDN_T_SAVE_NAVIGATION_CONTENT, e.getMessage()));
}
}
public String getCards() {
- try {
- List contents =
- contentItemRepository.findByType(ContentType.CARD).orElse(new ArrayList<>());
- if (contents.isEmpty()) {
- return "[]";
- } else {
-
- return contents.get(0).getContent();
- }
- } catch (Exception e) {
- log.error("Couldn't parse card", e);
- throw new SystemException(ContentService.class, COULDN_T_PARSE_CARD,
- String.format(COULDN_T_PARSE_CARD, e.getMessage()));
+ try {
+ List contents =
+ contentItemRepository.findByType(ContentType.CARD).orElse(new ArrayList<>());
+ if (contents.isEmpty()) {
+ return "[]";
+ } else {
+
+ return contents.get(0).getContent();
}
+ } catch (Exception e) {
+ log.error("Couldn't parse card", e);
+ throw new SystemException(ContentService.class, COULDN_T_PARSE_CARD,
+ String.format(COULDN_T_PARSE_CARD, e.getMessage()));
+ }
}
public void setCards(List cardDtos) {
try {
- List contents =
- contentItemRepository.findByType(ContentType.CARD).orElse(new ArrayList<>());
- Content navigation;
- if (contents.isEmpty()) {
- navigation = Content.builder().type(ContentType.CARD).build();
- } else {
- navigation = contents.get(0);
- }
-
- navigation.setContent(mapper.writeValueAsString(cardDtos));
- contentItemRepository.save(navigation);
+ List contents =
+ contentItemRepository.findByType(ContentType.CARD).orElse(new ArrayList<>());
+ Content navigation;
+ if (contents.isEmpty()) {
+ navigation = Content.builder().type(ContentType.CARD).build();
+ } else {
+ navigation = contents.get(0);
+ }
+
+ navigation.setContent(mapper.writeValueAsString(cardDtos));
+ contentItemRepository.save(navigation);
} catch (Exception e) {
log.error("Couldn't save card", e);
throw new SystemException(ContentService.class, COULDN_T_SAVE_CARD,
- String.format(COULDN_T_SAVE_CARD, e.getMessage()));
+ String.format(COULDN_T_SAVE_CARD, e.getMessage()));
}
}
- public List getClinics(String loggedInUserId) {
- userDetailsService.checkIsUserApproved(loggedInUserId);
- QueryResponseData responseData = ehrBaseService.executePlainQuery(LIST_CLINICS);
- return responseData.getRows().stream()
- .map(row -> (String) row.get(0))
- .collect(Collectors.toList());
- }
+ public List getClinics(String loggedInUserId) {
+ userDetailsService.checkIsUserApproved(loggedInUserId);
+ QueryResponseData responseData = ehrBaseService.executePlainQuery(LIST_CLINICS);
+ return responseData.getRows().stream()
+ .map(row -> (String) row.get(0))
+ .collect(Collectors.toList());
+ }
public Map getClinicDistributions(String name) {
Map distributions = new LinkedHashMap<>();
@@ -202,7 +196,7 @@ public Map getClinicDistributions(String name) {
}
public Map getClinicAverages(String loggedInUserId) {
- userDetailsService.checkIsUserApproved(loggedInUserId);
+ userDetailsService.checkIsUserApproved(loggedInUserId);
Map averages = new LinkedHashMap<>();
List clinics = getClinics(loggedInUserId);
for (String clinic : clinics) {
diff --git a/src/main/java/org/highmed/numportal/service/ManagerService.java b/src/main/java/org/highmed/numportal/service/ManagerService.java
new file mode 100644
index 00000000..0525f88a
--- /dev/null
+++ b/src/main/java/org/highmed/numportal/service/ManagerService.java
@@ -0,0 +1,105 @@
+package org.highmed.numportal.service;
+
+import org.highmed.numportal.domain.dto.CohortDto;
+import org.highmed.numportal.domain.model.ExportType;
+import org.highmed.numportal.domain.model.Organization;
+import org.highmed.numportal.domain.model.Project;
+import org.highmed.numportal.domain.model.ProjectStatus;
+import org.highmed.numportal.domain.model.admin.UserDetails;
+import org.highmed.numportal.service.atna.AtnaService;
+import org.highmed.numportal.service.exception.SystemException;
+import org.highmed.numportal.service.util.ExportUtil;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.ehrbase.openehr.sdk.response.dto.QueryResponseData;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
+
+import java.time.LocalDate;
+import java.time.OffsetDateTime;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.ERROR_WHILE_RETRIEVING_DATA;
+
+
+@Service
+@Slf4j
+@AllArgsConstructor
+public class ManagerService {
+
+ private final UserDetailsService userDetailsService;
+
+ private final AtnaService atnaService;
+
+ private final CohortService cohortService;
+
+ private final ExportUtil exportUtil;
+
+ private final ObjectMapper mapper;
+
+
+ public String executeManagerProject(CohortDto cohortDto, List templates, String userId) {
+ var queryResponse = StringUtils.EMPTY;
+ var project = createManagerProject();
+ try {
+ userDetailsService.checkIsUserApproved(userId);
+ var templateMap = CollectionUtils.isNotEmpty(templates) ? templates.stream().collect(Collectors.toMap(k -> k, v -> v)) : Collections.emptyMap();
+ List responseData =
+ exportUtil.executeDefaultConfiguration(
+ project.getId(), cohortService.toCohort(cohortDto), (Map) templateMap);
+ queryResponse = mapper.writeValueAsString(responseData);
+
+ } catch (Exception e) {
+ atnaService.logDataExport(userId, project.getId(), project, false);
+ throw new SystemException(ProjectService.class, ERROR_WHILE_RETRIEVING_DATA,
+ String.format(ERROR_WHILE_RETRIEVING_DATA, e.getLocalizedMessage()));
+ }
+ atnaService.logDataExport(userId, project.getId(), project, true);
+ return queryResponse;
+ }
+
+ public StreamingResponseBody getManagerExportResponseBody(CohortDto cohortDto, List templates, String userId, ExportType format) {
+ userDetailsService.checkIsUserApproved(userId);
+ var project = createManagerProject();
+
+ var templateMap = templates.stream().collect(Collectors.toMap(k -> k, v -> v));
+
+ List response =
+ exportUtil.executeDefaultConfiguration(
+ project.getId(), cohortService.toCohort(cohortDto), templateMap);
+
+ if (format == ExportType.json) {
+ return exportUtil.exportJson(response);
+ } else {
+ return exportUtil.exportCsv(response, project.getId());
+ }
+ }
+
+ private Project createManagerProject() {
+ var undef = "undef";
+ return Project.builder()
+ .id(0L)
+ .name("Manager data retrieval project")
+ .createDate(OffsetDateTime.now())
+ .startDate(LocalDate.now())
+ .description("Adhoc temp project for manager data retrieval")
+ .goal(undef)
+ .usedOutsideEu(false)
+ .firstHypotheses(undef)
+ .secondHypotheses(undef)
+ .description("Temporary project for manager data retrieval")
+ .coordinator(UserDetails.builder().userId(undef).organization(Organization.builder().id(0L).build()).build())
+ .status(ProjectStatus.DENIED)
+ .build();
+ }
+
+
+}
diff --git a/src/main/java/org/highmed/numportal/service/OrganizationService.java b/src/main/java/org/highmed/numportal/service/OrganizationService.java
index 85f1c317..eec3ec58 100644
--- a/src/main/java/org/highmed/numportal/service/OrganizationService.java
+++ b/src/main/java/org/highmed/numportal/service/OrganizationService.java
@@ -10,44 +10,61 @@
import org.highmed.numportal.domain.repository.OrganizationRepository;
import org.highmed.numportal.domain.specification.OrganizationSpecification;
import org.highmed.numportal.events.DeactivateUserEvent;
+import org.highmed.numportal.service.exception.BadRequestException;
+import org.highmed.numportal.service.exception.ForbiddenException;
+import org.highmed.numportal.service.exception.ResourceNotFound;
+
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
-import org.highmed.numportal.service.exception.BadRequestException;
-import org.highmed.numportal.service.exception.ForbiddenException;
-import org.highmed.numportal.service.exception.ResourceNotFound;
import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.data.domain.*;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import java.util.*;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import static org.highmed.numportal.domain.templates.ExceptionsTemplate.*;
-
-/** Service responsible for retrieving organization information from the terminology server */
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.CANNOT_ACCESS_THIS_RESOURCE;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.CANNOT_UPDATE_ORGANIZATION;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.INVALID_MAIL_DOMAIN;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.NOT_ALLOWED_TO_UPDATE_OWN_ORGANIZATION_STATUS;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.ORGANIZATION_IS_NOT_EMPTY_CANT_DELETE_IT;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.ORGANIZATION_MAIL_DOMAIN_ALREADY_EXISTS;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.ORGANIZATION_MAIL_DOMAIN_CANNOT_BE_NULL_OR_EMPTY;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.ORGANIZATION_NAME_MUST_BE_UNIQUE;
+import static org.highmed.numportal.domain.templates.ExceptionsTemplate.ORGANIZATION_NOT_FOUND;
+
+/**
+ * Service responsible for retrieving organization information from the terminology server
+ */
@Slf4j
@Service
@AllArgsConstructor
public class OrganizationService {
+ private static final String DOMAIN_SEPARATOR = "@";
+ private static final String DOMAIN_VALIDATION_REGEX =
+ "^(\\*\\.)?((?!-)[A-Za-z0-9-]{1,63}(? resolveOrganization(String email) {
public List getMailDomainsByActiveOrganizations() {
log.info("Load all mail domains from active organizations");
return mailDomainRepository.findAllByActiveOrganization().stream()
- .map(MailDomain::getName)
- .collect(Collectors.toList());
+ .map(MailDomain::getName)
+ .collect(Collectors.toList());
}
/**
@@ -90,9 +107,9 @@ public long countOrganizations() {
/**
* Retrieves a list with available organizations
*
- * @return List with available organizations
* @param roles
* @param loggedInUserId
+ * @return List with available organizations
*/
public List getAllOrganizations(List roles, String loggedInUserId) {
UserDetails user = userDetailsService.checkIsUserApproved(loggedInUserId);
@@ -107,6 +124,7 @@ public List getAllOrganizations(List roles, String loggedI
/**
* Retrieves a list with available organizations
+ *
* @param roles
* @param loggedInUserId
* @param searchCriteria
@@ -118,13 +136,15 @@ public Page getAllOrganizations(List roles, String loggedI
OrganizationSpecification organizationSpecification = new OrganizationSpecification(searchCriteria.getFilter());
Optional sortBy = validateAndGetSort(searchCriteria);
if (roles.contains(Roles.SUPER_ADMIN)) {
- PageRequest pageRequest = sortBy.map(sort -> PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), sort)).orElseGet(() -> PageRequest.of(pageable.getPageNumber(), pageable.getPageSize()));
+ PageRequest pageRequest = sortBy.map(sort -> PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), sort))
+ .orElseGet(() -> PageRequest.of(pageable.getPageNumber(), pageable.getPageSize()));
return organizationRepository.findAll(organizationSpecification, pageRequest);
} else if (roles.contains(Roles.ORGANIZATION_ADMIN)) {
return new PageImpl<>(List.of(user.getOrganization()));
}
return new PageImpl<>(Collections.emptyList());
}
+
/**
* Retrieves an organization by external identifier
*
@@ -134,8 +154,8 @@ public Page getAllOrganizations(List roles, String loggedI
public Organization getOrganizationById(Long id) {
return organizationRepository
- .findById(id)
- .orElseThrow(() -> new ResourceNotFound(OrganizationService.class, ORGANIZATION_NOT_FOUND, String.format(ORGANIZATION_NOT_FOUND, id)));
+ .findById(id)
+ .orElseThrow(() -> new ResourceNotFound(OrganizationService.class, ORGANIZATION_NOT_FOUND, String.format(ORGANIZATION_NOT_FOUND, id)));
}
@Transactional
@@ -145,68 +165,69 @@ public Organization create(String loggedInUserId, OrganizationDto organizationDt
validateUniqueOrganizationName(organizationDto.getName(), null);
validateMailDomains(organizationDto.getMailDomains());
organizationDto
- .getMailDomains()
- .forEach(
- domain -> {
- Optional mailDomain =
- mailDomainRepository.findByName(domain.toLowerCase());
- if (mailDomain.isPresent()) {
- throw new BadRequestException(Organization.class, ORGANIZATION_MAIL_DOMAIN_ALREADY_EXISTS,
- String.format(ORGANIZATION_MAIL_DOMAIN_ALREADY_EXISTS, organizationDto.getName()));
- }
- });
+ .getMailDomains()
+ .forEach(
+ domain -> {
+ Optional mailDomain =
+ mailDomainRepository.findByName(domain.toLowerCase());
+ if (mailDomain.isPresent()) {
+ throw new BadRequestException(Organization.class, ORGANIZATION_MAIL_DOMAIN_ALREADY_EXISTS,
+ String.format(ORGANIZATION_MAIL_DOMAIN_ALREADY_EXISTS, organizationDto.getName()));
+ }
+ });
Organization organization = Organization.builder()
- .name(organizationDto.getName())
- .active(Boolean.TRUE)
- .build();
+ .name(organizationDto.getName())
+ .active(Boolean.TRUE)
+ .build();
organization.setDomains(
- organizationDto.getMailDomains().stream()
- .map(
- domain ->
- MailDomain.builder()
- .name(domain.toLowerCase())
- .organization(organization)
- .build())
- .collect(Collectors.toSet()));
+ organizationDto.getMailDomains().stream()
+ .map(
+ domain ->
+ MailDomain.builder()
+ .name(domain.toLowerCase())
+ .organization(organization)
+ .build())
+ .collect(Collectors.toSet()));
return organizationRepository.save(organization);
}
@Transactional
public Organization update(
- Long organizationId,
- OrganizationDto organizationDto,
- List roles,
- String loggedInUserId) {
+ Long organizationId,
+ OrganizationDto organizationDto,
+ List roles,
+ String loggedInUserId) {
UserDetails user = userDetailsService.checkIsUserApproved(loggedInUserId);
Organization organizationToEdit =
- organizationRepository
- .findById(organizationId)
- .orElseThrow(() -> new ResourceNotFound(OrganizationService.class, ORGANIZATION_NOT_FOUND, String.format(ORGANIZATION_NOT_FOUND, organizationId)));
+ organizationRepository
+ .findById(organizationId)
+ .orElseThrow(
+ () -> new ResourceNotFound(OrganizationService.class, ORGANIZATION_NOT_FOUND, String.format(ORGANIZATION_NOT_FOUND, organizationId)));
validateStatusChange(organizationId, organizationDto.getActive(), organizationToEdit.getActive(), user);
validateUniqueOrganizationName(organizationDto.getName(), organizationId);
validateMailDomains(organizationDto.getMailDomains());
organizationDto
- .getMailDomains()
- .forEach(
- domain -> {
- Optional mailDomain =
- mailDomainRepository.findByName(domain.toLowerCase());
- if (mailDomain.isPresent()
- && !mailDomain
- .get()
- .getOrganization()
- .getId()
- .equals(organizationToEdit.getId())) {
- throw new BadRequestException(OrganizationService.class, ORGANIZATION_MAIL_DOMAIN_ALREADY_EXISTS,
- String.format(ORGANIZATION_MAIL_DOMAIN_ALREADY_EXISTS, domain));
- }
- });
+ .getMailDomains()
+ .forEach(
+ domain -> {
+ Optional mailDomain =
+ mailDomainRepository.findByName(domain.toLowerCase());
+ if (mailDomain.isPresent()
+ && !mailDomain
+ .get()
+ .getOrganization()
+ .getId()
+ .equals(organizationToEdit.getId())) {
+ throw new BadRequestException(OrganizationService.class, ORGANIZATION_MAIL_DOMAIN_ALREADY_EXISTS,
+ String.format(ORGANIZATION_MAIL_DOMAIN_ALREADY_EXISTS, domain));
+ }
+ });
if (Roles.isSuperAdmin(roles)) {
updateOrganization(organizationDto, organizationToEdit, loggedInUserId);
@@ -214,7 +235,8 @@ public Organization update(
if (user.getOrganization().getId().equals(organizationId)) {
updateOrganization(organizationDto, organizationToEdit, loggedInUserId);
} else {
- throw new ForbiddenException(OrganizationService.class, CANNOT_UPDATE_ORGANIZATION, String.format(CANNOT_UPDATE_ORGANIZATION, organizationId));
+ throw new ForbiddenException(
+ OrganizationService.class, CANNOT_UPDATE_ORGANIZATION, String.format(CANNOT_UPDATE_ORGANIZATION, organizationId));
}
} else {
throw new ForbiddenException(OrganizationService.class, CANNOT_ACCESS_THIS_RESOURCE);
@@ -245,37 +267,38 @@ public boolean isAllowedToBeDeleted(Long organizationId) {
}
private void validateMailDomains(Set domains) {
- if(Objects.nonNull(domains)) {
+ if (Objects.nonNull(domains)) {
domains.forEach(
- domain -> {
- if (StringUtils.isEmpty(domain)) {
- throw new BadRequestException(OrganizationService.class, ORGANIZATION_MAIL_DOMAIN_CANNOT_BE_NULL_OR_EMPTY);
- }
-
- if (!Pattern.matches(DOMAIN_VALIDATION_REGEX, domain.toLowerCase())) {
- throw new BadRequestException(OrganizationService.class, INVALID_MAIL_DOMAIN,
- String.format(INVALID_MAIL_DOMAIN, domain));
- }
- });
+ domain -> {
+ if (StringUtils.isEmpty(domain)) {
+ throw new BadRequestException(OrganizationService.class, ORGANIZATION_MAIL_DOMAIN_CANNOT_BE_NULL_OR_EMPTY);
+ }
+
+ if (!Pattern.matches(DOMAIN_VALIDATION_REGEX, domain.toLowerCase())) {
+ throw new BadRequestException(OrganizationService.class, INVALID_MAIL_DOMAIN,
+ String.format(INVALID_MAIL_DOMAIN, domain));
+ }
+ });
}
}
private void validateUniqueOrganizationName(String name, Long organizationId) {
organizationRepository
- .findByName(name)
- .ifPresent(
- d -> {
- if (Objects.isNull(organizationId) || !d.getId().equals(organizationId)) {
- throw new BadRequestException(OrganizationService.class, ORGANIZATION_NAME_MUST_BE_UNIQUE,
- String.format(ORGANIZATION_NAME_MUST_BE_UNIQUE, name));
- }
- });
+ .findByName(name)
+ .ifPresent(
+ d -> {
+ if (Objects.isNull(organizationId) || !d.getId().equals(organizationId)) {
+ throw new BadRequestException(OrganizationService.class, ORGANIZATION_NAME_MUST_BE_UNIQUE,
+ String.format(ORGANIZATION_NAME_MUST_BE_UNIQUE, name));
+ }
+ });
}
private void validateStatusChange(Long organizationId, Boolean newStatus, Boolean oldStatus, UserDetails loggedInUser) {
if (statusChanged(oldStatus, newStatus) && loggedInUser.getOrganization().getId().equals(organizationId)) {
log.warn("User {} is not allowed to change status for own organization {}", loggedInUser.getUserId(), organizationId);
- throw new ForbiddenException(OrganizationService.class, NOT_ALLOWED_TO_UPDATE_OWN_ORGANIZATION_STATUS, NOT_ALLOWED_TO_UPDATE_OWN_ORGANIZATION_STATUS);
+ throw new ForbiddenException(
+ OrganizationService.class, NOT_ALLOWED_TO_UPDATE_OWN_ORGANIZATION_STATUS, NOT_ALLOWED_TO_UPDATE_OWN_ORGANIZATION_STATUS);
}
}
@@ -294,30 +317,32 @@ private void updateOrganization(OrganizationDto dto, Organization organization,
if (Objects.nonNull(dto.getActive())) {
organization.setActive(dto.getActive());
if (statusChanged(oldOrganizationStatus, dto.getActive()) && Boolean.FALSE.equals(dto.getActive())) {
- log.info("Organization {} was deactivated by {}, so trigger event to deactivate all users assigned to this organization", organization.getId(), loggedInUserId);
- DeactivateUserEvent deactivateUserEvent = new DeactivateUserEvent(this, organization.getId(), loggedInUserId);
- applicationEventPublisher.publishEvent(deactivateUserEvent);
+ log.info(
+ "Organization {} was deactivated by {}, so trigger event to deactivate all users assigned to this organization", organization.getId(),
+ loggedInUserId);
+ DeactivateUserEvent deactivateUserEvent = new DeactivateUserEvent(this, organization.getId(), loggedInUserId);
+ applicationEventPublisher.publishEvent(deactivateUserEvent);
}
}
Set newDomains = new HashSet<>();
dto.getMailDomains()
- .forEach(
- domainName -> {
- Optional mailDomain =
- mailDomainRepository.findByName(domainName.toLowerCase());
- if (mailDomain.isEmpty()) {
- newDomains.add(
- mailDomainRepository.save(
- MailDomain.builder()
- .name(domainName.toLowerCase())
- .organization(organization)
- .build()));
- } else {
- newDomains.add(mailDomain.get());
- }
- });
+ .forEach(
+ domainName -> {
+ Optional mailDomain =
+ mailDomainRepository.findByName(domainName.toLowerCase());
+ if (mailDomain.isEmpty()) {
+ newDomains.add(
+ mailDomainRepository.save(
+ MailDomain.builder()
+ .name(domainName.toLowerCase())
+ .organization(organization)
+ .build()));
+ } else {
+ newDomains.add(mailDomain.get());
+ }
+ });
if (organization.getDomains() != null) {
organization.getDomains().clear();
@@ -342,8 +367,7 @@ private Optional matchOrganization(String domain) {
}
/**
- * Converts an organization email domain list into a list containing correlation between domains
- * and subdomains and sorts matches descending
+ * Converts an organization email domain list into a list containing correlation between domains and subdomains and sorts matches descending
*
* @param allDomains
* @return
@@ -352,13 +376,13 @@ private List toMailDomainDetails(List allDomains)
List mailDomainDetails = new LinkedList<>();
allDomains.forEach(
- mailDomain ->
- mailDomainDetails.add(
- MailDomainDetails.builder()
- .domain(mailDomain.getName().toLowerCase())
- .regex(domainToRegex(mailDomain.getName().toLowerCase()))
- .organization(mailDomain.getOrganization())
- .build()));
+ mailDomain ->
+ mailDomainDetails.add(
+ MailDomainDetails.builder()
+ .domain(mailDomain.getName().toLowerCase())
+ .regex(domainToRegex(mailDomain.getName().toLowerCase()))
+ .organization(mailDomain.getOrganization())
+ .build()));
for (MailDomainDetails d1 : mailDomainDetails) {
for (MailDomainDetails d2 : mailDomainDetails) {
@@ -379,10 +403,12 @@ private String domainToRegex(String domain) {
private Optional