diff --git a/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/dao/EmpiLinkDaoSvc.java b/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/dao/EmpiLinkDaoSvc.java index 13dd6060c79..4e3d242bdbe 100644 --- a/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/dao/EmpiLinkDaoSvc.java +++ b/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/dao/EmpiLinkDaoSvc.java @@ -29,6 +29,8 @@ import ca.uhn.fhir.empi.model.EmpiTransactionContext; import ca.uhn.fhir.jpa.dao.data.IEmpiLinkDao; import ca.uhn.fhir.jpa.dao.index.IdHelperService; import ca.uhn.fhir.jpa.entity.EmpiLink; +import ca.uhn.fhir.jpa.model.entity.ResourceTable; +import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IBaseResource; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; @@ -308,6 +310,26 @@ public class EmpiLinkDaoSvc { return myEmpiLinkDao.findAll(example); } + + /** + * Finds all {@link EmpiLink} entities in which theSourceResource's PID is the source + * of the relationship. + * + * @param theSourceResource the source resource to find links for. + * + * @return all links for the source. + */ + public List findEmpiMatchLinksBySource(IBaseResource theSourceResource) { + Long pid = myIdHelperService.getPidOrNull(theSourceResource); + if (pid == null) { + return Collections.emptyList(); + } + EmpiLink exampleLink = myEmpiLinkFactory.newEmpiLink().setSourceResourcePid(pid); + exampleLink.setMatchResult(EmpiMatchResultEnum.MATCH); + Example example = Example.of(exampleLink); + return myEmpiLinkDao.findAll(example); + } + /** * Factory delegation method, whenever you need a new EmpiLink, use this factory method. * //TODO Should we make the constructor private for EmpiLink? or work out some way to ensure they can only be instantiated via factory. diff --git a/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/svc/EmpiEidUpdateService.java b/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/svc/EmpiEidUpdateService.java index 02baf5dd3b0..e1eea4514fb 100644 --- a/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/svc/EmpiEidUpdateService.java +++ b/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/svc/EmpiEidUpdateService.java @@ -71,14 +71,14 @@ public class EmpiEidUpdateService { // myPersonHelper.updatePersonFromUpdatedEmpiTarget(updateContext.getMatchedPerson(), theResource, theEmpiTransactionContext); if (!updateContext.isIncomingResourceHasAnEid() || updateContext.isHasEidsInCommon()) { //update to patient that uses internal EIDs only. - myEmpiLinkSvc.updateLink(updateContext.getMatchedPerson(), theResource, theMatchedSourceResourceCandidate.getMatchResult(), EmpiLinkSourceEnum.AUTO, theEmpiTransactionContext); + myEmpiLinkSvc.updateLink(updateContext.getMatchedSourceResource(), theResource, theMatchedSourceResourceCandidate.getMatchResult(), EmpiLinkSourceEnum.AUTO, theEmpiTransactionContext); } else if (!updateContext.isHasEidsInCommon()) { handleNoEidsInCommon(theResource, theMatchedSourceResourceCandidate, theEmpiTransactionContext, updateContext); } } else { //This is a new linking scenario. we have to break the existing link and link to the new person. For now, we create duplicate. //updated patient has an EID that matches to a new candidate. Link them, and set the persons possible duplicates - linkToNewPersonAndFlagAsDuplicate(theResource, updateContext.getExistingPerson(), updateContext.getMatchedPerson(), theEmpiTransactionContext); + linkToNewPersonAndFlagAsDuplicate(theResource, updateContext.getExistingPerson(), updateContext.getMatchedSourceResource(), theEmpiTransactionContext); } } @@ -86,15 +86,16 @@ public class EmpiEidUpdateService { // the user is simply updating their EID. We propagate this change to the Person. //overwrite. No EIDS in common, but still same person. if (myEmpiSettings.isPreventMultipleEids()) { - if (myPersonHelper.getLinkCount(theUpdateContext.getMatchedPerson()) <= 1) { // If there is only 0/1 link on the person, we can safely overwrite the EID. - handleExternalEidOverwrite(theUpdateContext.getMatchedPerson(), theResource, theEmpiTransactionContext); + if (myEmpiLinkDaoSvc.findEmpiMatchLinksBySource(theUpdateContext.getMatchedSourceResource()).size() <= 1) { // If there is only 0/1 link on the person, we can safely overwrite the EID. + // if (myPersonHelper.getLinkCount(theUpdateContext.getMatchedSourceResource()) <= 1) { // If there is only 0/1 link on the person, we can safely overwrite the EID. + handleExternalEidOverwrite(theUpdateContext.getMatchedSourceResource(), theResource, theEmpiTransactionContext); } else { // If the person has multiple patients tied to it, we can't just overwrite the EID, so we split the person. createNewPersonAndFlagAsDuplicate(theResource, theEmpiTransactionContext, theUpdateContext.getExistingPerson()); } } else { - myPersonHelper.handleExternalEidAddition(theUpdateContext.getMatchedPerson(), theResource, theEmpiTransactionContext); + myPersonHelper.handleExternalEidAddition(theUpdateContext.getMatchedSourceResource(), theResource, theEmpiTransactionContext); } - myEmpiLinkSvc.updateLink(theUpdateContext.getMatchedPerson(), theResource, theMatchedSourceResourceCandidate.getMatchResult(), EmpiLinkSourceEnum.AUTO, theEmpiTransactionContext); + myEmpiLinkSvc.updateLink(theUpdateContext.getMatchedSourceResource(), theResource, theMatchedSourceResourceCandidate.getMatchResult(), EmpiLinkSourceEnum.AUTO, theEmpiTransactionContext); } private void handleExternalEidOverwrite(IAnyResource thePerson, IAnyResource theResource, EmpiTransactionContext theEmpiTransactionContext) { @@ -138,17 +139,17 @@ public class EmpiEidUpdateService { private IAnyResource myExistingPerson; private boolean myRemainsMatchedToSamePerson; - public IAnyResource getMatchedPerson() { - return myMatchedPerson; + public IAnyResource getMatchedSourceResource() { + return myMatchedSourceResource; } - private final IAnyResource myMatchedPerson; + private final IAnyResource myMatchedSourceResource; EmpiUpdateContext(MatchedSourceResourceCandidate theMatchedSourceResourceCandidate, IAnyResource theResource) { final String resourceType = theResource.getIdElement().getResourceType(); - myMatchedPerson = myEmpiSourceResourceFindingSvc.getSourceResourceFromMatchedSourceResourceCandidate(theMatchedSourceResourceCandidate, resourceType); + myMatchedSourceResource = myEmpiSourceResourceFindingSvc.getSourceResourceFromMatchedSourceResourceCandidate(theMatchedSourceResourceCandidate, resourceType); - myHasEidsInCommon = myEIDHelper.hasEidOverlap(myMatchedPerson, theResource); + myHasEidsInCommon = myEIDHelper.hasEidOverlap(myMatchedSourceResource, theResource); myIncomingResourceHasAnEid = !myEIDHelper.getExternalEid(theResource).isEmpty(); Optional theExistingMatchLink = myEmpiLinkDaoSvc.getMatchedLinkForTarget(theResource); diff --git a/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/svc/EmpiLinkSvcImpl.java b/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/svc/EmpiLinkSvcImpl.java index 61a558a3852..ba64c13845b 100644 --- a/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/svc/EmpiLinkSvcImpl.java +++ b/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/svc/EmpiLinkSvcImpl.java @@ -105,7 +105,8 @@ public class EmpiLinkSvcImpl implements IEmpiLinkSvc { @Override @Transactional public void syncEmpiLinksToPersonLinks(IAnyResource thePersonResource, EmpiTransactionContext theEmpiTransactionContext) { - int origLinkCount = myPersonHelper.getLinkCount(thePersonResource); + // int origLinkCount = myPersonHelper.getLinkCount(thePersonResource); + int origLinkCount = myEmpiLinkDaoSvc.findEmpiMatchLinksBySource(thePersonResource).size(); List empiLinks = myEmpiLinkDaoSvc.findEmpiLinksByPerson(thePersonResource); diff --git a/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/svc/EmpiResourceDaoSvc.java b/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/svc/EmpiResourceDaoSvc.java index a1cf801ff0e..a9e6fbe747e 100644 --- a/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/svc/EmpiResourceDaoSvc.java +++ b/hapi-fhir-jpaserver-empi/src/main/java/ca/uhn/fhir/jpa/empi/svc/EmpiResourceDaoSvc.java @@ -73,8 +73,8 @@ public class EmpiResourceDaoSvc { map.setLoadSynchronous(true); map.add("identifier", new TokenParam(myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem(), theEid)); // TODO NG - During person dedup do we set this to false? We might be setting a person to inactive... - // map.add("active", new TokenParam("true")); - map.add("_tag", new TokenParam(EmpiConstants.SYSTEM_EMPI_MANAGED, EmpiConstants.CODE_HAPI_EMPI_MANAGED)); + map.add("active", new TokenParam("true")); +// map.add("_tag", new TokenParam(EmpiConstants.SYSTEM_EMPI_MANAGED, EmpiConstants.CODE_HAPI_EMPI_MANAGED)); IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao(theResourceType); IBundleProvider search = resourceDao.search(map); diff --git a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/matcher/IsSameSourceResourceAs.java b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/matcher/IsSameSourceResourceAs.java index 0ccf79c55a7..8c21ef2da83 100644 --- a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/matcher/IsSameSourceResourceAs.java +++ b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/matcher/IsSameSourceResourceAs.java @@ -24,7 +24,7 @@ public class IsSameSourceResourceAs extends BaseSourceResourceMatcher { sourceResourcePidsToMatch = myBaseResources.stream().map(this::getMatchedResourcePidFromResource).collect(Collectors.toList()); boolean allToCheckAreSame = sourceResourcePidsToMatch.stream().allMatch(pid -> pid.equals(sourceResourcePidsToMatch.get(0))); if (!allToCheckAreSame) { - throw new IllegalStateException("You wanted to do a source resource comparison, but the pool of persons you submitted for checking don't match! We won't even check the incoming person against them."); + throw new IllegalStateException("You wanted to do a source resource comparison, but the pool of source resources you submitted for checking don't match! We won't even check the incoming source resource against them."); } return sourceResourcePidsToMatch.contains(incomingSourceResourcePid); } diff --git a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/svc/EmpiMatchLinkSvcTest.java b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/svc/EmpiMatchLinkSvcTest.java index 1762351429b..455998511d0 100644 --- a/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/svc/EmpiMatchLinkSvcTest.java +++ b/hapi-fhir-jpaserver-empi/src/test/java/ca/uhn/fhir/jpa/empi/svc/EmpiMatchLinkSvcTest.java @@ -41,14 +41,15 @@ import static org.junit.jupiter.api.Assertions.*; import static org.slf4j.LoggerFactory.getLogger; public class EmpiMatchLinkSvcTest extends BaseEmpiR4Test { + private static final Logger ourLog = getLogger(EmpiMatchLinkSvcTest.class); + @Autowired IEmpiLinkSvc myEmpiLinkSvc; @Autowired private EIDHelper myEidHelper; @Autowired private PersonHelper myPersonHelper; - @Autowired private EmpiResourceDaoSvc myEmpiResourceDaoSvc; // TODO NG - remove? @@ -117,19 +118,26 @@ public class EmpiMatchLinkSvcTest extends BaseEmpiR4Test { @Test public void testWhenPOSSIBLE_MATCHOccursOnPersonThatHasBeenManuallyNOMATCHedThatItIsBlocked() { Patient originalJane = createPatientAndUpdateLinks(buildJanePatient()); - IBundleProvider search = myPersonDao.search(new SearchParameterMap()); + + IBundleProvider search = myPatientDao.search(new SearchParameterMap()); IAnyResource janePerson = (IAnyResource) search.getResources(0, 1).get(0); Patient unmatchedPatient = createPatient(buildJanePatient()); //This simulates an admin specifically saying that unmatchedPatient does NOT match janePerson. myEmpiLinkSvc.updateLink(janePerson, unmatchedPatient, EmpiMatchOutcome.NO_MATCH, EmpiLinkSourceEnum.MANUAL, createContextForCreate("Patient")); - //TODO change this so that it will only partially match. + // TODO change this so that it will only partially match. //Now normally, when we run update links, it should link to janePerson. However, this manual NO_MATCH link //should cause a whole new Person to be created. myEmpiMatchLinkSvc.updateEmpiLinksForEmpiTarget(unmatchedPatient, createContextForCreate("Patient")); + System.out.println("Unmatched Patient"); + print(unmatchedPatient); + + System.out.println("Jane"); + print(janePerson); + assertThat(unmatchedPatient, is(not(sameSourceResourceAs(janePerson)))); assertThat(unmatchedPatient, is(not(linkedTo(originalJane)))); @@ -225,35 +233,9 @@ public class EmpiMatchLinkSvcTest extends BaseEmpiR4Test { Patient patient1 = addExternalEID(buildJanePatient(), "uniqueid"); createPatientAndUpdateLinks(patient1); - { - // state is now > Patient/ID.JANE.123[name=jane & EID = uniqueid] <-- EMPI Link -- Patient/[name=jane & EDI = uniqueid & EMPI_MANAGED = true] - IBundleProvider bundle = myPatientDao.search(new SearchParameterMap()); - List resources = bundle.getResources(0, bundle.size()); - resources.forEach(r -> { - print(r); - assertFalse(myEidHelper.getExternalEid(r).isEmpty()); - }); - assertEquals(2, resources.size()); - - IBaseResource testPatient1 = resources.get(0); - IBaseResource testPatient2 = resources.get(1); - - assertThat((Patient) testPatient1, is(sameSourceResourceAs((Patient) testPatient2))); - - Optional empiLinkByTarget = myEmpiLinkDaoSvc.findEmpiLinkByTarget(patient1); - assertTrue(empiLinkByTarget.isPresent()); - System.out.println(empiLinkByTarget.get()); - } Patient patient2 = buildPaulPatient(); - patient2.setActive(true); patient2 = addExternalEID(patient2, "uniqueid"); createPatientAndUpdateLinks(patient2); - // state should be > Patient/ID.JANE.123[name=jane & EID = uniqueid] <--> Patient/[name=jane & EDI = uniqueid] <--> Patient/[name=paul & EDI = uniqueid] - IBundleProvider search = myPatientDao.search(new SearchParameterMap()); - search.getResources(0, search.size()).forEach( r -> { - print(r); - } - ); assertThat(patient1, is(sameSourceResourceAs(patient2))); } @@ -552,8 +534,8 @@ public class EmpiMatchLinkSvcTest extends BaseEmpiR4Test { } @Test - //Test Case #2 public void testSinglyLinkedPersonThatGetsAnUpdatedEidSimplyUpdatesEID() { + //Use Case # 2 String EID_1 = "123"; String EID_2 = "456"; @@ -568,7 +550,12 @@ public class EmpiMatchLinkSvcTest extends BaseEmpiR4Test { clearExternalEIDs(paul); addExternalEID(paul, EID_2); + System.out.println("Paul Before"); + print(paul); + Patient pailTemp = paul; paul = updatePatientAndUpdateLinks(paul); + System.out.println("Paul After"); + print(pailTemp); assertNoDuplicates(); diff --git a/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/api/IEmpiLinkSvc.java b/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/api/IEmpiLinkSvc.java index 15c1c621f22..3b11fcd23cb 100644 --- a/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/api/IEmpiLinkSvc.java +++ b/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/api/IEmpiLinkSvc.java @@ -48,5 +48,4 @@ public interface IEmpiLinkSvc { * @param theResource */ void deleteLink(IAnyResource theExistingPerson, IAnyResource theResource, EmpiTransactionContext theEmpiTransactionContext); - } diff --git a/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/util/PersonHelper.java b/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/util/PersonHelper.java index 503ae43aa73..18775bdc1e1 100644 --- a/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/util/PersonHelper.java +++ b/hapi-fhir-server-empi/src/main/java/ca/uhn/fhir/empi/util/PersonHelper.java @@ -32,6 +32,7 @@ import ca.uhn.fhir.empi.model.CanonicalEID; import ca.uhn.fhir.empi.model.CanonicalIdentityAssuranceLevel; import ca.uhn.fhir.empi.model.EmpiTransactionContext; import ca.uhn.fhir.fhirpath.IFhirPath; +import ca.uhn.fhir.model.primitive.BooleanDt; import ca.uhn.fhir.util.FhirTerser; import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.instance.model.api.IAnyResource; @@ -43,6 +44,7 @@ import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.hl7.fhir.r4.model.Address; +import org.hl7.fhir.r4.model.BooleanType; import org.hl7.fhir.r4.model.ContactPoint; import org.hl7.fhir.r4.model.HumanName; import org.hl7.fhir.r4.model.Identifier; @@ -243,9 +245,20 @@ public class PersonHelper { populateMetaTag(newSourceResource); + setActive(newSourceResource, resourceDefinition); + return (T) newSourceResource; } + private void setActive(IBaseResource theNewSourceResource, RuntimeResourceDefinition theResourceDefinition) { + BaseRuntimeChildDefinition activeChildDefinition = theResourceDefinition.getChildByName("active"); + if (activeChildDefinition == null) { + ourLog.warn(String.format("Unable to set active flag on the provided source resource %s.", theNewSourceResource)); + return; + } + activeChildDefinition.getMutator().setValue(theNewSourceResource, toBooleanType(true)); + } + /** * If there are no external EIDs on the incoming resource, create a new HAPI EID on the new SourceResource. */ @@ -262,19 +275,19 @@ public class PersonHelper { /** * Given an Child Definition of `identifier`, a R4/DSTU3 EID Identifier, and a new resource, clone the EID into that resources' identifier list. */ - private void cloneExternalEidIntoNewSourceResource(BaseRuntimeChildDefinition sourceResourceIdentifier, IBase theEid, IBase newSourceResource) { + private void cloneExternalEidIntoNewSourceResource(BaseRuntimeChildDefinition theSourceResourceIdentifier, IBase theEid, IBase theNewSourceResource) { // FHIR choice types - fields within fhir where we have a choice of ids - BaseRuntimeElementCompositeDefinition childIdentifier = (BaseRuntimeElementCompositeDefinition) sourceResourceIdentifier.getChildByName("identifier"); + BaseRuntimeElementCompositeDefinition childIdentifier = (BaseRuntimeElementCompositeDefinition) theSourceResourceIdentifier.getChildByName("identifier"); FhirTerser terser = myFhirContext.newTerser(); IBase sourceResourceNewIdentifier = childIdentifier.newInstance(); terser.cloneInto(theEid, sourceResourceNewIdentifier, true); - sourceResourceIdentifier.getMutator().addValue(newSourceResource, sourceResourceNewIdentifier); + theSourceResourceIdentifier.getMutator().addValue(theNewSourceResource, sourceResourceNewIdentifier); } - private void cloneAllExternalEidsIntoNewSourceResource(BaseRuntimeChildDefinition sourceResourceIdentifier, IBase theSourceResource, IBase newSourceResource) { + private void cloneAllExternalEidsIntoNewSourceResource(BaseRuntimeChildDefinition theSourceResourceIdentifier, IBase theSourceResource, IBase theNewSourceResource) { // FHIR choice types - fields within fhir where we have a choice of ids IFhirPath fhirPath = myFhirContext.newFhirPath(); - List sourceResourceIdentifiers = sourceResourceIdentifier.getAccessor().getValues(theSourceResource); + List sourceResourceIdentifiers = theSourceResourceIdentifier.getAccessor().getValues(theSourceResource); for (IBase base : sourceResourceIdentifiers) { Optional system = fhirPath.evaluateFirst(base, "system", IPrimitiveType.class); @@ -282,8 +295,8 @@ public class PersonHelper { String empiSystem = myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem(); String baseSystem = system.get().getValueAsString(); if (Objects.equals(baseSystem, empiSystem)) { - cloneExternalEidIntoNewSourceResource(sourceResourceIdentifier, base, newSourceResource); - } else { + cloneExternalEidIntoNewSourceResource(theSourceResourceIdentifier, base, theNewSourceResource); + } else if (ourLog.isDebugEnabled()) { ourLog.debug(String.format("System %s differs from system in the EMPI rules %s", baseSystem, empiSystem)); } } else { @@ -336,25 +349,67 @@ public class PersonHelper { return theSourceResource; } - public IBaseResource overwriteExternalEids(IBaseResource thePerson, List theNewEid) { - clearExternalEids(thePerson); - addCanonicalEidsToSourceResourceIfAbsent(thePerson, theNewEid); - return thePerson; + public IBaseResource overwriteExternalEids(IBaseResource theSourceResource, List theNewEid) { + clearExternalEids(theSourceResource); + addCanonicalEidsToSourceResourceIfAbsent(theSourceResource, theNewEid); + return theSourceResource; } - private void clearExternalEids(IBaseResource thePerson) { - switch (myFhirContext.getVersion().getVersion()) { - case R4: - Person personR4 = (Person) thePerson; - personR4.getIdentifier().removeIf(theIdentifier -> theIdentifier.getSystem().equalsIgnoreCase(myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem())); - break; - case DSTU3: - org.hl7.fhir.dstu3.model.Person personDstu3 = (org.hl7.fhir.dstu3.model.Person) thePerson; - personDstu3.getIdentifier().removeIf(theIdentifier -> theIdentifier.getSystem().equalsIgnoreCase(myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem())); - break; - default: - throw new UnsupportedOperationException("Version not supported: " + myFhirContext.getVersion().getVersion()); + private void clearExternalEidsFromTheSourceResource(BaseRuntimeChildDefinition theSourceResourceIdentifier, IBase theSourceResource) { + IFhirPath fhirPath = myFhirContext.newFhirPath(); + List sourceResourceIdentifiers = theSourceResourceIdentifier.getAccessor().getValues(theSourceResource); + List clonedIdentifiers = new ArrayList<>(); + + for (IBase base : sourceResourceIdentifiers) { + Optional system = fhirPath.evaluateFirst(base, "system", IPrimitiveType.class); + if (system.isPresent()) { + String empiSystem = myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem(); + String baseSystem = system.get().getValueAsString(); + if (Objects.equals(baseSystem, empiSystem)) { + if (ourLog.isDebugEnabled()) { + ourLog.debug(String.format("Found EID confirming to EMPI rules %s. It should not be copied, skipping", baseSystem)); + } + continue; + } + } + if (ourLog.isDebugEnabled()) { + ourLog.debug("Copying non-EMPI EID"); + } + + BaseRuntimeElementCompositeDefinition childIdentifier = (BaseRuntimeElementCompositeDefinition) + theSourceResourceIdentifier.getChildByName("identifier"); + FhirTerser terser = myFhirContext.newTerser(); + IBase sourceResourceNewIdentifier = childIdentifier.newInstance(); + terser.cloneInto(base, sourceResourceNewIdentifier, true); + + clonedIdentifiers.add(sourceResourceNewIdentifier); } + + sourceResourceIdentifiers.clear(); + sourceResourceIdentifiers.addAll(clonedIdentifiers); + } + + private void clearExternalEids(IBaseResource theSourceResource) { + // validate the system - if it's set to EID system - then clear it - type and STU version + validateContextSupported(); + + // get a ref to the actual ID Field + RuntimeResourceDefinition resourceDefinition = myFhirContext.getResourceDefinition(theSourceResource); + BaseRuntimeChildDefinition sourceResourceIdentifier = resourceDefinition.getChildByName("identifier"); + clearExternalEidsFromTheSourceResource(sourceResourceIdentifier, theSourceResource); + +// switch (myFhirContext.getVersion().getVersion()) { +// case R4: +// Person personR4 = (Person) theSourceResource; +// personR4.getIdentifier().removeIf(theIdentifier -> theIdentifier.getSystem().equalsIgnoreCase(myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem())); +// break; +// case DSTU3: +// org.hl7.fhir.dstu3.model.Person personDstu3 = (org.hl7.fhir.dstu3.model.Person) theSourceResource; +// personDstu3.getIdentifier().removeIf(theIdentifier -> theIdentifier.getSystem().equalsIgnoreCase(myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem())); +// break; +// default: +// throw new UnsupportedOperationException("Version not supported: " + myFhirContext.getVersion().getVersion()); +// } } /** @@ -376,6 +431,8 @@ public class PersonHelper { } } + + private T toId(CanonicalEID eid) { switch (myFhirContext.getVersion().getVersion()) { case R4: @@ -386,6 +443,17 @@ public class PersonHelper { throw new IllegalStateException("Unsupported FHIR version " + myFhirContext.getVersion().getVersion()); } + + private T toBooleanType(boolean theFlag) { + switch (myFhirContext.getVersion().getVersion()) { + case R4: + return (T) new BooleanType(theFlag); + case DSTU3: + return (T) new org.hl7.fhir.dstu3.model.BooleanType(theFlag); + } + throw new IllegalStateException("Unsupported FHIR version " + myFhirContext.getVersion().getVersion()); + } + /** * To avoid adding duplicate * @@ -534,18 +602,18 @@ public class PersonHelper { person.setLink(links); } - public int getLinkCount(IAnyResource thePerson) { - switch (myFhirContext.getVersion().getVersion()) { - case R4: - Person personR4 = (Person) thePerson; - return personR4.getLink().size(); - case DSTU3: - org.hl7.fhir.dstu3.model.Person personStu3 = (org.hl7.fhir.dstu3.model.Person) thePerson; - return personStu3.getLink().size(); - default: - throw new UnsupportedOperationException("Version not supported: " + myFhirContext.getVersion().getVersion()); - } - } +// public int getLinkCount(IAnyResource theSourceResource) { +// switch (myFhirContext.getVersion().getVersion()) { +// case R4: +// Person personR4 = (Person) theSourceResource; +// return personR4.getLink().size(); +// case DSTU3: +// org.hl7.fhir.dstu3.model.Person personStu3 = (org.hl7.fhir.dstu3.model.Person) theSourceResource; +// return personStu3.getLink().size(); +// default: +// throw new UnsupportedOperationException("Version not supported: " + myFhirContext.getVersion().getVersion()); +// } +// } private void log(EmpiTransactionContext theEmpiTransactionContext, String theMessage) { theEmpiTransactionContext.addTransactionLogMessage(theMessage);