Search in sources :

Example 1 with ExternalShareInfoCountAndLatestDate

use of de.symeda.sormas.backend.share.ExternalShareInfoCountAndLatestDate in project SORMAS-Project by hzi-braunschweig.

the class CaseFacadeEjb method getIndexDetailedList.

@Override
public List<CaseIndexDetailedDto> getIndexDetailedList(CaseCriteria caseCriteria, Integer first, Integer max, List<SortProperty> sortProperties) {
    CriteriaQuery<CaseIndexDetailedDto> cq = listQueryBuilder.buildIndexDetailedCriteria(caseCriteria, sortProperties);
    List<CaseIndexDetailedDto> cases = QueryHelper.getResultList(em, cq, first, max);
    // Load latest events info
    // Adding a second query here is not perfect, but selecting the last event with a criteria query
    // doesn't seem to be possible and using a native query is not an option because of user filters
    List<EventSummaryDetails> eventSummaries = eventService.getEventSummaryDetailsByCases(cases.stream().map(CaseIndexDetailedDto::getId).collect(Collectors.toList()));
    Map<String, ExternalShareInfoCountAndLatestDate> survToolShareCountAndDates = null;
    if (externalSurveillanceToolGatewayFacade.isFeatureEnabled()) {
        survToolShareCountAndDates = externalShareInfoService.getCaseShareCountAndLatestDate(cases.stream().map(CaseIndexDto::getId).collect(Collectors.toList())).stream().collect(Collectors.toMap(ExternalShareInfoCountAndLatestDate::getAssociatedObjectUuid, Function.identity()));
    }
    Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService::hasRight, I18nProperties.getCaption(Captions.inaccessibleValue));
    for (CaseIndexDetailedDto caze : cases) {
        if (survToolShareCountAndDates != null) {
            ExternalShareInfoCountAndLatestDate survToolShareCountAndDate = survToolShareCountAndDates.get(caze.getUuid());
            if (survToolShareCountAndDate != null) {
                caze.setSurveillanceToolShareCount(survToolShareCountAndDate.getCount());
                caze.setSurveillanceToolLastShareDate(survToolShareCountAndDate.getLatestDate());
                caze.setSurveillanceToolStatus(survToolShareCountAndDate.getLatestStatus());
            }
        }
        if (caze.getEventCount() > 0) {
            eventSummaries.stream().filter(v -> v.getCaseId() == caze.getId()).max(Comparator.comparing(EventSummaryDetails::getEventDate)).ifPresent(eventSummary -> {
                caze.setLatestEventId(eventSummary.getEventUuid());
                caze.setLatestEventStatus(eventSummary.getEventStatus());
                caze.setLatestEventTitle(eventSummary.getEventTitle());
            });
        }
        Boolean isInJurisdiction = caze.getInJurisdiction();
        pseudonymizer.pseudonymizeDto(CaseIndexDetailedDto.class, caze, isInJurisdiction, c -> {
            pseudonymizer.pseudonymizeDto(AgeAndBirthDateDto.class, caze.getAgeAndBirthDate(), isInJurisdiction, null);
            pseudonymizer.pseudonymizeUser(userService.getByUuid(caze.getReportingUser().getUuid()), userService.getCurrentUser(), caze::setReportingUser);
        });
    }
    return cases;
}
Also used : Pseudonymizer(de.symeda.sormas.backend.util.Pseudonymizer) EventSummaryDetails(de.symeda.sormas.backend.event.EventSummaryDetails) CaseIndexDetailedDto(de.symeda.sormas.api.caze.CaseIndexDetailedDto) ExternalShareInfoCountAndLatestDate(de.symeda.sormas.backend.share.ExternalShareInfoCountAndLatestDate)

Example 2 with ExternalShareInfoCountAndLatestDate

use of de.symeda.sormas.backend.share.ExternalShareInfoCountAndLatestDate in project SORMAS-Project by hzi-braunschweig.

the class CaseFacadeEjb method getIndexList.

@Override
public List<CaseIndexDto> getIndexList(CaseCriteria caseCriteria, Integer first, Integer max, List<SortProperty> sortProperties) {
    CriteriaQuery<CaseIndexDto> cq = listQueryBuilder.buildIndexCriteria(caseCriteria, sortProperties);
    List<CaseIndexDto> cases = QueryHelper.getResultList(em, cq, first, max);
    List<Long> caseIds = cases.stream().map(CaseIndexDto::getId).collect(Collectors.toList());
    Map<String, ExternalShareInfoCountAndLatestDate> survToolShareCountAndDates = null;
    if (externalSurveillanceToolGatewayFacade.isFeatureEnabled()) {
        survToolShareCountAndDates = externalShareInfoService.getCaseShareCountAndLatestDate(caseIds).stream().collect(Collectors.toMap(ExternalShareInfoCountAndLatestDate::getAssociatedObjectUuid, Function.identity()));
    }
    Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService::hasRight, I18nProperties.getCaption(Captions.inaccessibleValue));
    for (CaseIndexDto caze : cases) {
        if (survToolShareCountAndDates != null) {
            ExternalShareInfoCountAndLatestDate survToolShareCountAndDate = survToolShareCountAndDates.get(caze.getUuid());
            if (survToolShareCountAndDate != null) {
                caze.setSurveillanceToolShareCount(survToolShareCountAndDate.getCount());
                caze.setSurveillanceToolLastShareDate(survToolShareCountAndDate.getLatestDate());
                caze.setSurveillanceToolStatus(survToolShareCountAndDate.getLatestStatus());
            }
        }
        Boolean isInJurisdiction = caze.getInJurisdiction();
        pseudonymizer.pseudonymizeDto(CaseIndexDto.class, caze, isInJurisdiction, c -> pseudonymizer.pseudonymizeDto(AgeAndBirthDateDto.class, caze.getAgeAndBirthDate(), isInJurisdiction, null));
    }
    return cases;
}
Also used : AgeAndBirthDateDto(de.symeda.sormas.api.caze.AgeAndBirthDateDto) Pseudonymizer(de.symeda.sormas.backend.util.Pseudonymizer) AtomicLong(java.util.concurrent.atomic.AtomicLong) ExternalShareInfoCountAndLatestDate(de.symeda.sormas.backend.share.ExternalShareInfoCountAndLatestDate) CaseIndexDto(de.symeda.sormas.api.caze.CaseIndexDto)

Example 3 with ExternalShareInfoCountAndLatestDate

use of de.symeda.sormas.backend.share.ExternalShareInfoCountAndLatestDate in project SORMAS-Project by hzi-braunschweig.

the class EventFacadeEjb method getIndexList.

@Override
public List<EventIndexDto> getIndexList(EventCriteria eventCriteria, Integer first, Integer max, List<SortProperty> sortProperties) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<EventIndexDto> cq = cb.createQuery(EventIndexDto.class);
    Root<Event> event = cq.from(Event.class);
    EventQueryContext eventQueryContext = new EventQueryContext(cb, cq, event);
    EventJoins<Event> eventJoins = (EventJoins<Event>) eventQueryContext.getJoins();
    Join<Event, Location> location = eventJoins.getLocation();
    Join<Location, Region> region = eventJoins.getRegion();
    Join<Location, District> district = eventJoins.getDistrict();
    Join<Location, Community> community = eventJoins.getCommunity();
    Join<Event, User> reportingUser = eventJoins.getReportingUser();
    Join<Event, User> responsibleUser = eventJoins.getResponsibleUser();
    cq.multiselect(event.get(Event.ID), event.get(Event.UUID), event.get(Event.EXTERNAL_ID), event.get(Event.EXTERNAL_TOKEN), event.get(Event.INTERNAL_TOKEN), event.get(Event.EVENT_STATUS), event.get(Event.RISK_LEVEL), event.get(Event.SPECIFIC_RISK), event.get(Event.EVENT_INVESTIGATION_STATUS), event.get(Event.EVENT_MANAGEMENT_STATUS), event.get(Event.DISEASE), event.get(Event.DISEASE_VARIANT), event.get(Event.DISEASE_DETAILS), event.get(Event.START_DATE), event.get(Event.END_DATE), event.get(Event.EVOLUTION_DATE), event.get(Event.EVENT_TITLE), region.get(Region.UUID), region.get(Region.NAME), district.get(District.UUID), district.get(District.NAME), community.get(Community.UUID), community.get(Community.NAME), location.get(Location.CITY), location.get(Location.STREET), location.get(Location.HOUSE_NUMBER), location.get(Location.ADDITIONAL_INFORMATION), event.get(Event.SRC_TYPE), event.get(Event.SRC_FIRST_NAME), event.get(Event.SRC_LAST_NAME), event.get(Event.SRC_TEL_NO), event.get(Event.SRC_MEDIA_WEBSITE), event.get(Event.SRC_MEDIA_NAME), event.get(Event.REPORT_DATE_TIME), reportingUser.get(User.UUID), reportingUser.get(User.FIRST_NAME), reportingUser.get(User.LAST_NAME), responsibleUser.get(User.UUID), responsibleUser.get(User.FIRST_NAME), responsibleUser.get(User.LAST_NAME), JurisdictionHelper.booleanSelector(cb, service.inJurisdictionOrOwned(eventQueryContext)), event.get(Event.CHANGE_DATE), event.get(Event.EVENT_IDENTIFICATION_SOURCE));
    Predicate filter = null;
    if (eventCriteria != null) {
        if (eventCriteria.getUserFilterIncluded()) {
            EventUserFilterCriteria eventUserFilterCriteria = new EventUserFilterCriteria();
            eventUserFilterCriteria.includeUserCaseAndEventParticipantFilter(true);
            filter = service.createUserFilter(cb, cq, event, eventUserFilterCriteria);
        }
        Predicate criteriaFilter = service.buildCriteriaFilter(eventCriteria, eventQueryContext);
        filter = CriteriaBuilderHelper.and(cb, filter, criteriaFilter);
    }
    if (filter != null) {
        cq.where(filter);
    }
    if (sortProperties != null && sortProperties.size() > 0) {
        List<Order> order = new ArrayList<Order>(sortProperties.size());
        for (SortProperty sortProperty : sortProperties) {
            Expression<?> expression;
            switch(sortProperty.propertyName) {
                case EventIndexDto.UUID:
                case EventIndexDto.EXTERNAL_ID:
                case EventIndexDto.EXTERNAL_TOKEN:
                case EventIndexDto.INTERNAL_TOKEN:
                case EventIndexDto.EVENT_STATUS:
                case EventIndexDto.RISK_LEVEL:
                case EventIndexDto.SPECIFIC_RISK:
                case EventIndexDto.EVENT_INVESTIGATION_STATUS:
                case EventIndexDto.EVENT_MANAGEMENT_STATUS:
                case EventIndexDto.DISEASE:
                case EventIndexDto.DISEASE_VARIANT:
                case EventIndexDto.DISEASE_DETAILS:
                case EventIndexDto.START_DATE:
                case EventIndexDto.EVOLUTION_DATE:
                case EventIndexDto.EVENT_TITLE:
                case EventIndexDto.SRC_FIRST_NAME:
                case EventIndexDto.SRC_LAST_NAME:
                case EventIndexDto.SRC_TEL_NO:
                case EventIndexDto.SRC_TYPE:
                case EventIndexDto.REPORT_DATE_TIME:
                case EventIndexDto.EVENT_IDENTIFICATION_SOURCE:
                    expression = event.get(sortProperty.propertyName);
                    break;
                case EventIndexDto.EVENT_LOCATION:
                    expression = region.get(Region.NAME);
                    order.add(sortProperty.ascending ? cb.asc(expression) : cb.desc(expression));
                    expression = district.get(District.NAME);
                    order.add(sortProperty.ascending ? cb.asc(expression) : cb.desc(expression));
                    expression = community.get(Community.NAME);
                    break;
                case EventIndexDto.REGION:
                    expression = region.get(Region.NAME);
                    break;
                case EventIndexDto.DISTRICT:
                    expression = district.get(District.NAME);
                    break;
                case EventIndexDto.COMMUNITY:
                    expression = community.get(Community.NAME);
                    break;
                case EventIndexDto.ADDRESS:
                    expression = location.get(Location.CITY);
                    order.add(sortProperty.ascending ? cb.asc(expression) : cb.desc(expression));
                    expression = location.get(Location.STREET);
                    order.add(sortProperty.ascending ? cb.asc(expression) : cb.desc(expression));
                    expression = location.get(Location.HOUSE_NUMBER);
                    order.add(sortProperty.ascending ? cb.asc(expression) : cb.desc(expression));
                    expression = location.get(Location.ADDITIONAL_INFORMATION);
                    break;
                case EventIndexDto.REPORTING_USER:
                    expression = reportingUser.get(User.FIRST_NAME);
                    order.add(sortProperty.ascending ? cb.asc(expression) : cb.desc(expression));
                    expression = reportingUser.get(User.LAST_NAME);
                    break;
                case EventIndexDto.RESPONSIBLE_USER:
                    expression = responsibleUser.get(User.FIRST_NAME);
                    order.add(sortProperty.ascending ? cb.asc(expression) : cb.desc(expression));
                    expression = responsibleUser.get(User.LAST_NAME);
                    break;
                default:
                    throw new IllegalArgumentException(sortProperty.propertyName);
            }
            order.add(sortProperty.ascending ? cb.asc(expression) : cb.desc(expression));
        }
        cq.orderBy(order);
    } else {
        cq.orderBy(cb.desc(event.get(Event.CHANGE_DATE)));
    }
    cq.distinct(true);
    List<EventIndexDto> indexList = QueryHelper.getResultList(em, cq, first, max);
    Map<String, Long> participantCounts = new HashMap<>();
    Map<String, Long> caseCounts = new HashMap<>();
    Map<String, Long> deathCounts = new HashMap<>();
    Map<String, Long> contactCounts = new HashMap<>();
    Map<String, Long> contactCountsSourceInEvent = new HashMap<>();
    Map<String, EventGroupsIndexDto> eventGroupsByEventId = new HashMap<>();
    Map<String, ExternalShareInfoCountAndLatestDate> survToolShareCountAndDates = new HashMap<>();
    if (CollectionUtils.isNotEmpty(indexList)) {
        List<String> eventUuids = indexList.stream().map(EventIndexDto::getUuid).collect(Collectors.toList());
        List<Long> eventIds = indexList.stream().map(EventIndexDto::getId).collect(Collectors.toList());
        List<Object[]> objectQueryList = null;
        // Participant, Case and Death Count
        CriteriaQuery<Object[]> participantCQ = cb.createQuery(Object[].class);
        Root<EventParticipant> epRoot = participantCQ.from(EventParticipant.class);
        Join<EventParticipant, Case> caseJoin = epRoot.join(EventParticipant.RESULTING_CASE, JoinType.LEFT);
        Predicate notDeleted = cb.isFalse(epRoot.get(EventParticipant.DELETED));
        Predicate isInIndexlist = CriteriaBuilderHelper.andInValues(eventUuids, null, cb, epRoot.get(EventParticipant.EVENT).get(AbstractDomainObject.UUID));
        participantCQ.multiselect(epRoot.get(EventParticipant.EVENT).get(AbstractDomainObject.UUID), cb.count(epRoot), cb.sum(cb.selectCase().when(cb.isNotNull(epRoot.get(EventParticipant.RESULTING_CASE)), 1).otherwise(0).as(Long.class)), cb.sum(cb.selectCase().when(cb.equal(caseJoin.get(Case.OUTCOME), CaseOutcome.DECEASED), 1).otherwise(0).as(Long.class)));
        participantCQ.where(notDeleted, isInIndexlist);
        participantCQ.groupBy(epRoot.get(EventParticipant.EVENT).get(AbstractDomainObject.UUID));
        objectQueryList = em.createQuery(participantCQ).getResultList();
        if (objectQueryList != null) {
            objectQueryList.forEach(r -> {
                participantCounts.put((String) r[0], (Long) r[1]);
                caseCounts.put((String) r[0], (Long) r[2]);
                deathCounts.put((String) r[0], (Long) r[3]);
            });
        }
        // Contact Count (with and without sourcecase in event) using theta join
        CriteriaQuery<Object[]> contactCQ = cb.createQuery(Object[].class);
        epRoot = contactCQ.from(EventParticipant.class);
        Root<Contact> contactRoot = contactCQ.from(Contact.class);
        Predicate participantPersonEqualsContactPerson = cb.equal(epRoot.get(EventParticipant.PERSON), contactRoot.get(Contact.PERSON));
        notDeleted = cb.isFalse(epRoot.get(EventParticipant.DELETED));
        Predicate contactNotDeleted = cb.isFalse(contactRoot.get(Contact.DELETED));
        isInIndexlist = CriteriaBuilderHelper.andInValues(eventUuids, null, cb, epRoot.get(EventParticipant.EVENT).get(AbstractDomainObject.UUID));
        Subquery<EventParticipant> sourceCaseSubquery = contactCQ.subquery(EventParticipant.class);
        Root<EventParticipant> epr2 = sourceCaseSubquery.from(EventParticipant.class);
        sourceCaseSubquery.select(epr2);
        sourceCaseSubquery.where(cb.equal(epr2.get(EventParticipant.RESULTING_CASE), contactRoot.get(Contact.CAZE)), cb.equal(epr2.get(EventParticipant.EVENT), epRoot.get(EventParticipant.EVENT)));
        contactCQ.multiselect(epRoot.get(EventParticipant.EVENT).get(AbstractDomainObject.UUID), cb.count(epRoot), cb.sum(cb.selectCase().when(cb.exists(sourceCaseSubquery), 1).otherwise(0).as(Long.class)));
        contactCQ.where(participantPersonEqualsContactPerson, notDeleted, contactNotDeleted, isInIndexlist);
        contactCQ.groupBy(epRoot.get(EventParticipant.EVENT).get(AbstractDomainObject.UUID));
        objectQueryList = em.createQuery(contactCQ).getResultList();
        if (objectQueryList != null) {
            objectQueryList.forEach(r -> {
                contactCounts.put((String) r[0], ((Long) r[1]));
                contactCountsSourceInEvent.put((String) r[0], ((Long) r[2]));
            });
        }
        if (featureConfigurationFacade.isFeatureEnabled(FeatureType.EVENT_GROUPS)) {
            // Get latest EventGroup with EventGroup count
            CriteriaQuery<Object[]> latestEventCQ = cb.createQuery(Object[].class);
            Root<Event> eventRoot = latestEventCQ.from(Event.class);
            Join<Event, EventGroup> eventGroupJoin = eventRoot.join(Event.EVENT_GROUPS, JoinType.INNER);
            isInIndexlist = CriteriaBuilderHelper.andInValues(eventUuids, null, cb, eventRoot.get(Event.UUID));
            latestEventCQ.where(isInIndexlist);
            latestEventCQ.multiselect(eventRoot.get(Event.UUID), CriteriaBuilderHelper.windowFirstValueDesc(cb, eventGroupJoin.get(EventGroup.UUID), eventRoot.get(Event.UUID), eventGroupJoin.get(EventGroup.CREATION_DATE)), CriteriaBuilderHelper.windowFirstValueDesc(cb, eventGroupJoin.get(EventGroup.NAME), eventRoot.get(Event.UUID), eventGroupJoin.get(EventGroup.CREATION_DATE)), CriteriaBuilderHelper.windowCount(cb, eventGroupJoin.get(EventGroup.ID), eventRoot.get(Event.UUID)));
            objectQueryList = em.createQuery(latestEventCQ).getResultList();
            if (objectQueryList != null) {
                objectQueryList.forEach(r -> {
                    EventGroupReferenceDto eventGroupReference = new EventGroupReferenceDto((String) r[1], (String) r[2]);
                    EventGroupsIndexDto eventGroups = new EventGroupsIndexDto(eventGroupReference, ((Number) r[3]).longValue());
                    eventGroupsByEventId.put((String) r[0], eventGroups);
                });
            }
        }
        if (externalSurveillanceToolFacade.isFeatureEnabled()) {
            survToolShareCountAndDates = externalShareInfoService.getEventShareCountAndLatestDate(eventIds).stream().collect(Collectors.toMap(ExternalShareInfoCountAndLatestDate::getAssociatedObjectUuid, Function.identity()));
        }
    }
    if (indexList != null) {
        for (EventIndexDto eventDto : indexList) {
            Optional.ofNullable(participantCounts.get(eventDto.getUuid())).ifPresent(eventDto::setParticipantCount);
            Optional.ofNullable(caseCounts.get(eventDto.getUuid())).ifPresent(eventDto::setCaseCount);
            Optional.ofNullable(deathCounts.get(eventDto.getUuid())).ifPresent(eventDto::setDeathCount);
            Optional.ofNullable(contactCounts.get(eventDto.getUuid())).ifPresent(eventDto::setContactCount);
            Optional.ofNullable(contactCountsSourceInEvent.get(eventDto.getUuid())).ifPresent(eventDto::setContactCountSourceInEvent);
            Optional.ofNullable(eventGroupsByEventId.get(eventDto.getUuid())).ifPresent(eventDto::setEventGroups);
            Optional.ofNullable(survToolShareCountAndDates.get(eventDto.getUuid())).ifPresent((c) -> {
                eventDto.setSurveillanceToolStatus(c.getLatestStatus());
                eventDto.setSurveillanceToolLastShareDate(c.getLatestDate());
                eventDto.setSurveillanceToolShareCount(c.getCount());
            });
        }
    }
    Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService::hasRight, I18nProperties.getCaption(Captions.inaccessibleValue));
    pseudonymizer.pseudonymizeDtoCollection(EventIndexDto.class, indexList, EventIndexDto::getInJurisdictionOrOwned, (c, isInJurisdiction) -> {
    });
    return indexList;
}
Also used : Pseudonymizer(de.symeda.sormas.backend.util.Pseudonymizer) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ExternalShareInfoCountAndLatestDate(de.symeda.sormas.backend.share.ExternalShareInfoCountAndLatestDate) Predicate(javax.persistence.criteria.Predicate) SortProperty(de.symeda.sormas.api.utils.SortProperty) CriteriaBuilder(javax.persistence.criteria.CriteriaBuilder) Order(javax.persistence.criteria.Order) EventGroupsIndexDto(de.symeda.sormas.api.event.EventGroupsIndexDto) EventGroupReferenceDto(de.symeda.sormas.api.event.EventGroupReferenceDto) Region(de.symeda.sormas.backend.infrastructure.region.Region) AbstractDomainObject(de.symeda.sormas.backend.common.AbstractDomainObject) District(de.symeda.sormas.backend.infrastructure.district.District) User(de.symeda.sormas.backend.user.User) EventIndexDto(de.symeda.sormas.api.event.EventIndexDto) Case(de.symeda.sormas.backend.caze.Case) Contact(de.symeda.sormas.backend.contact.Contact) EventJoins(de.symeda.sormas.utils.EventJoins) Community(de.symeda.sormas.backend.infrastructure.community.Community) Location(de.symeda.sormas.backend.location.Location)

Aggregations

ExternalShareInfoCountAndLatestDate (de.symeda.sormas.backend.share.ExternalShareInfoCountAndLatestDate)3 Pseudonymizer (de.symeda.sormas.backend.util.Pseudonymizer)3 AgeAndBirthDateDto (de.symeda.sormas.api.caze.AgeAndBirthDateDto)1 CaseIndexDetailedDto (de.symeda.sormas.api.caze.CaseIndexDetailedDto)1 CaseIndexDto (de.symeda.sormas.api.caze.CaseIndexDto)1 EventGroupReferenceDto (de.symeda.sormas.api.event.EventGroupReferenceDto)1 EventGroupsIndexDto (de.symeda.sormas.api.event.EventGroupsIndexDto)1 EventIndexDto (de.symeda.sormas.api.event.EventIndexDto)1 SortProperty (de.symeda.sormas.api.utils.SortProperty)1 Case (de.symeda.sormas.backend.caze.Case)1 AbstractDomainObject (de.symeda.sormas.backend.common.AbstractDomainObject)1 Contact (de.symeda.sormas.backend.contact.Contact)1 EventSummaryDetails (de.symeda.sormas.backend.event.EventSummaryDetails)1 Community (de.symeda.sormas.backend.infrastructure.community.Community)1 District (de.symeda.sormas.backend.infrastructure.district.District)1 Region (de.symeda.sormas.backend.infrastructure.region.Region)1 Location (de.symeda.sormas.backend.location.Location)1 User (de.symeda.sormas.backend.user.User)1 EventJoins (de.symeda.sormas.utils.EventJoins)1 ArrayList (java.util.ArrayList)1