Skip to content

Commit

Permalink
HL7 Patient Merge Messages : Optionally allow reversing merging of pa…
Browse files Browse the repository at this point in the history
…tient records if clients send duplicated ADT^A40 patient merge messages repeatedly, just reversing the patient identifier values in PID / MRG segments #4589
  • Loading branch information
vrindanayak committed Oct 23, 2024
1 parent e600188 commit 536f91f
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@

/**
* @author Gunter Zeilinger ([email protected])
* @author Vrinda Nayak <[email protected]>
* @since Apr 2020
*/
public enum HL7ReferredMergedPatientPolicy {
REJECT, IGNORE, IGNORE_DUPLICATE_MERGE
REJECT, IGNORE, IGNORE_DUPLICATE_MERGE, UNMERGE_DUPLICATED_REPEATED_MERGE
}
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ private static Patient changePIDOrMergePatient(
ArchiveHL7ApplicationExtension arcHL7App) throws HL7Exception {
UnparsedHL7Message msg = ctx.getUnparsedHL7Message();
try {
ctx.setHl7ReferredMergedPatientPolicy(arcHL7App.hl7ReferredMergedPatientPolicy());
return msg.msh().getMessageType().equals(CHANGE_PATIENT_IDENTIFIER)
? patientService.changePatientID(ctx)
: patientService.mergePatient(ctx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import org.dcm4che3.soundex.FuzzyStr;
import org.dcm4chee.arc.conf.ArchiveAEExtension;
import org.dcm4chee.arc.conf.AttributeFilter;
import org.dcm4chee.arc.conf.HL7ReferredMergedPatientPolicy;
import org.dcm4chee.arc.entity.Patient;
import org.dcm4chee.arc.keycloak.HttpServletRequestInfo;

Expand Down Expand Up @@ -138,4 +139,8 @@ public interface PatientMgtContext {
Connection getConnection();

Socket getSocket();

HL7ReferredMergedPatientPolicy getHl7ReferredMergedPatientPolicy();

void setHl7ReferredMergedPatientPolicy(HL7ReferredMergedPatientPolicy hl7ReferredMergedPatientPolicy);
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public class PatientMgtContextImpl implements PatientMgtContext {
private Collection<IDWithIssuer> previousPatientIDs;
private Attributes previousAttributes;
private Attributes.UpdatePolicy attributeUpdatePolicy = Attributes.UpdatePolicy.OVERWRITE;
private HL7ReferredMergedPatientPolicy hl7ReferredMergedPatientPolicy;
private String eventActionCode = AuditMessages.EventActionCode.Read;
private Exception exception;
private Patient patient;
Expand Down Expand Up @@ -329,4 +330,14 @@ public Connection getConnection() {
public Socket getSocket() {
return socket;
}

@Override
public HL7ReferredMergedPatientPolicy getHl7ReferredMergedPatientPolicy() {
return hl7ReferredMergedPatientPolicy;
}

@Override
public void setHl7ReferredMergedPatientPolicy(HL7ReferredMergedPatientPolicy hl7ReferredMergedPatientPolicy) {
this.hl7ReferredMergedPatientPolicy = hl7ReferredMergedPatientPolicy;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import org.dcm4chee.arc.conf.ArchiveDeviceExtension;
import org.dcm4chee.arc.conf.ArchiveHL7ApplicationExtension;
import org.dcm4chee.arc.conf.AttributeFilter;
import org.dcm4chee.arc.conf.HL7ReferredMergedPatientPolicy;
import org.dcm4chee.arc.entity.*;
import org.dcm4chee.arc.patient.*;
import org.hibernate.annotations.QueryHints;
Expand Down Expand Up @@ -148,6 +149,31 @@ private void logSuppressPatientCreate(PatientMgtContext ctx) {
LOG.info("{}: Suppress creation of Patient[id={}] by {}", ctx, ctx.getPatientIDs(), ctx.getUnparsedHL7Message().msh());
}

public Patient findPatient(Collection<IDWithIssuer> pids, Collection<IDWithIssuer> prev,
HL7ReferredMergedPatientPolicy hl7ReferredMergedPatientPolicy)
throws NonUniquePatientException, PatientMergedException {
Collection<Patient> list = findPatients(pids);
if (list.isEmpty())
return null;

if (list.size() > 1)
throw new NonUniquePatientException("Multiple Patients with ID " + pids);

Patient pat = list.iterator().next();
Patient mergedWith = pat.getMergedWith();
if (mergedWith != null) {
if (hl7ReferredMergedPatientPolicy != HL7ReferredMergedPatientPolicy.UNMERGE_DUPLICATED_REPEATED_MERGE
|| mergedWith.getPatientIDs().stream()
.map(PatientID::getIDWithIssuer)
.collect(Collectors.toList())
.stream()
.noneMatch(prev::contains))
throw new PatientMergedException("" + pat + " merged with " + mergedWith);
}

return pat;
}

public Patient findPatient(Collection<IDWithIssuer> pids)
throws NonUniquePatientException, PatientMergedException {
Collection<Patient> list = findPatients(pids);
Expand Down Expand Up @@ -276,7 +302,8 @@ private static IDWithIssuer removeByID(Collection<IDWithIssuer> newPatientIDs, S

public Patient mergePatient(PatientMgtContext ctx)
throws NonUniquePatientException, PatientMergedException {
Patient pat = findPatient(ctx.getPatientIDs());
HL7ReferredMergedPatientPolicy hl7ReferredMergedPatientPolicy = ctx.getHl7ReferredMergedPatientPolicy();
Patient pat = findPatient(ctx.getPatientIDs(), ctx.getPreviousPatientIDs(), hl7ReferredMergedPatientPolicy);
Patient prev = findPatient(ctx.getPreviousPatientIDs());
if (pat == null && prev == null && ctx.isNoPatientCreate()) {
logSuppressPatientCreate(ctx);
Expand All @@ -301,6 +328,8 @@ public Patient mergePatient(PatientMgtContext ctx)
ctx.setAttributes(pat.getAttributes());
ctx.setPreviousAttributes(prev.getAttributes());
}
if (hl7ReferredMergedPatientPolicy == HL7ReferredMergedPatientPolicy.UNMERGE_DUPLICATED_REPEATED_MERGE)
pat.setMergedWith(null);
prev.setMergedWith(pat);
return pat;
}
Expand Down

0 comments on commit 536f91f

Please sign in to comment.