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

Commit b65acf0

Browse files
Merge pull request SORMAS-Foundation#3994 from hzi-braunschweig/feature-3517-bulk-sending-cases-to-survnet
SORMAS-Foundation#3517 - Added bulk edit button
2 parents c50fa9d + 86584c0 commit b65acf0

10 files changed

Lines changed: 97 additions & 20 deletions

File tree

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@
2727
import de.symeda.sormas.api.CaseMeasure;
2828
import de.symeda.sormas.api.Disease;
2929
import de.symeda.sormas.api.Language;
30-
import de.symeda.sormas.api.messaging.ManualMessageLogDto;
31-
import de.symeda.sormas.api.messaging.MessageType;
3230
import de.symeda.sormas.api.contact.ContactReferenceDto;
3331
import de.symeda.sormas.api.contact.DashboardQuarantineDataDto;
3432
import de.symeda.sormas.api.event.EventParticipantReferenceDto;
3533
import de.symeda.sormas.api.importexport.ExportConfigurationDto;
34+
import de.symeda.sormas.api.messaging.ManualMessageLogDto;
35+
import de.symeda.sormas.api.messaging.MessageType;
3636
import de.symeda.sormas.api.person.PresentCondition;
3737
import de.symeda.sormas.api.region.DistrictDto;
3838
import de.symeda.sormas.api.region.DistrictReferenceDto;
@@ -183,4 +183,6 @@ List<DashboardQuarantineDataDto> getQuarantineDataForDashBoard(
183183
long countCasesWithMissingContactInformation(List<String> caseUuids, MessageType messageType);
184184

185185
List<ManualMessageLogDto> getMessageLog(String caseUuid, MessageType messageType);
186+
187+
String getFirstCaseUuidWithOwnershipHandedOver(List<String> caseUuids);
186188
}

sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,6 +1502,7 @@ public interface Captions {
15021502
String statisticsStatistics = "statisticsStatistics";
15031503
String statisticsVisualizationType = "statisticsVisualizationType";
15041504
String SurvnetGateway_send = "SurvnetGateway.send";
1505+
String SurvnetGateway_sendShort = "SurvnetGateway.sendShort";
15051506
String SurvnetGateway_title = "SurvnetGateway.title";
15061507
String Symptoms = "Symptoms";
15071508
String Symptoms_abdominalPain = "Symptoms.abdominalPain";

sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,8 @@ public interface Strings {
200200
String errorSormasToSormasSend = "errorSormasToSormasSend";
201201
String errorSormasToSormasServerAccess = "errorSormasToSormasServerAccess";
202202
String errorSormasToSormasShare = "errorSormasToSormasShare";
203+
String errorSurvNetCaseNotOwned = "errorSurvNetCaseNotOwned";
204+
String errorSurvNetNonCoronavirusCase = "errorSurvNetNonCoronavirusCase";
203205
String errorViewNotFound = "errorViewNotFound";
204206
String errorWasReported = "errorWasReported";
205207
String fileName = "fileName";
@@ -773,6 +775,7 @@ public interface Strings {
773775
String notAnswered = "notAnswered";
774776
String notificationCaseClassificationChanged = "notificationCaseClassificationChanged";
775777
String notificationCaseInvestigationDone = "notificationCaseInvestigationDone";
778+
String notificationCasesSentToSurvNet = "notificationCasesSentToSurvNet";
776779
String notificationContactSymptomatic = "notificationContactSymptomatic";
777780
String notificationContactWithoutCaseSymptomatic = "notificationContactWithoutCaseSymptomatic";
778781
String notificationDiseaseChanged = "notificationDiseaseChanged";

sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/SormasToSormasOriginInfoFacade.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@
1919

2020
@Remote
2121
public interface SormasToSormasOriginInfoFacade {
22+
2223
}

sormas-api/src/main/resources/captions.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2062,6 +2062,7 @@ BAGExport=BAG Export
20622062
# Survnet Gateway
20632063
SurvnetGateway.title=SurvNet
20642064
SurvnetGateway.send=send to own SurvNet instance
2065+
SurvnetGateway.sendShort=Send to SurvNet
20652066

20662067
patientDiaryRegistrationError=Could not register person in the patient diary.
20672068
patientDiaryPersonNotExportable=Cannot export the person to the patient diary. The person needs a valid birthdate and either a valid phone number or email address.

sormas-api/src/main/resources/strings.properties

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,9 @@ errorCampaignDiagramTotalsCalculationError=At least part of the percentage value
255255
errorNoPopulationDataLocations=No population data was found for the following locations: %s
256256
errorNoPopulationDataFound=There is no population data available. Switching to absolute data view
257257
errorFormIdPopulationAgeGroup=Both "Form Id" and "Population Age Group" options are set
258+
errorSurvNetNonCoronavirusCase=Could not send the selected cases to SurvNet because the case %s is not a %s case.
259+
errorSurvNetCaseNotOwned=Could not send the selected cases to SurvNet because your SORMAS instance is not the owner of the case %s.
260+
258261
# headings
259262
headingAccessDenied = Access denied
260263
headingAdditionalTests = Additional tests
@@ -831,6 +834,7 @@ notificationTaskStartGeneral = Your %s task should be started today.
831834
notificationTaskStartSpecific = Your %s task for %s should be started today.
832835
notificationVisitCompleted = A follow-up visit for contact %s assigned to user %s has been completed.
833836
notificationSmsSent = Message sent
837+
notificationCasesSentToSurvNet = All selected cases have been successfully sent to your SurvNet instance.
834838

835839
#Labels
836840
labelNumberOfUsers = No. of users

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

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import java.util.Collections;
3232
import java.util.Comparator;
3333
import java.util.Date;
34-
import java.util.EnumSet;
3534
import java.util.HashMap;
3635
import java.util.List;
3736
import java.util.Map;
@@ -1817,33 +1816,36 @@ public void onCaseChanged(CaseDataDto existingCase, Case newCase) {
18171816
// If the case is a newly created case or if it was not in a CONFIRMED status
18181817
// and now the case is in a CONFIRMED status, notify related surveillance officers
18191818
Set<CaseClassification> confirmedClassifications = CaseClassification.getConfirmedClassifications();
1820-
if ((existingCase == null || !confirmedClassifications.contains(existingCase.getCaseClassification())) && confirmedClassifications.contains(newCase.getCaseClassification())) {
1819+
if ((existingCase == null || !confirmedClassifications.contains(existingCase.getCaseClassification()))
1820+
&& confirmedClassifications.contains(newCase.getCaseClassification())) {
18211821
sendConfirmedCaseNotificationsForEvents(newCase);
18221822
}
18231823
}
18241824

18251825
private void sendConfirmedCaseNotificationsForEvents(Case caze) {
18261826
Date fromDate = Date.from(Instant.now().minus(Duration.ofDays(30)));
1827-
Map<String, User> surveillanceOfficerByEventByEventUuid = eventService.getAllEventUuidWithSurveillanceOfficerByCaseAfterDateForNotification(caze, fromDate);
1827+
Map<String, User> surveillanceOfficerByEventByEventUuid =
1828+
eventService.getAllEventUuidWithSurveillanceOfficerByCaseAfterDateForNotification(caze, fromDate);
18281829
for (Map.Entry<String, User> entry : surveillanceOfficerByEventByEventUuid.entrySet()) {
18291830
try {
18301831
messagingService.sendMessage(
1831-
entry.getValue(),
1832-
MessageSubject.EVENT_PARTICIPANT_CASE_CLASSIFICATION_CONFIRMED,
1833-
new Object[] { caze.getDisease().getName() },
1834-
String.format(
1835-
I18nProperties.getString(MessagingService.CONTENT_EVENT_PARTICIPANT_CASE_CLASSIFICATION_CONFIRMED),
1836-
DataHelper.getShortUuid(entry.getKey()),
1837-
caze.getDisease().getName(),
1838-
DataHelper.getShortUuid(caze.getUuid())),
1839-
MessageType.EMAIL,
1840-
MessageType.SMS);
1832+
entry.getValue(),
1833+
MessageSubject.EVENT_PARTICIPANT_CASE_CLASSIFICATION_CONFIRMED,
1834+
new Object[] {
1835+
caze.getDisease().getName() },
1836+
String.format(
1837+
I18nProperties.getString(MessagingService.CONTENT_EVENT_PARTICIPANT_CASE_CLASSIFICATION_CONFIRMED),
1838+
DataHelper.getShortUuid(entry.getKey()),
1839+
caze.getDisease().getName(),
1840+
DataHelper.getShortUuid(caze.getUuid())),
1841+
MessageType.EMAIL,
1842+
MessageType.SMS);
18411843
} catch (NotificationDeliveryFailedException e) {
18421844
logger.error(
1843-
String.format(
1844-
"NotificationDeliveryFailedException when trying to notify event surveillance officer about a newly confirmed case. "
1845-
+ "Failed to send " + e.getMessageType() + " to user with UUID %s.",
1846-
entry.getValue().getUuid()));
1845+
String.format(
1846+
"NotificationDeliveryFailedException when trying to notify event surveillance officer about a newly confirmed case. "
1847+
+ "Failed to send " + e.getMessageType() + " to user with UUID %s.",
1848+
entry.getValue().getUuid()));
18471849
}
18481850
}
18491851
}
@@ -3223,6 +3225,24 @@ public List<ManualMessageLogDto> getMessageLog(String personUuid, MessageType me
32233225
.collect(Collectors.toList());
32243226
}
32253227

3228+
@Override
3229+
public String getFirstCaseUuidWithOwnershipHandedOver(List<String> caseUuids) {
3230+
CriteriaBuilder cb = em.getCriteriaBuilder();
3231+
CriteriaQuery<String> cq = cb.createQuery(String.class);
3232+
Root<Case> caseRoot = cq.from(Case.class);
3233+
Join<Case, SormasToSormasShareInfo> sormasToSormasJoin = caseRoot.join(Case.SORMAS_TO_SORMAS_SHARES, JoinType.LEFT);
3234+
3235+
cq.select(caseRoot.get(Case.UUID));
3236+
cq.where(cb.isTrue(sormasToSormasJoin.get(SormasToSormasShareInfo.OWNERSHIP_HANDED_OVER)));
3237+
cq.orderBy(cb.asc(caseRoot.get(AbstractDomainObject.CREATION_DATE)));
3238+
3239+
try {
3240+
return em.createQuery(cq).setMaxResults(1).getSingleResult();
3241+
} catch (NoResultException e) {
3242+
return null;
3243+
}
3244+
}
3245+
32263246
@LocalBean
32273247
@Stateless
32283248
public static class CaseFacadeEjbLocal extends CaseFacadeEjb {

sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.Date;
2222
import java.util.List;
2323
import java.util.Objects;
24+
import java.util.Optional;
2425
import java.util.function.Consumer;
2526
import java.util.stream.Collectors;
2627

@@ -101,6 +102,7 @@
101102
import de.symeda.sormas.ui.epidata.EpiDataForm;
102103
import de.symeda.sormas.ui.hospitalization.HospitalizationForm;
103104
import de.symeda.sormas.ui.hospitalization.HospitalizationView;
105+
import de.symeda.sormas.ui.survnet.SurvnetGateway;
104106
import de.symeda.sormas.ui.symptoms.SymptomsForm;
105107
import de.symeda.sormas.ui.therapy.TherapyView;
106108
import de.symeda.sormas.ui.utils.AbstractView;
@@ -1344,4 +1346,39 @@ public VerticalLayout getCaseViewTitleLayout(CaseDataDto caseData) {
13441346

13451347
return titleLayout;
13461348
}
1349+
1350+
public void sendCasesToSurvnet(Collection<? extends CaseIndexDto> selectedCases, Runnable reloadCallback) {
1351+
List<String> selectedUuids = selectedCases.stream().map(CaseIndexDto::getUuid).collect(Collectors.toList());
1352+
1353+
// Show an error when at least one selected case is not a CORONAVIRUS case
1354+
Optional<? extends CaseIndexDto> nonCoronavirusCase = selectedCases.stream().filter(c -> c.getDisease() != Disease.CORONAVIRUS).findFirst();
1355+
if (nonCoronavirusCase.isPresent()) {
1356+
Notification.show(
1357+
String.format(
1358+
I18nProperties.getString(Strings.errorSurvNetNonCoronavirusCase),
1359+
DataHelper.getShortUuid(nonCoronavirusCase.get().getUuid()),
1360+
I18nProperties.getEnumCaption(Disease.CORONAVIRUS)),
1361+
"",
1362+
Type.ERROR_MESSAGE);
1363+
return;
1364+
}
1365+
1366+
// Show an error when at least one selected case is not owned by this server because ownership has been handed over
1367+
String ownershipHandedOverUuid = FacadeProvider.getCaseFacade().getFirstCaseUuidWithOwnershipHandedOver(selectedUuids);
1368+
if (ownershipHandedOverUuid != null) {
1369+
Notification.show(
1370+
String.format(I18nProperties.getString(Strings.errorSurvNetCaseNotOwned), DataHelper.getShortUuid(ownershipHandedOverUuid)),
1371+
"",
1372+
Type.ERROR_MESSAGE);
1373+
return;
1374+
}
1375+
1376+
SurvnetGateway.sendToSurvnet(selectedUuids);
1377+
1378+
Notification successNotification =
1379+
new Notification(I18nProperties.getString(Strings.notificationCasesSentToSurvNet), "", Type.HUMANIZED_MESSAGE);
1380+
successNotification.setDelayMsec(10000);
1381+
successNotification.show(Page.getCurrent());
1382+
}
1383+
13471384
}

sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,13 @@ public HorizontalLayout createStatusFilterBar() {
680680
mi -> ControllerProvider.getSormasToSormasController()
681681
.shareSelectedCases(caseGrid.asMultiSelect().getSelectedItems(), () -> navigateTo(criteria)),
682682
FacadeProvider.getSormasToSormasFacade().isFeatureEnabled()));
683+
menuBarItems.add(
684+
new MenuBarHelper.MenuBarItem(
685+
I18nProperties.getCaption(Captions.SurvnetGateway_sendShort),
686+
VaadinIcons.SHARE,
687+
mi -> ControllerProvider.getCaseController()
688+
.sendCasesToSurvnet(caseGrid.asMultiSelect().getSelectedItems(), () -> navigateTo(criteria)),
689+
FacadeProvider.getSurvnetGatewayFacade().isFeatureEnabled()));
683690

684691
bulkOperationsDropdown = MenuBarHelper.createDropDown(Captions.bulkActions, menuBarItems);
685692

@@ -864,4 +871,5 @@ private HorizontalLayout buildScrollLayout() {
864871
scrollLayout.addComponent(plusDaysButton);
865872
return scrollLayout;
866873
}
874+
867875
}

sormas-ui/src/main/java/de/symeda/sormas/ui/survnet/SurvnetGateway.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public static void addComponentToLayout(CustomLayout targetLayout, Supplier<List
5454
targetLayout.addComponent(layout, SURVNET_GATEWAY_LOC);
5555
}
5656

57-
private static void sendToSurvnet(List<String> caseUuids) {
57+
public static void sendToSurvnet(List<String> caseUuids) {
5858

5959
int statusCode = FacadeProvider.getSurvnetGatewayFacade().sendCases(caseUuids);
6060

0 commit comments

Comments
 (0)