Search in sources :

Example 1 with Contact

use of de.symeda.sormas.backend.contact.Contact in project SORMAS-Project by hzi-braunschweig.

the class StartupShutdownService method upgrade.

private void upgrade() {
    @SuppressWarnings("unchecked") List<Integer> versionsNeedingUpgrade = em.createNativeQuery("SELECT version_number FROM schema_version WHERE upgradeNeeded").getResultList();
    for (Integer versionNeedingUpgrade : versionsNeedingUpgrade) {
        switch(versionNeedingUpgrade) {
            case 95:
                // update follow up and status for all contacts
                for (Contact contact : contactService.getAll()) {
                    contactService.updateFollowUpDetails(contact, false);
                    contactService.udpateContactStatus(contact);
                }
                break;
            case 354:
                CountryReferenceDto serverCountry = countryFacade.getServerCountry();
                if (serverCountry != null) {
                    Country country = countryService.getByUuid(serverCountry.getUuid());
                    em.createQuery("UPDATE Region set country = :server_country, changeDate = :change_date WHERE country is null").setParameter("server_country", country).setParameter("change_date", new Timestamp(new Date().getTime())).executeUpdate();
                }
                break;
            default:
                throw new NoSuchElementException(DataHelper.toStringNullable(versionNeedingUpgrade));
        }
        int updatedRows = em.createNativeQuery("UPDATE schema_version SET upgradeNeeded=false WHERE version_number=?1").setParameter(1, versionNeedingUpgrade).executeUpdate();
        if (updatedRows != 1) {
            logger.error("Could not UPDATE schema_version table. Missing user rights?");
        }
    }
}
Also used : CountryReferenceDto(de.symeda.sormas.api.infrastructure.country.CountryReferenceDto) Country(de.symeda.sormas.backend.infrastructure.country.Country) Timestamp(java.sql.Timestamp) Date(java.util.Date) NoSuchElementException(java.util.NoSuchElementException) Contact(de.symeda.sormas.backend.contact.Contact)

Example 2 with Contact

use of de.symeda.sormas.backend.contact.Contact in project SORMAS-Project by hzi-braunschweig.

the class PersonFacadeEjb method onPersonChanged.

public void onPersonChanged(PersonDto existingPerson, Person newPerson, boolean syncShares) {
    List<Case> personCases = null;
    // Do not bother to update existing cases/contacts/eventparticipants on new Persons, as none should exist yet
    if (existingPerson != null) {
        personCases = caseService.findBy(new CaseCriteria().person(new PersonReferenceDto(newPerson.getUuid())), true);
        // Attention: this may lead to infinite recursion when not properly implemented
        for (Case personCase : personCases) {
            CaseDataDto existingCase = caseFacade.toDto(personCase);
            caseFacade.onCaseChanged(existingCase, personCase, syncShares);
        }
        List<Contact> personContacts = contactService.findBy(new ContactCriteria().setPerson(new PersonReferenceDto(newPerson.getUuid())), null);
        // Attention: this may lead to infinite recursion when not properly implemented
        for (Contact personContact : personContacts) {
            contactFacade.onContactChanged(contactFacade.toDto(personContact), syncShares);
        }
        List<EventParticipant> personEventParticipants = eventParticipantService.findBy(new EventParticipantCriteria().withPerson(new PersonReferenceDto(newPerson.getUuid())), null);
        // Attention: this may lead to infinite recursion when not properly implemented
        for (EventParticipant personEventParticipant : personEventParticipants) {
            eventParticipantFacade.onEventParticipantChanged(eventFacade.toDto(personEventParticipant.getEvent()), eventParticipantFacade.toDto(personEventParticipant), personEventParticipant, syncShares);
        }
        // get the updated personCases
        personCases = caseService.findBy(new CaseCriteria().person(new PersonReferenceDto(newPerson.getUuid())), true);
        // sort cases based on recency
        Collections.sort(personCases, (c1, c2) -> CaseLogic.getStartDate(c1.getSymptoms().getOnsetDate(), c1.getReportDate()).before(CaseLogic.getStartDate(c2.getSymptoms().getOnsetDate(), c2.getReportDate())) ? 1 : -1);
        if (newPerson.getPresentCondition() != null && existingPerson.getPresentCondition() != newPerson.getPresentCondition()) {
            // get the latest case with disease==causeofdeathdisease
            Case personCase = personCases.stream().filter(caze -> caze.getDisease() == newPerson.getCauseOfDeathDisease()).findFirst().orElse(null);
            if (newPerson.getPresentCondition().isDeceased() && newPerson.getDeathDate() != null && newPerson.getCauseOfDeath() == CauseOfDeath.EPIDEMIC_DISEASE && newPerson.getCauseOfDeathDisease() != null) {
                // update the latest associated case
                if (personCase != null && personCase.getOutcome() != CaseOutcome.DECEASED && (personCase.getReportDate().before(DateHelper.addDays(newPerson.getDeathDate(), 30)) && personCase.getReportDate().after(DateHelper.subtractDays(newPerson.getDeathDate(), 30)))) {
                    CaseDataDto existingCase = caseFacade.toDto(personCase);
                    personCase.setOutcome(CaseOutcome.DECEASED);
                    personCase.setOutcomeDate(newPerson.getDeathDate());
                    caseFacade.onCaseChanged(existingCase, personCase, syncShares);
                }
            } else if (!newPerson.getPresentCondition().isDeceased() && (existingPerson.getPresentCondition() == PresentCondition.DEAD || existingPerson.getPresentCondition() == PresentCondition.BURIED)) {
                // Person was put "back alive"
                // make sure other values are set to null
                newPerson.setCauseOfDeath(null);
                newPerson.setCauseOfDeathDisease(null);
                newPerson.setDeathPlaceDescription(null);
                newPerson.setDeathPlaceType(null);
                newPerson.setBurialDate(null);
                newPerson.setCauseOfDeathDisease(null);
                // update the latest associated case, if it was set to deceased && and if the case-disease was also the causeofdeath-disease
                if (personCase != null && personCase.getOutcome() == CaseOutcome.DECEASED) {
                    CaseDataDto existingCase = caseFacade.toDto(personCase);
                    personCase.setOutcome(CaseOutcome.NO_OUTCOME);
                    personCase.setOutcomeDate(null);
                    caseFacade.onCaseChanged(existingCase, personCase, syncShares);
                }
            }
        } else if (newPerson.getPresentCondition() != null && newPerson.getPresentCondition().isDeceased() && !Objects.equals(newPerson.getDeathDate(), existingPerson.getDeathDate()) && newPerson.getDeathDate() != null) {
            // only Deathdate has changed
            // update the latest associated case to the new deathdate, if causeOfDeath matches
            Case personCase = personCases.isEmpty() ? null : personCases.get(0);
            if (personCase != null && personCase.getOutcome() == CaseOutcome.DECEASED && newPerson.getCauseOfDeath() == CauseOfDeath.EPIDEMIC_DISEASE) {
                CaseDataDto existingCase = caseFacade.toDto(personCase);
                personCase.setOutcomeDate(newPerson.getDeathDate());
                caseFacade.onCaseChanged(existingCase, personCase, syncShares);
            }
        }
    }
    // Set approximate age if it hasn't been set before
    if (newPerson.getApproximateAge() == null && newPerson.getBirthdateYYYY() != null) {
        Pair<Integer, ApproximateAgeType> pair = ApproximateAgeHelper.getApproximateAge(newPerson.getBirthdateYYYY(), newPerson.getBirthdateMM(), newPerson.getBirthdateDD(), newPerson.getDeathDate());
        newPerson.setApproximateAge(pair.getElement0());
        newPerson.setApproximateAgeType(pair.getElement1());
        newPerson.setApproximateAgeReferenceDate(newPerson.getDeathDate() != null ? newPerson.getDeathDate() : new Date());
    }
    // Update caseAge of all associated cases when approximateAge has changed
    if (existingPerson != null && existingPerson.getApproximateAge() != newPerson.getApproximateAge()) {
        // Update case list after previous onCaseChanged
        personCases = caseService.findBy(new CaseCriteria().person(new PersonReferenceDto(newPerson.getUuid())), true);
        for (Case personCase : personCases) {
            CaseDataDto existingCase = caseFacade.toDto(personCase);
            if (newPerson.getApproximateAge() == null) {
                personCase.setCaseAge(null);
            } else if (newPerson.getApproximateAgeType() == ApproximateAgeType.MONTHS) {
                personCase.setCaseAge(0);
            } else {
                Date now = new Date();
                personCase.setCaseAge(newPerson.getApproximateAge() - DateHelper.getYearsBetween(personCase.getReportDate(), now));
                if (personCase.getCaseAge() < 0) {
                    personCase.setCaseAge(0);
                }
            }
            caseFacade.onCaseChanged(existingCase, personCase, syncShares);
        }
    }
    // For newly created persons, assume no registration in external journals
    if (existingPerson == null && newPerson.getSymptomJournalStatus() == null) {
        newPerson.setSymptomJournalStatus(SymptomJournalStatus.UNREGISTERED);
    }
    cleanUp(newPerson);
}
Also used : CaseDataDto(de.symeda.sormas.api.caze.CaseDataDto) PersonReferenceDto(de.symeda.sormas.api.person.PersonReferenceDto) Date(java.util.Date) Case(de.symeda.sormas.backend.caze.Case) Contact(de.symeda.sormas.backend.contact.Contact) ApproximateAgeType(de.symeda.sormas.api.person.ApproximateAgeType) CaseCriteria(de.symeda.sormas.api.caze.CaseCriteria) ContactCriteria(de.symeda.sormas.api.contact.ContactCriteria) EventParticipantCriteria(de.symeda.sormas.api.event.EventParticipantCriteria) EventParticipant(de.symeda.sormas.backend.event.EventParticipant)

Example 3 with Contact

use of de.symeda.sormas.backend.contact.Contact in project SORMAS-Project by hzi-braunschweig.

the class SampleFacadeEjb method getSimilarSamples.

@Override
public List<SampleDto> getSimilarSamples(SampleSimilarityCriteria criteria) {
    final CriteriaBuilder cb = em.getCriteriaBuilder();
    final CriteriaQuery<Sample> cq = cb.createQuery(Sample.class);
    final Root<Sample> root = cq.from(Sample.class);
    cq.distinct(true);
    SampleJoins<Sample> joins = new SampleJoins<>(root);
    SampleCriteria sampleCriteria = new SampleCriteria();
    sampleCriteria.caze(criteria.getCaze()).contact(criteria.getContact()).eventParticipant(criteria.getEventParticipant());
    Predicate filter = sampleService.createUserFilter(cq, cb, joins, sampleCriteria);
    filter = CriteriaBuilderHelper.and(cb, filter, sampleService.buildCriteriaFilter(sampleCriteria, cb, joins));
    Predicate similarityFilter = null;
    if (criteria.getLabSampleId() != null) {
        similarityFilter = cb.equal(root.get(Sample.LAB_SAMPLE_ID), criteria.getLabSampleId());
    }
    Date sampleDateTime = criteria.getSampleDateTime();
    SampleMaterial sampleMaterial = criteria.getSampleMaterial();
    if (sampleDateTime != null && sampleMaterial != null) {
        Predicate dateAndMaterialFilter = cb.and(cb.between(root.get(Sample.SAMPLE_DATE_TIME), DateHelper.getStartOfDay(DateHelper.subtractDays(sampleDateTime, SIMILARITY_DATE_TIME_THRESHOLD)), DateHelper.getEndOfDay(DateHelper.addDays(sampleDateTime, SIMILARITY_DATE_TIME_THRESHOLD))), cb.equal(root.get(Sample.SAMPLE_MATERIAL), sampleMaterial));
        similarityFilter = CriteriaBuilderHelper.or(cb, similarityFilter, dateAndMaterialFilter);
    }
    filter = CriteriaBuilderHelper.and(cb, filter, similarityFilter);
    if (filter != null) {
        cq.where(filter);
    }
    List<Sample> samples = em.createQuery(cq).getResultList();
    if (samples.size() == 0 && (sampleDateTime == null || sampleMaterial == null)) {
        return getByCriteria(sampleCriteria);
    }
    Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService::hasRight);
    return samples.stream().map(s -> convertToDto(s, pseudonymizer)).collect(Collectors.toList());
}
Also used : CriteriaBuilder(javax.persistence.criteria.CriteriaBuilder) DtoHelper(de.symeda.sormas.backend.util.DtoHelper) StringUtils(org.apache.commons.lang3.StringUtils) Valid(javax.validation.Valid) Page(de.symeda.sormas.api.common.Page) Predicate(javax.persistence.criteria.Predicate) UserFacadeEjb(de.symeda.sormas.backend.user.UserFacadeEjb) Map(java.util.Map) CriteriaBuilder(javax.persistence.criteria.CriteriaBuilder) SormasToSormasOriginInfoFacadeEjb(de.symeda.sormas.backend.sormastosormas.origin.SormasToSormasOriginInfoFacadeEjb) EventParticipantReferenceDto(de.symeda.sormas.api.event.EventParticipantReferenceDto) CriteriaQuery(javax.persistence.criteria.CriteriaQuery) FacilityService(de.symeda.sormas.backend.infrastructure.facility.FacilityService) DiseaseHelper(de.symeda.sormas.api.DiseaseHelper) FacilityHelper(de.symeda.sormas.api.infrastructure.facility.FacilityHelper) NotNull(javax.validation.constraints.NotNull) UserService(de.symeda.sormas.backend.user.UserService) User(de.symeda.sormas.backend.user.User) PathogenTestResultType(de.symeda.sormas.api.sample.PathogenTestResultType) CaseFacadeEjbLocal(de.symeda.sormas.backend.caze.CaseFacadeEjb.CaseFacadeEjbLocal) EventFacadeEjb(de.symeda.sormas.backend.event.EventFacadeEjb) UserRoleConfigFacadeEjbLocal(de.symeda.sormas.backend.user.UserRoleConfigFacadeEjb.UserRoleConfigFacadeEjbLocal) SampleCriteria(de.symeda.sormas.api.sample.SampleCriteria) EventParticipant(de.symeda.sormas.backend.event.EventParticipant) Community(de.symeda.sormas.backend.infrastructure.community.Community) QueryHelper(de.symeda.sormas.backend.util.QueryHelper) Selection(javax.persistence.criteria.Selection) FacilityFacadeEjb(de.symeda.sormas.backend.infrastructure.facility.FacilityFacadeEjb) SampleFacade(de.symeda.sormas.api.sample.SampleFacade) EventParticipantFacadeEjbLocal(de.symeda.sormas.backend.event.EventParticipantFacadeEjb.EventParticipantFacadeEjbLocal) ArrayList(java.util.ArrayList) CaseReferenceDto(de.symeda.sormas.api.caze.CaseReferenceDto) Case(de.symeda.sormas.backend.caze.Case) SampleReferenceDto(de.symeda.sormas.api.sample.SampleReferenceDto) SampleListEntryDto(de.symeda.sormas.api.sample.SampleListEntryDto) LocalBean(javax.ejb.LocalBean) SampleIndexDto(de.symeda.sormas.api.sample.SampleIndexDto) SampleJurisdictionFlagsDto(de.symeda.sormas.api.sample.SampleJurisdictionFlagsDto) EJB(javax.ejb.EJB) Root(javax.persistence.criteria.Root) DataHelper(de.symeda.sormas.api.utils.DataHelper) EntityManager(javax.persistence.EntityManager) PersistenceContext(javax.persistence.PersistenceContext) SortProperty(de.symeda.sormas.api.utils.SortProperty) Captions(de.symeda.sormas.api.i18n.Captions) EventParticipantFacadeEjb(de.symeda.sormas.backend.event.EventParticipantFacadeEjb) ContactService(de.symeda.sormas.backend.contact.ContactService) SampleDto(de.symeda.sormas.api.sample.SampleDto) ContactFacadeEjb(de.symeda.sormas.backend.contact.ContactFacadeEjb) AbstractDomainObject(de.symeda.sormas.backend.common.AbstractDomainObject) Date(java.util.Date) I18nProperties(de.symeda.sormas.api.i18n.I18nProperties) LoggerFactory(org.slf4j.LoggerFactory) AccessDeniedException(de.symeda.sormas.api.utils.AccessDeniedException) Facility(de.symeda.sormas.backend.infrastructure.facility.Facility) NotificationService(de.symeda.sormas.backend.common.NotificationService) UserRole(de.symeda.sormas.api.user.UserRole) Contact(de.symeda.sormas.backend.contact.Contact) Stateless(javax.ejb.Stateless) CaseService(de.symeda.sormas.backend.caze.CaseService) NotificationDeliveryFailedException(de.symeda.sormas.backend.common.messaging.NotificationDeliveryFailedException) Person(de.symeda.sormas.backend.person.Person) CaseCriteria(de.symeda.sormas.api.caze.CaseCriteria) Collection(java.util.Collection) Region(de.symeda.sormas.backend.infrastructure.region.Region) District(de.symeda.sormas.backend.infrastructure.district.District) Pseudonymizer(de.symeda.sormas.backend.util.Pseudonymizer) Collectors(java.util.stream.Collectors) List(java.util.List) MessageContents(de.symeda.sormas.backend.common.messaging.MessageContents) CoreAdo(de.symeda.sormas.backend.common.CoreAdo) Location(de.symeda.sormas.backend.location.Location) ValidationRuntimeException(de.symeda.sormas.api.utils.ValidationRuntimeException) FacilityDto(de.symeda.sormas.api.infrastructure.facility.FacilityDto) ContactFacadeEjbLocal(de.symeda.sormas.backend.contact.ContactFacadeEjb.ContactFacadeEjbLocal) DateHelper(de.symeda.sormas.api.utils.DateHelper) CaseFacadeEjb(de.symeda.sormas.backend.caze.CaseFacadeEjb) Function(java.util.function.Function) PathogenTestFacadeEjbLocal(de.symeda.sormas.backend.sample.PathogenTestFacadeEjb.PathogenTestFacadeEjbLocal) EventParticipantService(de.symeda.sormas.backend.event.EventParticipantService) AdditionalTestFacadeEjbLocal(de.symeda.sormas.backend.sample.AdditionalTestFacadeEjb.AdditionalTestFacadeEjbLocal) IterableHelper(de.symeda.sormas.backend.util.IterableHelper) CaseQueryContext(de.symeda.sormas.backend.caze.CaseQueryContext) CriteriaBuilderHelper(de.symeda.sormas.backend.common.CriteriaBuilderHelper) SormasToSormasOriginInfoFacadeEjbLocal(de.symeda.sormas.backend.sormastosormas.origin.SormasToSormasOriginInfoFacadeEjb.SormasToSormasOriginInfoFacadeEjbLocal) ModelConstants(de.symeda.sormas.backend.util.ModelConstants) Logger(org.slf4j.Logger) Validations(de.symeda.sormas.api.i18n.Validations) MessageSubject(de.symeda.sormas.backend.common.messaging.MessageSubject) SampleMaterial(de.symeda.sormas.api.sample.SampleMaterial) Event(de.symeda.sormas.backend.event.Event) UserRight(de.symeda.sormas.api.user.UserRight) SampleExportDto(de.symeda.sormas.api.sample.SampleExportDto) NotificationType(de.symeda.sormas.api.user.NotificationType) ContactReferenceDto(de.symeda.sormas.api.contact.ContactReferenceDto) SampleSimilarityCriteria(de.symeda.sormas.api.sample.SampleSimilarityCriteria) ShareInfoHelper(de.symeda.sormas.backend.sormastosormas.share.shareinfo.ShareInfoHelper) Strings(de.symeda.sormas.api.i18n.Strings) Collections(java.util.Collections) Pseudonymizer(de.symeda.sormas.backend.util.Pseudonymizer) SampleCriteria(de.symeda.sormas.api.sample.SampleCriteria) Date(java.util.Date) Predicate(javax.persistence.criteria.Predicate) SampleMaterial(de.symeda.sormas.api.sample.SampleMaterial)

Example 4 with Contact

use of de.symeda.sormas.backend.contact.Contact 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();
    CriteriaBuilder cb = em.getCriteriaBuilder();
    // persons by LGA
    CriteriaQuery<Person> personsQuery = cb.createQuery(Person.class);
    Root<Person> personsRoot = personsQuery.from(Person.class);
    Join<Person, Location> address = personsRoot.join(Person.ADDRESS);
    Predicate lgaFilter = cb.equal(address.get(Location.DISTRICT), user.getDistrict());
    // date range
    if (date != null) {
        Predicate dateFilter = createChangeDateFilter(cb, personsRoot, DateHelper.toTimestampUpper(date), lastSynchronizedUuid);
        lgaFilter = cb.and(lgaFilter, dateFilter);
    }
    personsQuery.where(lgaFilter);
    List<Person> lgaResultList = 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(cb, casePersonsQuery, 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(cb, contactPersonsQuery, 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(cb, eventPersonsQuery, 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(cb, immunizationPersonsQuery, 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(cb, tepQuery, 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(lgaResultList, 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) ArrayList(java.util.ArrayList) Predicate(javax.persistence.criteria.Predicate) Case(de.symeda.sormas.backend.caze.Case) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) CriteriaBuilder(javax.persistence.criteria.CriteriaBuilder) Immunization(de.symeda.sormas.backend.immunization.entity.Immunization) Contact(de.symeda.sormas.backend.contact.Contact) EventParticipant(de.symeda.sormas.backend.event.EventParticipant) Location(de.symeda.sormas.backend.location.Location)

Example 5 with Contact

use of de.symeda.sormas.backend.contact.Contact in project SORMAS-Project by hzi-braunschweig.

the class PersonService method getSimilarPersonDtos.

public List<SimilarPersonDto> getSimilarPersonDtos(PersonSimilarityCriteria criteria, Integer limit) {
    setSimilarityThresholdQuery();
    boolean activeEntriesOnly = configFacade.isDuplicateChecksExcludePersonsOfArchivedEntries();
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Person> personQuery = cb.createQuery(Person.class);
    Root<Person> personRoot = personQuery.from(Person.class);
    Join<Person, Case> personCaseJoin = personRoot.join(Person.CASES, JoinType.LEFT);
    Join<Person, Contact> personContactJoin = personRoot.join(Person.CONTACTS, JoinType.LEFT);
    Join<Person, EventParticipant> personEventParticipantJoin = personRoot.join(Person.EVENT_PARTICIPANTS, JoinType.LEFT);
    Join<Person, Immunization> personImmunizationJoin = personRoot.join(Person.IMMUNIZATIONS, JoinType.LEFT);
    Join<Person, TravelEntry> personTravelEntryJoin = personRoot.join(Person.TRAVEL_ENTRIES, JoinType.LEFT);
    // Persons of active cases
    Predicate personSimilarityFilter = buildSimilarityCriteriaFilter(criteria, cb, personRoot);
    Predicate activeCasesFilter = activeEntriesOnly ? caseService.createActiveCasesFilter(cb, personCaseJoin) : caseService.createDefaultFilter(cb, personCaseJoin);
    Predicate caseUserFilter = caseService.createUserFilter(cb, personQuery, personCaseJoin);
    Predicate personCasePredicate = and(cb, personCaseJoin.get(Case.ID).isNotNull(), activeCasesFilter, caseUserFilter);
    // Persons of active contacts
    Predicate activeContactsFilter = activeEntriesOnly ? contactService.createActiveContactsFilter(cb, personContactJoin) : contactService.createDefaultFilter(cb, personContactJoin);
    Predicate contactUserFilter = contactService.createUserFilter(cb, personQuery, personContactJoin);
    Predicate personContactPredicate = and(cb, personContactJoin.get(Contact.ID).isNotNull(), contactUserFilter, activeContactsFilter);
    // Persons of event participants in active events
    Predicate activeEventParticipantsFilter = activeEntriesOnly ? eventParticipantService.createActiveEventParticipantsInActiveEventsFilter(cb, personEventParticipantJoin) : eventParticipantService.createDefaultInUndeletedEventsFilter(cb, personEventParticipantJoin);
    Predicate eventParticipantUserFilter = eventParticipantService.createUserFilter(cb, personQuery, personEventParticipantJoin);
    Predicate personEventParticipantPredicate = and(cb, personEventParticipantJoin.get(EventParticipant.ID).isNotNull(), activeEventParticipantsFilter, eventParticipantUserFilter);
    // Persons of active immunizations
    Predicate personImmunizationPredicate = null;
    if (!featureConfigurationFacade.isPropertyValueTrue(FeatureType.IMMUNIZATION_MANAGEMENT, FeatureTypeProperty.REDUCED)) {
        Predicate activeImmunizationsFilter = activeEntriesOnly ? immunizationService.createActiveImmunizationsFilter(cb, personImmunizationJoin) : immunizationService.createDefaultFilter(cb, personImmunizationJoin);
        Predicate immunizationUserFilter = immunizationService.createUserFilter(cb, personQuery, personImmunizationJoin);
        personImmunizationPredicate = and(cb, personImmunizationJoin.get(Immunization.ID).isNotNull(), immunizationUserFilter, activeImmunizationsFilter);
    }
    // Persons of active travel entries
    Predicate activeTravelEntriesFilter = activeEntriesOnly ? travelEntryService.createActiveTravelEntriesFilter(cb, personTravelEntryJoin) : travelEntryService.createDefaultFilter(cb, personTravelEntryJoin);
    Predicate travelEntryUserFilter = travelEntryService.createUserFilter(cb, personQuery, personTravelEntryJoin);
    Predicate personTravelEntryPredicate = and(cb, personTravelEntryJoin.get(TravelEntry.ID).isNotNull(), travelEntryUserFilter, activeTravelEntriesFilter);
    Predicate finalPredicate = CriteriaBuilderHelper.or(cb, personCasePredicate, personContactPredicate, personEventParticipantPredicate, personImmunizationPredicate, personTravelEntryPredicate);
    personQuery.where(and(cb, personSimilarityFilter, finalPredicate));
    personQuery.distinct(true);
    TypedQuery<Person> query = em.createQuery(personQuery);
    if (limit != null) {
        query.setMaxResults(limit);
    }
    List<Person> persons = query.getResultList();
    List<Long> personsInJurisdiction = getInJurisdictionIDs(persons);
    return persons.stream().filter(p -> personsInJurisdiction.contains(p.getId())).map(this::toSimilarPersonDto).collect(Collectors.toList());
}
Also used : CriteriaBuilder(javax.persistence.criteria.CriteriaBuilder) TravelEntry(de.symeda.sormas.backend.travelentry.TravelEntry) Immunization(de.symeda.sormas.backend.immunization.entity.Immunization) Case(de.symeda.sormas.backend.caze.Case) Contact(de.symeda.sormas.backend.contact.Contact) Predicate(javax.persistence.criteria.Predicate) EventParticipant(de.symeda.sormas.backend.event.EventParticipant)

Aggregations

Contact (de.symeda.sormas.backend.contact.Contact)53 CriteriaBuilder (javax.persistence.criteria.CriteriaBuilder)30 Case (de.symeda.sormas.backend.caze.Case)28 Predicate (javax.persistence.criteria.Predicate)24 User (de.symeda.sormas.backend.user.User)20 ArrayList (java.util.ArrayList)18 Date (java.util.Date)16 List (java.util.List)15 EventParticipant (de.symeda.sormas.backend.event.EventParticipant)14 Person (de.symeda.sormas.backend.person.Person)13 LocalBean (javax.ejb.LocalBean)13 Stateless (javax.ejb.Stateless)13 ContactService (de.symeda.sormas.backend.contact.ContactService)12 Collectors (java.util.stream.Collectors)12 EJB (javax.ejb.EJB)12 DataHelper (de.symeda.sormas.api.utils.DataHelper)11 District (de.symeda.sormas.backend.infrastructure.district.District)11 Collections (java.util.Collections)11 CaseService (de.symeda.sormas.backend.caze.CaseService)10 Location (de.symeda.sormas.backend.location.Location)10