use of de.symeda.sormas.api.dashboard.DashboardContactDto in project SORMAS-Project by hzi-braunschweig.
the class ContactService method getContactsForDashboard.
public List<DashboardContactDto> getContactsForDashboard(Region region, District district, Disease disease, Date from, Date to, User user) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<DashboardContactDto> cq = cb.createQuery(DashboardContactDto.class);
Root<Contact> contact = cq.from(getElementClass());
Join<Contact, Case> caze = contact.join(Contact.CAZE, JoinType.LEFT);
Predicate filter = createDefaultFilter(cb, contact);
filter = CriteriaBuilderHelper.and(cb, filter, createUserFilter(cb, cq, contact));
Predicate dateFilter = buildDateFilter(cb, contact, from, to);
if (filter != null) {
filter = cb.and(filter, dateFilter);
} else {
filter = dateFilter;
}
filter = CriteriaBuilderHelper.and(cb, filter, getRegionDistrictDiseasePredicate(region, district, disease, cb, contact, caze));
if (filter != null) {
cq.where(filter);
cq.multiselect(contact.get(AbstractDomainObject.ID), contact.get(Contact.REPORT_DATE_TIME), contact.get(Contact.CONTACT_STATUS), contact.get(Contact.CONTACT_CLASSIFICATION), contact.get(Contact.FOLLOW_UP_STATUS), contact.get(Contact.FOLLOW_UP_UNTIL), contact.get(Contact.DISEASE), contact.get(Contact.QUARANTINE_FROM), contact.get(Contact.QUARANTINE_TO));
List<DashboardContactDto> dashboardContacts = em.createQuery(cq).getResultList();
if (!dashboardContacts.isEmpty()) {
List<Long> dashboardContactIds = dashboardContacts.stream().map(DashboardContactDto::getId).collect(Collectors.toList());
CriteriaQuery<DashboardVisit> visitsCq = cb.createQuery(DashboardVisit.class);
Root<Contact> visitsCqRoot = visitsCq.from(getElementClass());
Join<Contact, Visit> visitsJoin = visitsCqRoot.join(Contact.VISITS, JoinType.LEFT);
Join<Visit, Symptoms> visitSymptomsJoin = visitsJoin.join(Visit.SYMPTOMS, JoinType.LEFT);
visitsCq.where(CriteriaBuilderHelper.and(cb, contact.get(AbstractDomainObject.ID).in(dashboardContactIds), cb.isNotEmpty(visitsCqRoot.get(Contact.VISITS))));
visitsCq.multiselect(visitsCqRoot.get(AbstractDomainObject.ID), visitSymptomsJoin.get(Symptoms.SYMPTOMATIC), visitsJoin.get(Visit.VISIT_STATUS), visitsJoin.get(Visit.VISIT_DATE_TIME));
List<DashboardVisit> contactVisits = em.createQuery(visitsCq).getResultList();
// Add visit information to the DashboardContactDtos
for (DashboardContactDto dashboardContact : dashboardContacts) {
List<DashboardVisit> visits = contactVisits.stream().filter(v -> v.getContactId() == dashboardContact.getId()).collect(Collectors.toList());
DashboardVisit lastVisit = visits.stream().max((v1, v2) -> v1.getVisitDateTime().compareTo(v2.getVisitDateTime())).orElse(null);
if (lastVisit != null) {
dashboardContact.setLastVisitDateTime(lastVisit.getVisitDateTime());
dashboardContact.setLastVisitStatus(lastVisit.getVisitStatus());
dashboardContact.setSymptomatic(lastVisit.isSymptomatic());
List<VisitStatus> visitStatuses = visits.stream().map(DashboardVisit::getVisitStatus).collect(Collectors.toList());
Map<VisitStatus, Integer> frequency = new EnumMap<>(VisitStatus.class);
for (VisitStatus status : VisitStatus.values()) {
int freq = Collections.frequency(visitStatuses, status);
frequency.put(status, freq);
}
dashboardContact.setVisitStatusMap(frequency);
}
}
return dashboardContacts;
}
}
return Collections.emptyList();
}
use of de.symeda.sormas.api.dashboard.DashboardContactDto in project SORMAS-Project by hzi-braunschweig.
the class DashboardFacadeEjb method getDashboardContactStatistic.
@RolesAllowed(UserRight._DASHBOARD_CONTACT_VIEW)
public DashboardContactStatisticDto getDashboardContactStatistic(DashboardCriteria dashboardCriteria) {
List<DashboardContactDto> dashboardContacts = contactFacade.getContactsForDashboard(dashboardCriteria.getRegion(), dashboardCriteria.getDistrict(), dashboardCriteria.getDisease(), dashboardCriteria.getDateFrom(), dashboardCriteria.getDateTo());
List<DashboardContactDto> previousDashboardContacts = contactFacade.getContactsForDashboard(dashboardCriteria.getRegion(), dashboardCriteria.getDistrict(), dashboardCriteria.getDisease(), dashboardCriteria.getPreviousDateFrom(), dashboardCriteria.getPreviousDateTo());
int contactsCount = dashboardContacts.size();
int newContactsCount = (int) dashboardContacts.stream().filter(c -> c.getReportDate().after(dashboardCriteria.getDateFrom()) || c.getReportDate().equals(dashboardCriteria.getDateFrom())).count();
int newContactsPercentage = calculatePercentage(newContactsCount, contactsCount);
int symptomaticContactsCount = (int) dashboardContacts.stream().filter(c -> Boolean.TRUE.equals(c.getSymptomatic())).count();
int symptomaticContactsPercentage = calculatePercentage(symptomaticContactsCount, contactsCount);
int contactClassificationUnconfirmedCount = (int) dashboardContacts.stream().filter(c -> c.getContactClassification() == ContactClassification.UNCONFIRMED).count();
int contactClassificationUnconfirmedPercentage = calculatePercentage(contactClassificationUnconfirmedCount, contactsCount);
int contactClassificationConfirmedCount = (int) dashboardContacts.stream().filter(c -> c.getContactClassification() == ContactClassification.CONFIRMED).count();
int contactClassificationConfirmedPercentage = calculatePercentage(contactClassificationConfirmedCount, contactsCount);
int contactClassificationNotAContactCount = (int) dashboardContacts.stream().filter(c -> c.getContactClassification() == ContactClassification.NO_CONTACT).count();
int contactClassificationNotAContactPercentage = calculatePercentage(contactClassificationNotAContactCount, contactsCount);
Map<Disease, Map<String, Integer>> diseaseMap = new TreeMap<>();
for (Disease disease : diseaseConfigurationFacade.getAllDiseasesWithFollowUp()) {
Map<String, Integer> countValues = new HashMap<>();
countValues.put(PREVIOUS_CONTACTS, (int) previousDashboardContacts.stream().filter(c -> c.getDisease() == disease).count());
countValues.put(CURRENT_CONTACTS, (int) dashboardContacts.stream().filter(c -> c.getDisease() == disease).count());
diseaseMap.put(disease, countValues);
}
Map<Disease, Map<String, Integer>> orderedDiseaseMap = diseaseMap.entrySet().stream().sorted(Map.Entry.comparingByValue((o1, o2) -> -Integer.compare(o1.get(CURRENT_CONTACTS), o2.get(CURRENT_CONTACTS)))).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
DashboardContactFollowUpDto dashboardContactFollowUp = calculateContactFollowUpStatistics(dashboardContacts, dashboardCriteria.getDateTo());
DashboardContactStoppedFollowUpDto dashboardContactStoppedFollowUp = calculateContactStoppedFollowUpStatistics(dashboardContacts);
DashboardContactVisitDto dashboardContactVisit = calculateContactVisitStatistics(dashboardContacts, previousDashboardContacts);
return new DashboardContactStatisticDto(contactsCount, newContactsCount, newContactsPercentage, symptomaticContactsCount, symptomaticContactsPercentage, contactClassificationConfirmedCount, contactClassificationConfirmedPercentage, contactClassificationUnconfirmedCount, contactClassificationUnconfirmedPercentage, contactClassificationNotAContactCount, contactClassificationNotAContactPercentage, orderedDiseaseMap, dashboardContactFollowUp, dashboardContactStoppedFollowUp, dashboardContactVisit);
}
use of de.symeda.sormas.api.dashboard.DashboardContactDto in project SORMAS-Project by hzi-braunschweig.
the class DashboardFacadeEjb method calculateContactVisitStatistics.
private DashboardContactVisitDto calculateContactVisitStatistics(List<DashboardContactDto> contacts, List<DashboardContactDto> previousContacts) {
Map<VisitStatus, Integer> visitStatusMap = new EnumMap<>(VisitStatus.class);
Map<VisitStatus, Integer> previousVisitStatusMap = new EnumMap<>(VisitStatus.class);
// only visits that needed to be done, i.e. at most the amount of follow-up days
int doneEssentialVisitsCount = 0;
int previousDoneEssentialVisitsCount = 0;
Date now = new Date();
int totalFollowUpDays = 0;
int previousTotalFollowUpDays = 0;
for (DashboardContactDto contact : contacts) {
for (VisitStatus visitStatus : contact.getVisitStatusMap().keySet()) {
int value = 0;
if (visitStatusMap.containsKey(visitStatus)) {
value = visitStatusMap.get(visitStatus);
}
visitStatusMap.put(visitStatus, value + contact.getVisitStatusMap().get(visitStatus));
}
if (contact.getFollowUpUntil() != null) {
int contactFollowUpDays = Math.min(DateHelper.getDaysBetween(contact.getReportDate(), now), DateHelper.getDaysBetween(contact.getReportDate(), contact.getFollowUpUntil()));
totalFollowUpDays += contactFollowUpDays;
int visitCount = contact.getVisitStatusMap().values().stream().reduce(0, Integer::sum);
doneEssentialVisitsCount += (Math.min(visitCount, contactFollowUpDays));
}
}
for (DashboardContactDto contact : previousContacts) {
for (VisitStatus visitStatus : contact.getVisitStatusMap().keySet()) {
int value = 0;
if (previousVisitStatusMap.containsKey(visitStatus)) {
value = previousVisitStatusMap.get(visitStatus);
}
previousVisitStatusMap.put(visitStatus, value + contact.getVisitStatusMap().get(visitStatus));
}
if (contact.getFollowUpUntil() != null) {
int contactFollowUpDays = Math.min(DateHelper.getDaysBetween(contact.getReportDate(), now), DateHelper.getDaysBetween(contact.getReportDate(), contact.getFollowUpUntil()));
previousTotalFollowUpDays += contactFollowUpDays;
int visitCount = contact.getVisitStatusMap().values().stream().reduce(0, Integer::sum);
previousDoneEssentialVisitsCount += (Math.min(visitCount, contactFollowUpDays));
}
}
int visitsCount = visitStatusMap.values().stream().reduce(0, Integer::sum);
int missedVisitsCount = totalFollowUpDays - doneEssentialVisitsCount;
int unavailableVisitsCount = Optional.ofNullable(visitStatusMap.get(VisitStatus.UNAVAILABLE)).orElse(0).intValue();
int uncooperativeVisitsCount = Optional.ofNullable(visitStatusMap.get(VisitStatus.UNCOOPERATIVE)).orElse(0).intValue();
int cooperativeVisitsCount = Optional.ofNullable(visitStatusMap.get(VisitStatus.COOPERATIVE)).orElse(0).intValue();
int previousMissedVisitsCount = previousTotalFollowUpDays - previousDoneEssentialVisitsCount;
int previousUnavailableVisitsCount = Optional.ofNullable(previousVisitStatusMap.get(VisitStatus.UNAVAILABLE)).orElse(0).intValue();
int previousUncooperativeVisitsCount = Optional.ofNullable(previousVisitStatusMap.get(VisitStatus.UNCOOPERATIVE)).orElse(0).intValue();
int previousCooperativeVisitsCount = Optional.ofNullable(previousVisitStatusMap.get(VisitStatus.COOPERATIVE)).orElse(0).intValue();
int missedVisitsGrowth = calculateGrowth(missedVisitsCount, previousMissedVisitsCount);
int unavailableVisitsGrowth = calculateGrowth(unavailableVisitsCount, previousUnavailableVisitsCount);
int uncooperativeVisitsGrowth = calculateGrowth(uncooperativeVisitsCount, previousUncooperativeVisitsCount);
int cooperativeVisitsGrowth = calculateGrowth(cooperativeVisitsCount, previousCooperativeVisitsCount);
return new DashboardContactVisitDto(visitsCount, missedVisitsCount, missedVisitsGrowth, unavailableVisitsCount, unavailableVisitsGrowth, uncooperativeVisitsCount, uncooperativeVisitsGrowth, cooperativeVisitsCount, cooperativeVisitsGrowth, previousMissedVisitsCount, previousUnavailableVisitsCount, previousUncooperativeVisitsCount, previousCooperativeVisitsCount);
}
use of de.symeda.sormas.api.dashboard.DashboardContactDto in project SORMAS-Project by hzi-braunschweig.
the class DashboardFacadeEjb method calculateContactFollowUpStatistics.
private DashboardContactFollowUpDto calculateContactFollowUpStatistics(List<DashboardContactDto> contacts, Date dateTo) {
List<DashboardContactDto> followUpContacts = contacts.stream().filter(c -> c.getFollowUpStatus() == FollowUpStatus.FOLLOW_UP).collect(Collectors.toList());
int followUpContactsCount = followUpContacts.size();
int cooperativeContactsCount = (int) followUpContacts.stream().filter(c -> c.getLastVisitStatus() == VisitStatus.COOPERATIVE).count();
int uncooperativeContactsCount = (int) followUpContacts.stream().filter(c -> c.getLastVisitStatus() == VisitStatus.UNCOOPERATIVE).count();
int unavailableContactsCount = (int) followUpContacts.stream().filter(c -> c.getLastVisitStatus() == VisitStatus.UNAVAILABLE).count();
int notVisitedContactsCount = (int) followUpContacts.stream().filter(c -> c.getLastVisitStatus() == null).count();
int cooperativeContactsPercentage = calculatePercentage(cooperativeContactsCount, followUpContactsCount);
int uncooperativeContactsPercentage = calculatePercentage(uncooperativeContactsCount, followUpContactsCount);
int unavailableContactsPercentage = calculatePercentage(unavailableContactsCount, followUpContactsCount);
int notVisitedContactsPercentage = calculatePercentage(notVisitedContactsCount, followUpContactsCount);
int missedVisitsOneDayCount = 0;
int missedVisitsTwoDaysCount = 0;
int missedVisitsThreeDaysCount = 0;
int missedVisitsGtThreeDaysCount = 0;
for (DashboardContactDto contact : followUpContacts) {
Date lastVisitDateTime = contact.getLastVisitDateTime() != null ? contact.getLastVisitDateTime() : contact.getReportDate();
Date referenceDate = dateTo.after(new Date()) ? new Date() : dateTo;
int missedDays = DateHelper.getFullDaysBetween(lastVisitDateTime, referenceDate);
switch(missedDays <= 3 ? missedDays : 4) {
case 1:
missedVisitsOneDayCount++;
break;
case 2:
missedVisitsTwoDaysCount++;
break;
case 3:
missedVisitsThreeDaysCount++;
break;
case 4:
missedVisitsGtThreeDaysCount++;
break;
default:
break;
}
}
return new DashboardContactFollowUpDto(followUpContactsCount, cooperativeContactsCount, cooperativeContactsPercentage, uncooperativeContactsCount, uncooperativeContactsPercentage, unavailableContactsCount, unavailableContactsPercentage, notVisitedContactsCount, notVisitedContactsPercentage, missedVisitsOneDayCount, missedVisitsTwoDaysCount, missedVisitsThreeDaysCount, missedVisitsGtThreeDaysCount);
}
use of de.symeda.sormas.api.dashboard.DashboardContactDto in project SORMAS-Project by hzi-braunschweig.
the class ContactService method getContactsForDashboard.
public List<DashboardContactDto> getContactsForDashboard(Region region, District district, Disease disease, Date from, Date to) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<DashboardContactDto> cq = cb.createQuery(DashboardContactDto.class);
Root<Contact> contact = cq.from(getElementClass());
ContactQueryContext cqc = new ContactQueryContext(cb, cq, contact);
Join<Contact, Case> caze = cqc.getJoins().getCaze();
Predicate filter = createDefaultFilter(cb, contact);
filter = CriteriaBuilderHelper.and(cb, filter, createUserFilter(cqc, null));
Predicate dateFilter = buildDateFilter(cb, contact, from, to);
if (filter != null) {
filter = cb.and(filter, dateFilter);
} else {
filter = dateFilter;
}
filter = CriteriaBuilderHelper.and(cb, filter, getRegionDistrictDiseasePredicate(region, district, disease, cb, contact, caze));
if (filter != null) {
cq.where(filter);
cq.multiselect(contact.get(AbstractDomainObject.ID), contact.get(Contact.REPORT_DATE_TIME), contact.get(Contact.CONTACT_STATUS), contact.get(Contact.CONTACT_CLASSIFICATION), contact.get(Contact.FOLLOW_UP_STATUS), contact.get(Contact.FOLLOW_UP_UNTIL), contact.get(Contact.DISEASE), contact.get(Contact.QUARANTINE_FROM), contact.get(Contact.QUARANTINE_TO));
List<DashboardContactDto> dashboardContacts = em.createQuery(cq).getResultList();
if (!dashboardContacts.isEmpty()) {
List<Long> dashboardContactIds = dashboardContacts.stream().map(DashboardContactDto::getId).collect(Collectors.toList());
CriteriaQuery<DashboardVisit> visitsCq = cb.createQuery(DashboardVisit.class);
Root<Contact> visitsCqRoot = visitsCq.from(getElementClass());
Join<Contact, Visit> visitsJoin = visitsCqRoot.join(Contact.VISITS, JoinType.LEFT);
Join<Visit, Symptoms> visitSymptomsJoin = visitsJoin.join(Visit.SYMPTOMS, JoinType.LEFT);
visitsCq.where(CriteriaBuilderHelper.and(cb, contact.get(AbstractDomainObject.ID).in(dashboardContactIds), cb.isNotEmpty(visitsCqRoot.get(Contact.VISITS))));
visitsCq.multiselect(visitsCqRoot.get(AbstractDomainObject.ID), visitSymptomsJoin.get(Symptoms.SYMPTOMATIC), visitsJoin.get(Visit.VISIT_STATUS), visitsJoin.get(Visit.VISIT_DATE_TIME));
List<DashboardVisit> contactVisits = em.createQuery(visitsCq).getResultList();
// Add visit information to the DashboardContactDtos
for (DashboardContactDto dashboardContact : dashboardContacts) {
List<DashboardVisit> visits = contactVisits.stream().filter(v -> v.getContactId() == dashboardContact.getId()).collect(Collectors.toList());
DashboardVisit lastVisit = visits.stream().max((v1, v2) -> v1.getVisitDateTime().compareTo(v2.getVisitDateTime())).orElse(null);
if (lastVisit != null) {
dashboardContact.setLastVisitDateTime(lastVisit.getVisitDateTime());
dashboardContact.setLastVisitStatus(lastVisit.getVisitStatus());
dashboardContact.setSymptomatic(lastVisit.isSymptomatic());
List<VisitStatus> visitStatuses = visits.stream().map(DashboardVisit::getVisitStatus).collect(Collectors.toList());
Map<VisitStatus, Integer> frequency = new EnumMap<>(VisitStatus.class);
for (VisitStatus status : VisitStatus.values()) {
int freq = Collections.frequency(visitStatuses, status);
frequency.put(status, freq);
}
dashboardContact.setVisitStatusMap(frequency);
}
}
return dashboardContacts;
}
}
return Collections.emptyList();
}
Aggregations