ContactFacadeEjb implements ContactFacade { @Override public List<SimilarContactDto> getMatchingContacts(ContactSimilarityCriteria criteria) { final CriteriaBuilder cb = em.getCriteriaBuilder(); final CriteriaQuery<SimilarContactDto> cq = cb.createQuery(SimilarContactDto.class); final Root<Contact> contactRoot = cq.from(Contact.class); ContactJoins joins = new ContactJoins(contactRoot); cq.multiselect( Stream .concat( Stream.of( joins.getPerson().get(Person.FIRST_NAME), joins.getPerson().get(Person.LAST_NAME), contactRoot.get(Contact.UUID), joins.getCaze().get(Case.UUID), joins.getCasePerson().get(Person.FIRST_NAME), joins.getCasePerson().get(Person.LAST_NAME), contactRoot.get(Contact.CASE_ID_EXTERNAL_SYSTEM), contactRoot.get(Contact.LAST_CONTACT_DATE), contactRoot.get(Contact.CONTACT_PROXIMITY), contactRoot.get(Contact.CONTACT_CLASSIFICATION), contactRoot.get(Contact.CONTACT_STATUS), contactRoot.get(Contact.FOLLOW_UP_STATUS)), listCriteriaBuilder.getJurisdictionSelections(joins)) .collect(Collectors.toList())); final Predicate defaultFilter = contactService.createDefaultFilter(cb, contactRoot); final Predicate userFilter = contactService.createUserFilter(cb, cq, contactRoot); final PersonReferenceDto person = criteria.getPerson(); final Predicate samePersonFilter = person != null ? cb.equal(joins.getPerson().get(Person.UUID), person.getUuid()) : null; final Disease disease = criteria.getDisease(); final Predicate diseaseFilter = disease != null ? cb.equal(contactRoot.get(Contact.DISEASE), disease) : null; final CaseReferenceDto caze = criteria.getCaze(); final Predicate cazeFilter = caze != null ? cb.equal(joins.getCaze().get(Case.UUID), caze.getUuid()) : null; final Date reportDate = criteria.getReportDate(); final Date lastContactDate = criteria.getLastContactDate(); final Predicate recentContactsFilter = AbstractAdoService.and( cb, contactService.recentDateFilter(cb, reportDate, contactRoot.get(Contact.REPORT_DATE_TIME), 30), contactService.recentDateFilter(cb, lastContactDate, contactRoot.get(Contact.LAST_CONTACT_DATE), 30)); cq.where(AbstractAdoService.and(cb, defaultFilter, userFilter, samePersonFilter, diseaseFilter, cazeFilter, recentContactsFilter)); List<SimilarContactDto> contacts = em.createQuery(cq).getResultList(); Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService::hasRight); pseudonymizer.pseudonymizeDtoCollection( SimilarContactDto.class, contacts, c -> contactJurisdictionChecker.isInJurisdictionOrOwned(c.getJurisdiction()), (c, isInJurisdiction) -> { CaseReferenceDto contactCase = c.getCaze(); if (contactCase != null) { pseudonymizer.pseudonymizeDto( CaseReferenceDto.class, contactCase, caseJurisdictionChecker.isInJurisdictionOrOwned(c.getCaseJurisdiction()), null); } }); return contacts; }  @Override List<String> getAllActiveUuids(); @Override List<ContactDto> getAllActiveContactsAfter(Date date); @Override List<ContactDto> getByUuids(List<String> uuids); @Override List<String> getDeletedUuidsSince(Date since); @Override ContactDto getContactByUuid(String uuid); @Override Boolean isValidContactUuid(String uuid); @Override ContactReferenceDto getReferenceByUuid(String uuid); @Override ContactDto saveContact(ContactDto dto); @Override ContactDto saveContact(ContactDto dto, boolean handleChanges); @Override List<MapContactDto> getContactsForMap(
		RegionReferenceDto regionRef,
		DistrictReferenceDto districtRef,
		Disease disease,
		Date fromDate,
		Date toDate,
		List<MapCaseDto> mapCaseDtos); @Override void deleteContact(String contactUuid); @Override List<ContactExportDto> getExportList(ContactCriteria contactCriteria, int first, int max, Language userLanguage); @Override List<VisitSummaryExportDto> getVisitSummaryExportList(ContactCriteria contactCriteria, int first, int max, Language userLanguage); @Override long countMaximumFollowUpDays(ContactCriteria contactCriteria); @Override long count(ContactCriteria contactCriteria); @Override List<ContactFollowUpDto> getContactFollowUpList(
		ContactCriteria contactCriteria,
		Date referenceDate,
		int interval,
		Integer first,
		Integer max,
		List<SortProperty> sortProperties); @Override List<ContactIndexDto> getIndexList(ContactCriteria contactCriteria, Integer first, Integer max, List<SortProperty> sortProperties); @Override List<ContactIndexDetailedDto> getIndexDetailedList(
		ContactCriteria contactCriteria,
		Integer first,
		Integer max,
		List<SortProperty> sortProperties); @Override int[] getContactCountsByCasesForDashboard(List<Long> contactIds); @Override int getNonSourceCaseCountForDashboard(List<String> caseUuids); Contact fromDto(@NotNull ContactDto source); @Override boolean isDeleted(String contactUuid); @Override List<DashboardContactDto> getContactsForDashboard(
		RegionReferenceDto regionRef,
		DistrictReferenceDto districtRef,
		Disease disease,
		Date from,
		Date to); @Override List<DashboardQuarantineDataDto> getQuarantineDataForDashBoard(
		RegionReferenceDto regionRef,
		DistrictReferenceDto districtRef,
		Disease disease,
		Date from,
		Date to); @Override Map<ContactStatus, Long> getNewContactCountPerStatus(ContactCriteria contactCriteria); @Override Map<ContactClassification, Long> getNewContactCountPerClassification(ContactCriteria contactCriteria); @Override Map<FollowUpStatus, Long> getNewContactCountPerFollowUpStatus(ContactCriteria contactCriteria); @Override int getFollowUpUntilCount(ContactCriteria contactCriteria); ContactDto convertToDto(Contact source, Pseudonymizer pseudonymizer); static ContactReferenceDto toReferenceDto(Contact source); static ContactDto toDto(Contact source); @RolesAllowed(UserRole._SYSTEM) @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) void generateContactFollowUpTasks(); @Override void validate(ContactDto contact); @Override List<SimilarContactDto> getMatchingContacts(ContactSimilarityCriteria criteria); @Override boolean exists(String uuid); @Override boolean isContactEditAllowed(String contactUuid);  }
@Test public void testGetMatchingContacts() { RDCFEntities rdcf = creator.createRDCFEntities("Region", "District", "Community", "Facility"); UserDto user = creator .createUser(rdcf.region.getUuid(), rdcf.district.getUuid(), rdcf.facility.getUuid(), "Surv", "Sup", UserRole.SURVEILLANCE_SUPERVISOR); PersonDto cazePerson = creator.createPerson("Case", "Person"); CaseDataDto caze = creator.createCase( user.toReference(), cazePerson.toReference(), Disease.CORONAVIRUS, CaseClassification.PROBABLE, InvestigationStatus.PENDING, new Date(), rdcf); PersonDto contactPerson = creator.createPerson("Contact", "Person"); ContactDto contact1 = creator.createContact(user.toReference(), user.toReference(), contactPerson.toReference(), caze, new Date(), new Date(), null); contact1.setContactClassification(ContactClassification.CONFIRMED); getContactFacade().saveContact(contact1); ContactDto contact2 = creator.createContact( user.toReference(), user.toReference(), contactPerson.toReference(), caze, DateHelper.subtractDays(new Date(), 15), new Date(), null); ContactDto contact3 = creator.createContact( user.toReference(), user.toReference(), contactPerson.toReference(), caze, DateHelper.subtractDays(new Date(), 15), DateHelper.subtractDays(new Date(), 31), null); final ContactSimilarityCriteria contactSimilarityCriteria = new ContactSimilarityCriteria(); contactSimilarityCriteria.setDisease(Disease.CORONAVIRUS); contactSimilarityCriteria.setPerson(new PersonReferenceDto(contactPerson.getUuid())); contactSimilarityCriteria.setCaze(new CaseReferenceDto(caze.getUuid())); contactSimilarityCriteria.setLastContactDate(new Date()); contactSimilarityCriteria.setReportDate(new Date()); final List<SimilarContactDto> matchingContacts = getContactFacade().getMatchingContacts(contactSimilarityCriteria); Assert.assertNotNull(matchingContacts); Assert.assertEquals(2, matchingContacts.size()); final SimilarContactDto similarContactDto1 = matchingContacts.get(0); Assert.assertEquals(contact1.getUuid(), similarContactDto1.getUuid()); final SimilarContactDto similarContactDto2 = matchingContacts.get(1); Assert.assertEquals(contact2.getUuid(), similarContactDto2.getUuid()); }