@@ -334,57 +334,74 @@ public List<EventIndexDto> getIndexList(EventCriteria eventCriteria, Integer fir
334334 }
335335
336336 Map <String , Long > participantCounts = new HashMap <>();
337- Map <String , Long > caseCounts = new HashMap <>();;
337+ Map <String , Long > caseCounts = new HashMap <>();
338338 Map <String , Long > deathCounts = new HashMap <>();
339+ Map <String , Long > contactCounts = new HashMap <>();
340+ Map <String , Long > contactCountsSourceInEvent = new HashMap <>();
339341 if (indexList != null ) {
340342 List <Object []> objectQueryList = null ;
341343
342- CriteriaQuery <Object []> objectCQ = cb .createQuery (Object [].class );
343- Root <Event > eventRoot = objectCQ .from (Event .class );
344-
345- // number of Participants
346- Subquery <Long > participantCount = objectCQ .subquery (Long .class );
347- Root <EventParticipant > eventParticipantRoot = participantCount .from (EventParticipant .class );
348- Predicate assignedToEvent = cb .equal (eventParticipantRoot .get (EventParticipant .EVENT ), eventRoot .get (AbstractDomainObject .ID ));
349- Predicate notDeleted = cb .isFalse (eventParticipantRoot .get (EventParticipant .DELETED ));
350- participantCount .select (cb .count (eventParticipantRoot ));
351- participantCount .where (assignedToEvent , notDeleted );
352-
353- // number of cases among event participants
354- Subquery <Long > caseCount = objectCQ .subquery (Long .class );
355- eventParticipantRoot = caseCount .from (EventParticipant .class );
356- assignedToEvent = cb .equal (eventParticipantRoot .get (EventParticipant .EVENT ), eventRoot .get (AbstractDomainObject .ID ));
357- notDeleted = cb .isFalse (eventParticipantRoot .get (EventParticipant .DELETED ));
358- Predicate isCase = cb .isNotNull (eventParticipantRoot .get (EventParticipant .RESULTING_CASE ));
359- caseCount .select (cb .count (eventParticipantRoot ));
360- caseCount .where (assignedToEvent , notDeleted , isCase );
361-
362- // number of fatalities among event participant cases
363- Subquery <Long > deathsCount = objectCQ .subquery (Long .class );
364- eventParticipantRoot = deathsCount .from (EventParticipant .class );
365- Join <EventParticipant , Case > caseJoin = eventParticipantRoot .join (EventParticipant .RESULTING_CASE , JoinType .LEFT );
366- assignedToEvent = cb .equal (eventParticipantRoot .get (EventParticipant .EVENT ), eventRoot .get (AbstractDomainObject .ID ));
367- notDeleted = cb .isFalse (eventParticipantRoot .get (EventParticipant .DELETED ));
368- isCase = cb .isNotNull (eventParticipantRoot .get (EventParticipant .RESULTING_CASE ));
369- Predicate isDead = cb .equal (caseJoin .get (Case .OUTCOME ), CaseOutcome .DECEASED );
370- deathsCount .select (cb .count (eventParticipantRoot ));
371- deathsCount .where (assignedToEvent , notDeleted , isCase , isDead );
372-
373- objectCQ .multiselect (eventRoot .get (Event .UUID ), participantCount , caseCount , deathsCount );
374- objectQueryList = em .createQuery (objectCQ ).getResultList ();
375- objectQueryList .forEach (r -> {
376- participantCounts .put ((String ) r [0 ], (Long ) r [1 ]);
377- caseCounts .put ((String ) r [0 ], (Long ) r [2 ]);
378- deathCounts .put ((String ) r [0 ], (Long ) r [3 ]);
379- });
344+ // Participant, Case and Death Count
345+ CriteriaQuery <Object []> participantCQ = cb .createQuery (Object [].class );
346+ Root <EventParticipant > epRoot = participantCQ .from (EventParticipant .class );
347+ Join <EventParticipant , Case > caseJoin = epRoot .join (EventParticipant .RESULTING_CASE , JoinType .LEFT );
348+ Predicate notDeleted = cb .isFalse (epRoot .get (EventParticipant .DELETED ));
349+ participantCQ .multiselect (
350+ epRoot .get (EventParticipant .EVENT ).get (AbstractDomainObject .UUID ),
351+ cb .count (epRoot ),
352+ cb .sum (cb .selectCase ().when (cb .isNotNull (epRoot .get (EventParticipant .RESULTING_CASE )), 1 ).otherwise (0 ).as (Long .class )),
353+ cb .sum (cb .selectCase ().when (cb .equal (caseJoin .get (Case .OUTCOME ), CaseOutcome .DECEASED ), 1 ).otherwise (0 ).as (Long .class )));
354+ participantCQ .where (notDeleted );
355+ participantCQ .groupBy (epRoot .get (EventParticipant .EVENT ).get (AbstractDomainObject .UUID ));
356+
357+ objectQueryList = em .createQuery (participantCQ ).getResultList ();
358+
359+ if (objectQueryList != null ) {
360+ objectQueryList .forEach (r -> {
361+ participantCounts .put ((String ) r [0 ], (Long ) r [1 ]);
362+ caseCounts .put ((String ) r [0 ], (Long ) r [2 ]);
363+ deathCounts .put ((String ) r [0 ], (Long ) r [3 ]);
364+ });
365+ }
380366
367+ // Contact Count (with and without sourcecase in event) using theta join
368+ CriteriaQuery <Object []> contactCQ = cb .createQuery (Object [].class );
369+ epRoot = contactCQ .from (EventParticipant .class );
370+ Root <Contact > contactRoot = contactCQ .from (Contact .class );
371+ Predicate participantPersonEqualsContactPerson = cb .equal (epRoot .get (EventParticipant .PERSON ), contactRoot .get (Contact .PERSON ));
372+ notDeleted = cb .isFalse (epRoot .get (EventParticipant .DELETED ));
373+ Predicate contactNotDeleted = cb .isFalse (contactRoot .get (Contact .DELETED ));
374+
375+ Subquery <EventParticipant > sourceCaseSubquery = contactCQ .subquery (EventParticipant .class );
376+ Root <EventParticipant > epr2 = sourceCaseSubquery .from (EventParticipant .class );
377+ sourceCaseSubquery .select (epr2 );
378+ sourceCaseSubquery .where (
379+ cb .equal (epr2 .get (EventParticipant .RESULTING_CASE ), contactRoot .get (Contact .CAZE )),
380+ cb .equal (epr2 .get (EventParticipant .EVENT ), epRoot .get (EventParticipant .EVENT )));
381+
382+ contactCQ .multiselect (
383+ epRoot .get (EventParticipant .EVENT ).get (AbstractDomainObject .UUID ),
384+ cb .count (epRoot ),
385+ cb .sum (cb .selectCase ().when (cb .exists (sourceCaseSubquery ), 1 ).otherwise (0 ).as (Long .class )));
386+ contactCQ .where (participantPersonEqualsContactPerson , notDeleted , contactNotDeleted );
387+ contactCQ .groupBy (epRoot .get (EventParticipant .EVENT ).get (AbstractDomainObject .UUID ));
388+
389+ objectQueryList = em .createQuery (contactCQ ).getResultList ();
390+ if (objectQueryList != null ) {
391+ objectQueryList .forEach (r -> {
392+ contactCounts .put ((String ) r [0 ], ((Long ) r [1 ]));
393+ contactCountsSourceInEvent .put ((String ) r [0 ], ((Long ) r [2 ]));
394+ });
395+ }
381396 }
382397
383398 if (indexList != null ) {
384399 for (EventIndexDto eventDto : indexList ) {
385400 Optional .ofNullable (participantCounts .get (eventDto .getUuid ())).ifPresent (eventDto ::setParticipantCount );
386401 Optional .ofNullable (caseCounts .get (eventDto .getUuid ())).ifPresent (eventDto ::setCaseCount );
387402 Optional .ofNullable (deathCounts .get (eventDto .getUuid ())).ifPresent (eventDto ::setDeathCount );
403+ Optional .ofNullable (contactCounts .get (eventDto .getUuid ())).ifPresent (eventDto ::setContactCount );
404+ Optional .ofNullable (contactCountsSourceInEvent .get (eventDto .getUuid ())).ifPresent (eventDto ::setContactCountSourceInEvent );
388405 }
389406 }
390407
@@ -465,57 +482,74 @@ public List<EventExportDto> getExportList(EventCriteria eventCriteria, Integer f
465482 }
466483
467484 Map <String , Long > participantCounts = new HashMap <>();
468- Map <String , Long > caseCounts = new HashMap <>();;
485+ Map <String , Long > caseCounts = new HashMap <>();
469486 Map <String , Long > deathCounts = new HashMap <>();
487+ Map <String , Long > contactCounts = new HashMap <>();
488+ Map <String , Long > contactCountsSourceInEvent = new HashMap <>();
470489 if (exportList != null ) {
471490 List <Object []> objectQueryList = null ;
472491
473- CriteriaQuery <Object []> objectCQ = cb .createQuery (Object [].class );
474- Root <Event > eventRoot = objectCQ .from (Event .class );
475-
476- // number of Participants
477- Subquery <Long > participantCount = objectCQ .subquery (Long .class );
478- Root <EventParticipant > eventParticipantRoot = participantCount .from (EventParticipant .class );
479- Predicate assignedToEvent = cb .equal (eventParticipantRoot .get (EventParticipant .EVENT ), eventRoot .get (AbstractDomainObject .ID ));
480- Predicate notDeleted = cb .isFalse (eventParticipantRoot .get (EventParticipant .DELETED ));
481- participantCount .select (cb .count (eventParticipantRoot ));
482- participantCount .where (assignedToEvent , notDeleted );
483-
484- // number of cases among event participants
485- Subquery <Long > caseCount = objectCQ .subquery (Long .class );
486- eventParticipantRoot = caseCount .from (EventParticipant .class );
487- assignedToEvent = cb .equal (eventParticipantRoot .get (EventParticipant .EVENT ), eventRoot .get (AbstractDomainObject .ID ));
488- notDeleted = cb .isFalse (eventParticipantRoot .get (EventParticipant .DELETED ));
489- Predicate isCase = cb .isNotNull (eventParticipantRoot .get (EventParticipant .RESULTING_CASE ));
490- caseCount .select (cb .count (eventParticipantRoot ));
491- caseCount .where (assignedToEvent , notDeleted , isCase );
492-
493- // number of fatalities among event participant cases
494- Subquery <Long > deathsCount = objectCQ .subquery (Long .class );
495- eventParticipantRoot = deathsCount .from (EventParticipant .class );
496- Join <EventParticipant , Case > caseJoin = eventParticipantRoot .join (EventParticipant .RESULTING_CASE , JoinType .LEFT );
497- assignedToEvent = cb .equal (eventParticipantRoot .get (EventParticipant .EVENT ), eventRoot .get (AbstractDomainObject .ID ));
498- notDeleted = cb .isFalse (eventParticipantRoot .get (EventParticipant .DELETED ));
499- isCase = cb .isNotNull (eventParticipantRoot .get (EventParticipant .RESULTING_CASE ));
500- Predicate isDead = cb .equal (caseJoin .get (Case .OUTCOME ), CaseOutcome .DECEASED );
501- deathsCount .select (cb .count (eventParticipantRoot ));
502- deathsCount .where (assignedToEvent , notDeleted , isCase , isDead );
503-
504- objectCQ .multiselect (eventRoot .get (Event .UUID ), participantCount , caseCount , deathsCount );
505- objectQueryList = em .createQuery (objectCQ ).getResultList ();
506- objectQueryList .forEach (r -> {
507- participantCounts .put ((String ) r [0 ], (Long ) r [1 ]);
508- caseCounts .put ((String ) r [0 ], (Long ) r [2 ]);
509- deathCounts .put ((String ) r [0 ], (Long ) r [3 ]);
510- });
492+ // Participant, Case and Death Count
493+ CriteriaQuery <Object []> participantCQ = cb .createQuery (Object [].class );
494+ Root <EventParticipant > epRoot = participantCQ .from (EventParticipant .class );
495+ Join <EventParticipant , Case > caseJoin = epRoot .join (EventParticipant .RESULTING_CASE , JoinType .LEFT );
496+ Predicate notDeleted = cb .isFalse (epRoot .get (EventParticipant .DELETED ));
497+ participantCQ .multiselect (
498+ epRoot .get (EventParticipant .EVENT ).get (AbstractDomainObject .UUID ),
499+ cb .count (epRoot ),
500+ cb .sum (cb .selectCase ().when (cb .isNotNull (epRoot .get (EventParticipant .RESULTING_CASE )), 1 ).otherwise (0 ).as (Long .class )),
501+ cb .sum (cb .selectCase ().when (cb .equal (caseJoin .get (Case .OUTCOME ), CaseOutcome .DECEASED ), 1 ).otherwise (0 ).as (Long .class )));
502+ participantCQ .where (notDeleted );
503+ participantCQ .groupBy (epRoot .get (EventParticipant .EVENT ).get (AbstractDomainObject .UUID ));
504+
505+ objectQueryList = em .createQuery (participantCQ ).getResultList ();
506+
507+ if (objectQueryList != null ) {
508+ objectQueryList .forEach (r -> {
509+ participantCounts .put ((String ) r [0 ], (Long ) r [1 ]);
510+ caseCounts .put ((String ) r [0 ], (Long ) r [2 ]);
511+ deathCounts .put ((String ) r [0 ], (Long ) r [3 ]);
512+ });
513+ }
511514
515+ // Contact Count (with and without sourcecase in event) using theta join
516+ CriteriaQuery <Object []> contactCQ = cb .createQuery (Object [].class );
517+ epRoot = contactCQ .from (EventParticipant .class );
518+ Root <Contact > contactRoot = contactCQ .from (Contact .class );
519+ Predicate participantPersonEqualsContactPerson = cb .equal (epRoot .get (EventParticipant .PERSON ), contactRoot .get (Contact .PERSON ));
520+ notDeleted = cb .isFalse (epRoot .get (EventParticipant .DELETED ));
521+ Predicate contactNotDeleted = cb .isFalse (contactRoot .get (Contact .DELETED ));
522+
523+ Subquery <EventParticipant > sourceCaseSubquery = contactCQ .subquery (EventParticipant .class );
524+ Root <EventParticipant > epr2 = sourceCaseSubquery .from (EventParticipant .class );
525+ sourceCaseSubquery .select (epr2 );
526+ sourceCaseSubquery .where (
527+ cb .equal (epr2 .get (EventParticipant .RESULTING_CASE ), contactRoot .get (Contact .CAZE )),
528+ cb .equal (epr2 .get (EventParticipant .EVENT ), epRoot .get (EventParticipant .EVENT )));
529+
530+ contactCQ .multiselect (
531+ epRoot .get (EventParticipant .EVENT ).get (AbstractDomainObject .UUID ),
532+ cb .count (epRoot ),
533+ cb .sum (cb .selectCase ().when (cb .exists (sourceCaseSubquery ), 1 ).otherwise (0 ).as (Long .class )));
534+ contactCQ .where (participantPersonEqualsContactPerson , notDeleted , contactNotDeleted );
535+ contactCQ .groupBy (epRoot .get (EventParticipant .EVENT ).get (AbstractDomainObject .UUID ));
536+
537+ objectQueryList = em .createQuery (contactCQ ).getResultList ();
538+ if (objectQueryList != null ) {
539+ objectQueryList .forEach (r -> {
540+ contactCounts .put ((String ) r [0 ], ((Long ) r [1 ]));
541+ contactCountsSourceInEvent .put ((String ) r [0 ], ((Long ) r [2 ]));
542+ });
543+ }
512544 }
513545
514546 if (exportList != null ) {
515547 for (EventExportDto exportDto : exportList ) {
516548 Optional .ofNullable (participantCounts .get (exportDto .getUuid ())).ifPresent (exportDto ::setParticipantCount );
517549 Optional .ofNullable (caseCounts .get (exportDto .getUuid ())).ifPresent (exportDto ::setCaseCount );
518550 Optional .ofNullable (deathCounts .get (exportDto .getUuid ())).ifPresent (exportDto ::setDeathCount );
551+ Optional .ofNullable (contactCounts .get (exportDto .getUuid ())).ifPresent (exportDto ::setContactCount );
552+ Optional .ofNullable (contactCountsSourceInEvent .get (exportDto .getUuid ())).ifPresent (exportDto ::setContactCountSourceInEvent );
519553 }
520554 }
521555
0 commit comments