Fixed code for use case #2 test case
This commit is contained in:
parent
ac3b1e3e17
commit
4865e8a410
|
@ -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.data.IEmpiLinkDao;
|
||||||
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
|
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
|
||||||
import ca.uhn.fhir.jpa.entity.EmpiLink;
|
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.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -308,6 +310,26 @@ public class EmpiLinkDaoSvc {
|
||||||
return myEmpiLinkDao.findAll(example);
|
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<EmpiLink> 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<EmpiLink> example = Example.of(exampleLink);
|
||||||
|
return myEmpiLinkDao.findAll(example);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory delegation method, whenever you need a new EmpiLink, use this factory method.
|
* 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.
|
* //TODO Should we make the constructor private for EmpiLink? or work out some way to ensure they can only be instantiated via factory.
|
||||||
|
|
|
@ -71,14 +71,14 @@ public class EmpiEidUpdateService {
|
||||||
// myPersonHelper.updatePersonFromUpdatedEmpiTarget(updateContext.getMatchedPerson(), theResource, theEmpiTransactionContext);
|
// myPersonHelper.updatePersonFromUpdatedEmpiTarget(updateContext.getMatchedPerson(), theResource, theEmpiTransactionContext);
|
||||||
if (!updateContext.isIncomingResourceHasAnEid() || updateContext.isHasEidsInCommon()) {
|
if (!updateContext.isIncomingResourceHasAnEid() || updateContext.isHasEidsInCommon()) {
|
||||||
//update to patient that uses internal EIDs only.
|
//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()) {
|
} else if (!updateContext.isHasEidsInCommon()) {
|
||||||
handleNoEidsInCommon(theResource, theMatchedSourceResourceCandidate, theEmpiTransactionContext, updateContext);
|
handleNoEidsInCommon(theResource, theMatchedSourceResourceCandidate, theEmpiTransactionContext, updateContext);
|
||||||
}
|
}
|
||||||
} else {
|
} 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.
|
//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
|
//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.
|
// the user is simply updating their EID. We propagate this change to the Person.
|
||||||
//overwrite. No EIDS in common, but still same person.
|
//overwrite. No EIDS in common, but still same person.
|
||||||
if (myEmpiSettings.isPreventMultipleEids()) {
|
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.
|
if (myEmpiLinkDaoSvc.findEmpiMatchLinksBySource(theUpdateContext.getMatchedSourceResource()).size() <= 1) { // If there is only 0/1 link on the person, we can safely overwrite the EID.
|
||||||
handleExternalEidOverwrite(theUpdateContext.getMatchedPerson(), theResource, theEmpiTransactionContext);
|
// 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.
|
} 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());
|
createNewPersonAndFlagAsDuplicate(theResource, theEmpiTransactionContext, theUpdateContext.getExistingPerson());
|
||||||
}
|
}
|
||||||
} else {
|
} 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) {
|
private void handleExternalEidOverwrite(IAnyResource thePerson, IAnyResource theResource, EmpiTransactionContext theEmpiTransactionContext) {
|
||||||
|
@ -138,17 +139,17 @@ public class EmpiEidUpdateService {
|
||||||
private IAnyResource myExistingPerson;
|
private IAnyResource myExistingPerson;
|
||||||
private boolean myRemainsMatchedToSamePerson;
|
private boolean myRemainsMatchedToSamePerson;
|
||||||
|
|
||||||
public IAnyResource getMatchedPerson() {
|
public IAnyResource getMatchedSourceResource() {
|
||||||
return myMatchedPerson;
|
return myMatchedSourceResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final IAnyResource myMatchedPerson;
|
private final IAnyResource myMatchedSourceResource;
|
||||||
|
|
||||||
EmpiUpdateContext(MatchedSourceResourceCandidate theMatchedSourceResourceCandidate, IAnyResource theResource) {
|
EmpiUpdateContext(MatchedSourceResourceCandidate theMatchedSourceResourceCandidate, IAnyResource theResource) {
|
||||||
final String resourceType = theResource.getIdElement().getResourceType();
|
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();
|
myIncomingResourceHasAnEid = !myEIDHelper.getExternalEid(theResource).isEmpty();
|
||||||
|
|
||||||
Optional<EmpiLink> theExistingMatchLink = myEmpiLinkDaoSvc.getMatchedLinkForTarget(theResource);
|
Optional<EmpiLink> theExistingMatchLink = myEmpiLinkDaoSvc.getMatchedLinkForTarget(theResource);
|
||||||
|
|
|
@ -105,7 +105,8 @@ public class EmpiLinkSvcImpl implements IEmpiLinkSvc {
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void syncEmpiLinksToPersonLinks(IAnyResource thePersonResource, EmpiTransactionContext theEmpiTransactionContext) {
|
public void syncEmpiLinksToPersonLinks(IAnyResource thePersonResource, EmpiTransactionContext theEmpiTransactionContext) {
|
||||||
int origLinkCount = myPersonHelper.getLinkCount(thePersonResource);
|
// int origLinkCount = myPersonHelper.getLinkCount(thePersonResource);
|
||||||
|
int origLinkCount = myEmpiLinkDaoSvc.findEmpiMatchLinksBySource(thePersonResource).size();
|
||||||
|
|
||||||
List<EmpiLink> empiLinks = myEmpiLinkDaoSvc.findEmpiLinksByPerson(thePersonResource);
|
List<EmpiLink> empiLinks = myEmpiLinkDaoSvc.findEmpiLinksByPerson(thePersonResource);
|
||||||
|
|
||||||
|
|
|
@ -73,8 +73,8 @@ public class EmpiResourceDaoSvc {
|
||||||
map.setLoadSynchronous(true);
|
map.setLoadSynchronous(true);
|
||||||
map.add("identifier", new TokenParam(myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem(), theEid));
|
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...
|
// 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("active", new TokenParam("true"));
|
||||||
map.add("_tag", new TokenParam(EmpiConstants.SYSTEM_EMPI_MANAGED, EmpiConstants.CODE_HAPI_EMPI_MANAGED));
|
// map.add("_tag", new TokenParam(EmpiConstants.SYSTEM_EMPI_MANAGED, EmpiConstants.CODE_HAPI_EMPI_MANAGED));
|
||||||
|
|
||||||
IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao(theResourceType);
|
IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao(theResourceType);
|
||||||
IBundleProvider search = resourceDao.search(map);
|
IBundleProvider search = resourceDao.search(map);
|
||||||
|
|
|
@ -24,7 +24,7 @@ public class IsSameSourceResourceAs extends BaseSourceResourceMatcher {
|
||||||
sourceResourcePidsToMatch = myBaseResources.stream().map(this::getMatchedResourcePidFromResource).collect(Collectors.toList());
|
sourceResourcePidsToMatch = myBaseResources.stream().map(this::getMatchedResourcePidFromResource).collect(Collectors.toList());
|
||||||
boolean allToCheckAreSame = sourceResourcePidsToMatch.stream().allMatch(pid -> pid.equals(sourceResourcePidsToMatch.get(0)));
|
boolean allToCheckAreSame = sourceResourcePidsToMatch.stream().allMatch(pid -> pid.equals(sourceResourcePidsToMatch.get(0)));
|
||||||
if (!allToCheckAreSame) {
|
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);
|
return sourceResourcePidsToMatch.contains(incomingSourceResourcePid);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,14 +41,15 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import static org.slf4j.LoggerFactory.getLogger;
|
||||||
|
|
||||||
public class EmpiMatchLinkSvcTest extends BaseEmpiR4Test {
|
public class EmpiMatchLinkSvcTest extends BaseEmpiR4Test {
|
||||||
|
|
||||||
private static final Logger ourLog = getLogger(EmpiMatchLinkSvcTest.class);
|
private static final Logger ourLog = getLogger(EmpiMatchLinkSvcTest.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
IEmpiLinkSvc myEmpiLinkSvc;
|
IEmpiLinkSvc myEmpiLinkSvc;
|
||||||
@Autowired
|
@Autowired
|
||||||
private EIDHelper myEidHelper;
|
private EIDHelper myEidHelper;
|
||||||
@Autowired
|
@Autowired
|
||||||
private PersonHelper myPersonHelper;
|
private PersonHelper myPersonHelper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private EmpiResourceDaoSvc myEmpiResourceDaoSvc; // TODO NG - remove?
|
private EmpiResourceDaoSvc myEmpiResourceDaoSvc; // TODO NG - remove?
|
||||||
|
|
||||||
|
@ -117,19 +118,26 @@ public class EmpiMatchLinkSvcTest extends BaseEmpiR4Test {
|
||||||
@Test
|
@Test
|
||||||
public void testWhenPOSSIBLE_MATCHOccursOnPersonThatHasBeenManuallyNOMATCHedThatItIsBlocked() {
|
public void testWhenPOSSIBLE_MATCHOccursOnPersonThatHasBeenManuallyNOMATCHedThatItIsBlocked() {
|
||||||
Patient originalJane = createPatientAndUpdateLinks(buildJanePatient());
|
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);
|
IAnyResource janePerson = (IAnyResource) search.getResources(0, 1).get(0);
|
||||||
|
|
||||||
Patient unmatchedPatient = createPatient(buildJanePatient());
|
Patient unmatchedPatient = createPatient(buildJanePatient());
|
||||||
|
|
||||||
//This simulates an admin specifically saying that unmatchedPatient does NOT match janePerson.
|
//This simulates an admin specifically saying that unmatchedPatient does NOT match janePerson.
|
||||||
myEmpiLinkSvc.updateLink(janePerson, unmatchedPatient, EmpiMatchOutcome.NO_MATCH, EmpiLinkSourceEnum.MANUAL, createContextForCreate("Patient"));
|
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
|
//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.
|
//should cause a whole new Person to be created.
|
||||||
myEmpiMatchLinkSvc.updateEmpiLinksForEmpiTarget(unmatchedPatient, createContextForCreate("Patient"));
|
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(sameSourceResourceAs(janePerson))));
|
||||||
assertThat(unmatchedPatient, is(not(linkedTo(originalJane))));
|
assertThat(unmatchedPatient, is(not(linkedTo(originalJane))));
|
||||||
|
|
||||||
|
@ -225,35 +233,9 @@ public class EmpiMatchLinkSvcTest extends BaseEmpiR4Test {
|
||||||
Patient patient1 = addExternalEID(buildJanePatient(), "uniqueid");
|
Patient patient1 = addExternalEID(buildJanePatient(), "uniqueid");
|
||||||
createPatientAndUpdateLinks(patient1);
|
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<IBaseResource> 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<EmpiLink> empiLinkByTarget = myEmpiLinkDaoSvc.findEmpiLinkByTarget(patient1);
|
|
||||||
assertTrue(empiLinkByTarget.isPresent());
|
|
||||||
System.out.println(empiLinkByTarget.get());
|
|
||||||
}
|
|
||||||
Patient patient2 = buildPaulPatient();
|
Patient patient2 = buildPaulPatient();
|
||||||
patient2.setActive(true);
|
|
||||||
patient2 = addExternalEID(patient2, "uniqueid");
|
patient2 = addExternalEID(patient2, "uniqueid");
|
||||||
createPatientAndUpdateLinks(patient2);
|
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)));
|
assertThat(patient1, is(sameSourceResourceAs(patient2)));
|
||||||
}
|
}
|
||||||
|
@ -552,8 +534,8 @@ public class EmpiMatchLinkSvcTest extends BaseEmpiR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
//Test Case #2
|
|
||||||
public void testSinglyLinkedPersonThatGetsAnUpdatedEidSimplyUpdatesEID() {
|
public void testSinglyLinkedPersonThatGetsAnUpdatedEidSimplyUpdatesEID() {
|
||||||
|
//Use Case # 2
|
||||||
String EID_1 = "123";
|
String EID_1 = "123";
|
||||||
String EID_2 = "456";
|
String EID_2 = "456";
|
||||||
|
|
||||||
|
@ -568,7 +550,12 @@ public class EmpiMatchLinkSvcTest extends BaseEmpiR4Test {
|
||||||
clearExternalEIDs(paul);
|
clearExternalEIDs(paul);
|
||||||
addExternalEID(paul, EID_2);
|
addExternalEID(paul, EID_2);
|
||||||
|
|
||||||
|
System.out.println("Paul Before");
|
||||||
|
print(paul);
|
||||||
|
Patient pailTemp = paul;
|
||||||
paul = updatePatientAndUpdateLinks(paul);
|
paul = updatePatientAndUpdateLinks(paul);
|
||||||
|
System.out.println("Paul After");
|
||||||
|
print(pailTemp);
|
||||||
|
|
||||||
assertNoDuplicates();
|
assertNoDuplicates();
|
||||||
|
|
||||||
|
|
|
@ -48,5 +48,4 @@ public interface IEmpiLinkSvc {
|
||||||
* @param theResource
|
* @param theResource
|
||||||
*/
|
*/
|
||||||
void deleteLink(IAnyResource theExistingPerson, IAnyResource theResource, EmpiTransactionContext theEmpiTransactionContext);
|
void deleteLink(IAnyResource theExistingPerson, IAnyResource theResource, EmpiTransactionContext theEmpiTransactionContext);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import ca.uhn.fhir.empi.model.CanonicalEID;
|
||||||
import ca.uhn.fhir.empi.model.CanonicalIdentityAssuranceLevel;
|
import ca.uhn.fhir.empi.model.CanonicalIdentityAssuranceLevel;
|
||||||
import ca.uhn.fhir.empi.model.EmpiTransactionContext;
|
import ca.uhn.fhir.empi.model.EmpiTransactionContext;
|
||||||
import ca.uhn.fhir.fhirpath.IFhirPath;
|
import ca.uhn.fhir.fhirpath.IFhirPath;
|
||||||
|
import ca.uhn.fhir.model.primitive.BooleanDt;
|
||||||
import ca.uhn.fhir.util.FhirTerser;
|
import ca.uhn.fhir.util.FhirTerser;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
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.IIdType;
|
||||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
import org.hl7.fhir.r4.model.Address;
|
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.ContactPoint;
|
||||||
import org.hl7.fhir.r4.model.HumanName;
|
import org.hl7.fhir.r4.model.HumanName;
|
||||||
import org.hl7.fhir.r4.model.Identifier;
|
import org.hl7.fhir.r4.model.Identifier;
|
||||||
|
@ -243,9 +245,20 @@ public class PersonHelper {
|
||||||
|
|
||||||
populateMetaTag(newSourceResource);
|
populateMetaTag(newSourceResource);
|
||||||
|
|
||||||
|
setActive(newSourceResource, resourceDefinition);
|
||||||
|
|
||||||
return (T) newSourceResource;
|
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.
|
* 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.
|
* 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
|
// 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();
|
FhirTerser terser = myFhirContext.newTerser();
|
||||||
IBase sourceResourceNewIdentifier = childIdentifier.newInstance();
|
IBase sourceResourceNewIdentifier = childIdentifier.newInstance();
|
||||||
terser.cloneInto(theEid, sourceResourceNewIdentifier, true);
|
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
|
// FHIR choice types - fields within fhir where we have a choice of ids
|
||||||
IFhirPath fhirPath = myFhirContext.newFhirPath();
|
IFhirPath fhirPath = myFhirContext.newFhirPath();
|
||||||
List<IBase> sourceResourceIdentifiers = sourceResourceIdentifier.getAccessor().getValues(theSourceResource);
|
List<IBase> sourceResourceIdentifiers = theSourceResourceIdentifier.getAccessor().getValues(theSourceResource);
|
||||||
|
|
||||||
for (IBase base : sourceResourceIdentifiers) {
|
for (IBase base : sourceResourceIdentifiers) {
|
||||||
Optional<IPrimitiveType> system = fhirPath.evaluateFirst(base, "system", IPrimitiveType.class);
|
Optional<IPrimitiveType> system = fhirPath.evaluateFirst(base, "system", IPrimitiveType.class);
|
||||||
|
@ -282,8 +295,8 @@ public class PersonHelper {
|
||||||
String empiSystem = myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem();
|
String empiSystem = myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem();
|
||||||
String baseSystem = system.get().getValueAsString();
|
String baseSystem = system.get().getValueAsString();
|
||||||
if (Objects.equals(baseSystem, empiSystem)) {
|
if (Objects.equals(baseSystem, empiSystem)) {
|
||||||
cloneExternalEidIntoNewSourceResource(sourceResourceIdentifier, base, newSourceResource);
|
cloneExternalEidIntoNewSourceResource(theSourceResourceIdentifier, base, theNewSourceResource);
|
||||||
} else {
|
} else if (ourLog.isDebugEnabled()) {
|
||||||
ourLog.debug(String.format("System %s differs from system in the EMPI rules %s", baseSystem, empiSystem));
|
ourLog.debug(String.format("System %s differs from system in the EMPI rules %s", baseSystem, empiSystem));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -336,25 +349,67 @@ public class PersonHelper {
|
||||||
return theSourceResource;
|
return theSourceResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IBaseResource overwriteExternalEids(IBaseResource thePerson, List<CanonicalEID> theNewEid) {
|
public IBaseResource overwriteExternalEids(IBaseResource theSourceResource, List<CanonicalEID> theNewEid) {
|
||||||
clearExternalEids(thePerson);
|
clearExternalEids(theSourceResource);
|
||||||
addCanonicalEidsToSourceResourceIfAbsent(thePerson, theNewEid);
|
addCanonicalEidsToSourceResourceIfAbsent(theSourceResource, theNewEid);
|
||||||
return thePerson;
|
return theSourceResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearExternalEids(IBaseResource thePerson) {
|
private void clearExternalEidsFromTheSourceResource(BaseRuntimeChildDefinition theSourceResourceIdentifier, IBase theSourceResource) {
|
||||||
switch (myFhirContext.getVersion().getVersion()) {
|
IFhirPath fhirPath = myFhirContext.newFhirPath();
|
||||||
case R4:
|
List<IBase> sourceResourceIdentifiers = theSourceResourceIdentifier.getAccessor().getValues(theSourceResource);
|
||||||
Person personR4 = (Person) thePerson;
|
List<IBase> clonedIdentifiers = new ArrayList<>();
|
||||||
personR4.getIdentifier().removeIf(theIdentifier -> theIdentifier.getSystem().equalsIgnoreCase(myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem()));
|
|
||||||
break;
|
for (IBase base : sourceResourceIdentifiers) {
|
||||||
case DSTU3:
|
Optional<IPrimitiveType> system = fhirPath.evaluateFirst(base, "system", IPrimitiveType.class);
|
||||||
org.hl7.fhir.dstu3.model.Person personDstu3 = (org.hl7.fhir.dstu3.model.Person) thePerson;
|
if (system.isPresent()) {
|
||||||
personDstu3.getIdentifier().removeIf(theIdentifier -> theIdentifier.getSystem().equalsIgnoreCase(myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem()));
|
String empiSystem = myEmpiConfig.getEmpiRules().getEnterpriseEIDSystem();
|
||||||
break;
|
String baseSystem = system.get().getValueAsString();
|
||||||
default:
|
if (Objects.equals(baseSystem, empiSystem)) {
|
||||||
throw new UnsupportedOperationException("Version not supported: " + myFhirContext.getVersion().getVersion());
|
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> T toId(CanonicalEID eid) {
|
private <T> T toId(CanonicalEID eid) {
|
||||||
switch (myFhirContext.getVersion().getVersion()) {
|
switch (myFhirContext.getVersion().getVersion()) {
|
||||||
case R4:
|
case R4:
|
||||||
|
@ -386,6 +443,17 @@ public class PersonHelper {
|
||||||
throw new IllegalStateException("Unsupported FHIR version " + myFhirContext.getVersion().getVersion());
|
throw new IllegalStateException("Unsupported FHIR version " + myFhirContext.getVersion().getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private <T extends IBase> 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
|
* To avoid adding duplicate
|
||||||
*
|
*
|
||||||
|
@ -534,18 +602,18 @@ public class PersonHelper {
|
||||||
person.setLink(links);
|
person.setLink(links);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLinkCount(IAnyResource thePerson) {
|
// public int getLinkCount(IAnyResource theSourceResource) {
|
||||||
switch (myFhirContext.getVersion().getVersion()) {
|
// switch (myFhirContext.getVersion().getVersion()) {
|
||||||
case R4:
|
// case R4:
|
||||||
Person personR4 = (Person) thePerson;
|
// Person personR4 = (Person) theSourceResource;
|
||||||
return personR4.getLink().size();
|
// return personR4.getLink().size();
|
||||||
case DSTU3:
|
// case DSTU3:
|
||||||
org.hl7.fhir.dstu3.model.Person personStu3 = (org.hl7.fhir.dstu3.model.Person) thePerson;
|
// org.hl7.fhir.dstu3.model.Person personStu3 = (org.hl7.fhir.dstu3.model.Person) theSourceResource;
|
||||||
return personStu3.getLink().size();
|
// return personStu3.getLink().size();
|
||||||
default:
|
// default:
|
||||||
throw new UnsupportedOperationException("Version not supported: " + myFhirContext.getVersion().getVersion());
|
// throw new UnsupportedOperationException("Version not supported: " + myFhirContext.getVersion().getVersion());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
private void log(EmpiTransactionContext theEmpiTransactionContext, String theMessage) {
|
private void log(EmpiTransactionContext theEmpiTransactionContext, String theMessage) {
|
||||||
theEmpiTransactionContext.addTransactionLogMessage(theMessage);
|
theEmpiTransactionContext.addTransactionLogMessage(theMessage);
|
||||||
|
|
Loading…
Reference in New Issue