use of de.symeda.sormas.api.person.PersonAssociation in project SORMAS-Project by hzi-braunschweig.
the class PersonFacadeEjb method count.
@Override
public long count(PersonCriteria criteria) {
long startTime = DateHelper.startTime();
final PersonCriteria nullSafeCriteria = Optional.ofNullable(criteria).orElse(new PersonCriteria());
final long count;
if (nullSafeCriteria.getPersonAssociation() == PersonAssociation.ALL) {
// Fetch Person.id per association and find the distinct count.
Set<Long> distinctPersonIds = new HashSet<>();
boolean immunizationModuleReduced = featureConfigurationFacade.isPropertyValueTrue(FeatureType.IMMUNIZATION_MANAGEMENT, FeatureTypeProperty.REDUCED);
Arrays.stream(PersonAssociation.getSingleAssociations()).filter(e -> !(immunizationModuleReduced && e == PersonAssociation.IMMUNIZATION)).map(e -> getPersonIds(SerializationUtils.clone(nullSafeCriteria).personAssociation(e))).forEach(distinctPersonIds::addAll);
count = distinctPersonIds.size();
} else {
// Directly fetch the count for the only required association
count = getPersonIds(criteria).size();
}
logger.debug("count() finished. association={}, count={}, {}ms", nullSafeCriteria.getPersonAssociation().name(), count, DateHelper.durationMillies(startTime));
return count;
}
use of de.symeda.sormas.api.person.PersonAssociation in project SORMAS-Project by hzi-braunschweig.
the class PersonFacadeEjbTest method testCountAndGetIndexListWithAssociations.
/**
* Test all {@link PersonAssociation} variants if they work. Also serves to review the generated SQL.
*/
@Test
public void testCountAndGetIndexListWithAssociations() {
PersonFacade cut = getPersonFacade();
Integer offset = null;
Integer limit = null;
List<SortProperty> sortProperties = null;
RDCF rdcf = creator.createRDCF();
UserDto user = creator.createUser(rdcf.region.getUuid(), null, null, null, "Surv", "Sup", UserRole.SURVEILLANCE_SUPERVISOR);
loginWith(user);
// 1a. Test for all available PersonAssociations
for (PersonAssociation pa : PersonAssociation.values()) {
PersonCriteria criteria = new PersonCriteria().personAssociation(pa);
assertThat("Failed for testing association on count: " + pa.name(), cut.count(criteria), equalTo(0L));
assertThat(criteria.getPersonAssociation(), equalTo(pa));
assertThat("Failed for testing association on getIndexList: " + pa.name(), cut.getIndexList(criteria, offset, limit, sortProperties), is(empty()));
assertThat(criteria.getPersonAssociation(), equalTo(pa));
}
// 1b. Test that calling with "null" as criteria also works
assertThat(cut.count(null), equalTo(0L));
assertThat(cut.getIndexList(null, offset, limit, sortProperties), is(empty()));
// 2. Test paging windows
final PersonDto person1 = creator.createPerson("James", "Smith", Sex.MALE, 1920, 1, 1);
final CaseDataDto case1 = creator.createCase(user.toReference(), person1.toReference(), Disease.EVD, CaseClassification.PROBABLE, InvestigationStatus.PENDING, new Date(), rdcf);
final PersonDto person2 = creator.createPerson("Maria", "Garcia", Sex.FEMALE, 1920, 1, 1);
final ContactDto contact2 = creator.createContact(user.toReference(), user.toReference(), person2.toReference(), null, new Date(), new Date(), Disease.EVD, rdcf);
// 2a. count
assertThat(cut.count(new PersonCriteria().personAssociation(PersonAssociation.ALL)), equalTo(2L));
assertThat(cut.count(new PersonCriteria().personAssociation(PersonAssociation.CASE)), equalTo(1L));
assertThat(cut.count(new PersonCriteria().personAssociation(PersonAssociation.CONTACT)), equalTo(1L));
// 2b. getIndexList with all persons in the paging window
assertPersonsFound(case1, contact2, cut, offset, limit, sortProperties);
offset = 0;
limit = 2;
assertPersonsFound(case1, contact2, cut, offset, limit, sortProperties);
offset = 0;
limit = 1;
assertPersonsFound(case1, contact2, cut, offset, limit, sortProperties);
// 2c. getIndexList [PersonAssociation.ALL] with only the contact person in the paging window (default sorting by changeDate)
offset = 1;
limit = 2;
assertPersonsFound(null, null, Arrays.asList(contact2.getPerson()), cut, offset, limit, sortProperties);
}
use of de.symeda.sormas.api.person.PersonAssociation in project SORMAS-Project by hzi-braunschweig.
the class PersonService method createUserFilter.
@SuppressWarnings({ "rawtypes", "unchecked" })
public Predicate createUserFilter(PersonQueryContext personQueryContext, PersonCriteria personCriteria) {
final CriteriaBuilder cb = personQueryContext.getCriteriaBuilder();
final CriteriaQuery cq = personQueryContext.getQuery();
final PersonJoins joins = (PersonJoins) personQueryContext.getJoins();
final boolean fullImmunizationModuleUsed = !featureConfigurationFacade.isPropertyValueTrue(FeatureType.IMMUNIZATION_MANAGEMENT, FeatureTypeProperty.REDUCED);
// 1. Define filters per association lazy to avoid superfluous joins
final Supplier<Predicate> caseFilter = () -> CriteriaBuilderHelper.and(cb, caseService.createUserFilter(cb, cq, joins.getCaze(), new CaseUserFilterCriteria()), caseService.createDefaultFilter(cb, joins.getCaze()));
final Supplier<Predicate> contactFilter = () -> {
final Predicate contactUserFilter = contactService.createUserFilterForJoin(new ContactQueryContext(cb, cq, joins.getContact()), new ContactCriteria().includeContactsFromOtherJurisdictions(false));
return CriteriaBuilderHelper.and(cb, contactUserFilter, contactService.createDefaultFilter(cb, joins.getContact()));
};
final Supplier<Predicate> eventParticipantFilter = () -> CriteriaBuilderHelper.and(cb, eventParticipantService.createUserFilterForJoin(cb, cq, joins.getEventParticipant(), new EventUserFilterCriteria().includeUserCaseAndEventParticipantFilter(false).forceRegionJurisdiction(true)), eventParticipantService.createDefaultFilter(cb, joins.getEventParticipant()));
final Supplier<Predicate> immunizationFilter = fullImmunizationModuleUsed ? () -> CriteriaBuilderHelper.and(cb, immunizationService.createUserFilter(cb, cq, joins.getImmunization()), immunizationService.createDefaultFilter(cb, joins.getImmunization())) : () -> null;
final Supplier<Predicate> travelEntryFilter = () -> CriteriaBuilderHelper.and(cb, travelEntryService.createUserFilter(cb, cq, joins.getTravelEntry()), travelEntryService.createDefaultFilter(cb, joins.getTravelEntry()));
// 2. Define the Joins on associations where needed
PersonAssociation personAssociation = Optional.ofNullable(personCriteria).map(e -> e.getPersonAssociation()).orElse(PersonCriteria.DEFAULT_ASSOCIATION);
switch(personAssociation) {
case ALL:
return CriteriaBuilderHelper.or(cb, caseFilter.get(), contactFilter.get(), eventParticipantFilter.get(), fullImmunizationModuleUsed ? immunizationFilter.get() : null, travelEntryFilter.get());
case CASE:
return caseFilter.get();
case CONTACT:
return contactFilter.get();
case EVENT_PARTICIPANT:
return eventParticipantFilter.get();
case IMMUNIZATION:
if (!fullImmunizationModuleUsed) {
throw new UnsupportedOperationException("Filtering persons by immunizations is not supported when the reduced immunization module is used.");
}
return immunizationFilter.get();
case TRAVEL_ENTRY:
return travelEntryFilter.get();
default:
throw new IllegalArgumentException(personAssociation.toString());
}
}
use of de.symeda.sormas.api.person.PersonAssociation in project SORMAS-Project by hzi-braunschweig.
the class PersonsView method createAssociationFilterBar.
public HorizontalLayout createAssociationFilterBar() {
HorizontalLayout associationFilterLayout = new HorizontalLayout();
associationFilterLayout.setSpacing(true);
associationFilterLayout.setMargin(false);
associationFilterLayout.setWidth(100, Unit.PERCENTAGE);
associationFilterLayout.addStyleName(CssStyles.VSPACE_3);
associationButtons = new HashMap<>();
for (PersonAssociation association : PersonAssociation.values()) {
if (association == PersonAssociation.IMMUNIZATION && (FacadeProvider.getFeatureConfigurationFacade().isFeatureDisabled(FeatureType.IMMUNIZATION_MANAGEMENT) || FacadeProvider.getFeatureConfigurationFacade().isPropertyValueTrue(FeatureType.IMMUNIZATION_MANAGEMENT, FeatureTypeProperty.REDUCED)) || association == PersonAssociation.TRAVEL_ENTRY && (FacadeProvider.getFeatureConfigurationFacade().isFeatureDisabled(FeatureType.TRAVEL_ENTRIES) || !FacadeProvider.getConfigFacade().isConfiguredCountry(CountryHelper.COUNTRY_CODE_GERMANY)) || association == PersonAssociation.CONTACT && FacadeProvider.getFeatureConfigurationFacade().isFeatureDisabled(FeatureType.CONTACT_TRACING) || association == PersonAssociation.CASE && FacadeProvider.getFeatureConfigurationFacade().isFeatureDisabled(FeatureType.CASE_SURVEILANCE) || association == PersonAssociation.EVENT_PARTICIPANT && FacadeProvider.getFeatureConfigurationFacade().isFeatureDisabled(FeatureType.EVENT_SURVEILLANCE)) {
continue;
}
Button associationButton = ButtonHelper.createButton(association.toString(), e -> {
if (!UserProvider.getCurrent().hasUserRole(UserRole.NATIONAL_USER) && association == PersonAssociation.ALL) {
Label contentLabel = new Label(I18nProperties.getString(Strings.confirmationSeeAllPersons));
VaadinUiUtil.showConfirmationPopup(I18nProperties.getString(Strings.headingSeeAllPersons), contentLabel, I18nProperties.getString(Strings.yes), I18nProperties.getString(Strings.no), 640, ee -> {
if (ee.booleanValue() == true) {
criteria.personAssociation(association);
navigateTo(criteria);
}
});
} else {
criteria.personAssociation(association);
navigateTo(criteria);
}
}, ValoTheme.BUTTON_BORDERLESS, CssStyles.BUTTON_FILTER, CssStyles.BUTTON_FILTER_LIGHT);
associationButton.setData(association);
associationButton.setCaptionAsHtml(true);
associationFilterLayout.addComponent(associationButton);
associationFilterLayout.setComponentAlignment(associationButton, Alignment.MIDDLE_LEFT);
associationButtons.put(associationButton, association.toString());
}
Label emptyLabel = new Label("");
associationFilterLayout.addComponent(emptyLabel);
associationFilterLayout.setComponentAlignment(emptyLabel, Alignment.MIDDLE_RIGHT);
associationFilterLayout.setExpandRatio(emptyLabel, 1);
return associationFilterLayout;
}
Aggregations