Skip to content

Commit 101067d

Browse files
sergiupacurariuSergiuPacurariu
andauthored
#13211 - Update case when person's condition is set to "Dead" or "Bur… (#13249)
* #13211 - Update case when person's condition is set to "Dead" or "Buried" * #13211 - Update case when person's condition is set to "Dead" or "Buried" * #13211 - Update case when person's condition is set to "Dead" or "Buried" * #13211 - Update case when person's condition is set to "Dead" or "Buried" * #13205 - Add information about legal guardian for "minor / incapacitated" to person entity --------- Co-authored-by: SergiuPacurariu <sergiu.pacurariu@she.ro>
1 parent 47c42a6 commit 101067d

File tree

5 files changed

+143
-5
lines changed

5 files changed

+143
-5
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,7 @@ public interface Strings {
12041204
String messageCaseTransfered = "messageCaseTransfered";
12051205
String messageChangePathogenTestResult = "messageChangePathogenTestResult";
12061206
String messageChangingCaseOutcome = "messageChangingCaseOutcome";
1207+
String messageChangingPersonPresentCondition = "messageChangingPersonPresentCondition";
12071208
String messageCheckInputData = "messageCheckInputData";
12081209
String messageClinicalCourseSaved = "messageClinicalCourseSaved";
12091210
String messageClinicalVisitCreated = "messageClinicalVisitCreated";

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,6 +1575,7 @@ messageSyncUsersFromAuthProviderConfigurationError=Syncing users from authentica
15751575
messageCountriesExcludedFromDataProtection=Countries excluded from data protection for this field:
15761576
messageChangingCaseOutcome=Changing this information will also affect the associated person.
15771577
messageReviewChangesAndConfirm=Please review the changes and confirm them:
1578+
messageChangingPersonPresentCondition = Changing this information will also affect the associated cases.
15781579

15791580
# Notifications
15801581
notificationCaseClassificationChanged = The classification of case %s has changed to %s.

sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,12 @@ public Long getPersonIdByUuid(String uuid) {
330330
UserRight._PERSON_VIEW,
331331
UserRight._EXTERNAL_VISITS })
332332
public PersonDto getByUuid(String uuid) {
333-
return super.getByUuid(uuid);
333+
return Optional.of(uuid).map(u -> service.getByUuid(u, true)).map(person -> {
334+
// fixes some cases where EntityManager retrieves recently updated entities from cache instead of querying the database
335+
// e.g. after saving a case person the UI shows the original data
336+
em.refresh(person);
337+
return person;
338+
}).map(this::toPseudonymizedDto).orElse(null);
334339
}
335340

336341
@Override
@@ -1171,6 +1176,20 @@ public void onPersonChanged(PersonDto existingPerson, Person newPerson, boolean
11711176
caseFacade.onCaseChanged(existingCase, personCase, syncShares);
11721177
}
11731178

1179+
if (newPerson.getCauseOfDeathDisease() != null) {
1180+
List<Case> causeOfDeathDiseasePersonCases = personCases.stream()
1181+
.filter(caseDataDto -> caseDataDto.getDisease().equals(newPerson.getCauseOfDeathDisease()))
1182+
.collect(Collectors.toList());
1183+
if (!causeOfDeathDiseasePersonCases.isEmpty()) {
1184+
Case lastCase = Collections.max(causeOfDeathDiseasePersonCases, Comparator.comparing(Case::getReportDate));
1185+
lastCase.setOutcome(CaseOutcome.DECEASED);
1186+
lastCase.setOutcomeDate(newPerson.getDeathDate());
1187+
lastCase.setSequelae(null);
1188+
lastCase.setSequelaeDetails("");
1189+
caseService.ensurePersisted(lastCase);
1190+
}
1191+
}
1192+
11741193
List<Contact> personContacts = contactService.findBy(new ContactCriteria().setPerson(new PersonReferenceDto(newPerson.getUuid())), null);
11751194
// Call onContactChanged once for every contact
11761195
// Attention: this may lead to infinite recursion when not properly implemented

sormas-backend/src/test/java/de/symeda/sormas/backend/person/PersonFacadeEjbTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2350,4 +2350,9 @@ public void testIsSharedOrReceived() {
23502350

23512351
assertTrue(getPersonFacade().isSharedOrReceived(person.getUuid()));
23522352
}
2353+
2354+
@Test
2355+
public void testGetByUnknownUuid() {
2356+
assertNull(getPersonFacade().getByUuid("UNKNOWN_UUID"));
2357+
}
23532358
}

sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonController.java

Lines changed: 116 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
import java.util.ArrayList;
2121
import java.util.Arrays;
22+
import java.util.Collections;
23+
import java.util.Comparator;
2224
import java.util.Date;
2325
import java.util.List;
2426
import java.util.Map;
@@ -29,13 +31,16 @@
2931

3032
import org.apache.commons.lang3.StringUtils;
3133

34+
import com.vaadin.icons.VaadinIcons;
3235
import com.vaadin.navigator.Navigator;
3336
import com.vaadin.server.Page;
37+
import com.vaadin.server.Sizeable;
3438
import com.vaadin.server.Sizeable.Unit;
3539
import com.vaadin.shared.ui.ContentMode;
3640
import com.vaadin.ui.Alignment;
3741
import com.vaadin.ui.Button;
3842
import com.vaadin.ui.Grid;
43+
import com.vaadin.ui.HorizontalLayout;
3944
import com.vaadin.ui.Label;
4045
import com.vaadin.ui.Notification;
4146
import com.vaadin.ui.Notification.Type;
@@ -48,20 +53,24 @@
4853
import de.symeda.sormas.api.Disease;
4954
import de.symeda.sormas.api.FacadeProvider;
5055
import de.symeda.sormas.api.caze.CaseClassification;
56+
import de.symeda.sormas.api.caze.CaseDataDto;
57+
import de.symeda.sormas.api.caze.CaseOutcome;
5158
import de.symeda.sormas.api.event.EventParticipantSelectionDto;
5259
import de.symeda.sormas.api.event.EventReferenceDto;
5360
import de.symeda.sormas.api.externaljournal.ExternalJournalSyncResponseDto;
5461
import de.symeda.sormas.api.i18n.Captions;
5562
import de.symeda.sormas.api.i18n.I18nProperties;
5663
import de.symeda.sormas.api.i18n.Strings;
5764
import de.symeda.sormas.api.i18n.Validations;
65+
import de.symeda.sormas.api.person.CauseOfDeath;
5866
import de.symeda.sormas.api.person.PersonContext;
5967
import de.symeda.sormas.api.person.PersonCriteria;
6068
import de.symeda.sormas.api.person.PersonDto;
6169
import de.symeda.sormas.api.person.PersonFacade;
6270
import de.symeda.sormas.api.person.PersonHelper;
6371
import de.symeda.sormas.api.person.PersonIndexDto;
6472
import de.symeda.sormas.api.person.PersonReferenceDto;
73+
import de.symeda.sormas.api.person.PresentCondition;
6574
import de.symeda.sormas.api.person.SimilarPersonDto;
6675
import de.symeda.sormas.api.user.UserRight;
6776
import de.symeda.sormas.api.utils.DataHelper;
@@ -75,6 +84,8 @@
7584
import de.symeda.sormas.ui.utils.ButtonHelper;
7685
import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent;
7786
import de.symeda.sormas.ui.utils.ConfirmationComponent;
87+
import de.symeda.sormas.ui.utils.CssStyles;
88+
import de.symeda.sormas.ui.utils.DateFormatHelper;
7889
import de.symeda.sormas.ui.utils.VaadinUiUtil;
7990
import de.symeda.sormas.ui.utils.ViewMode;
8091
import de.symeda.sormas.ui.utils.components.page.title.TitleLayout;
@@ -418,7 +429,7 @@ public CommitDiscardWrapperComponent<PersonEditForm> getPersonEditComponent(Stri
418429
editView.addCommitListener(() -> {
419430
if (!editForm.getFieldGroup().isModified()) {
420431
PersonDto dto = editForm.getValue();
421-
savePerson(dto);
432+
savePersonWithPersonConditionChanged(dto);
422433
}
423434
});
424435

@@ -443,7 +454,7 @@ public CommitDiscardWrapperComponent<PersonEditForm> getPersonEditComponent(
443454
editView.addCommitListener(() -> {
444455
if (!editForm.getFieldGroup().isModified()) {
445456
PersonDto dto = editForm.getValue();
446-
savePerson(dto);
457+
savePersonWithPersonConditionChanged(dto);
447458
}
448459
});
449460

@@ -478,16 +489,117 @@ public CommitDiscardWrapperComponent<PersonEditForm> getPersonEditComponent(
478489
CommitDiscardWrapperComponent<PersonSelectionGrid> content =
479490
(CommitDiscardWrapperComponent<PersonSelectionGrid>) editView.getWrappedComponent().getWarningSimilarPersons().getContent();
480491
content.getDiscardButton().setVisible(true);
481-
content.addCommitListener(() -> savePerson(dto));
492+
content.addCommitListener(() -> savePersonWithPersonConditionChanged(dto));
482493
} else {
483-
savePerson(dto);
494+
savePersonWithPersonConditionChanged(dto);
484495
}
485496
}
486497
});
487498

488499
return editView;
489500
}
490501

502+
private void savePersonWithPersonConditionChanged(PersonDto editedPerson) {
503+
504+
CaseDataDto lastCase;
505+
if (editedPerson.getCauseOfDeathDisease() != null) {
506+
List<CaseDataDto> personCases = FacadeProvider.getCaseFacade()
507+
.getAllCasesOfPerson(editedPerson.getUuid())
508+
.stream()
509+
.filter(caseDataDto -> caseDataDto.getDisease().equals(editedPerson.getCauseOfDeathDisease()))
510+
.collect(Collectors.toList());
511+
lastCase = personCases.isEmpty() ? null : Collections.max(personCases, Comparator.comparing(CaseDataDto::getReportDate));
512+
} else {
513+
lastCase = null;
514+
}
515+
516+
PresentCondition editedPresentCondition = editedPerson.getPresentCondition();
517+
if (lastCase != null
518+
&& (Arrays.asList(PresentCondition.BURIED, PresentCondition.DEAD).contains(editedPresentCondition))
519+
&& editedPerson.getCauseOfDeath().equals(CauseOfDeath.EPIDEMIC_DISEASE)) {
520+
521+
PersonDto initialPerson = FacadeProvider.getPersonFacade().getByUuid(editedPerson.getUuid());
522+
PresentCondition initialPresentCondition = initialPerson.getPresentCondition();
523+
524+
if (Arrays.asList(PresentCondition.BURIED, PresentCondition.DEAD).contains(initialPresentCondition)
525+
&& lastCase.getOutcome().equals(CaseOutcome.DECEASED)
526+
&& ((editedPerson.getDeathDate() == null && lastCase.getOutcomeDate() == null)
527+
|| (editedPerson.getDeathDate() != null && editedPerson.getDeathDate().equals(lastCase.getOutcomeDate())))) {
528+
529+
savePerson(editedPerson);
530+
return;
531+
} else {
532+
VerticalLayout warningLayout = new VerticalLayout();
533+
warningLayout.setSpacing(false);
534+
CommitDiscardWrapperComponent<VerticalLayout> warningComponent = new CommitDiscardWrapperComponent<>(warningLayout);
535+
warningComponent.setWidth(100, Unit.PERCENTAGE);
536+
537+
Window popupWindow = VaadinUiUtil.showPopupWindow(warningComponent, I18nProperties.getString(Strings.warning));
538+
Label infoLabel = new Label(I18nProperties.getString(Strings.messageChangingPersonPresentCondition));
539+
CssStyles.style(infoLabel, CssStyles.LABEL_LARGE, CssStyles.LABEL_WHITE_SPACE_NORMAL);
540+
warningLayout.addComponent(infoLabel);
541+
542+
// case information
543+
warningLayout.addComponent(new Label(lastCase.buildCaption()));
544+
545+
// confirmation message
546+
Label confirmationMessage = new Label(I18nProperties.getString(Strings.messageReviewChangesAndConfirm));
547+
confirmationMessage.addStyleName(CssStyles.VSPACE_TOP_3);
548+
warningLayout.addComponent(confirmationMessage);
549+
550+
// changes listed
551+
HorizontalLayout changesLayout = new HorizontalLayout();
552+
changesLayout.setMargin(false);
553+
changesLayout.addStyleNames(CssStyles.VSPACE_TOP_1, CssStyles.VSPACE_2);
554+
555+
VerticalLayout fieldsLayout = new VerticalLayout();
556+
fieldsLayout.setMargin(false);
557+
Label fieldsLabel = new Label(I18nProperties.getCaption(Captions.confirmChangesField));
558+
fieldsLayout.addComponent(fieldsLabel);
559+
fieldsLabel.addStyleName(CssStyles.LABEL_SECONDARY);
560+
fieldsLayout.addComponent(new Label(I18nProperties.getPrefixCaption(CaseDataDto.I18N_PREFIX, CaseDataDto.OUTCOME)));
561+
fieldsLayout.addComponent(new Label(I18nProperties.getPrefixCaption(CaseDataDto.I18N_PREFIX, CaseDataDto.OUTCOME_DATE)));
562+
563+
VerticalLayout arrowsLayout = new VerticalLayout();
564+
arrowsLayout.setMargin(false);
565+
arrowsLayout.addComponent(new Label());
566+
arrowsLayout.addComponent(new Label(VaadinIcons.ARROW_RIGHT.getHtml(), ContentMode.HTML));
567+
arrowsLayout.addComponent(new Label(VaadinIcons.ARROW_RIGHT.getHtml(), ContentMode.HTML));
568+
569+
VerticalLayout valuesLayout = new VerticalLayout();
570+
valuesLayout.setMargin(false);
571+
572+
Label valuesLabel = new Label(I18nProperties.getCaption(Captions.confirmChangesValue));
573+
valuesLabel.addStyleName(CssStyles.LABEL_SECONDARY);
574+
valuesLayout.addComponent(valuesLabel);
575+
576+
valuesLayout.addComponent(new Label(CaseOutcome.DECEASED.toString()));
577+
valuesLayout.addComponent(new Label(DateFormatHelper.formatDate(editedPerson.getDeathDate())));
578+
579+
changesLayout.addComponent(fieldsLayout);
580+
changesLayout.addComponent(arrowsLayout);
581+
changesLayout.addComponent(valuesLayout);
582+
warningLayout.addComponent(changesLayout);
583+
584+
// actions
585+
warningComponent.addCommitListener(() -> {
586+
savePerson(editedPerson);
587+
popupWindow.close();
588+
});
589+
590+
warningComponent.addDiscardListener(() -> popupWindow.close());
591+
592+
// popup configuration
593+
popupWindow.addCloseListener(e -> popupWindow.close());
594+
popupWindow.setWidth(600, Sizeable.Unit.PIXELS);
595+
596+
return;
597+
}
598+
}
599+
600+
savePerson(editedPerson);
601+
}
602+
491603
private void savePerson(PersonDto personDto) {
492604
DataHelper.Pair<CaseClassification, PersonDto> saveResult = personFacade.savePersonWithoutNotifyingExternalJournal(personDto);
493605

0 commit comments

Comments
 (0)