diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/audit/Constants.java b/sormas-api/src/main/java/de/symeda/sormas/api/audit/Constants.java index 62fa8c57d7c..7d868d760c3 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/audit/Constants.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/audit/Constants.java @@ -62,6 +62,7 @@ public class Constants { "cancel", "end", "accept", + "execute", "sync", "request", "revoke", diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/externalmessage/ExternalMessageFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/externalmessage/ExternalMessageFacade.java index f06be399ca6..eac3ddef95b 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/externalmessage/ExternalMessageFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/externalmessage/ExternalMessageFacade.java @@ -87,6 +87,15 @@ default List saveAndProcessSurveyResponses() { ExternalMessageDto getForSurveillanceReport(SurveillanceReportReferenceDto surveillanceReport); + /** + * Re-submits a survey response. + * + * @param uuid + * UUID of the external message (must be of type SURVEY_RESPONSE) + * @return updated ExternalMessageDto after reprocessing + */ + ExternalMessageDto executeSurveyProcessing(String uuid); + /** * Re-submits a survey response with a corrected patch dictionary after previous processing failures. * diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/symptoms/SymptomsDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/symptoms/SymptomsDto.java index ce45e48142f..6785155bf75 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/symptoms/SymptomsDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/symptoms/SymptomsDto.java @@ -346,14 +346,6 @@ public class SymptomsDto extends PseudonymizableDto { public static final String WEIGHT_LOSS = "weightLoss"; public static final String WEIGHT_LOSS_AMOUNT = "weightLossAmount"; public static final String BLOATING = "bloating"; - - public static final String LOSS_OF_APPETITE = "lossOfAppetite"; - public static final String FLATULENCE = "flatulence"; - public static final String SMELLY_BURPS = "smellyBurps"; - public static final String COUGHING_ATTACKS = "coughingAttacks"; - public static final String COUGHING_AT_NIGHT = "coughingAtNight"; - public static final String ABDOMINAL_CRAMPS = "abdominalCramps"; - public static final String REOCCURRENCE = "reoccurrence"; public static final String OVERNIGHT_STAY_REQUIRED = "overnightStayRequired"; public static final String SYMPTOM_CURRENT_STATUS = "symptomCurrentStatus"; @@ -2958,34 +2950,6 @@ public static SymptomsDto build() { GIARDIASIS }) @SymptomGrouping(SymptomGroup.GASTROINTESTINAL) private SymptomState bloating; - - @Diseases({ - CRYPTOSPORIDIOSIS, - GIARDIASIS, - RESPIRATORY_SYNCYTIAL_VIRUS }) - private SymptomState lossOfAppetite; - - @Diseases({ - GIARDIASIS }) - private SymptomState flatulence; - - @Diseases({ - GIARDIASIS }) - private SymptomState smellyBurps; - - @Diseases({ - PERTUSSIS }) - private SymptomState coughingAttacks; - - @Diseases({ - PERTUSSIS }) - private SymptomState coughingAtNight; - - @Diseases({ - CRYPTOSPORIDIOSIS, - GIARDIASIS }) - private SymptomState abdominalCramps; - private DiagnosisType diagnosis; private InfectionSite majorSite; private String otherMajorSiteDetails; @@ -5352,54 +5316,6 @@ public void setEyeIrritation(SymptomState eyeIrritation) { this.eyeIrritation = eyeIrritation; } - public SymptomState getCoughingAtNight() { - return coughingAtNight; - } - - public void setCoughingAtNight(SymptomState coughingAtNight) { - this.coughingAtNight = coughingAtNight; - } - - public SymptomState getLossOfAppetite() { - return lossOfAppetite; - } - - public void setLossOfAppetite(SymptomState lossOfAppetite) { - this.lossOfAppetite = lossOfAppetite; - } - - public SymptomState getFlatulence() { - return flatulence; - } - - public void setFlatulence(SymptomState flatulence) { - this.flatulence = flatulence; - } - - public SymptomState getSmellyBurps() { - return smellyBurps; - } - - public void setSmellyBurps(SymptomState smellyBurps) { - this.smellyBurps = smellyBurps; - } - - public SymptomState getCoughingAttacks() { - return coughingAttacks; - } - - public void setCoughingAttacks(SymptomState coughingAttacks) { - this.coughingAttacks = coughingAttacks; - } - - public SymptomState getAbdominalCramps() { - return abdominalCramps; - } - - public void setAbdominalCramps(SymptomState abdominalCramps) { - this.abdominalCramps = abdominalCramps; - } - public SymptomState getTenesmus() { return tenesmus; } diff --git a/sormas-api/src/main/resources/strings.properties b/sormas-api/src/main/resources/strings.properties index f9eecd5320d..dfd9f3b4dfb 100644 --- a/sormas-api/src/main/resources/strings.properties +++ b/sormas-api/src/main/resources/strings.properties @@ -2096,7 +2096,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_ar-SA.properties b/sormas-api/src/main/resources/strings_ar-SA.properties index e66ac526392..cffdd1836f2 100644 --- a/sormas-api/src/main/resources/strings_ar-SA.properties +++ b/sormas-api/src/main/resources/strings_ar-SA.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_cs-CZ.properties b/sormas-api/src/main/resources/strings_cs-CZ.properties index 508402702e6..6132c39153b 100644 --- a/sormas-api/src/main/resources/strings_cs-CZ.properties +++ b/sormas-api/src/main/resources/strings_cs-CZ.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_de-CH.properties b/sormas-api/src/main/resources/strings_de-CH.properties index bf769252d06..d36ee009ed9 100644 --- a/sormas-api/src/main/resources/strings_de-CH.properties +++ b/sormas-api/src/main/resources/strings_de-CH.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_de-DE.properties b/sormas-api/src/main/resources/strings_de-DE.properties index e7ff782bf37..d3055de2c66 100644 --- a/sormas-api/src/main/resources/strings_de-DE.properties +++ b/sormas-api/src/main/resources/strings_de-DE.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_en-AF.properties b/sormas-api/src/main/resources/strings_en-AF.properties index e1bdb0f2cfc..d1f31c28cbc 100644 --- a/sormas-api/src/main/resources/strings_en-AF.properties +++ b/sormas-api/src/main/resources/strings_en-AF.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_en-GH.properties b/sormas-api/src/main/resources/strings_en-GH.properties index 3364a5a0167..c1388d08a78 100644 --- a/sormas-api/src/main/resources/strings_en-GH.properties +++ b/sormas-api/src/main/resources/strings_en-GH.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_en-GM.properties b/sormas-api/src/main/resources/strings_en-GM.properties index f76d60d0791..024f2556465 100644 --- a/sormas-api/src/main/resources/strings_en-GM.properties +++ b/sormas-api/src/main/resources/strings_en-GM.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_en-KE.properties b/sormas-api/src/main/resources/strings_en-KE.properties index 34e28924c8f..c4ef262e4a3 100644 --- a/sormas-api/src/main/resources/strings_en-KE.properties +++ b/sormas-api/src/main/resources/strings_en-KE.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_en-LR.properties b/sormas-api/src/main/resources/strings_en-LR.properties index f76d60d0791..024f2556465 100644 --- a/sormas-api/src/main/resources/strings_en-LR.properties +++ b/sormas-api/src/main/resources/strings_en-LR.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_en-NG.properties b/sormas-api/src/main/resources/strings_en-NG.properties index 9f5ef764206..1d9527cb7ba 100644 --- a/sormas-api/src/main/resources/strings_en-NG.properties +++ b/sormas-api/src/main/resources/strings_en-NG.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_es-BO.properties b/sormas-api/src/main/resources/strings_es-BO.properties index e3450b74415..d1549ec31ff 100644 --- a/sormas-api/src/main/resources/strings_es-BO.properties +++ b/sormas-api/src/main/resources/strings_es-BO.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_fa-AF.properties b/sormas-api/src/main/resources/strings_fa-AF.properties index ffca4e8ef2a..261f01a20cc 100644 --- a/sormas-api/src/main/resources/strings_fa-AF.properties +++ b/sormas-api/src/main/resources/strings_fa-AF.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_fi-FI.properties b/sormas-api/src/main/resources/strings_fi-FI.properties index 84d3e7268d7..9a627e94e45 100644 --- a/sormas-api/src/main/resources/strings_fi-FI.properties +++ b/sormas-api/src/main/resources/strings_fi-FI.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_fr-CH.properties b/sormas-api/src/main/resources/strings_fr-CH.properties index 587a610f5e3..45e53dc51b7 100644 --- a/sormas-api/src/main/resources/strings_fr-CH.properties +++ b/sormas-api/src/main/resources/strings_fr-CH.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_fr-FR.properties b/sormas-api/src/main/resources/strings_fr-FR.properties index 5f3ef79ab66..3eb1e0d82aa 100644 --- a/sormas-api/src/main/resources/strings_fr-FR.properties +++ b/sormas-api/src/main/resources/strings_fr-FR.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_fr-TN.properties b/sormas-api/src/main/resources/strings_fr-TN.properties index bb1d14b1aee..6f311982291 100644 --- a/sormas-api/src/main/resources/strings_fr-TN.properties +++ b/sormas-api/src/main/resources/strings_fr-TN.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_it-CH.properties b/sormas-api/src/main/resources/strings_it-CH.properties index 39f13764d62..8bc6d07b335 100644 --- a/sormas-api/src/main/resources/strings_it-CH.properties +++ b/sormas-api/src/main/resources/strings_it-CH.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_it-IT.properties b/sormas-api/src/main/resources/strings_it-IT.properties index 6654edba704..76050208928 100644 --- a/sormas-api/src/main/resources/strings_it-IT.properties +++ b/sormas-api/src/main/resources/strings_it-IT.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_ka-GE.properties b/sormas-api/src/main/resources/strings_ka-GE.properties index 7eb86d844f5..aed47e4bcae 100644 --- a/sormas-api/src/main/resources/strings_ka-GE.properties +++ b/sormas-api/src/main/resources/strings_ka-GE.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_pl-PL.properties b/sormas-api/src/main/resources/strings_pl-PL.properties index 9f8c44484f4..653c8cdead2 100644 --- a/sormas-api/src/main/resources/strings_pl-PL.properties +++ b/sormas-api/src/main/resources/strings_pl-PL.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_ps-AF.properties b/sormas-api/src/main/resources/strings_ps-AF.properties index a63dd9b73cc..df6aa6a20cf 100644 --- a/sormas-api/src/main/resources/strings_ps-AF.properties +++ b/sormas-api/src/main/resources/strings_ps-AF.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_pt-BR.properties b/sormas-api/src/main/resources/strings_pt-BR.properties index 4b5087d67ab..1a97375b149 100644 --- a/sormas-api/src/main/resources/strings_pt-BR.properties +++ b/sormas-api/src/main/resources/strings_pt-BR.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_pt-CV.properties b/sormas-api/src/main/resources/strings_pt-CV.properties index de5920a3e70..0750dc40a19 100644 --- a/sormas-api/src/main/resources/strings_pt-CV.properties +++ b/sormas-api/src/main/resources/strings_pt-CV.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_ru-RU.properties b/sormas-api/src/main/resources/strings_ru-RU.properties index fe1a46a8f3d..1adce04f2d5 100644 --- a/sormas-api/src/main/resources/strings_ru-RU.properties +++ b/sormas-api/src/main/resources/strings_ru-RU.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_sr-CS.properties b/sormas-api/src/main/resources/strings_sr-CS.properties index 369652d2ae4..ff75118548f 100644 --- a/sormas-api/src/main/resources/strings_sr-CS.properties +++ b/sormas-api/src/main/resources/strings_sr-CS.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_sw-TZ.properties b/sormas-api/src/main/resources/strings_sw-TZ.properties index 7eb86d844f5..aed47e4bcae 100644 --- a/sormas-api/src/main/resources/strings_sw-TZ.properties +++ b/sormas-api/src/main/resources/strings_sw-TZ.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_ur-PK.properties b/sormas-api/src/main/resources/strings_ur-PK.properties index 48ec95b07b8..bb6c9694c47 100644 --- a/sormas-api/src/main/resources/strings_ur-PK.properties +++ b/sormas-api/src/main/resources/strings_ur-PK.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-api/src/main/resources/strings_zh-CN.properties b/sormas-api/src/main/resources/strings_zh-CN.properties index 9244eaa6899..8b13bdf5619 100644 --- a/sormas-api/src/main/resources/strings_zh-CN.properties +++ b/sormas-api/src/main/resources/strings_zh-CN.properties @@ -2095,7 +2095,7 @@ headingSurveyResponseDetails=Response Details headingSurveyResponseFailures=Validation Issues headingSurveyResponseCorrectAndReprocess=Correct & Reprocess messageSurveyResponseAllFieldsApplied=All fields were successfully applied -messageSurveyResponseNotYetProcessed=This response has not been processed yet +messageSurveyResponseNotYetProcessed=There was an issue when building the survey request, please fetch the surveys again or wait for the next automatic fetch messageSurveyResponseReprocessed=The response has been successfully reprocessed messageSurveyResponseReprocessedFailure=There was a failure when reprocessing the response, please try to edit it again to check what caused the issue. diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseListCriteriaBuilder.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseListCriteriaBuilder.java index ed52a00cc50..ba946054e90 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseListCriteriaBuilder.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseListCriteriaBuilder.java @@ -264,6 +264,8 @@ private List> getIndexOrders(SortProperty sortProperty, Root switch (sortProperty.propertyName) { case CaseIndexDto.PERSON_UUID: return Collections.singletonList(joins.getPerson().get(Person.UUID)); + case CaseIndexDto.DISEASE_VARIANT: + return Collections.singletonList(caze.get(Case.DISEASE_VARIANT_VALUE)); case CaseIndexDto.ID: case CaseIndexDto.UUID: case CaseIndexDto.EPID_NUMBER: @@ -279,8 +281,6 @@ private List> getIndexOrders(SortProperty sortProperty, Root case CaseIndexDto.FOLLOW_UP_STATUS: case CaseIndexDto.FOLLOW_UP_UNTIL: case CaseIndexDto.VACCINATION_STATUS: - case CaseIndexDto.DISEASE_VARIANT: - return Collections.singletonList(caze.get(Case.DISEASE_VARIANT_VALUE)); case CaseIndexDto.EXTERNAL_ID: case CaseIndexDto.EXTERNAL_TOKEN: case CaseIndexDto.INTERNAL_TOKEN: diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageFacadeEjb.java index df8c3358292..e25854bc6da 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageFacadeEjb.java @@ -30,6 +30,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import javax.annotation.Nullable; import javax.annotation.security.PermitAll; import javax.ejb.EJB; import javax.ejb.LocalBean; @@ -50,7 +51,6 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import javax.persistence.criteria.Selection; -import javax.transaction.Transactional; import javax.validation.Valid; import javax.validation.constraints.NotNull; @@ -330,9 +330,6 @@ private ExternalMessageDto saveWithFallback(ExternalMessageDto dto) { @Override @RightsAllowed(UserRight._EXTERNAL_MESSAGE_SURVEY_RESPONSE_PROCESS) - @Transactional(value = Transactional.TxType.REQUIRES_NEW, - rollbackOn = { - Exception.class }) public List saveAndProcessSurveyResponses(Date since) { if (since == null) { @@ -393,7 +390,10 @@ public List saveAndProcessSurveyResponses(Date since) { processingResults.forEach(wrapper -> { ProcessingResultStatus result = wrapper.getResultStatus(); if (result == null || result.isCanceled()) { - logger.error("Processing of surveyResponse with UUID {} has been canceled", wrapper.getExternalMessage().getUuid()); + logger.error( + "Processing of surveyResponse with UUID {} has been canceled, result: [{}]", + wrapper.getExternalMessage().getUuid(), + wrapper); } }); } catch (InterruptedException e) { @@ -402,7 +402,10 @@ public List saveAndProcessSurveyResponses(Date since) { } catch (ExecutionException e) { logger.error("Could not process survey responses with UUID [{}]", extractUuids(filteredSurveyResponses), e); } finally { - savedDtos = filteredSurveyResponses.stream().map(this::save).collect(toList()); + savedDtos = filteredSurveyResponses.stream() + .peek(externalMessageDto -> externalMessageDto.setChangeDate(new Date())) + .map(this::save) + .collect(toList()); } if (logger.isTraceEnabled()) { @@ -1044,10 +1047,23 @@ public ExternalMessageDto getForSurveillanceReport(SurveillanceReportReferenceDt @Override @RightsAllowed(UserRight._EXTERNAL_MESSAGE_SURVEY_RESPONSE_PROCESS) - public ExternalMessageDto overwriteSurveyResponse(String uuid, PatchDictionary correctedDictionary) { + public ExternalMessageDto executeSurveyProcessing(String uuid) { + logger.debug("reAttemptSurveyProcessing: [{}]", uuid); + return overwriteSurveyResponse(uuid, null); + } + + @Override + @RightsAllowed(UserRight._EXTERNAL_MESSAGE_SURVEY_RESPONSE_PROCESS) + public ExternalMessageDto overwriteSurveyResponse(String uuid, @Nullable PatchDictionary correctedDictionary) { logger.debug("overwriteSurveyResponse: [{}],[{}]", uuid, correctedDictionary); ExternalMessageDto externalMessage = getByUuid(uuid); - ExternalMessageSurveyResponseRequest latestRequest = externalMessage.getSurveyResponseData().getLatest().getRequest(); + ExternalSurveyResponseData surveyResponseData = externalMessage.getSurveyResponseData(); + + if (surveyResponseData == null) { + throw new IllegalStateException(String.format("Missing surveyResponseData for external message: [%s]", uuid)); + } + + ExternalMessageSurveyResponseRequest latestRequest = surveyResponseData.getLatest().getRequest(); logger.info("On reprocessing replacement strategy is set to ALWAYS to allow override values, enable debug to see request"); logger.debug("Request before transformation: [{}]", latestRequest); @@ -1063,13 +1079,14 @@ public ExternalMessageDto overwriteSurveyResponse(String uuid, PatchDictionary c .setAllowFallbackValues(latestRequest.isAllowFallbackValues()) .setSkipIfAlreadyProcessed(latestRequest.isSkipIfAlreadyProcessed()) .setPatchedInCaseOfFailures(latestRequest.isPatchedInCaseOfFailures()) - .setPatchDictionary(correctedDictionary) + .setPatchDictionary(correctedDictionary != null ? correctedDictionary : latestRequest.getPatchDictionary()) .setExcludedPatchDictionary(latestRequest.getExcludedPatchDictionary()); logger.debug("Request after transformation: [{}]", correctedRequest); ExternalMessageSurveyResponseWrapper updatedWrapper = new ExternalMessageSurveyResponseWrapper().setRequest(correctedRequest); - externalMessage.getSurveyResponseData().setUpdated(updatedWrapper); + surveyResponseData.setUpdated(updatedWrapper); + externalMessage.setChangeDate(new Date()); ExternalMessageDto result; try { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/survey/AutomaticSurveyResponseProcessor.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/survey/AutomaticSurveyResponseProcessor.java index 588ad2cb0bd..1a404d22d68 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/survey/AutomaticSurveyResponseProcessor.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/survey/AutomaticSurveyResponseProcessor.java @@ -2,8 +2,10 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; @@ -32,7 +34,6 @@ import de.symeda.sormas.api.utils.dataprocessing.ProcessingResultStatus; import de.symeda.sormas.backend.survey.SurveyFacadeEjb; import de.symeda.sormas.backend.survey.SurveyTokenFacadeEjb; -import de.symeda.sormas.backend.util.CollectorUtils; /** * Performs the coordinating for patch operations out of Survey-responses. @@ -63,7 +64,9 @@ public AutomaticSurveyResponseProcessor( this.surveyTokenFacade = surveyTokenFacade; } - @Transactional(Transactional.TxType.REQUIRES_NEW) + @Transactional(value = Transactional.TxType.REQUIRES_NEW, + rollbackOn = { + Exception.class }) public List processSurveyResponses(List externalMessages) throws InterruptedException, ExecutionException { @@ -72,17 +75,22 @@ public List processSurveyResponses(List tokenByExternalSurveyIdDictionary = - externalMessages.stream().map(ExternalMessageDto::getSurveyResponseData).map(responseData -> { - ExternalMessageSurveyResponseRequest request = responseData.getLatest().getRequest(); - return new Tuple<>(request.getExternalSurveyId(), request.getToken()); - }).collect(CollectorUtils.toOrderedNullSafeMap(Tuple::getFirst, Tuple::getSecond)); + Map> tokensByExternalIds = externalMessages.stream().map(ExternalMessageDto::getSurveyResponseData).map(responseData -> { + ExternalMessageSurveyResponseRequest request = responseData.getLatest().getRequest(); + return new Tuple<>(request.getExternalSurveyId(), request.getToken()); + }).collect(Collectors.groupingBy(Tuple::getFirst, Collectors.mapping(Tuple::getSecond, Collectors.toList()))); - List externalSurveyIds = new ArrayList<>(tokenByExternalSurveyIdDictionary.keySet()); + logger.debug("tokensByExternalIds: [{}]", tokensByExternalIds); + + List externalSurveyIds = new ArrayList<>(tokensByExternalIds.keySet()); List> tokenBySurveyReferenceTuples = surveyFacade.getByExternalIds(externalSurveyIds) .stream() - .map(survey -> new Tuple<>(survey.toReference(), tokenByExternalSurveyIdDictionary.get(survey.getExternalId()))) + .flatMap( + survey -> tokensByExternalIds.get(survey.getExternalId()) + .stream() + .filter(Objects::nonNull) + .map(token -> new Tuple<>(survey.toReference(), token))) .collect(Collectors.toList()); List surveyTokens = surveyTokenFacade.getBySurveyReferenceTokenTuples(tokenBySurveyReferenceTuples); @@ -94,15 +102,15 @@ public List processSurveyResponses(List surveyTokens) { logger.trace("tryProcessExternalMessage: [{}], [{}]", externalMessage, surveyTokens); - SurveyResponseProcessingResult surveyResponseProcessingResult = new SurveyResponseProcessingResult().setExternalMessage(externalMessage); + SurveyResponseProcessingResult surveyResponseProcessingResult = + new SurveyResponseProcessingResult().setExternalMessage(externalMessage).setResultStatus(ProcessingResultStatus.DONE); ExternalMessageSurveyResponseWrapper latestResponseWrapper = externalMessage.getSurveyResponseData().getLatest(); ExternalMessageSurveyResponseRequest request = latestResponseWrapper.getRequest(); + String externalMessageUuid = externalMessage.getUuid(); if (latestResponseWrapper.getResult() != null && request.isSkipIfAlreadyProcessed()) { - logger.info( - "Skipping survey response for external message [{}]: already processed and skipIfAlreadyProcessed=true", - externalMessage.getUuid()); + logger.info("Skipping survey response for external message [{}]: already processed and skipIfAlreadyProcessed=true", externalMessageUuid); return surveyResponseProcessingResult.setResultStatus(ProcessingResultStatus.CANCELED); } @@ -111,7 +119,10 @@ public List processSurveyResponses(List tokenCandidate.getToken().equals(requestToken)).findAny(); if (surveyToken.isEmpty()) { - logger.error("Token could not be found within available survey token DTOs: [{}]. Survey response processing is cancelled.", requestToken); + logger.error( + "Token could not be found within available survey token DTOs: [{}]. Survey response processing for: [{}] is cancelled.", + requestToken, + externalMessageUuid); return surveyResponseProcessingResult.setResultStatus(ProcessingResultStatus.CANCELED); } @@ -120,6 +131,7 @@ public List processSurveyResponses(List processSurveyResponses(List processSurveyResponses(List, LeafAttacher> leafAttacherRegistry = new LinkedHashMap<>(); + private final Map, LeafAttacher> leafAttacherDictionary = new LinkedHashMap<>(); + + /** + * Attached directly to case data. + * Will be saved in one shot with the case. + */ + private final Map, LeafAttacher> caseDataLeafAttacherDictionary = new LinkedHashMap<>(); @PostConstruct private void init() { @@ -178,19 +193,25 @@ private void registerLeafAttacherOperations() { } immunization.getVaccinations().add((VaccinationDto) leaf); }); - registerLeafAttacher(ExposureDto.class, (leaf, groupIndex, list) -> { + + // directly linked to the case + registerCaseDataLeafAttacher(ExposureDto.class, (leaf, groupIndex, list) -> { requireCaseData(list).getEpiData().getExposures().add((ExposureDto) leaf); }); - registerLeafAttacher(ActivityAsCaseDto.class, (leaf, groupIndex, list) -> { + registerCaseDataLeafAttacher(ActivityAsCaseDto.class, (leaf, groupIndex, list) -> { requireCaseData(list).getEpiData().getActivitiesAsCase().add((ActivityAsCaseDto) leaf); }); - registerLeafAttacher(PreviousHospitalizationDto.class, (leaf, groupIndex, list) -> { + registerCaseDataLeafAttacher(PreviousHospitalizationDto.class, (leaf, groupIndex, list) -> { requireCaseData(list).getHospitalization().getPreviousHospitalizations().add((PreviousHospitalizationDto) leaf); }); } private void registerLeafAttacher(Class leafClass, LeafAttacher attacher) { - leafAttacherRegistry.put(leafClass, attacher); + leafAttacherDictionary.put(leafClass, attacher); + } + + private void registerCaseDataLeafAttacher(Class leafClass, LeafAttacher attacher) { + caseDataLeafAttacherDictionary.put(leafClass, attacher); } private CaseDataDto requireCaseData(List> dtosInProgress) { @@ -301,9 +322,26 @@ private T saveDirectEntity(@NotNull EntityDto entityDto) { } public void save(@NotNull List> entityDtosByKey) { + Predicate> allButCaseDataDto = tuple -> tuple.getSecond() instanceof CaseDataDto; + Optional caseDataOpt = entityDtosByKey.stream().filter(allButCaseDataDto).map(Tuple::getSecond).findAny(); + List> dtosInProgress = new ArrayList<>(entityDtosByKey); - leafAttacherRegistry.forEach((leafClass, attacher) -> { + // must be attached to case data before being stored, otherwise those entities are lost. + caseDataLeafAttacherDictionary.forEach((leafClass, attacher) -> { + List> leaves = + dtosInProgress.stream().filter(t -> leafClass.isInstance(t.getSecond())).collect(Collectors.toList()); + + leaves.forEach(leafTuple -> { + dtosInProgress.remove(leafTuple); + attacher.attachLeaf(leafTuple.getSecond(), leafTuple.getFirst(), dtosInProgress); + }); + }); + + // case data must be stored up-front because "logically-attached" entities might update it again: immunization etc. + caseDataOpt.ifPresent(this::saveDirectEntity); + + leafAttacherDictionary.forEach((leafClass, attacher) -> { List> leaves = dtosInProgress.stream().filter(t -> leafClass.isInstance(t.getSecond())).collect(Collectors.toList()); @@ -313,7 +351,7 @@ public void save(@NotNull List> entityDtosByKey) { }); }); - dtosInProgress.stream().map(Tuple::getSecond).forEach(this::saveDirectEntity); + dtosInProgress.stream().filter(Predicate.not(allButCaseDataDto)).map(Tuple::getSecond).forEach(this::saveDirectEntity); } @FunctionalInterface diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/patch/DataPatcherImpl.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/patch/DataPatcherImpl.java index 053077467ab..243b808d755 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/patch/DataPatcherImpl.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/patch/DataPatcherImpl.java @@ -111,9 +111,7 @@ public DataPatcherImpl( this.configFacade = configFacade; } - @Transactional(value = Transactional.TxType.REQUIRES_NEW, - rollbackOn = { - Exception.class }) + @Transactional(rollbackOn = Exception.class) @Override public DataPatchResponse patch(CaseDataPatchRequest request) { logger.debug("patch: [{}]", request); @@ -247,7 +245,7 @@ private PlainSinglePatchResult produceSinglePatchResult( private void saveDTOsIfAppropriate(Map, AttachedEntityWrapper> entityCache) { List> toSave = entityCache.entrySet() .stream() - .map(entry -> Tuple. of(entry.getKey().getSecond(), entry.getValue().getEntityDto())) + .map(entry -> Tuple.of(entry.getKey().getSecond(), entry.getValue().getEntityDto())) .collect(Collectors.toList()); if (toSave.isEmpty()) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/patch/PropertyAccessor.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/patch/PropertyAccessor.java index 7457126ca15..3372ff8eead 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/patch/PropertyAccessor.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/patch/PropertyAccessor.java @@ -39,7 +39,7 @@ public static Tuple, Object>, PropertyAccessFailure> getNestedPro return new Tuple<>(null, PropertyAccessFailure.INVALID_INPUT); } - boolean notNestedPath = fieldName.indexOf(PATH_SEPARATOR) == fieldName.lastIndexOf(PATH_SEPARATOR); + boolean notNestedPath = fieldName.indexOf(PATH_SEPARATOR) == -1; if (notNestedPath) { return getPropertyTypeAndValue(bean, fieldName, fieldVisibilityCheckers); @@ -47,7 +47,8 @@ public static Tuple, Object>, PropertyAccessFailure> getNestedPro String leafPath = fieldName.substring(fieldName.lastIndexOf(PATH_SEPARATOR) + 1); - return getNestedProperty(bean, fieldName).map(leafParent -> getPropertyTypeAndValue(leafParent, leafPath, fieldVisibilityCheckers)) + return getNestedProperty(bean, fieldName.substring(0, fieldName.lastIndexOf(PATH_SEPARATOR))) + .map(leafParent -> getPropertyTypeAndValue(leafParent, leafPath, fieldVisibilityCheckers)) .orElseGet(() -> new Tuple<>(null, PropertyAccessFailure.FIELD_DOES_NOT_EXIST)); } @@ -59,7 +60,7 @@ public static Tuple, PropertyAccessFailure> getNestedPropertyType( return INVALID_INPUT; } - boolean notNestedPath = fieldName.indexOf(PATH_SEPARATOR) == fieldName.lastIndexOf(PATH_SEPARATOR); + boolean notNestedPath = fieldName.indexOf(PATH_SEPARATOR) == -1; if (notNestedPath) { return getPropertyType(bean, fieldName, fieldVisibilityCheckers); @@ -67,7 +68,8 @@ public static Tuple, PropertyAccessFailure> getNestedPropertyType( String leafPath = fieldName.substring(fieldName.lastIndexOf(PATH_SEPARATOR) + 1); - return getNestedProperty(bean, fieldName).map(leafParent -> getPropertyType(leafParent, leafPath, fieldVisibilityCheckers)) + return getNestedProperty(bean, fieldName.substring(0, fieldName.lastIndexOf(PATH_SEPARATOR))) + .map(leafParent -> getPropertyType(leafParent, leafPath, fieldVisibilityCheckers)) .orElse(FIELD_DOES_NOT_EXIST); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/symptoms/SymptomsFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/symptoms/SymptomsFacadeEjb.java index 43b777b05f6..63eafeafa2b 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/symptoms/SymptomsFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/symptoms/SymptomsFacadeEjb.java @@ -248,13 +248,6 @@ public Symptoms fillOrBuildEntity(SymptomsDto source, Symptoms target, boolean c target.setWeightLossAmount(source.getWeightLossAmount()); target.setBloating(source.getBloating()); target.setOvernightStayRequired(source.getOvernightStayRequired()); - target.setLossOfAppetite(source.getLossOfAppetite()); - target.setFlatulence(source.getFlatulence()); - target.setSmellyBurps(source.getSmellyBurps()); - target.setCoughingAttacks(source.getCoughingAttacks()); - target.setCoughingAtNight(source.getCoughingAtNight()); - target.setAbdominalCramps(source.getAbdominalCramps()); - target.setClammySkin(source.getClammySkin()); target.setColdSkin(source.getColdSkin()); target.setEncephalitis(source.getEncephalitis()); @@ -548,12 +541,6 @@ public static SymptomsDto toSymptomsDto(Symptoms symptoms) { target.setConstipation(source.getConstipation()); target.setDysuria(source.getDysuria()); target.setEyeIrritation(source.getEyeIrritation()); - target.setLossOfAppetite(source.getLossOfAppetite()); - target.setFlatulence(source.getFlatulence()); - target.setSmellyBurps(source.getSmellyBurps()); - target.setCoughingAttacks(source.getCoughingAttacks()); - target.setCoughingAtNight(source.getCoughingAtNight()); - target.setAbdominalCramps(source.getAbdominalCramps()); target.setTenesmus(source.getTenesmus()); target.setHaemolyticUremicSyndrome(source.getHaemolyticUremicSyndrome()); target.setBloodyDiarrhea(source.getBloodyDiarrhea()); diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/ArchitectureTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/ArchitectureTest.java index b0fffdf2d20..25ebf7f70e6 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/ArchitectureTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/ArchitectureTest.java @@ -1,6 +1,9 @@ package de.symeda.sormas.backend; -import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.*; +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes; +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.fields; +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.methods; +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; import java.util.Arrays; import java.util.Collections; @@ -291,6 +294,7 @@ public void testExternalMessageFacadeEjbAuthorization(JavaClasses classes) { "bulkAssignExternalMessages", "delete", "overwriteSurveyResponse", + "reAttemptSurveyProcessing", "saveAndProcessSurveyResponses"), classes); } diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/patch/PropertyAccessorTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/patch/PropertyAccessorTest.java index 76514d4f25c..e919ae3c8c5 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/patch/PropertyAccessorTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/patch/PropertyAccessorTest.java @@ -141,12 +141,10 @@ void getNestedPropertyType_invisibleField_returnsUnsupportedField() { AddressBean address = new AddressBean(); PersonBean person = new PersonBean(); person.setAddress(address); - FieldVisibilityCheckers hideAll = - FieldVisibilityCheckers.withCheckers((FieldVisibilityCheckers.FieldNameBaseChecker) (type, id) -> false); + FieldVisibilityCheckers hideAll = FieldVisibilityCheckers.withCheckers((FieldVisibilityCheckers.FieldNameBaseChecker) (type, id) -> false); // EXECUTE - Tuple, PropertyAccessFailure> result = - PropertyAccessor.getNestedPropertyType(person, "address.street", hideAll); + Tuple, PropertyAccessFailure> result = PropertyAccessor.getNestedPropertyType(person, "address.street", hideAll); // CHECK assertEquals(PropertyAccessFailure.UNSUPPORTED_FIELD_FOR_DISEASE_OR_COUNTRY_OR_FEATURE, result.getSecond()); @@ -183,9 +181,7 @@ void getNestedPropertyAndType_twoSegmentPath_returnsTypeAndValue() { @Test void getNestedPropertyAndType_threeSegmentPath_returnsTypeAndValue() { // PREPARE - AddressBean level4 = new AddressBean(); AddressBean level3 = new AddressBean(); - level3.setAddress(level4); AddressBean level2 = new AddressBean(); level2.setAddress(level3); AddressBean level1 = new AddressBean(); @@ -200,7 +196,7 @@ void getNestedPropertyAndType_threeSegmentPath_returnsTypeAndValue() { // CHECK assertNull(result.getSecond()); assertEquals(AddressBean.class, result.getFirst().getFirst()); - assertEquals(level4, result.getFirst().getSecond()); + assertEquals(level3, result.getFirst().getSecond()); } @Test @@ -254,12 +250,10 @@ void getPropertyTypeAndValue_nonExistentField_returnsFieldDoesNotExist() { void getPropertyTypeAndValue_invisibleField_returnsUnsupportedField() { // PREPARE AddressBean address = new AddressBean(); - FieldVisibilityCheckers hideAll = - FieldVisibilityCheckers.withCheckers((FieldVisibilityCheckers.FieldNameBaseChecker) (type, id) -> false); + FieldVisibilityCheckers hideAll = FieldVisibilityCheckers.withCheckers((FieldVisibilityCheckers.FieldNameBaseChecker) (type, id) -> false); // EXECUTE - Tuple, Object>, PropertyAccessFailure> result = - PropertyAccessor.getPropertyTypeAndValue(address, "street", hideAll); + Tuple, Object>, PropertyAccessFailure> result = PropertyAccessor.getPropertyTypeAndValue(address, "street", hideAll); // CHECK assertEquals(PropertyAccessFailure.UNSUPPORTED_FIELD_FOR_DISEASE_OR_COUNTRY_OR_FEATURE, result.getSecond()); diff --git a/sormas-backend/src/test/java/de/symeda/sormas/patch/DataPatcherImplTest.java b/sormas-backend/src/test/java/de/symeda/sormas/patch/DataPatcherImplTest.java index c60457d0e8c..598da825382 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/patch/DataPatcherImplTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/patch/DataPatcherImplTest.java @@ -24,7 +24,9 @@ import de.symeda.sormas.api.activityascase.ActivityAsCaseDto; import de.symeda.sormas.api.activityascase.ActivityAsCaseType; import de.symeda.sormas.api.caze.CaseDataDto; +import de.symeda.sormas.api.caze.VaccinationStatus; import de.symeda.sormas.api.caze.Vaccine; +import de.symeda.sormas.api.contact.FollowUpStatus; import de.symeda.sormas.api.customizableenum.CustomizableEnumTranslation; import de.symeda.sormas.api.customizableenum.CustomizableEnumType; import de.symeda.sormas.api.customizablefield.CustomizableFieldContext; @@ -43,6 +45,7 @@ import de.symeda.sormas.api.hospitalization.PreviousHospitalizationDto; import de.symeda.sormas.api.immunization.ImmunizationDto; import de.symeda.sormas.api.immunization.ImmunizationStatus; +import de.symeda.sormas.api.immunization.MeansOfImmunization; import de.symeda.sormas.api.infrastructure.country.CountryDto; import de.symeda.sormas.api.infrastructure.country.CountryReferenceDto; import de.symeda.sormas.api.infrastructure.facility.FacilityDto; @@ -479,6 +482,27 @@ void patch_notSupportedForCountry() { () -> Assertions.assertEquals(expectedFailures, response.getFailures())); } + @Test + void patch_notSupportedForDisease_symptoms_offset() { + // PREPARE + CaseDataDto originalCase = creator.createUnclassifiedCase(Disease.GIARDIASIS); + + Map patchDictionary = Map.of("CaseData.symptoms.offsetDate", new java.util.Date()); + + // EXECUTE + DataPatchResponse response = + victim().patch(new CaseDataPatchRequest().setCaseUuid(originalCase.getUuid()).setPatchDictionary(patchDictionary)); + + // CHECK + Map expectedFailures = + buildDictionaryOfFailureType(patchDictionary, DataPatchFailureCause.UNSUPPORTED_FIELD_FOR_DISEASE_OR_COUNTRY_OR_FEATURE); + + Assertions.assertAll( + () -> Assertions.assertTrue(response.getValidPatchDictionary().isEmpty(), "Nothing should have been patched, should be empty"), + // FAILURES + () -> Assertions.assertEquals(expectedFailures, response.getFailures())); + } + @Test void patch_notSupportedFeature() { // PREPARE @@ -1014,6 +1038,116 @@ void patch_exposure() { () -> Assertions.assertEquals("market visit", exposures.get(0).getDescription())); } + @Test + void patch_multipleEntities_caseDataExposureHospitalizationSymptoms() { + // This modifies many entities are triggers case update. + // Might require changing outdated range to reproduce every time + // PREPARE + Disease disease = Disease.MEASLES; + CaseDataDto originalCase = creator.createUnclassifiedCase(disease); + + // EXECUTE + DataPatchResponse response = victim().patch( + new CaseDataPatchRequest().setCaseUuid(originalCase.getUuid()) + .setReplacementStrategy(DataReplacementStrategy.ALWAYS) + .setPatchDictionary( + Map.ofEntries( + // CaseData + Map.entry("CaseData.quarantineChangeComment", "some comment"), + Map.entry(toFieldName(CaseDataDto.I18N_PREFIX, CaseDataDto.FOLLOW_UP_STATUS), FollowUpStatus.FOLLOW_UP), + + // Exposures + Map.entry(toFieldName(ExposureDto.I18N_PREFIX, ExposureDto.EXPOSURE_TYPE), "WORK"), + Map.entry(toFieldName(ExposureDto.I18N_PREFIX, ExposureDto.DESCRIPTION), "market visit"), + + // EpiData + Map.entry("EpiData.exposureDetailsKnown", "YES"), + Map.entry("EpiData.contactWithSourceCaseKnown", "NO"), + + // Hospitalization + Map.entry(toFieldName(HospitalizationDto.I18N_PREFIX, HospitalizationDto.ADMITTED_TO_HEALTH_FACILITY), "YES"), + Map.entry(toFieldName(HospitalizationDto.I18N_PREFIX, HospitalizationDto.ADMISSION_DATE), "2024-05-10"), + + // Previous hospitalization + Map.entry(toFieldName(PreviousHospitalizationDto.I18N_PREFIX, PreviousHospitalizationDto.ADMITTED_TO_HEALTH_FACILITY), "YES"), + Map.entry(toFieldName(PreviousHospitalizationDto.I18N_PREFIX, PreviousHospitalizationDto.ADMISSION_DATE), "2024-03-15"), + Map.entry(toFieldName(PreviousHospitalizationDto.I18N_PREFIX, PreviousHospitalizationDto.ICU_LENGTH_OF_STAY), "7"), + + // Immunization — deliberately made ACQUIRED + valid across the case reportDate so that + // saving the Immunization/Vaccination (their own facades, not CaseFacade) forces + // CaseService#updateDeterminedVaccinationStatuses to recompute and persist the Case's vaccinationStatus. + Map.entry(toFieldName(ImmunizationDto.I18N_PREFIX, ImmunizationDto.IMMUNIZATION_STATUS), "ACQUIRED"), + Map.entry(toFieldName(ImmunizationDto.I18N_PREFIX, ImmunizationDto.MEANS_OF_IMMUNIZATION), "VACCINATION"), + Map.entry(toFieldName(ImmunizationDto.I18N_PREFIX, ImmunizationDto.VALID_FROM), "2020-01-01"), + Map.entry(toFieldName(ImmunizationDto.I18N_PREFIX, ImmunizationDto.VALID_UNTIL), "2035-01-01"), + + // Vaccination + Map.entry(toFieldName(VaccinationDto.I18N_PREFIX, VaccinationDto.VACCINE_NAME), "COMIRNATY"), + Map.entry(toFieldName(VaccinationDto.I18N_PREFIX, VaccinationDto.VACCINATION_DATE), "2024-05-01"), + Map.entry(toFieldName(VaccinationDto.I18N_PREFIX, VaccinationDto.VACCINE_DOSE), "1"), + + // Person — saving Person cascades into CaseFacade#onCaseChanged for every case of that person + Map.entry("Person.sex", "MALE"), + + // Symptoms + Map.entry("Symptoms.cough", "YES")))); + + // CHECK + CaseDataDto actualCase = getCaseFacade().getByUuid(originalCase.getUuid()); + List exposures = actualCase.getEpiData().getExposures(); + List previousHospitalizations = actualCase.getHospitalization().getPreviousHospitalizations(); + List immunizations = getImmunizationFacade().getByPersonUuids(List.of(originalCase.getPerson().getUuid())); + PersonDto actualPerson = getPersonFacade().getByUuid(originalCase.getPerson().getUuid()); + + Assertions.assertAll( + () -> Assertions.assertTrue(response.getFailures().isEmpty(), "Failures: " + response.getFailures()), + () -> Assertions.assertTrue(response.isApplied()), + + // CaseData + () -> Assertions.assertEquals("some comment", actualCase.getQuarantineChangeComment()), + + // Exposures + () -> Assertions.assertEquals(1, exposures.size()), + () -> Assertions.assertEquals(ExposureType.WORK, exposures.get(0).getExposureType()), + () -> Assertions.assertEquals("market visit", exposures.get(0).getDescription()), + + // EpiData + () -> Assertions.assertEquals(YesNoUnknown.YES, actualCase.getEpiData().getExposureDetailsKnown()), + () -> Assertions.assertEquals(YesNoUnknown.NO, actualCase.getEpiData().getContactWithSourceCaseKnown()), + + // Hospitalization + () -> Assertions.assertEquals(YesNoUnknown.YES, actualCase.getHospitalization().getAdmittedToHealthFacility()), + () -> Assertions.assertEquals( + Date.from(LocalDate.parse("2024-05-10").atStartOfDay(ZoneId.systemDefault()).toInstant()), + actualCase.getHospitalization().getAdmissionDate()), + + // Previous hospitalization + () -> Assertions.assertEquals(1, previousHospitalizations.size()), + () -> Assertions.assertEquals(YesNoUnknown.YES, previousHospitalizations.get(0).getAdmittedToHealthFacility()), + () -> Assertions.assertEquals( + Date.from(LocalDate.parse("2024-03-15").atStartOfDay(ZoneId.systemDefault()).toInstant()), + previousHospitalizations.get(0).getAdmissionDate()), + () -> Assertions.assertEquals(7, previousHospitalizations.get(0).getIcuLengthOfStay()), + + // Immunization / Vaccination + () -> Assertions.assertEquals(1, immunizations.size()), + () -> Assertions.assertEquals(ImmunizationStatus.ACQUIRED, immunizations.get(0).getImmunizationStatus()), + () -> Assertions.assertEquals(MeansOfImmunization.VACCINATION, immunizations.get(0).getMeansOfImmunization()), + () -> Assertions.assertEquals(1, immunizations.get(0).getVaccinations().size()), + () -> Assertions.assertEquals(Vaccine.COMIRNATY, immunizations.get(0).getVaccinations().get(0).getVaccineName()), + () -> Assertions.assertEquals("1", immunizations.get(0).getVaccinations().get(0).getVaccineDose()), + + // Case's vaccinationStatus is not set directly by the patch — it is only recomputed as a side effect + // of ImmunizationFacade/VaccinationFacade#save() calling CaseService#updateDeterminedVaccinationStatuses + () -> Assertions.assertEquals(VaccinationStatus.VACCINATED, actualCase.getVaccinationStatus()), + + // Person — proves saving Person cascades an update into the case as well + () -> Assertions.assertEquals(Sex.MALE, actualPerson.getSex()), + + // Symptoms + () -> Assertions.assertEquals(SymptomState.YES, actualCase.getSymptoms().getCough())); + } + @Test void patch_grouped_twoExposures() { // PREPARE diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageController.java index a18982f824d..1befde860f0 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageController.java @@ -160,7 +160,7 @@ public void showExternalMessage(String messageUuid, boolean withActions, Runnabl form.setValue(newDto); } - public void processSurveyResponse(String surveyResponseMessageUuid) { + public void processSurveyResponse(String surveyResponseMessageUuid, Runnable successRunnable) { ExternalMessageDto externalMessage = FacadeProvider.getExternalMessageFacade().getByUuid(surveyResponseMessageUuid); de.symeda.sormas.api.externalmessage.survey.ExternalMessageSurveyResponseResult result = @@ -168,6 +168,19 @@ public void processSurveyResponse(String surveyResponseMessageUuid) { ? externalMessage.getSurveyResponseData().getLatest().getResult() : null; + // In case of failure during operation, attempt to process the message again. + if (result == null) { + try { + result = FacadeProvider.getExternalMessageFacade() + .executeSurveyProcessing(surveyResponseMessageUuid) + .getSurveyResponseData() + .getLatest() + .getResult(); + } catch (RuntimeException e) { + Notification.show(I18nProperties.getString(Strings.messageSurveyResponseNotYetProcessed), Notification.Type.HUMANIZED_MESSAGE); + } + } + if (result == null) { Notification.show(I18nProperties.getString(Strings.messageSurveyResponseNotYetProcessed), Notification.Type.HUMANIZED_MESSAGE); return; @@ -189,6 +202,8 @@ public void processSurveyResponse(String surveyResponseMessageUuid) { UI.getCurrent().addWindow(editor); } else { Notification.show(I18nProperties.getString(Strings.messageSurveyResponseAllFieldsApplied), Notification.Type.HUMANIZED_MESSAGE); + + successRunnable.run(); } } @@ -607,4 +622,4 @@ private Consumer> bulkOperationCallback( } }; } -} \ No newline at end of file +} diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageGrid.java index 741049ecb6b..fa5a570c1b2 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageGrid.java @@ -226,7 +226,7 @@ private Component buildProcessComponent(ExternalMessageIndexDto indexDto) { } else if (ExternalMessageType.PHYSICIANS_REPORT == indexDto.getType()) { ControllerProvider.getExternalMessageController().processDoctorDeclarationMessage(indexDto.getUuid()); } else if (ExternalMessageType.SURVEY_RESPONSE == indexDto.getType()) { - ControllerProvider.getExternalMessageController().processSurveyResponse(indexDto.getUuid()); + ControllerProvider.getExternalMessageController().processSurveyResponse(indexDto.getUuid(), this::reload); } }, ValoTheme.BUTTON_PRIMARY); } else { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/surveyresponse/SurveyResponseDetailsWindow.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/surveyresponse/SurveyResponseDetailsWindow.java index 1adbf3ad37a..ac725fcb8e1 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/surveyresponse/SurveyResponseDetailsWindow.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/surveyresponse/SurveyResponseDetailsWindow.java @@ -21,14 +21,25 @@ import com.vaadin.server.ExternalResource; import com.vaadin.server.Sizeable; -import com.vaadin.ui.*; +import com.vaadin.ui.Button; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Label; +import com.vaadin.ui.Link; +import com.vaadin.ui.Notification; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; import de.symeda.sormas.api.DiseaseHelper; import de.symeda.sormas.api.FacadeProvider; import de.symeda.sormas.api.externalmessage.ExternalMessageDto; import de.symeda.sormas.api.externalmessage.ExternalMessageStatus; -import de.symeda.sormas.api.externalmessage.survey.*; +import de.symeda.sormas.api.externalmessage.survey.ExternalMessageSurveyResponseRequest; +import de.symeda.sormas.api.externalmessage.survey.ExternalMessageSurveyResponseResult; +import de.symeda.sormas.api.externalmessage.survey.ExternalMessageSurveyResponseWrapper; +import de.symeda.sormas.api.externalmessage.survey.PatchDictionary; +import de.symeda.sormas.api.externalmessage.survey.PatchField; import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.i18n.Strings; @@ -165,6 +176,15 @@ public SurveyResponseDetailsWindow(ExternalMessageDto externalMessage, Runnable layout.addComponent(dictionaryGrid); } + if (result == null) { + try { + externalMessage = FacadeProvider.getExternalMessageFacade().executeSurveyProcessing(uuid); + result = externalMessage.getSurveyResponseData().getLatest().getResult(); + } catch (RuntimeException e) { + Notification.show(I18nProperties.getString(Strings.messageSurveyResponseNotYetProcessed), Notification.Type.HUMANIZED_MESSAGE); + } + } + // --- Processing Result section --- if (result != null) { Label resultHeading = new Label(I18nProperties.getCaption(Captions.surveyResponseProcessingResult)); @@ -186,7 +206,7 @@ public SurveyResponseDetailsWindow(ExternalMessageDto externalMessage, Runnable I18nProperties.getCaption(Captions.surveyResponseApplied), patchResponse.isApplied() ? I18nProperties.getCaption(Captions.actionYes) : I18nProperties.getCaption(Captions.actionNo)); - if (patchResponse.hasFailures()) { + if (patchResponse.hasFailures() || externalMessage.getStatus() == ExternalMessageStatus.UNPROCESSED) { Label failuresHeading = new Label(I18nProperties.getString(Strings.headingSurveyResponseFailures)); CssStyles.style(failuresHeading, CssStyles.H4); layout.addComponent(failuresHeading);