Skip to content
This repository was archived by the owner on May 5, 2021. It is now read-only.

Commit 255ad6c

Browse files
authored
Merge pull request SORMAS-Foundation#4250 from hzi-braunschweig/feature/4247-reportingDateTolerance
Feature/4247 report date tolerance
2 parents 832af4c + 51377da commit 255ad6c

3 files changed

Lines changed: 87 additions & 4 deletions

File tree

sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,5 +205,7 @@ void saveBulkEditWithFacilities(
205205
boolean surveillanceOfficerChange,
206206
Boolean doTransfer);
207207

208+
List<CasePersonDto> getDuplicates(CasePersonDto casePerson, int reportDateThreshold);
209+
208210
List<CasePersonDto> getDuplicates(CasePersonDto casePerson);
209211
}

sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.java

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
import javax.validation.constraints.NotNull;
7373

7474
import org.apache.commons.lang3.StringUtils;
75+
import org.joda.time.DateTime;
7576
import org.slf4j.Logger;
7677
import org.slf4j.LoggerFactory;
7778

@@ -3432,12 +3433,18 @@ public String getFirstCaseUuidWithOwnershipHandedOver(List<String> caseUuids) {
34323433
* * same externalToken
34333434
* * same first name, last name, date of birth, sex (null is considered equal to any sex), disease, reportDate (ignore time), district
34343435
*
3436+
* The reportDateThreshold allows to return duplicates where
3437+
* -reportDateThreshold <= match.reportDate <= reportDateThreshold
3438+
*
34353439
* @param casePerson
34363440
* - case and person
3441+
* @param reportDateThreshold
3442+
* - the range bounds on match.reportDate
34373443
* @return list of duplicate cases
34383444
*/
34393445
@Override
3440-
public List<CasePersonDto> getDuplicates(CasePersonDto casePerson) {
3446+
public List<CasePersonDto> getDuplicates(CasePersonDto casePerson, int reportDateThreshold) {
3447+
34413448
CaseDataDto searchCaze = casePerson.getCaze();
34423449
PersonDto searchPerson = casePerson.getPerson();
34433450

@@ -3502,13 +3509,32 @@ public List<CasePersonDto> getDuplicates(CasePersonDto casePerson) {
35023509
and(cb, personPredicate, or(cb, cb.isNull(person.get(Person.SEX)), cb.equal(person.get(Person.SEX), searchPerson.getSex())));
35033510
}
35043511

3512+
Predicate reportDatePredicate;
3513+
3514+
if (reportDateThreshold == 0){
3515+
// threshold is zero: we want to get exact matches
3516+
reportDatePredicate = cb.equal(
3517+
cb.function("date", Date.class, caseRoot.get(Case.REPORT_DATE)),
3518+
cb.function("date", Date.class, cb.literal(searchCaze.getReportDate()))
3519+
);
3520+
} else{
3521+
// threshold is nonzero: apply time range of threshold to the reportDate
3522+
Date reportDate = casePerson.getCaze().getReportDate();
3523+
Date dateBefore = new DateTime(reportDate).minusDays(reportDateThreshold).toDate();
3524+
Date dateAfter= new DateTime(reportDate).plusDays(reportDateThreshold).toDate();;
3525+
3526+
reportDatePredicate = cb.between(
3527+
cb.function("date", Date.class, caseRoot.get(Case.REPORT_DATE)),
3528+
cb.function("date", Date.class, cb.literal(dateBefore)),
3529+
cb.function("date", Date.class, cb.literal(dateAfter))
3530+
);
3531+
}
3532+
35053533
combinedPredicate = and(
35063534
cb,
35073535
personPredicate,
35083536
cb.equal(caseRoot.get(Case.DISEASE), searchCaze.getDisease()),
3509-
cb.equal(
3510-
cb.function("date", Date.class, caseRoot.get(Case.REPORT_DATE)),
3511-
cb.function("date", Date.class, cb.literal(searchCaze.getReportDate()))),
3537+
reportDatePredicate,
35123538
cb.equal(caseCaseJoins.getDistrict().get(District.UUID), searchCaze.getDistrict().getUuid()));
35133539
}
35143540

@@ -3529,6 +3555,11 @@ public List<CasePersonDto> getDuplicates(CasePersonDto casePerson) {
35293555
.collect(Collectors.toList());
35303556
}
35313557

3558+
@Override
3559+
public List<CasePersonDto> getDuplicates(CasePersonDto casePerson) {
3560+
return getDuplicates(casePerson, 0);
3561+
}
3562+
35323563
@LocalBean
35333564
@Stateless
35343565
public static class CaseFacadeEjbLocal extends CaseFacadeEjb {

sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
import org.hamcrest.MatcherAssert;
4444
import org.hibernate.internal.SessionImpl;
4545
import org.hibernate.query.spi.QueryImplementor;
46+
import org.hamcrest.MatcherAssert;
47+
import org.joda.time.DateTime;
4648
import org.junit.Assert;
4749
import org.junit.Rule;
4850
import org.junit.Test;
@@ -1552,6 +1554,54 @@ public void testCreateCaseWithoutUuid() {
15521554
MatcherAssert.assertThat(savedCaze.getEpiData().getExposures().get(0).getUuid(), not(isEmptyOrNullString()));
15531555
}
15541556

1557+
@Test
1558+
public void testGetDuplicatesWithReportDateThreshold() {
1559+
RDCF rdcf = creator.createRDCF();
1560+
Date now = new Date();
1561+
//case and person matching for asserts
1562+
PersonDto person = creator.createPerson("Fname", "Lname", (p) -> {
1563+
p.setBirthdateDD(12);
1564+
p.setBirthdateMM(3);
1565+
p.setBirthdateYYYY(1968);
1566+
});
1567+
1568+
CaseDataDto caze = creator.createCase(creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference(), rdcf, (c) -> {
1569+
c.setPerson(person.toReference());
1570+
c.setDisease(Disease.CORONAVIRUS);
1571+
c.setDistrict(rdcf.district);
1572+
c.setReportDate(new Date());
1573+
});
1574+
1575+
PersonDto person2 = creator.createPerson("Fname", "Lname", (p) -> {
1576+
p.setBirthdateMM(3);
1577+
p.setBirthdateYYYY(1968);
1578+
});
1579+
creator.createCase(creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference(), rdcf, (c) -> {
1580+
c.setPerson(person2.toReference());
1581+
c.setDisease(Disease.CORONAVIRUS);
1582+
c.setReportDate(new DateTime(now).minusDays(1).toDate());
1583+
});
1584+
1585+
CasePersonDto casePerson = new CasePersonDto();
1586+
PersonDto duplicatePerson = PersonDto.build();
1587+
CaseDataDto duplicateCaze = CaseDataDto.build(duplicatePerson.toReference(), Disease.CORONAVIRUS);
1588+
duplicateCaze.setDistrict(rdcf.district);
1589+
duplicateCaze.setReportDate(new Date());
1590+
1591+
casePerson.setCaze(duplicateCaze);
1592+
casePerson.setPerson(duplicatePerson);
1593+
1594+
List<CasePersonDto> duplicates;
1595+
1596+
duplicateCaze.setExternalToken(null);
1597+
duplicatePerson.setFirstName("Fname");
1598+
duplicatePerson.setLastName("Lname");
1599+
duplicates = getCaseFacade().getDuplicates(casePerson, 1);
1600+
MatcherAssert.assertThat(duplicates, hasSize(2));
1601+
}
1602+
1603+
1604+
15551605
// @Test
15561606
// public void testGetSimilarCases() {
15571607
// RDCFEntities rdcf = creator.createRDCFEntities("Region", "District", "Community", "Facility");

0 commit comments

Comments
 (0)