use of de.symeda.sormas.api.caze.CasePersonDto in project SORMAS-Project by hzi-braunschweig.
the class CaseFacadeEjbTest method testGetDuplicatesWithReportDateThreshold.
@Test
public void testGetDuplicatesWithReportDateThreshold() {
RDCF rdcf = creator.createRDCF();
Date now = new Date();
// case and person matching for asserts
PersonDto person = creator.createPerson("Fname", "Lname", (p) -> {
p.setBirthdateDD(12);
p.setBirthdateMM(3);
p.setBirthdateYYYY(1968);
});
final UserReferenceDto user = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference();
CaseDataDto caze = creator.createCase(user, rdcf, (c) -> {
c.setPerson(person.toReference());
c.setDisease(Disease.CORONAVIRUS);
c.setDistrict(rdcf.district);
c.setReportDate(new Date());
});
PersonDto person2 = creator.createPerson("Fname", "Lname", (p) -> {
p.setBirthdateMM(3);
p.setBirthdateYYYY(1968);
});
creator.createCase(user, rdcf, (c) -> {
c.setPerson(person2.toReference());
c.setDisease(Disease.CORONAVIRUS);
c.setReportDate(new DateTime(now).minusDays(1).toDate());
});
CasePersonDto casePerson = new CasePersonDto();
PersonDto duplicatePerson = PersonDto.build();
CaseDataDto duplicateCaze = CaseDataDto.build(duplicatePerson.toReference(), Disease.CORONAVIRUS);
duplicateCaze.setResponsibleDistrict(rdcf.district);
duplicateCaze.setReportDate(new Date());
casePerson.setCaze(duplicateCaze);
casePerson.setPerson(duplicatePerson);
List<CasePersonDto> duplicates;
duplicateCaze.setExternalToken(null);
duplicatePerson.setFirstName("Fname");
duplicatePerson.setLastName("Lname");
duplicates = getCaseFacade().getDuplicates(casePerson, 1);
MatcherAssert.assertThat(duplicates, hasSize(2));
}
use of de.symeda.sormas.api.caze.CasePersonDto in project SORMAS-Project by hzi-braunschweig.
the class CaseFacadeEjbTest method testGetDuplicates.
@Test
public void testGetDuplicates() {
RDCF rdcf = creator.createRDCF();
// case and person matching for asserts
PersonDto person = creator.createPerson("Fname", "Lname", (p) -> {
p.setBirthdateDD(12);
p.setBirthdateMM(3);
p.setBirthdateYYYY(1968);
});
final UserReferenceDto user = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference();
CaseDataDto caze = creator.createCase(user, rdcf, (c) -> {
c.setPerson(person.toReference());
c.setExternalID("test-ext-id");
c.setExternalToken("test-ext-token");
c.setDisease(Disease.CORONAVIRUS);
c.setDistrict(rdcf.district);
c.setReportDate(new Date());
});
// case and person matching for some asserts
PersonDto person2 = creator.createPerson("Fname", "Lname", (p) -> {
p.setBirthdateMM(3);
p.setBirthdateYYYY(1968);
});
creator.createCase(user, rdcf, (c) -> {
c.setPerson(person2.toReference());
c.setDisease(Disease.CORONAVIRUS);
});
creator.createCase(user, rdcf, (c) -> {
c.setPerson(creator.createPerson().toReference());
c.setDisease(Disease.CHOLERA);
});
creator.createCase(user, rdcf, (c) -> {
c.setPerson(person.toReference());
c.setDisease(Disease.CHOLERA);
});
CasePersonDto casePerson = new CasePersonDto();
PersonDto duplicatePerson = PersonDto.build();
CaseDataDto duplicateCaze = CaseDataDto.build(duplicatePerson.toReference(), Disease.CORONAVIRUS);
duplicateCaze.setResponsibleDistrict(rdcf.district);
duplicateCaze.setReportDate(new Date());
casePerson.setCaze(duplicateCaze);
casePerson.setPerson(duplicatePerson);
List<CasePersonDto> duplicates = getCaseFacade().getDuplicates(casePerson);
MatcherAssert.assertThat(duplicates, hasSize(0));
// match by external ID
duplicateCaze.setExternalID("test-ext-id");
duplicates = getCaseFacade().getDuplicates(casePerson);
MatcherAssert.assertThat(duplicates, hasSize(1));
// match by external ID case insensitive + trim
duplicateCaze.setExternalID(" test-EXT-id ");
duplicates = getCaseFacade().getDuplicates(casePerson);
MatcherAssert.assertThat(duplicates, hasSize(1));
// match by external token
duplicateCaze.setExternalID(null);
duplicateCaze.setExternalToken(caze.getExternalToken());
duplicates = getCaseFacade().getDuplicates(casePerson);
MatcherAssert.assertThat(duplicates, hasSize(1));
// match by external token case insensitive + trim
duplicateCaze.setExternalToken(" Test-ext-TOKEN ");
duplicates = getCaseFacade().getDuplicates(casePerson);
MatcherAssert.assertThat(duplicates, hasSize(1));
// match by first name and last name
duplicateCaze.setExternalToken(null);
duplicatePerson.setFirstName("Fname");
duplicatePerson.setLastName("Lname");
duplicates = getCaseFacade().getDuplicates(casePerson);
MatcherAssert.assertThat(duplicates, hasSize(2));
// match by name and birth day should match also the one with missing birth day
duplicatePerson.setBirthdateDD(12);
duplicates = getCaseFacade().getDuplicates(casePerson);
MatcherAssert.assertThat(duplicates, hasSize(2));
// match by name and birth day / month should match also the one with missing birth day
duplicatePerson.setBirthdateMM(3);
duplicates = getCaseFacade().getDuplicates(casePerson);
MatcherAssert.assertThat(duplicates, hasSize(2));
// match by name and birth day / month / year should match also the one with missing birth day
duplicatePerson.setBirthdateYYYY(1968);
duplicates = getCaseFacade().getDuplicates(casePerson);
MatcherAssert.assertThat(duplicates, hasSize(2));
// match by name and birth month / year
duplicatePerson.setBirthdateDD(null);
duplicates = getCaseFacade().getDuplicates(casePerson);
MatcherAssert.assertThat(duplicates, hasSize(2));
// case insensitive name
duplicatePerson.setFirstName(" fnamE");
duplicatePerson.setLastName("lName ");
duplicates = getCaseFacade().getDuplicates(casePerson);
MatcherAssert.assertThat(duplicates, hasSize(2));
}
use of de.symeda.sormas.api.caze.CasePersonDto in project SORMAS-Project by hzi-braunschweig.
the class CaseFacadeEjb method getDuplicates.
/**
* Find duplicates based on case and person dto
* Conditions:
* * same externalId
* * same externalToken
* * same first name, last name, date of birth, sex (null is considered equal to any sex), disease, reportDate (ignore time), district
*
* The reportDateThreshold allows to return duplicates where
* -reportDateThreshold <= match.reportDate <= reportDateThreshold
*
* @param casePerson
* - case and person
* @param reportDateThreshold
* - the range bounds on match.reportDate
* @return list of duplicate cases
*/
@Override
public List<CasePersonDto> getDuplicates(@Valid CasePersonDto casePerson, int reportDateThreshold) {
CaseDataDto searchCaze = casePerson.getCaze();
PersonDto searchPerson = casePerson.getPerson();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Object[]> cq = cb.createQuery(Object[].class);
Root<Case> caseRoot = cq.from(Case.class);
CaseJoins<Case> caseCaseJoins = new CaseJoins<>(caseRoot);
Join<Case, Person> person = caseCaseJoins.getPerson();
cq.multiselect(caseRoot.get(Case.UUID), person.get(Person.UUID));
Path<String> externalId = caseRoot.get(Case.EXTERNAL_ID);
Path<String> externalToken = caseRoot.get(Case.EXTERNAL_TOKEN);
Predicate externalIdPredicate = null;
if (searchCaze.getExternalID() != null) {
externalIdPredicate = and(cb, cb.isNotNull(externalId), cb.equal(cb.lower(externalId), searchCaze.getExternalID().toLowerCase().trim()));
}
Predicate externalTokenPredicate = null;
if (searchCaze.getExternalToken() != null) {
externalTokenPredicate = and(cb, cb.isNotNull(externalToken), cb.equal(cb.trim(cb.lower(externalToken)), searchCaze.getExternalToken().toLowerCase().trim()));
}
// todo this should use PersonService.buildSimilarityCriteriaFilter
Predicate combinedPredicate = null;
if (searchPerson.getFirstName() != null && searchPerson.getLastName() != null && searchCaze.getReportDate() != null && searchCaze.getResponsibleDistrict() != null) {
Predicate personPredicate = and(cb, cb.equal(cb.trim(cb.lower(person.get(Person.FIRST_NAME))), searchPerson.getFirstName().toLowerCase().trim()), cb.equal(cb.trim(cb.lower(person.get(Person.LAST_NAME))), searchPerson.getLastName().toLowerCase().trim()));
if (searchPerson.getBirthdateDD() != null) {
personPredicate = and(cb, personPredicate, or(cb, cb.isNull(person.get(Person.BIRTHDATE_DD)), cb.equal(person.get(Person.BIRTHDATE_DD), searchPerson.getBirthdateDD())));
}
if (searchPerson.getBirthdateMM() != null) {
personPredicate = and(cb, personPredicate, or(cb, cb.isNull(person.get(Person.BIRTHDATE_DD)), cb.equal(person.get(Person.BIRTHDATE_MM), searchPerson.getBirthdateMM())));
}
if (searchPerson.getBirthdateYYYY() != null) {
personPredicate = and(cb, personPredicate, or(cb, cb.isNull(person.get(Person.BIRTHDATE_YYYY)), cb.equal(person.get(Person.BIRTHDATE_YYYY), searchPerson.getBirthdateYYYY())));
}
if (searchPerson.getSex() != null) {
personPredicate = and(cb, personPredicate, or(cb, cb.isNull(person.get(Person.SEX)), cb.equal(person.get(Person.SEX), searchPerson.getSex())));
}
Predicate reportDatePredicate;
if (reportDateThreshold == 0) {
// threshold is zero: we want to get exact matches
reportDatePredicate = cb.equal(cb.function("date", Date.class, caseRoot.get(Case.REPORT_DATE)), cb.function("date", Date.class, cb.literal(searchCaze.getReportDate())));
} else {
// threshold is nonzero: apply time range of threshold to the reportDate
Date reportDate = casePerson.getCaze().getReportDate();
Date dateBefore = new DateTime(reportDate).minusDays(reportDateThreshold).toDate();
Date dateAfter = new DateTime(reportDate).plusDays(reportDateThreshold).toDate();
reportDatePredicate = cb.between(cb.function("date", Date.class, caseRoot.get(Case.REPORT_DATE)), cb.function("date", Date.class, cb.literal(dateBefore)), cb.function("date", Date.class, cb.literal(dateAfter)));
}
Predicate districtPredicate = CriteriaBuilderHelper.or(cb, cb.equal(caseCaseJoins.getResponsibleDistrict().get(District.UUID), searchCaze.getResponsibleDistrict().getUuid()), cb.equal(caseCaseJoins.getDistrict().get(District.UUID), searchCaze.getResponsibleDistrict().getUuid()));
if (searchCaze.getDistrict() != null) {
districtPredicate = CriteriaBuilderHelper.or(cb, districtPredicate, cb.equal(caseCaseJoins.getResponsibleDistrict().get(District.UUID), searchCaze.getDistrict().getUuid()), cb.equal(caseCaseJoins.getDistrict().get(District.UUID), searchCaze.getDistrict().getUuid()));
}
combinedPredicate = and(cb, personPredicate, cb.equal(caseRoot.get(Case.DISEASE), searchCaze.getDisease()), reportDatePredicate, districtPredicate);
}
Predicate filters = or(cb, externalIdPredicate, externalTokenPredicate, combinedPredicate);
if (filters == null) {
return Collections.emptyList();
}
cq.where(filters);
List<Object[]> duplicateUuids = em.createQuery(cq).getResultList();
return duplicateUuids.stream().map((casePersonUuids) -> new CasePersonDto(getCaseDataByUuid((String) casePersonUuids[0]), personFacade.getPersonByUuid((String) casePersonUuids[1]))).collect(Collectors.toList());
}
Aggregations