Search in sources :

Example 1 with CaseJoins

use of de.symeda.sormas.backend.caze.CaseJoins in project SORMAS-Project by hzi-braunschweig.

the class PersonFacadeEjb method getCaseLatestFollowUpEndDates.

private Stream<PersonFollowUpEndDto> getCaseLatestFollowUpEndDates(Date since, boolean forSymptomJournal) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<PersonFollowUpEndDto> cq = cb.createQuery(PersonFollowUpEndDto.class);
    Root<Case> caseRoot = cq.from(Case.class);
    Join<Case, Person> personJoin = caseRoot.join(Case.PERSON, JoinType.LEFT);
    Predicate filter = caseService.createUserFilter(new CaseQueryContext(cb, cq, new CaseJoins(caseRoot)));
    if (since != null) {
        filter = CriteriaBuilderHelper.and(cb, filter, caseService.createChangeDateFilter(cb, caseRoot, since));
    }
    if (forSymptomJournal) {
        filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(personJoin.get(Person.SYMPTOM_JOURNAL_STATUS), SymptomJournalStatus.ACCEPTED));
    }
    if (filter != null) {
        cq.where(filter);
    }
    final Date minDate = new Date(0);
    final Expression<Object> followUpStatusExpression = cb.selectCase().when(cb.equal(caseRoot.get(Case.FOLLOW_UP_STATUS), FollowUpStatus.CANCELED), cb.nullLiteral(Date.class)).otherwise(caseRoot.get(Case.FOLLOW_UP_UNTIL));
    cq.multiselect(personJoin.get(Person.UUID), followUpStatusExpression);
    cq.orderBy(cb.asc(personJoin.get(Person.UUID)), cb.desc(cb.coalesce(caseRoot.get(Case.FOLLOW_UP_UNTIL), minDate)));
    return em.createQuery(cq).getResultList().stream().distinct();
}
Also used : CriteriaBuilder(javax.persistence.criteria.CriteriaBuilder) Date(java.util.Date) Case(de.symeda.sormas.backend.caze.Case) Predicate(javax.persistence.criteria.Predicate) CaseQueryContext(de.symeda.sormas.backend.caze.CaseQueryContext) AbstractDomainObject(de.symeda.sormas.backend.common.AbstractDomainObject) CaseJoins(de.symeda.sormas.backend.caze.CaseJoins) PersonFollowUpEndDto(de.symeda.sormas.api.person.PersonFollowUpEndDto)

Example 2 with CaseJoins

use of de.symeda.sormas.backend.caze.CaseJoins in project SORMAS-Project by hzi-braunschweig.

the class PersonService method getAllAfter.

@Override
public // todo refactor this to use the create user filter form persons
List<Person> getAllAfter(Date date, Integer batchSize, String lastSynchronizedUuid) {
    User user = getCurrentUser();
    final CriteriaBuilder cb = em.getCriteriaBuilder();
    final CriteriaQuery<Person> personsQuery = cb.createQuery(Person.class);
    final Root<Person> personsRoot = personsQuery.from(Person.class);
    final PersonQueryContext personQueryContext = new PersonQueryContext(cb, personsQuery, personsRoot);
    final PersonJoins joins = personQueryContext.getJoins();
    // persons by district
    Join<Person, Location> address = joins.getAddress();
    Predicate districtFilter = cb.equal(address.get(Location.DISTRICT), user.getDistrict());
    // date range
    if (date != null) {
        Predicate dateFilter = createChangeDateFilter(personQueryContext, DateHelper.toTimestampUpper(date), lastSynchronizedUuid);
        districtFilter = cb.and(districtFilter, dateFilter);
    }
    personsQuery.where(districtFilter);
    List<Person> districtResultList = getBatchedQueryResults(cb, personsQuery, personsRoot, batchSize);
    // persons by case
    CriteriaQuery<Person> casePersonsQuery = cb.createQuery(Person.class);
    Root<Case> casePersonsRoot = casePersonsQuery.from(Case.class);
    Join<Person, Person> casePersonsSelect = casePersonsRoot.join(Case.PERSON);
    casePersonsSelect.fetch(Person.ADDRESS);
    casePersonsQuery.select(casePersonsSelect);
    Predicate casePersonsFilter = caseService.createUserFilter(new CaseQueryContext(cb, casePersonsQuery, new CaseJoins(casePersonsRoot)));
    // date range
    if (date != null) {
        Predicate dateFilter = createChangeDateFilter(cb, casePersonsSelect, DateHelper.toTimestampUpper(date), lastSynchronizedUuid);
        if (batchSize == null) {
            // include case change dates: When a case is relocated it may become available to another user and this will have to include the person as-well
            Predicate caseDateFilter = caseService.createChangeDateFilter(cb, casePersonsRoot, DateHelper.toTimestampUpper(date));
            dateFilter = cb.or(dateFilter, caseDateFilter);
        }
        if (casePersonsFilter != null) {
            casePersonsFilter = cb.and(casePersonsFilter, dateFilter);
        } else {
            casePersonsFilter = dateFilter;
        }
    }
    if (casePersonsFilter != null) {
        casePersonsQuery.where(casePersonsFilter);
    }
    casePersonsQuery.distinct(true);
    List<Person> casePersonsResultList = getBatchedQueryResults(cb, casePersonsQuery, casePersonsSelect, batchSize);
    // persons by contact
    CriteriaQuery<Person> contactPersonsQuery = cb.createQuery(Person.class);
    Root<Contact> contactPersonsRoot = contactPersonsQuery.from(Contact.class);
    Join<Person, Person> contactPersonsSelect = contactPersonsRoot.join(Contact.PERSON);
    contactPersonsSelect.fetch(Person.ADDRESS);
    contactPersonsQuery.select(contactPersonsSelect);
    Predicate contactPersonsFilter = contactService.createUserFilter(new ContactQueryContext(cb, contactPersonsQuery, new ContactJoins(contactPersonsRoot)));
    // date range
    if (date != null) {
        Predicate dateFilter = createChangeDateFilter(cb, contactPersonsSelect, DateHelper.toTimestampUpper(date), lastSynchronizedUuid);
        if (batchSize == null) {
            Predicate contactDateFilter = contactService.createChangeDateFilter(cb, contactPersonsRoot, date);
            dateFilter = cb.or(dateFilter, contactDateFilter);
        }
        contactPersonsFilter = and(cb, contactPersonsFilter, dateFilter);
    }
    if (contactPersonsFilter != null) {
        contactPersonsQuery.where(contactPersonsFilter);
    }
    contactPersonsQuery.distinct(true);
    List<Person> contactPersonsResultList = getBatchedQueryResults(cb, contactPersonsQuery, contactPersonsSelect, batchSize);
    // persons by event participant
    CriteriaQuery<Person> eventPersonsQuery = cb.createQuery(Person.class);
    Root<EventParticipant> eventPersonsRoot = eventPersonsQuery.from(EventParticipant.class);
    Join<Person, Person> eventPersonsSelect = eventPersonsRoot.join(EventParticipant.PERSON);
    eventPersonsSelect.fetch(Person.ADDRESS);
    eventPersonsQuery.select(eventPersonsSelect);
    Predicate eventPersonsFilter = eventParticipantService.createUserFilter(new EventParticipantQueryContext(cb, eventPersonsQuery, new EventParticipantJoins(eventPersonsRoot)));
    // date range
    if (date != null) {
        Predicate dateFilter = createChangeDateFilter(cb, eventPersonsSelect, DateHelper.toTimestampUpper(date), lastSynchronizedUuid);
        if (batchSize == null) {
            Predicate eventParticipantDateFilter = eventParticipantService.createChangeDateFilter(cb, eventPersonsRoot, DateHelper.toTimestampUpper(date));
            dateFilter = cb.or(dateFilter, eventParticipantDateFilter);
        }
        eventPersonsFilter = and(cb, eventPersonsFilter, dateFilter);
    }
    if (eventPersonsFilter != null) {
        eventPersonsQuery.where(eventPersonsFilter);
    }
    eventPersonsQuery.distinct(true);
    List<Person> eventPersonsResultList = getBatchedQueryResults(cb, eventPersonsQuery, eventPersonsSelect, batchSize);
    // persons by immunization
    List<Person> immunizationPersonsResultList = new ArrayList<>();
    if (!featureConfigurationFacade.isPropertyValueTrue(FeatureType.IMMUNIZATION_MANAGEMENT, FeatureTypeProperty.REDUCED)) {
        CriteriaQuery<Person> immunizationPersonsQuery = cb.createQuery(Person.class);
        Root<Immunization> immunizationPersonsRoot = immunizationPersonsQuery.from(Immunization.class);
        Join<Immunization, Person> immunizationPersonsSelect = immunizationPersonsRoot.join(Immunization.PERSON);
        immunizationPersonsSelect.fetch(Person.ADDRESS);
        immunizationPersonsQuery.select(immunizationPersonsSelect);
        Predicate immunizationPersonsFilter = immunizationService.createUserFilter(new ImmunizationQueryContext(cb, immunizationPersonsQuery, new ImmunizationJoins(immunizationPersonsRoot)));
        // date range
        if (date != null) {
            Predicate dateFilter = createChangeDateFilter(cb, immunizationPersonsSelect, DateHelper.toTimestampUpper(date), lastSynchronizedUuid);
            if (batchSize == null) {
                Predicate immunizationDateFilter = immunizationService.createChangeDateFilter(cb, immunizationPersonsRoot, DateHelper.toTimestampUpper(date));
                dateFilter = cb.or(dateFilter, immunizationDateFilter);
            }
            immunizationPersonsFilter = and(cb, immunizationPersonsFilter, dateFilter);
        }
        if (immunizationPersonsFilter != null) {
            immunizationPersonsQuery.where(immunizationPersonsFilter);
        }
        immunizationPersonsQuery.distinct(true);
        immunizationPersonsResultList = getBatchedQueryResults(cb, immunizationPersonsQuery, immunizationPersonsSelect, batchSize);
    }
    List<Person> travelEntryPersonsResultList = new ArrayList<>();
    // if a batch size is given, this is a sync from the mobile app where travel entries are not relevant for now
    if (batchSize == null) {
        // persons by travel entries
        CriteriaQuery<Person> tepQuery = cb.createQuery(Person.class);
        Root<TravelEntry> tepRoot = tepQuery.from(TravelEntry.class);
        Join<TravelEntry, Person> tepSelect = tepRoot.join(TravelEntry.PERSON);
        tepSelect.fetch(Person.ADDRESS);
        tepQuery.select(tepSelect);
        Predicate tepFilter = travelEntryService.createUserFilter(new TravelEntryQueryContext(cb, tepQuery, new TravelEntryJoins(tepRoot)));
        // date range
        if (date != null) {
            Predicate dateFilter = createChangeDateFilter(cb, tepSelect, DateHelper.toTimestampUpper(date));
            Predicate travelEntryDateFilter = travelEntryService.createChangeDateFilter(cb, tepRoot, DateHelper.toTimestampUpper(date));
            tepFilter = and(cb, tepFilter, cb.or(dateFilter, travelEntryDateFilter));
        }
        if (tepFilter != null) {
            tepQuery.where(tepFilter);
        }
        tepQuery.distinct(true);
        travelEntryPersonsResultList = em.createQuery(tepQuery).getResultList();
    }
    return Stream.of(districtResultList, casePersonsResultList, contactPersonsResultList, eventPersonsResultList, immunizationPersonsResultList, travelEntryPersonsResultList).flatMap(List<Person>::stream).distinct().sorted(new ChangeDateUuidComparator<>()).limit(batchSize == null ? Long.MAX_VALUE : batchSize).collect(Collectors.toList());
}
Also used : TravelEntry(de.symeda.sormas.backend.travelentry.TravelEntry) User(de.symeda.sormas.backend.user.User) TravelEntryJoins(de.symeda.sormas.backend.travelentry.TravelEntryJoins) ArrayList(java.util.ArrayList) Predicate(javax.persistence.criteria.Predicate) Case(de.symeda.sormas.backend.caze.Case) EventParticipantJoins(de.symeda.sormas.backend.event.EventParticipantJoins) CaseQueryContext(de.symeda.sormas.backend.caze.CaseQueryContext) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) ImmunizationQueryContext(de.symeda.sormas.backend.immunization.ImmunizationQueryContext) CaseJoins(de.symeda.sormas.backend.caze.CaseJoins) CriteriaBuilder(javax.persistence.criteria.CriteriaBuilder) Immunization(de.symeda.sormas.backend.immunization.entity.Immunization) ContactJoins(de.symeda.sormas.backend.contact.ContactJoins) ContactQueryContext(de.symeda.sormas.backend.contact.ContactQueryContext) EventParticipantQueryContext(de.symeda.sormas.backend.event.EventParticipantQueryContext) Contact(de.symeda.sormas.backend.contact.Contact) ImmunizationJoins(de.symeda.sormas.backend.immunization.ImmunizationJoins) TravelEntryQueryContext(de.symeda.sormas.backend.travelentry.TravelEntryQueryContext) EventParticipant(de.symeda.sormas.backend.event.EventParticipant) Location(de.symeda.sormas.backend.location.Location)

Example 3 with CaseJoins

use of de.symeda.sormas.backend.caze.CaseJoins in project SORMAS-Project by hzi-braunschweig.

the class EventGroupService method createCaseAndEventParticipantFilter.

public Predicate createCaseAndEventParticipantFilter(CriteriaBuilder cb, CriteriaQuery cq, From<?, Event> eventPath) {
    Join<Event, EventParticipant> eventParticipantJoin = eventPath.join(Event.EVENT_PERSONS, JoinType.LEFT);
    Join<EventParticipant, Case> caseJoin = eventParticipantJoin.join(EventParticipant.RESULTING_CASE, JoinType.LEFT);
    Subquery<Long> caseSubquery = cq.subquery(Long.class);
    Root<Case> caseRoot = caseSubquery.from(Case.class);
    caseSubquery.where(caseService.createUserFilter(new CaseQueryContext(cb, cq, new CaseJoins(caseRoot))));
    caseSubquery.select(caseRoot.get(Case.ID));
    Predicate filter = cb.in(caseJoin.get(Case.ID)).value(caseSubquery);
    final User currentUser = getCurrentUser();
    final JurisdictionLevel jurisdictionLevel = currentUser.getJurisdictionLevel();
    if (jurisdictionLevel == JurisdictionLevel.REGION || jurisdictionLevel == JurisdictionLevel.DISTRICT) {
        Subquery<Long> eventParticipantSubquery = cq.subquery(Long.class);
        Root<EventParticipant> epRoot = eventParticipantSubquery.from(EventParticipant.class);
        switch(jurisdictionLevel) {
            case REGION:
                if (currentUser.getRegion() != null) {
                    eventParticipantSubquery.where(cb.and(cb.equal(epRoot.get(EventParticipant.EVENT).get(Event.ID), eventPath.get(Event.ID)), cb.equal(epRoot.get(EventParticipant.REGION).get(Region.ID), currentUser.getRegion().getId())));
                }
                break;
            case DISTRICT:
                if (currentUser.getDistrict() != null) {
                    eventParticipantSubquery.where(cb.and(cb.equal(epRoot.get(EventParticipant.EVENT).get(Event.ID), eventPath.get(Event.ID)), cb.equal(epRoot.get(EventParticipant.DISTRICT).get(District.ID), currentUser.getDistrict().getId())));
                }
                break;
            default:
        }
        eventParticipantSubquery.select(epRoot.get(EventParticipant.ID));
        filter = CriteriaBuilderHelper.or(cb, filter, cb.in(eventParticipantJoin.get(EventParticipant.ID)).value(eventParticipantSubquery));
    }
    return filter;
}
Also used : User(de.symeda.sormas.backend.user.User) JurisdictionLevel(de.symeda.sormas.api.user.JurisdictionLevel) Case(de.symeda.sormas.backend.caze.Case) Predicate(javax.persistence.criteria.Predicate) CaseQueryContext(de.symeda.sormas.backend.caze.CaseQueryContext) CaseJoins(de.symeda.sormas.backend.caze.CaseJoins)

Example 4 with CaseJoins

use of de.symeda.sormas.backend.caze.CaseJoins in project SORMAS-Project by hzi-braunschweig.

the class DashboardService method getCasesCountPerPersonCondition.

public Map<PresentCondition, Integer> getCasesCountPerPersonCondition(DashboardCriteria dashboardCriteria) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Object[]> cq = cb.createQuery(Object[].class);
    Root<Case> caze = cq.from(Case.class);
    final CaseQueryContext caseQueryContext = new CaseQueryContext(cb, cq, caze);
    final CaseJoins joins = caseQueryContext.getJoins();
    Join<Case, Person> person = joins.getPerson();
    Predicate filter = caseService.createUserFilter(caseQueryContext, new CaseUserFilterCriteria().excludeCasesFromContacts(true));
    Predicate criteriaFilter = createCaseCriteriaFilter(dashboardCriteria, caseQueryContext);
    filter = CriteriaBuilderHelper.and(cb, filter, criteriaFilter);
    if (filter != null) {
        cq.where(filter);
    }
    cq.groupBy(person.get(Person.PRESENT_CONDITION));
    cq.multiselect(person.get(Person.PRESENT_CONDITION), cb.count(caze));
    List<Object[]> results = em.createQuery(cq).getResultList();
    Map<PresentCondition, Integer> resultMap = results.stream().collect(Collectors.toMap(e -> e[0] != null ? (PresentCondition) e[0] : PresentCondition.UNKNOWN, e -> ((Number) e[1]).intValue(), (v1, v2) -> v1 + v2));
    return resultMap;
}
Also used : CriteriaBuilder(javax.persistence.criteria.CriteriaBuilder) EventService(de.symeda.sormas.backend.event.EventService) Join(javax.persistence.criteria.Join) AbstractDomainObject(de.symeda.sormas.backend.common.AbstractDomainObject) Date(java.util.Date) DashboardEventDto(de.symeda.sormas.api.dashboard.DashboardEventDto) SpecimenCondition(de.symeda.sormas.api.sample.SpecimenCondition) StringUtils(org.apache.commons.lang3.StringUtils) Predicate(javax.persistence.criteria.Predicate) Map(java.util.Map) CriteriaBuilder(javax.persistence.criteria.CriteriaBuilder) JoinType(javax.persistence.criteria.JoinType) From(javax.persistence.criteria.From) DashboardCaseDto(de.symeda.sormas.api.dashboard.DashboardCaseDto) Stateless(javax.ejb.Stateless) CriteriaQuery(javax.persistence.criteria.CriteriaQuery) CaseService(de.symeda.sormas.backend.caze.CaseService) Person(de.symeda.sormas.backend.person.Person) Region(de.symeda.sormas.backend.infrastructure.region.Region) District(de.symeda.sormas.backend.infrastructure.district.District) Collectors(java.util.stream.Collectors) List(java.util.List) User(de.symeda.sormas.backend.user.User) PathogenTestResultType(de.symeda.sormas.api.sample.PathogenTestResultType) EventJoins(de.symeda.sormas.backend.event.EventJoins) JurisdictionHelper(de.symeda.sormas.backend.util.JurisdictionHelper) Order(javax.persistence.criteria.Order) Location(de.symeda.sormas.backend.location.Location) Sample(de.symeda.sormas.backend.sample.Sample) Community(de.symeda.sormas.backend.infrastructure.community.Community) CaseUserFilterCriteria(de.symeda.sormas.backend.caze.CaseUserFilterCriteria) QueryHelper(de.symeda.sormas.backend.util.QueryHelper) CaseClassification(de.symeda.sormas.api.caze.CaseClassification) DateHelper(de.symeda.sormas.api.utils.DateHelper) HashMap(java.util.HashMap) EventStatus(de.symeda.sormas.api.event.EventStatus) EventQueryContext(de.symeda.sormas.backend.event.EventQueryContext) ArrayList(java.util.ArrayList) Case(de.symeda.sormas.backend.caze.Case) DashboardCriteria(de.symeda.sormas.api.dashboard.DashboardCriteria) LocalBean(javax.ejb.LocalBean) CaseQueryContext(de.symeda.sormas.backend.caze.CaseQueryContext) Expression(javax.persistence.criteria.Expression) CriteriaBuilderHelper(de.symeda.sormas.backend.common.CriteriaBuilderHelper) CaseJoins(de.symeda.sormas.backend.caze.CaseJoins) EJB(javax.ejb.EJB) Root(javax.persistence.criteria.Root) ModelConstants(de.symeda.sormas.backend.util.ModelConstants) EntityManager(javax.persistence.EntityManager) PersistenceContext(javax.persistence.PersistenceContext) Event(de.symeda.sormas.backend.event.Event) PresentCondition(de.symeda.sormas.api.person.PresentCondition) Disease(de.symeda.sormas.api.Disease) Collections(java.util.Collections) PresentCondition(de.symeda.sormas.api.person.PresentCondition) CaseUserFilterCriteria(de.symeda.sormas.backend.caze.CaseUserFilterCriteria) Case(de.symeda.sormas.backend.caze.Case) Predicate(javax.persistence.criteria.Predicate) CaseQueryContext(de.symeda.sormas.backend.caze.CaseQueryContext) AbstractDomainObject(de.symeda.sormas.backend.common.AbstractDomainObject) Person(de.symeda.sormas.backend.person.Person) CaseJoins(de.symeda.sormas.backend.caze.CaseJoins)

Example 5 with CaseJoins

use of de.symeda.sormas.backend.caze.CaseJoins in project SORMAS-Project by hzi-braunschweig.

the class DashboardService method getCases.

public List<DashboardCaseDto> getCases(DashboardCriteria dashboardCriteria) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<DashboardCaseDto> cq = cb.createQuery(DashboardCaseDto.class);
    Root<Case> caze = cq.from(Case.class);
    final CaseQueryContext caseQueryContext = new CaseQueryContext(cb, cq, caze);
    final CaseJoins joins = caseQueryContext.getJoins();
    Join<Case, Person> person = joins.getPerson();
    Predicate filter = caseService.createUserFilter(caseQueryContext, new CaseUserFilterCriteria().excludeCasesFromContacts(true));
    Predicate criteriaFilter = createCaseCriteriaFilter(dashboardCriteria, caseQueryContext);
    filter = CriteriaBuilderHelper.and(cb, filter, criteriaFilter);
    List<DashboardCaseDto> result;
    if (filter != null) {
        cq.where(filter);
        cq.multiselect(caze.get(Case.ID), caze.get(Case.UUID), caze.get(Case.REPORT_DATE), caze.get(Case.CASE_CLASSIFICATION), caze.get(Case.DISEASE), person.get(Person.PRESENT_CONDITION), person.get(Person.CAUSE_OF_DEATH_DISEASE), caze.get(Case.QUARANTINE_FROM), caze.get(Case.QUARANTINE_TO), caze.get(Case.CASE_REFERENCE_DEFINITION));
        result = em.createQuery(cq).getResultList();
    } else {
        result = Collections.emptyList();
    }
    return result;
}
Also used : CriteriaBuilder(javax.persistence.criteria.CriteriaBuilder) CaseQueryContext(de.symeda.sormas.backend.caze.CaseQueryContext) DashboardCaseDto(de.symeda.sormas.api.dashboard.DashboardCaseDto) CaseUserFilterCriteria(de.symeda.sormas.backend.caze.CaseUserFilterCriteria) Person(de.symeda.sormas.backend.person.Person) CaseJoins(de.symeda.sormas.backend.caze.CaseJoins) Case(de.symeda.sormas.backend.caze.Case) Predicate(javax.persistence.criteria.Predicate)

Aggregations

Case (de.symeda.sormas.backend.caze.Case)18 CaseJoins (de.symeda.sormas.backend.caze.CaseJoins)18 CriteriaBuilder (javax.persistence.criteria.CriteriaBuilder)17 Predicate (javax.persistence.criteria.Predicate)16 CaseQueryContext (de.symeda.sormas.backend.caze.CaseQueryContext)15 ArrayList (java.util.ArrayList)8 Location (de.symeda.sormas.backend.location.Location)7 Person (de.symeda.sormas.backend.person.Person)7 CaseUserFilterCriteria (de.symeda.sormas.backend.caze.CaseUserFilterCriteria)6 District (de.symeda.sormas.backend.infrastructure.district.District)6 List (java.util.List)6 AbstractDomainObject (de.symeda.sormas.backend.common.AbstractDomainObject)5 Date (java.util.Date)5 Order (javax.persistence.criteria.Order)5 Disease (de.symeda.sormas.api.Disease)4 DashboardCaseDto (de.symeda.sormas.api.dashboard.DashboardCaseDto)4 PathogenTestResultType (de.symeda.sormas.api.sample.PathogenTestResultType)4 CriteriaBuilderHelper (de.symeda.sormas.backend.common.CriteriaBuilderHelper)4 Contact (de.symeda.sormas.backend.contact.Contact)4 ContactJoins (de.symeda.sormas.backend.contact.ContactJoins)4