diff --git a/src/main/java/de/medizininformatik_initiative/process/data_transfer/service/InsertData.java b/src/main/java/de/medizininformatik_initiative/process/data_transfer/service/InsertData.java index e8e41e7..ca28575 100644 --- a/src/main/java/de/medizininformatik_initiative/process/data_transfer/service/InsertData.java +++ b/src/main/java/de/medizininformatik_initiative/process/data_transfer/service/InsertData.java @@ -8,7 +8,9 @@ import org.camunda.bpm.engine.delegate.BpmnError; import org.camunda.bpm.engine.delegate.DelegateExecution; import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.DocumentReference; import org.hl7.fhir.r4.model.IdType; +import org.hl7.fhir.r4.model.Organization; import org.hl7.fhir.r4.model.Reference; import org.hl7.fhir.r4.model.ResourceType; import org.hl7.fhir.r4.model.Task; @@ -23,6 +25,7 @@ import de.medizininformatik_initiative.processes.common.util.DataSetStatusGenerator; import dev.dsf.bpe.v1.ProcessPluginApi; import dev.dsf.bpe.v1.activity.AbstractServiceDelegate; +import dev.dsf.bpe.v1.constants.NamingSystems; import dev.dsf.bpe.v1.variables.Variables; public class InsertData extends AbstractServiceDelegate implements InitializingBean @@ -66,7 +69,8 @@ protected void doExecute(DelegateExecution execution, Variables variables) try { - List createdIds = storeData(variables, fhirClient, bundle, sendingOrganization, projectIdentifier); + List createdIds = storeData(variables, fhirClient, bundle, sendingOrganization, projectIdentifier, + task); task.addOutput( statusGenerator.createDataSetStatusOutput(ConstantsBase.CODESYSTEM_DATA_SET_STATUS_VALUE_RECEIVE_OK, @@ -100,9 +104,11 @@ protected void doExecute(DelegateExecution execution, Variables variables) } private List storeData(Variables variables, FhirClient fhirClient, Bundle bundle, - String sendingOrganization, String projectIdentifier) + String sendingOrganization, String projectIdentifier, Task task) { - Bundle stored = fhirClient.executeTransaction(bundle); + Bundle transactionBundle = checkAndAdaptBundleForExistingData(fhirClient, bundle, sendingOrganization, + projectIdentifier, task); + Bundle stored = fhirClient.executeTransaction(transactionBundle); List idsOfCreatedResources = stored.getEntry().stream().filter(Bundle.BundleEntryComponent::hasResponse) .map(Bundle.BundleEntryComponent::getResponse).map(Bundle.BundleEntryResponseComponent::getLocation) @@ -116,6 +122,48 @@ private List storeData(Variables variables, FhirClient fhirClient, Bundl return idsOfCreatedResources; } + private Bundle checkAndAdaptBundleForExistingData(FhirClient fhirClient, Bundle bundle, String sendingOrganization, + String projectIdentifier, Task task) + { + Bundle searchResult = fhirClient.getGenericFhirClient().search().forResource(DocumentReference.class) + .where(DocumentReference.IDENTIFIER.exactly() + .systemAndCode(ConstantsBase.NAMINGSYSTEM_MII_PROJECT_IDENTIFIER, projectIdentifier)) + .and(DocumentReference.AUTHOR.hasChainedProperty(Organization.IDENTIFIER.exactly() + .systemAndCode(NamingSystems.OrganizationIdentifier.SID, sendingOrganization))) + .returnBundle(Bundle.class).execute(); + + List existingDocumentReferences = searchResult.getEntry().stream() + .filter(Bundle.BundleEntryComponent::hasResource).map(Bundle.BundleEntryComponent::getResource) + .filter(r -> r instanceof DocumentReference).map(r -> (DocumentReference) r).toList(); + + if (existingDocumentReferences.size() < 1) + return bundle; + + if (existingDocumentReferences.size() > 1) + logger.warn( + "Found more than one DocumentReference for project-identifier '{}' authored by '{}', using the first", + projectIdentifier, sendingOrganization); + + DocumentReference existingDocumentReference = existingDocumentReferences.get(0); + String existingDocumentReferenceId = existingDocumentReference.getIdElement().getIdPart(); + + logger.info( + "DocumentReference for project-identifier '{}' authored by '{}' already exists, updating data-set on FHIR server with baseUrl '{}' in Task with id '{}'", + projectIdentifier, sendingOrganization, fhirClient.getFhirBaseUrl(), task.getId()); + + bundle.getEntry().stream().filter(Bundle.BundleEntryComponent::hasResource) + .filter(e -> e.getResource() instanceof DocumentReference) + .filter(Bundle.BundleEntryComponent::hasRequest).filter(Bundle.BundleEntryComponent::hasResource) + .forEach(e -> + { + e.getRequest().setMethod(Bundle.HTTPVerb.PUT) + .setUrl(ResourceType.DocumentReference.name() + "/" + existingDocumentReferenceId); + e.getResource().setId(existingDocumentReferenceId); + }); + + return bundle; + } + private void sendMail(Task task, List createdIds, String sendingOrganization, String projectIdentifier) { String subject = "New data-set received in process '" + ConstantsDataTransfer.PROCESS_NAME_FULL_DATA_RECEIVE