use of de.symeda.sormas.api.visit.VisitStatus in project SORMAS-Project by hzi-braunschweig.
the class ContactsDashboardStatisticsComponent method updateFourthComponent.
@Override
protected void updateFourthComponent(int visibleDiseasesCount) {
List<DashboardContactDto> contacts = dashboardDataProvider.getContacts();
List<DashboardContactDto> previousContacts = dashboardDataProvider.getPreviousContacts();
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);
fourthComponent.updateCountLabel(visitsCount);
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 missedVisitsPercentage = totalFollowUpDays == 0 ? 0 : (int) ((missedVisitsCount * 100.0f) / totalFollowUpDays);
int unavailableVisitsPercentage = visitsCount == 0 ? 0 : (int) ((unavailableVisitsCount * 100.0f) / visitsCount);
int uncooperativeVisitsPercentage = visitsCount == 0 ? 0 : (int) ((uncooperativeVisitsCount * 100.0f) / visitsCount);
int cooperativeVisitsPercentage = visitsCount == 0 ? 0 : (int) ((cooperativeVisitsCount * 100.0f) / visitsCount);
int missedVisitsGrowth = calculateGrowth(missedVisitsCount, previousMissedVisitsCount);
int unavailableVisitsGrowth = calculateGrowth(unavailableVisitsCount, previousUnavailableVisitsCount);
int uncooperativeVisitsGrowth = calculateGrowth(uncooperativeVisitsCount, previousUncooperativeVisitsCount);
int cooperativeVisitsGrowth = calculateGrowth(cooperativeVisitsCount, previousCooperativeVisitsCount);
missedVisits.update(missedVisitsCount, missedVisitsPercentage, missedVisitsGrowth, false, false);
unavailableVisits.update(unavailableVisitsCount, unavailableVisitsPercentage, unavailableVisitsGrowth, false, false);
uncooperativeVisits.update(uncooperativeVisitsCount, uncooperativeVisitsPercentage, uncooperativeVisitsGrowth, false, false);
cooperativeVisits.update(cooperativeVisitsCount, cooperativeVisitsPercentage, cooperativeVisitsGrowth, true, false);
}
use of de.symeda.sormas.api.visit.VisitStatus 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.visit.VisitStatus in project SORMAS-Project by hzi-braunschweig.
the class ContactFacadeEjb method getContactFollowUpList.
@Override
public List<ContactFollowUpDto> getContactFollowUpList(ContactCriteria contactCriteria, Date referenceDate, int interval, Integer first, Integer max, List<SortProperty> sortProperties) {
Date end = DateHelper.getEndOfDay(referenceDate);
Date start = DateHelper.getStartOfDay(DateHelper.subtractDays(end, interval));
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<ContactFollowUpDto> cq = cb.createQuery(ContactFollowUpDto.class);
Root<Contact> contact = cq.from(Contact.class);
final ContactQueryContext contactQueryContext = new ContactQueryContext(cb, cq, contact);
final ContactJoins<Contact> joins = (ContactJoins<Contact>) contactQueryContext.getJoins();
cq.multiselect(contact.get(Contact.UUID), contact.get(Contact.CHANGE_DATE), joins.getPerson().get(Person.FIRST_NAME), joins.getPerson().get(Person.LAST_NAME), joins.getContactOfficer().get(User.UUID), joins.getContactOfficer().get(User.FIRST_NAME), joins.getContactOfficer().get(User.LAST_NAME), contact.get(Contact.LAST_CONTACT_DATE), contact.get(Contact.REPORT_DATE_TIME), contact.get(Contact.FOLLOW_UP_UNTIL), joins.getPerson().get(Person.SYMPTOM_JOURNAL_STATUS), contact.get(Contact.DISEASE), jurisdictionSelector(contactQueryContext));
// Only use user filter if no restricting case is specified
Predicate filter = listCriteriaBuilder.buildContactFilter(contactCriteria, contactQueryContext);
if (filter != null) {
cq.where(filter);
}
cq.distinct(true);
if (sortProperties != null && sortProperties.size() > 0) {
List<Order> order = new ArrayList<Order>(sortProperties.size());
for (SortProperty sortProperty : sortProperties) {
Expression<?> expression;
switch(sortProperty.propertyName) {
case FollowUpDto.UUID:
case ContactFollowUpDto.LAST_CONTACT_DATE:
case FollowUpDto.FOLLOW_UP_UNTIL:
expression = contact.get(sortProperty.propertyName);
break;
case FollowUpDto.REPORT_DATE:
expression = contact.get(Contact.REPORT_DATE_TIME);
break;
case FollowUpDto.SYMPTOM_JOURNAL_STATUS:
expression = joins.getPerson().get(Person.SYMPTOM_JOURNAL_STATUS);
break;
case FollowUpDto.FIRST_NAME:
expression = joins.getPerson().get(Person.FIRST_NAME);
break;
case FollowUpDto.LAST_NAME:
expression = joins.getPerson().get(Person.LAST_NAME);
break;
case ContactFollowUpDto.CONTACT_OFFICER:
expression = joins.getContactOfficer().get(User.FIRST_NAME);
order.add(sortProperty.ascending ? cb.asc(expression) : cb.desc(expression));
expression = joins.getContactOfficer().get(User.LAST_NAME);
break;
default:
throw new IllegalArgumentException(sortProperty.propertyName);
}
order.add(sortProperty.ascending ? cb.asc(expression) : cb.desc(expression));
}
cq.orderBy(order);
} else {
cq.orderBy(cb.desc(contact.get(Contact.CHANGE_DATE)));
}
List<ContactFollowUpDto> resultList = QueryHelper.getResultList(em, cq, first, max);
if (!resultList.isEmpty()) {
List<String> contactUuids = resultList.stream().map(d -> d.getUuid()).collect(Collectors.toList());
CriteriaQuery<Object[]> visitsCq = cb.createQuery(Object[].class);
Root<Contact> visitsCqRoot = visitsCq.from(Contact.class);
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.UUID).in(contactUuids), cb.isNotEmpty(visitsCqRoot.get(Contact.VISITS)), cb.between(visitsJoin.get(Visit.VISIT_DATE_TIME), start, end)));
visitsCq.multiselect(visitsCqRoot.get(Contact.UUID), visitsJoin.get(Visit.VISIT_DATE_TIME), visitsJoin.get(Visit.VISIT_STATUS), visitsJoin.get(Visit.ORIGIN), visitSymptomsJoin.get(Symptoms.SYMPTOMATIC));
visitsCq.orderBy(cb.asc(visitsJoin.get(Visit.VISIT_DATE_TIME)), cb.asc(visitsJoin.get(Visit.CREATION_DATE)));
List<Object[]> visits = em.createQuery(visitsCq).getResultList();
Map<String, ContactFollowUpDto> resultMap = resultList.stream().collect(Collectors.toMap(ContactFollowUpDto::getUuid, Function.identity()));
Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService::hasRight, I18nProperties.getCaption(Captions.inaccessibleValue));
for (ContactFollowUpDto contactFollowUpDto : resultMap.values()) {
contactFollowUpDto.initVisitSize(interval + 1);
boolean isInJurisdiction = contactFollowUpDto.getInJurisdiction();
pseudonymizer.pseudonymizeDto(ContactFollowUpDto.class, contactFollowUpDto, isInJurisdiction, null);
}
for (Object[] v : visits) {
int day = DateHelper.getDaysBetween(start, (Date) v[1]);
VisitResultDto result = getVisitResult((VisitStatus) v[2], (VisitOrigin) v[3], (Boolean) v[4]);
resultMap.get(v[0]).getVisitResults()[day - 1] = result;
}
}
return resultList;
}
Aggregations