Search in sources :

Example 1 with PersonIndexDto

use of de.symeda.sormas.api.person.PersonIndexDto in project SORMAS-Project by hzi-braunschweig.

the class PersonFacadeEjb method getIndexList.

@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public List<PersonIndexDto> getIndexList(PersonCriteria criteria, Integer first, Integer max, List<SortProperty> sortProperties) {
    long startTime = DateHelper.startTime();
    final CriteriaBuilder cb = em.getCriteriaBuilder();
    final CriteriaQuery<PersonIndexDto> cq = cb.createQuery(PersonIndexDto.class);
    final Root<Person> person = cq.from(Person.class);
    final PersonQueryContext personQueryContext = new PersonQueryContext(cb, cq, person);
    final PersonJoins personJoins = (PersonJoins) personQueryContext.getJoins();
    personJoins.configure(criteria);
    final Join<Person, Location> location = personJoins.getAddress();
    final Join<Location, District> district = personJoins.getAddressJoins().getDistrict();
    final Subquery<String> phoneSubQuery = cq.subquery(String.class);
    final Root<PersonContactDetail> phoneRoot = phoneSubQuery.from(PersonContactDetail.class);
    phoneSubQuery.where(cb.and(cb.equal(phoneRoot.get(PersonContactDetail.PERSON), person), cb.isTrue(phoneRoot.get(PersonContactDetail.PRIMARY_CONTACT)), cb.equal(phoneRoot.get(PersonContactDetail.PERSON_CONTACT_DETAIL_TYPE), PersonContactDetailType.PHONE)));
    phoneSubQuery.select(phoneRoot.get(PersonContactDetail.CONTACT_INFORMATION));
    final Subquery<String> emailSubQuery = cq.subquery(String.class);
    final Root<PersonContactDetail> emailRoot = emailSubQuery.from(PersonContactDetail.class);
    emailSubQuery.where(cb.and(cb.equal(emailRoot.get(PersonContactDetail.PERSON), person), cb.isTrue(emailRoot.get(PersonContactDetail.PRIMARY_CONTACT)), cb.equal(emailRoot.get(PersonContactDetail.PERSON_CONTACT_DETAIL_TYPE), PersonContactDetailType.EMAIL)));
    emailSubQuery.select(emailRoot.get(PersonContactDetail.CONTACT_INFORMATION));
    // make sure to check the sorting by the multi-select order if you extend the selections here
    cq.multiselect(person.get(Person.UUID), person.get(Person.FIRST_NAME), person.get(Person.LAST_NAME), person.get(Person.APPROXIMATE_AGE), person.get(Person.APPROXIMATE_AGE_TYPE), person.get(Person.BIRTHDATE_DD), person.get(Person.BIRTHDATE_MM), person.get(Person.BIRTHDATE_YYYY), person.get(Person.SEX), district.get(District.NAME), location.get(Location.STREET), location.get(Location.HOUSE_NUMBER), location.get(Location.POSTAL_CODE), location.get(Location.CITY), phoneSubQuery.alias(PersonIndexDto.PHONE), emailSubQuery.alias(PersonIndexDto.EMAIL_ADDRESS), person.get(Person.CHANGE_DATE), JurisdictionHelper.booleanSelector(cb, personService.inJurisdictionOrOwned(personQueryContext)));
    Predicate filter = createIndexListFilter(criteria, personQueryContext);
    if (filter != null) {
        cq.where(filter);
    }
    cq.distinct(true);
    if (sortProperties != null && sortProperties.size() > 0) {
        List<Order> order = new ArrayList<Order>(sortProperties.size());
        for (SortProperty sortProperty : sortProperties) {
            Expression<?> expression;
            switch(sortProperty.propertyName) {
                case PersonIndexDto.UUID:
                case PersonIndexDto.FIRST_NAME:
                case PersonIndexDto.LAST_NAME:
                case PersonIndexDto.SEX:
                    expression = person.get(sortProperty.propertyName);
                    break;
                case PersonIndexDto.PHONE:
                    // order in the multiselect - Postgres limitation - needed to make sure it uses the same expression for ordering
                    expression = cb.literal(15);
                    break;
                case PersonIndexDto.EMAIL_ADDRESS:
                    // order in the multiselect - Postgres limitation - needed to make sure it uses the same expression for ordering
                    expression = cb.literal(16);
                    break;
                case PersonIndexDto.AGE_AND_BIRTH_DATE:
                    expression = person.get(Person.APPROXIMATE_AGE);
                    break;
                case PersonIndexDto.DISTRICT:
                    expression = district.get(District.NAME);
                    break;
                case PersonIndexDto.STREET:
                case PersonIndexDto.HOUSE_NUMBER:
                case PersonIndexDto.POSTAL_CODE:
                case PersonIndexDto.CITY:
                    expression = location.get(sortProperty.propertyName);
                    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(person.get(Person.CHANGE_DATE)));
    }
    List<PersonIndexDto> persons = QueryHelper.getResultList(em, cq, first, max);
    Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService::hasRight, I18nProperties.getCaption(Captions.inaccessibleValue));
    pseudonymizer.pseudonymizeDtoCollection(PersonIndexDto.class, persons, p -> p.getInJurisdiction(), (p, isInJurisdiction) -> pseudonymizer.pseudonymizeDto(AgeAndBirthDateDto.class, p.getAgeAndBirthDate(), isInJurisdiction, null));
    logger.debug("getIndexList() finished. association={}, count={}, {}ms", Optional.ofNullable(criteria).orElse(new PersonCriteria()).getPersonAssociation().name(), persons.size(), DateHelper.durationMillies(startTime));
    return persons;
}
Also used : AgeAndBirthDateDto(de.symeda.sormas.api.caze.AgeAndBirthDateDto) Pseudonymizer(de.symeda.sormas.backend.util.Pseudonymizer) ArrayList(java.util.ArrayList) Predicate(javax.persistence.criteria.Predicate) SortProperty(de.symeda.sormas.api.utils.SortProperty) CriteriaBuilder(javax.persistence.criteria.CriteriaBuilder) Order(javax.persistence.criteria.Order) PersonIndexDto(de.symeda.sormas.api.person.PersonIndexDto) PersonCriteria(de.symeda.sormas.api.person.PersonCriteria) District(de.symeda.sormas.backend.infrastructure.district.District) Location(de.symeda.sormas.backend.location.Location)

Example 2 with PersonIndexDto

use of de.symeda.sormas.api.person.PersonIndexDto in project SORMAS-Project by hzi-braunschweig.

the class PersonGrid method setLazyDataProvider.

public void setLazyDataProvider() {
    DataProvider<PersonIndexDto, PersonCriteria> dataProvider = DataProvider.fromFilteringCallbacks(query -> FacadeProvider.getPersonFacade().getIndexList(query.getFilter().orElse(null), query.getOffset(), query.getLimit(), query.getSortOrders().stream().map(sortOrder -> new SortProperty(sortOrder.getSorted(), sortOrder.getDirection() == SortDirection.ASCENDING)).collect(Collectors.toList())).stream(), query -> (int) FacadeProvider.getPersonFacade().count(query.getFilter().orElse(null)));
    setDataProvider(dataProvider);
    setSelectionMode(SelectionMode.NONE);
}
Also used : SortProperty(de.symeda.sormas.api.utils.SortProperty) PersonIndexDto(de.symeda.sormas.api.person.PersonIndexDto) PersonCriteria(de.symeda.sormas.api.person.PersonCriteria)

Example 3 with PersonIndexDto

use of de.symeda.sormas.api.person.PersonIndexDto in project SORMAS-Project by hzi-braunschweig.

the class PersonGrid method initColumns.

private void initColumns() {
    setColumns(PersonIndexDto.UUID, PersonIndexDto.FIRST_NAME, PersonIndexDto.LAST_NAME, PersonIndexDto.AGE_AND_BIRTH_DATE, PersonIndexDto.SEX, PersonIndexDto.DISTRICT, PersonIndexDto.STREET, PersonIndexDto.HOUSE_NUMBER, PersonIndexDto.POSTAL_CODE, PersonIndexDto.CITY, PersonIndexDto.PHONE, PersonIndexDto.EMAIL_ADDRESS);
    ((Column<PersonIndexDto, String>) getColumn(PersonIndexDto.UUID)).setRenderer(new UuidRenderer());
    ((Column<PersonIndexDto, AgeAndBirthDateDto>) getColumn(PersonIndexDto.AGE_AND_BIRTH_DATE)).setRenderer(value -> value == null ? "" : PersonHelper.getAgeAndBirthdateString(value.getAge(), value.getAgeType(), value.getDateOfBirthDD(), value.getDateOfBirthMM(), value.getDateOfBirthYYYY()), new TextRenderer());
    for (Column<PersonIndexDto, ?> column : getColumns()) {
        column.setCaption(I18nProperties.findPrefixCaptionWithDefault(column.getId(), column.getCaption(), PersonIndexDto.I18N_PREFIX, PersonDto.I18N_PREFIX, LocationDto.I18N_PREFIX));
        column.setStyleGenerator(FieldAccessColumnStyleGenerator.getDefault(getBeanType(), column.getId()));
    }
}
Also used : PersonIndexDto(de.symeda.sormas.api.person.PersonIndexDto) UuidRenderer(de.symeda.sormas.ui.utils.UuidRenderer) TextRenderer(com.vaadin.ui.renderers.TextRenderer)

Example 4 with PersonIndexDto

use of de.symeda.sormas.api.person.PersonIndexDto in project SORMAS-Project by hzi-braunschweig.

the class PersonFacadeEjbTest method assertPersonsFound.

private static void assertPersonsFound(CaseDataDto caze, ContactDto contact, List<PersonReferenceDto> allPersons, PersonFacade cut, Integer offset, Integer limit, List<SortProperty> sortProperties) {
    List<String> casePersonUuids = caze == null ? Collections.emptyList() : Collections.singletonList(caze.getPerson().getUuid());
    List<String> contactPersonUuids = contact == null ? Collections.emptyList() : Collections.singletonList(contact.getPerson().getUuid());
    int allCount = Math.min(allPersons.size(), limit != null ? limit : Integer.MAX_VALUE);
    // single association
    List<PersonIndexDto> caseList = cut.getIndexList(new PersonCriteria().personAssociation(PersonAssociation.CASE), offset, limit, sortProperties);
    assertThat(caseList, hasSize(casePersonUuids.size()));
    List<PersonIndexDto> contactList = cut.getIndexList(new PersonCriteria().personAssociation(PersonAssociation.CONTACT), offset, limit, sortProperties);
    assertThat(contactList, hasSize(contactPersonUuids.size()));
    assertThat(cut.getIndexList(new PersonCriteria().personAssociation(PersonAssociation.EVENT_PARTICIPANT), offset, limit, sortProperties), is(empty()));
    assertThat(cut.getIndexList(new PersonCriteria().personAssociation(PersonAssociation.IMMUNIZATION), offset, limit, sortProperties), is(empty()));
    assertThat(cut.getIndexList(new PersonCriteria().personAssociation(PersonAssociation.TRAVEL_ENTRY), offset, limit, sortProperties), is(empty()));
    // ALL
    List<PersonIndexDto> allList = cut.getIndexList(new PersonCriteria().personAssociation(PersonAssociation.ALL), offset, limit, sortProperties);
    assertThat(allList, hasSize(allCount));
}
Also used : PersonIndexDto(de.symeda.sormas.api.person.PersonIndexDto) PersonCriteria(de.symeda.sormas.api.person.PersonCriteria) Matchers.isEmptyOrNullString(org.hamcrest.Matchers.isEmptyOrNullString)

Example 5 with PersonIndexDto

use of de.symeda.sormas.api.person.PersonIndexDto in project SORMAS-Project by hzi-braunschweig.

the class PersonFacadeEjbUserFilterTest method testGetPersonIndexListPersonNotIncludedIfContactOutsideJurisdiction.

@Test
public void testGetPersonIndexListPersonNotIncludedIfContactOutsideJurisdiction() {
    loginWith(nationalUser);
    PersonDto person1 = creator.createPerson("John", "Doe");
    PersonDto person2 = creator.createPerson("John2", "Doe2");
    CaseDataDto caze = creator.createCase(nationalUser.toReference(), person1.toReference(), Disease.EVD, CaseClassification.PROBABLE, InvestigationStatus.PENDING, new Date(), rdcf1);
    ContactDto contactInJurisdiction1 = creator.createContact(nationalUser.toReference(), null, person1.toReference(), caze, new Date(), new Date(), Disease.CORONAVIRUS, rdcf1);
    contactInJurisdiction1.setRegion(rdcf1.region);
    contactInJurisdiction1.setDistrict(rdcf1.district);
    getContactFacade().save(contactInJurisdiction1);
    ContactDto contactInJurisdiction2 = creator.createContact(nationalUser.toReference(), null, person2.toReference(), caze, new Date(), new Date(), Disease.CORONAVIRUS, rdcf2);
    contactInJurisdiction2.setRegion(rdcf2.region);
    contactInJurisdiction2.setDistrict(rdcf2.district);
    getContactFacade().save(contactInJurisdiction2);
    loginWith(districtUser1);
    List<PersonIndexDto> indexListForDistrictUser1 = getPersonFacade().getIndexList(null, null, null, null);
    assertEquals(2, indexListForDistrictUser1.size());
    loginWith(districtUser2);
    List<PersonIndexDto> indexListForDistrictUser2 = getPersonFacade().getIndexList(null, null, null, null);
    assertEquals(1, indexListForDistrictUser2.size());
    assertEquals(person2.getUuid(), indexListForDistrictUser2.get(0).getUuid());
}
Also used : CaseDataDto(de.symeda.sormas.api.caze.CaseDataDto) PersonIndexDto(de.symeda.sormas.api.person.PersonIndexDto) PersonDto(de.symeda.sormas.api.person.PersonDto) ContactDto(de.symeda.sormas.api.contact.ContactDto) Date(java.util.Date) Test(org.junit.Test) AbstractBeanTest(de.symeda.sormas.backend.AbstractBeanTest)

Aggregations

PersonIndexDto (de.symeda.sormas.api.person.PersonIndexDto)10 PersonCriteria (de.symeda.sormas.api.person.PersonCriteria)7 Date (java.util.Date)6 PersonDto (de.symeda.sormas.api.person.PersonDto)5 Test (org.junit.Test)5 CaseDataDto (de.symeda.sormas.api.caze.CaseDataDto)4 ContactDto (de.symeda.sormas.api.contact.ContactDto)4 UserDto (de.symeda.sormas.api.user.UserDto)3 AbstractBeanTest (de.symeda.sormas.backend.AbstractBeanTest)3 Collections (java.util.Collections)3 StreamResource (com.vaadin.server.StreamResource)2 TravelEntryDto (de.symeda.sormas.api.travelentry.TravelEntryDto)2 SortProperty (de.symeda.sormas.api.utils.SortProperty)2 TextRenderer (com.vaadin.ui.renderers.TextRenderer)1 Disease (de.symeda.sormas.api.Disease)1 EntityDto (de.symeda.sormas.api.EntityDto)1 AgeAndBirthDateDto (de.symeda.sormas.api.caze.AgeAndBirthDateDto)1 CaseClassification (de.symeda.sormas.api.caze.CaseClassification)1 CaseCriteria (de.symeda.sormas.api.caze.CaseCriteria)1 InvestigationStatus (de.symeda.sormas.api.caze.InvestigationStatus)1