use of de.symeda.sormas.api.sormastosormas.ShareTreeCriteria in project SORMAS-Project by hzi-braunschweig.
the class CaseFacadeEjb method onCaseChanged.
public void onCaseChanged(CaseDataDto existingCase, Case newCase, boolean syncShares) {
// If its a new case and the case is new and the geo coordinates of the case's
// health facility are null, set its coordinates to the case's report
// coordinates, if available. Else if case report coordinates are null set them
// to the facility's coordinates
Facility facility = newCase.getHealthFacility();
if (existingCase == null && facility != null && !FacilityHelper.isOtherOrNoneHealthFacility(facility.getUuid())) {
if ((facility.getLatitude() == null || facility.getLongitude() == null) && newCase.getReportLat() != null && newCase.getReportLon() != null) {
facility.setLatitude(newCase.getReportLat());
facility.setLongitude(newCase.getReportLon());
facilityService.ensurePersisted(facility);
} else if (newCase.getReportLat() == null && newCase.getReportLon() == null && newCase.getReportLatLonAccuracy() == null) {
newCase.setReportLat(facility.getLatitude());
newCase.setReportLon(facility.getLongitude());
}
}
// Clear facility type if no facility or home was selected
if (newCase.getHealthFacility() == null || FacilityDto.NONE_FACILITY_UUID.equals(newCase.getHealthFacility().getUuid())) {
newCase.setFacilityType(null);
}
// Generate epid number if missing or incomplete
FieldVisibilityCheckers fieldVisibilityCheckers = FieldVisibilityCheckers.withCountry(configFacade.getCountryLocale());
if (fieldVisibilityCheckers.isVisible(CaseDataDto.class, CaseDataDto.EPID_NUMBER) && !CaseLogic.isCompleteEpidNumber(newCase.getEpidNumber())) {
newCase.setEpidNumber(generateEpidNumber(newCase.getEpidNumber(), newCase.getUuid(), newCase.getDisease(), newCase.getReportDate(), newCase.getResponsibleDistrict().getUuid()));
}
// update the plague type based on symptoms
if (newCase.getDisease() == Disease.PLAGUE) {
PlagueType plagueType = DiseaseHelper.getPlagueTypeForSymptoms(SymptomsFacadeEjb.toDto(newCase.getSymptoms()));
if (plagueType != newCase.getPlagueType() && plagueType != null) {
newCase.setPlagueType(plagueType);
}
}
District survOffDistrict = newCase.getSurveillanceOfficer() != null ? newCase.getSurveillanceOfficer().getDistrict() : null;
if (survOffDistrict == null || (!survOffDistrict.equals(newCase.getResponsibleDistrict()) && !survOffDistrict.equals(newCase.getDistrict()))) {
setResponsibleSurveillanceOfficer(newCase);
}
updateInvestigationByStatus(existingCase, newCase);
updatePersonAndCaseByOutcome(existingCase, newCase);
updateCaseAge(existingCase, newCase);
// Change the disease of all contacts if the case disease or disease details have changed
if (existingCase != null && (newCase.getDisease() != existingCase.getDisease() || !StringUtils.equals(newCase.getDiseaseDetails(), existingCase.getDiseaseDetails()))) {
for (Contact contact : contactService.findBy(new ContactCriteria().caze(newCase.toReference()), null)) {
if (contact.getDisease() != newCase.getDisease() || !StringUtils.equals(contact.getDiseaseDetails(), newCase.getDiseaseDetails())) {
// Only do the change if it hasn't been done in the mobile app before
contact.setDisease(newCase.getDisease());
contact.setDiseaseDetails(newCase.getDiseaseDetails());
contactService.ensurePersisted(contact);
}
}
}
if (existingCase != null && (newCase.getDisease() != existingCase.getDisease() || !Objects.equals(newCase.getReportDate(), existingCase.getReportDate()) || !Objects.equals(newCase.getSymptoms().getOnsetDate(), existingCase.getSymptoms().getOnsetDate()))) {
// Update follow-up until and status of all contacts
for (Contact contact : contactService.findBy(new ContactCriteria().caze(newCase.toReference()), null)) {
contactService.updateFollowUpDetails(contact, false);
contactService.udpateContactStatus(contact);
}
for (Contact contact : contactService.getAllByResultingCase(newCase)) {
contactService.updateFollowUpDetails(contact, false);
contactService.udpateContactStatus(contact);
}
}
updateTasksOnCaseChanged(newCase, existingCase);
// Update case classification if the feature is enabled
CaseClassification classification = null;
if (configFacade.isFeatureAutomaticCaseClassification()) {
if (newCase.getCaseClassification() != CaseClassification.NO_CASE) {
// calculate classification
CaseDataDto newCaseDto = toDto(newCase);
classification = caseClassificationFacade.getClassification(newCaseDto);
// only update when classification by system changes - user may overwrite this
if (classification != newCase.getSystemCaseClassification()) {
newCase.setSystemCaseClassification(classification);
// really a change? (user may have already set it)
if (classification != newCase.getCaseClassification()) {
newCase.setCaseClassification(classification);
newCase.setClassificationUser(null);
newCase.setClassificationDate(new Date());
}
}
}
}
// calculate reference definition for cases
if (configFacade.isConfiguredCountry(CountryHelper.COUNTRY_CODE_GERMANY)) {
boolean fulfilled = evaluateFulfilledCondition(toDto(newCase), classification);
newCase.setCaseReferenceDefinition(fulfilled ? CaseReferenceDefinition.FULFILLED : CaseReferenceDefinition.NOT_FULFILLED);
}
// are not empty
if (!newCase.getHospitalization().getPreviousHospitalizations().isEmpty() && YesNoUnknown.YES != newCase.getHospitalization().getHospitalizedPreviously()) {
newCase.getHospitalization().setHospitalizedPreviously(YesNoUnknown.YES);
}
if (!newCase.getEpiData().getExposures().isEmpty() && !YesNoUnknown.YES.equals(newCase.getEpiData().getExposureDetailsKnown())) {
newCase.getEpiData().setExposureDetailsKnown(YesNoUnknown.YES);
}
// Update completeness value
newCase.setCompleteness(null);
// changed
if (existingCase != null && existingCase.getCaseClassification() != newCase.getCaseClassification()) {
try {
String message = String.format(I18nProperties.getString(MessageContents.CONTENT_CASE_CLASSIFICATION_CHANGED), DataHelper.getShortUuid(newCase.getUuid()), newCase.getCaseClassification().toString());
notificationService.sendNotifications(NotificationType.CASE_CLASSIFICATION_CHANGED, JurisdictionHelper.getCaseRegions(newCase), null, MessageSubject.CASE_CLASSIFICATION_CHANGED, message);
} catch (NotificationDeliveryFailedException e) {
logger.error("NotificationDeliveryFailedException when trying to notify supervisors about the change of a case classification. ");
}
}
// Unspecified VHF case has changed
if (existingCase != null && existingCase.getDisease() == Disease.UNSPECIFIED_VHF && existingCase.getDisease() != newCase.getDisease()) {
try {
String message = String.format(I18nProperties.getString(MessageContents.CONTENT_DISEASE_CHANGED), DataHelper.getShortUuid(newCase.getUuid()), existingCase.getDisease().toString(), newCase.getDisease().toString());
notificationService.sendNotifications(NotificationType.DISEASE_CHANGED, JurisdictionHelper.getCaseRegions(newCase), null, MessageSubject.DISEASE_CHANGED, message);
} catch (NotificationDeliveryFailedException e) {
logger.error("NotificationDeliveryFailedException when trying to notify supervisors about the change of a case disease.");
}
}
// If the case is a newly created case or if it was not in a CONFIRMED status
// and now the case is in a CONFIRMED status, notify related surveillance officers
Set<CaseClassification> confirmedClassifications = CaseClassification.getConfirmedClassifications();
if ((existingCase == null || !confirmedClassifications.contains(existingCase.getCaseClassification())) && confirmedClassifications.contains(newCase.getCaseClassification())) {
sendConfirmedCaseNotificationsForEvents(newCase);
}
if (existingCase != null && syncShares && sormasToSormasFacade.isFeatureConfigured()) {
syncSharesAsync(new ShareTreeCriteria(existingCase.getUuid()));
}
// This logic should be consistent with CaseDataForm.onQuarantineEndChange
if (existingCase != null && existingCase.getQuarantineTo() != null && !existingCase.getQuarantineTo().equals(newCase.getQuarantineTo())) {
newCase.setPreviousQuarantineTo(existingCase.getQuarantineTo());
}
if (existingCase == null) {
vaccinationFacade.updateVaccinationStatuses(newCase);
}
// On German systems, correct and clean up reinfection data
if (configFacade.isConfiguredCountry(CountryHelper.COUNTRY_CODE_GERMANY)) {
newCase.setReinfectionDetails(cleanUpReinfectionDetails(newCase.getReinfectionDetails()));
newCase.setReinfectionStatus(CaseLogic.calculateReinfectionStatus(newCase.getReinfectionDetails()));
}
}
use of de.symeda.sormas.api.sormastosormas.ShareTreeCriteria in project SORMAS-Project by hzi-braunschweig.
the class AbstractSormasToSormasInterface method getShareTrees.
@Override
public SormasToSormasEncryptedDataDto getShareTrees(SormasToSormasEncryptedDataDto encryptedCriteria) throws SormasToSormasException {
ShareTreeCriteria criteria = sormasToSormasEncryptionEjb.decryptAndVerify(encryptedCriteria, ShareTreeCriteria.class);
List<SormasToSormasShareTree> shares = getShareTrees(criteria, false);
return sormasToSormasEncryptionEjb.signAndEncrypt(shares, encryptedCriteria.getSenderId());
}
use of de.symeda.sormas.api.sormastosormas.ShareTreeCriteria in project SORMAS-Project by hzi-braunschweig.
the class AbstractSormasToSormasInterface method walkShareTree.
private void walkShareTree(ShareTreeCriteria criteria, WalkParent<ADO> walkParent, WalkReShare<ADO> walkReShare) {
ADO entity = getEntityService().getByUuid(criteria.getEntityUuid());
if (entity == null) {
return;
}
SormasToSormasOriginInfo originInfo = entity.getSormasToSormasOriginInfo();
List<SormasToSormasShareInfo> entityShares = entity.getSormasToSormasShares();
if (!criteria.isForwardOnly() && originInfo != null && !originInfo.getOrganizationId().equals(criteria.getExceptedOrganizationId())) {
SormasToSormasShareRequest shareRequest = originInfo.getRequest();
String ownOrganizationId = configFacadeEjb.getS2SConfig().getId();
if (shareRequest == null || shareRequest.getStatus() == ShareRequestStatus.ACCEPTED) {
walkParent.walk(entity, originInfo, new ShareTreeCriteria(criteria.getEntityUuid(), ownOrganizationId, false));
}
}
for (SormasToSormasShareInfo s : entityShares) {
boolean notAccepted = s.getRequests().stream().noneMatch(r -> r.getRequestStatus() == ShareRequestStatus.ACCEPTED);
boolean noForward = notAccepted || s.getOrganizationId().equals(criteria.getExceptedOrganizationId());
if (originInfo != null) {
noForward = noForward || s.getOrganizationId().equals(originInfo.getOrganizationId());
}
walkReShare.walk(entity, s, new ShareTreeCriteria(criteria.getEntityUuid(), criteria.getExceptedOrganizationId(), true), noForward);
}
}
use of de.symeda.sormas.api.sormastosormas.ShareTreeCriteria in project SORMAS-Project by hzi-braunschweig.
the class SormasToSormasEventFacadeEjbTest method testSyncEvent.
@Test
public void testSyncEvent() throws SormasToSormasException {
useSurveillanceOfficerLogin(rdcf);
UserReferenceDto officer = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference();
EventDto event = creator.createEvent(EventStatus.SCREENING, EventInvestigationStatus.ONGOING, "Test event title", "Test description", officer, e -> {
e.getEventLocation().setRegion(rdcf.region);
e.getEventLocation().setDistrict(rdcf.district);
SormasToSormasOriginInfoDto originInfo = new SormasToSormasOriginInfoDto();
originInfo.setSenderName("Test Name");
originInfo.setSenderEmail("test@email.com");
originInfo.setOrganizationId(DEFAULT_SERVER_ID);
originInfo.setOwnershipHandedOver(true);
originInfo.setWithEventParticipants(true);
e.setSormasToSormasOriginInfo(originInfo);
});
PersonDto person = creator.createPerson();
EventParticipantDto eventParticipant = creator.createEventParticipant(event.toReference(), person, "Involved", officer, ep -> {
SormasToSormasOriginInfoDto originInfo = new SormasToSormasOriginInfoDto();
originInfo.setSenderName("Test Name");
originInfo.setSenderEmail("test@email.com");
originInfo.setOrganizationId(DEFAULT_SERVER_ID);
originInfo.setOwnershipHandedOver(true);
originInfo.setWithEventParticipants(true);
ep.setSormasToSormasOriginInfo(originInfo);
}, null);
ShareRequestInfo shareRequestInfo = createShareRequestInfo(getUserService().getByUuid(officer.getUuid()), SECOND_SERVER_ID, false, ShareRequestStatus.ACCEPTED, i -> i.setEvent(getEventService().getByUuid(event.getUuid())));
shareRequestInfo.setWithEventParticipants(true);
shareRequestInfo.getShares().add(createShareInfo(SECOND_SERVER_ID, false, i -> i.setEventParticipant(getEventParticipantService().getByUuid(eventParticipant.getUuid()))));
getShareRequestInfoService().persist(shareRequestInfo);
EventParticipantDto newEventParticipant = creator.createEventParticipant(event.toReference(), person, "Involved", officer);
Mockito.when(MockProducer.getSormasToSormasClient().post(eq(DEFAULT_SERVER_ID), ArgumentMatchers.contains("/events/sync"), ArgumentMatchers.any(), ArgumentMatchers.any())).then(invocation -> {
SyncDataDto syncData = invocation.getArgument(2);
assertThat(syncData.getCriteria().getEntityUuid(), is(event.getUuid()));
assertThat(syncData.getCriteria().getExceptedOrganizationId(), is(DEFAULT_SERVER_ID));
assertThat(syncData.getCriteria().isForwardOnly(), is(false));
assertThat(syncData.getShareData().getEvents().get(0).getEntity().getUuid(), is(event.getUuid()));
// new event participant should not be shared
assertThat(syncData.getShareData().getEventParticipants(), hasSize(1));
return Response.noContent().build();
});
Mockito.when(MockProducer.getSormasToSormasClient().post(eq(SECOND_SERVER_ID), ArgumentMatchers.contains("/events/sync"), ArgumentMatchers.any(), ArgumentMatchers.any())).then(invocation -> {
SyncDataDto syncData = invocation.getArgument(2);
assertThat(syncData.getCriteria().getEntityUuid(), is(event.getUuid()));
assertThat(syncData.getCriteria().getExceptedOrganizationId(), is(nullValue()));
assertThat(syncData.getCriteria().isForwardOnly(), is(true));
assertThat(syncData.getShareData().getEvents().get(0).getEntity().getUuid(), is(event.getUuid()));
// the new event participant should not be shared
assertThat(syncData.getShareData().getEventParticipants(), hasSize(1));
assertThat(syncData.getShareData().getEventParticipants().get(0).getEntity().getUuid(), is(eventParticipant.getUuid()));
return Response.noContent().build();
});
getSormasToSormasEventFacade().syncShares(new ShareTreeCriteria(event.getUuid(), null, false));
// new event participant should have share info with ownership handed over
List<SormasToSormasShareInfoDto> newEventParticipantShareInfoList = getSormasToSormasShareInfoFacade().getIndexList(new SormasToSormasShareInfoCriteria().eventParticipant(newEventParticipant.toReference()), 0, 100);
assertThat(newEventParticipantShareInfoList, hasSize(0));
}
use of de.symeda.sormas.api.sormastosormas.ShareTreeCriteria in project SORMAS-Project by hzi-braunschweig.
the class SormasToSormasCaseFacadeEjbTest method testGetReShares.
@Test
public void testGetReShares() throws SormasToSormasException {
useSurveillanceOfficerLogin(rdcf);
UserReferenceDto officer = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference();
CaseDataDto caze = creator.createCase(officer, creator.createPerson().toReference(), rdcf);
User officerUser = getUserService().getByReferenceDto(officer);
ShareRequestInfo shareRequestInfo = createShareRequestInfo(officerUser, SECOND_SERVER_ID, true, ShareRequestStatus.ACCEPTED, i -> i.setCaze(getCaseService().getByReferenceDto(caze.toReference())));
getShareRequestInfoService().persist(shareRequestInfo);
Mockito.when(MockProducer.getSormasToSormasClient().post(eq(SECOND_SERVER_ID), eq("/sormasToSormas/cases/shares"), ArgumentMatchers.any(), ArgumentMatchers.any())).thenAnswer(invocation -> {
SormasToSormasShareInfoDto shareInfo = new SormasToSormasShareInfoDto();
shareInfo.setTargetDescriptor(new SormasServerDescriptor("dummy SORMAS"));
shareInfo.setOwnershipHandedOver(false);
shareInfo.setComment("re-shared");
return encryptShareDataAsArray(new SormasToSormasShareTree(null, shareInfo, Collections.emptyList(), false));
});
Mockito.when(MockProducer.getSormasToSormasClient().post(eq("dummy SORMAS"), eq("/sormasToSormas/cases/shares"), ArgumentMatchers.any(), ArgumentMatchers.any())).thenAnswer(invocation -> encryptShareData(Collections.emptyList()));
mockS2Snetwork();
SormasToSormasEncryptedDataDto encryptedCriteria = encryptShareData(new ShareTreeCriteria(caze.getUuid(), null, false));
SormasToSormasEncryptedDataDto encryptedShares = getSormasToSormasCaseFacade().getShareTrees(encryptedCriteria);
mockDefaultServerAccess();
SormasToSormasShareTree[] shares = getSormasToSormasEncryptionFacade().decryptAndVerify(new SormasToSormasEncryptedDataDto(SECOND_SERVER_ID, encryptedShares.getData()), SormasToSormasShareTree[].class);
assertThat(shares, arrayWithSize(1));
assertThat(shares[0].getShare().getTargetDescriptor().getId(), is(SECOND_SERVER_ID));
assertThat(shares[0].getShare().isOwnershipHandedOver(), is(true));
assertThat(shares[0].getReShares().get(0).getShare().getTargetDescriptor().getId(), is("dummy SORMAS"));
assertThat(shares[0].getReShares().get(0).getShare().isOwnershipHandedOver(), is(false));
assertThat(shares[0].getReShares().get(0).getReShares(), hasSize(0));
}
Aggregations