parent
5483c99e00
commit
558f419955
|
@ -2,6 +2,8 @@
|
|||
|
||||
Several operations exist that can be used to manage EMPI links. These operations are supplied by a [plain provider](/docs/server_plain/resource_providers.html#plain-providers) called [EmpiProvider](/hapi-fhir/apidocs/hapi-fhir-server-empi/ca/uhn/fhir/empi/provider/EmpiProviderR4.html).
|
||||
|
||||
In cases where the operation changes data, if a resource id parameter contains a version (e.g. `Person/123/_history/1`), then the operation will fail with a 409 CONFLICT if that is not the latest version of that resource. This could be used to prevent update conflicts in an environment where multiple users are working on the same set of empi links.
|
||||
|
||||
## Query links
|
||||
|
||||
Ue the `$empi-query-links` operation to view empi links. The results returned are based on the parameters provided. All parameters are optional. This operation takes the following parameters:
|
||||
|
@ -74,27 +76,25 @@ The following request body could be used to find all POSSIBLE_MATCH links in the
|
|||
This operation returns a `Parameters` resource that looks like the following:
|
||||
|
||||
```json
|
||||
<Parameters xmlns="http://hl7.org/fhir">
|
||||
<parameter>
|
||||
<name value="link"/>
|
||||
<part>
|
||||
<name value="personId"/>
|
||||
<valueString value="Person/123"/>
|
||||
</part>
|
||||
<part>
|
||||
<name value="targetId"/>
|
||||
<valueString value="Patient/456"/>
|
||||
</part>
|
||||
<part>
|
||||
<name value="matchResult"/>
|
||||
<valueString value="MATCH"/>
|
||||
</part>
|
||||
<part>
|
||||
<name value="linkSource"/>
|
||||
<valueString value="AUTO"/>
|
||||
</part>
|
||||
</parameter>
|
||||
</Parameters>
|
||||
{
|
||||
"resourceType": "Parameters",
|
||||
"parameter": [ {
|
||||
"name": "link",
|
||||
"part": [ {
|
||||
"name": "personId",
|
||||
"valueString": "Person/123"
|
||||
}, {
|
||||
"name": "targetId",
|
||||
"valueString": "Patient/456"
|
||||
}, {
|
||||
"name": "matchResult",
|
||||
"valueString": "POSSIBLE_MATCH"
|
||||
}, {
|
||||
"name": "linkSource",
|
||||
"valueString": "AUTO"
|
||||
} ]
|
||||
} ]
|
||||
}
|
||||
```
|
||||
|
||||
## Querying links via the Person resource
|
||||
|
@ -155,19 +155,93 @@ This operation returns `Parameters` similar to `$empi-query-links`:
|
|||
|
||||
|
||||
```json
|
||||
<Parameters xmlns="http://hl7.org/fhir">
|
||||
<parameter>
|
||||
<name value="link"/>
|
||||
<part>
|
||||
<name value="personId"/>
|
||||
<valueString value="Person/123"/>
|
||||
</part>
|
||||
<part>
|
||||
<name value="targetId"/>
|
||||
<valueString value="Person/789"/>
|
||||
</part>
|
||||
</parameter>
|
||||
</Parameters>
|
||||
{
|
||||
"resourceType": "Parameters",
|
||||
"parameter": [ {
|
||||
"name": "link",
|
||||
"part": [ {
|
||||
"name": "personId",
|
||||
"valueString": "Person/123"
|
||||
}, {
|
||||
"name": "targetId",
|
||||
"valueString": "Person/456"
|
||||
}, {
|
||||
"name": "matchResult",
|
||||
"valueString": "POSSIBLE_DUPLICATE"
|
||||
}, {
|
||||
"name": "linkSource",
|
||||
"valueString": "AUTO"
|
||||
} ]
|
||||
} ]
|
||||
}
|
||||
```
|
||||
|
||||
## Unduplicate Persons
|
||||
|
||||
Use the `$empi-not-duplicate` operation to mark duplicate persons as not duplicates. This operation takes the following parameters:
|
||||
|
||||
<table class="table table-striped table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Type</th>
|
||||
<th>Cardinality</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>personId</td>
|
||||
<td>String</td>
|
||||
<td>1..1</td>
|
||||
<td>
|
||||
The id of the Person resource.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>targetId</td>
|
||||
<td>String</td>
|
||||
<td>1..1</td>
|
||||
<td>
|
||||
The id of the Person that personId has a possible duplicate link to.
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Example
|
||||
|
||||
Use an HTTP POST to the following URL to invoke this operation:
|
||||
|
||||
```url
|
||||
http://example.com/$empi-not-duplicate
|
||||
```
|
||||
|
||||
The following request body could be used:
|
||||
|
||||
```json
|
||||
{
|
||||
"resourceType": "Parameters",
|
||||
"parameter": [ {
|
||||
"name": "personId",
|
||||
"valueString": "Person/123"
|
||||
}, {
|
||||
"name": "targetId",
|
||||
"valueString": "Person/456"
|
||||
} ]
|
||||
}
|
||||
```
|
||||
|
||||
When the operation is successful, it returns the following `Parameters`:
|
||||
|
||||
```json
|
||||
{
|
||||
"resourceType": "Parameters",
|
||||
"parameter": [ {
|
||||
"name": "success",
|
||||
"valueBoolean": true
|
||||
} ]
|
||||
}
|
||||
```
|
||||
|
||||
## Update Link
|
||||
|
|
|
@ -25,7 +25,6 @@ import ca.uhn.fhir.empi.api.EmpiMatchResultEnum;
|
|||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import org.hibernate.annotations.OptimisticLock;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
|
@ -157,6 +156,10 @@ public class EmpiLink {
|
|||
return myMatchResult == EmpiMatchResultEnum.POSSIBLE_MATCH;
|
||||
}
|
||||
|
||||
public boolean isPossibleDuplicate() {
|
||||
return myMatchResult == EmpiMatchResultEnum.POSSIBLE_DUPLICATE;
|
||||
}
|
||||
|
||||
public EmpiLinkSourceEnum getLinkSource() {
|
||||
return myLinkSource;
|
||||
}
|
||||
|
|
|
@ -63,13 +63,19 @@ public class EmpiLinkSvcImpl implements IEmpiLinkSvc {
|
|||
|
||||
@Override
|
||||
@Transactional
|
||||
public void updateLink(IAnyResource thePerson, IAnyResource theResource, EmpiMatchResultEnum theMatchResult, EmpiLinkSourceEnum theLinkSource, EmpiTransactionContext theEmpiTransactionContext) {
|
||||
IIdType resourceId = theResource.getIdElement().toUnqualifiedVersionless();
|
||||
public void updateLink(IAnyResource thePerson, IAnyResource theTarget, EmpiMatchResultEnum theMatchResult, EmpiLinkSourceEnum theLinkSource, EmpiTransactionContext theEmpiTransactionContext) {
|
||||
IIdType resourceId = theTarget.getIdElement().toUnqualifiedVersionless();
|
||||
|
||||
validateRequestIsLegal(thePerson, theResource, theMatchResult, theLinkSource);
|
||||
if (theMatchResult == EmpiMatchResultEnum.POSSIBLE_DUPLICATE && personsLinkedAsNoMatch(thePerson, theTarget)) {
|
||||
log(theEmpiTransactionContext, thePerson.getIdElement().toUnqualifiedVersionless() +
|
||||
" is linked as NO_MATCH with " +
|
||||
theTarget.getIdElement().toUnqualifiedVersionless() +
|
||||
" not linking as POSSIBLE_DUPLICATE.");
|
||||
return;
|
||||
}
|
||||
validateRequestIsLegal(thePerson, theTarget, theMatchResult, theLinkSource);
|
||||
switch (theMatchResult) {
|
||||
case MATCH:
|
||||
//deleteCurrentMatch(theResource);
|
||||
myPersonHelper.addOrUpdateLink(thePerson, resourceId, AssuranceLevelUtil.getAssuranceLevel(theMatchResult, theLinkSource), theEmpiTransactionContext);
|
||||
myEmpiResourceDaoSvc.updatePerson(thePerson);
|
||||
break;
|
||||
|
@ -83,8 +89,15 @@ public class EmpiLinkSvcImpl implements IEmpiLinkSvc {
|
|||
break;
|
||||
}
|
||||
myEmpiResourceDaoSvc.updatePerson(thePerson);
|
||||
createOrUpdateLinkEntity(thePerson, theResource, theMatchResult, theLinkSource, theEmpiTransactionContext);
|
||||
createOrUpdateLinkEntity(thePerson, theTarget, theMatchResult, theLinkSource, theEmpiTransactionContext);
|
||||
}
|
||||
|
||||
private boolean personsLinkedAsNoMatch(IAnyResource thePerson, IAnyResource theTarget) {
|
||||
Long personId = myIdHelperService.getPidOrThrowException(thePerson);
|
||||
Long targetId = myIdHelperService.getPidOrThrowException(theTarget);
|
||||
// TODO perf collapse into one query
|
||||
return myEmpiLinkDaoSvc.getEmpiLinksByPersonPidTargetPidAndMatchResult(personId, targetId, EmpiMatchResultEnum.NO_MATCH).isPresent() ||
|
||||
myEmpiLinkDaoSvc.getEmpiLinksByPersonPidTargetPidAndMatchResult(targetId, personId, EmpiMatchResultEnum.NO_MATCH).isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -33,7 +33,11 @@ import ca.uhn.fhir.jpa.dao.EmpiLinkDaoSvc;
|
|||
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
|
||||
import ca.uhn.fhir.jpa.entity.EmpiLink;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
|
||||
import ca.uhn.fhir.util.ParametersUtil;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||
import org.hl7.fhir.r4.model.Parameters;
|
||||
import org.slf4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
@ -92,15 +96,15 @@ public class EmpiLinkUpdaterSvcImpl implements IEmpiLinkUpdaterSvc {
|
|||
private void validateUpdateLinkRequest(IAnyResource thePerson, IAnyResource theTarget, EmpiMatchResultEnum theMatchResult, String theTargetType) {
|
||||
String personType = myFhirContext.getResourceType(thePerson);
|
||||
if (theMatchResult != EmpiMatchResultEnum.NO_MATCH &&
|
||||
theMatchResult != EmpiMatchResultEnum.MATCH) {
|
||||
theMatchResult != EmpiMatchResultEnum.MATCH) {
|
||||
throw new InvalidRequestException("Match Result may only be set to " + EmpiMatchResultEnum.NO_MATCH + " or " + EmpiMatchResultEnum.MATCH);
|
||||
}
|
||||
|
||||
if (!"Person".equals(personType)) {
|
||||
throw new InvalidRequestException("First argument to updateLink must be a Person. Was " + personType);
|
||||
throw new InvalidRequestException("First argument to " + ProviderConstants.EMPI_UPDATE_LINK + " must be a Person. Was " + personType);
|
||||
}
|
||||
if (!EmpiUtil.supportedTargetType(theTargetType)) {
|
||||
throw new InvalidRequestException("Second argument to updateLink must be a Patient or Practitioner. Was " + theTargetType);
|
||||
throw new InvalidRequestException("Second argument to " + ProviderConstants.EMPI_UPDATE_LINK + " must be a Patient or Practitioner. Was " + theTargetType);
|
||||
}
|
||||
|
||||
if (!EmpiUtil.isEmpiManaged(thePerson)) {
|
||||
|
@ -111,4 +115,46 @@ public class EmpiLinkUpdaterSvcImpl implements IEmpiLinkUpdaterSvc {
|
|||
throw new InvalidRequestException("The target is marked with the " + EmpiConstants.CODE_NO_EMPI_MANAGED + " tag which means it may not be EMPI linked.");
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public IBaseParameters notDuplicatePerson(IAnyResource thePerson, IAnyResource theTarget, EmpiTransactionContext theEmpiContext) {
|
||||
validateNotDuplicatePersonRequest(thePerson, theTarget);
|
||||
|
||||
Long personId = myIdHelperService.getPidOrThrowException(thePerson);
|
||||
Long targetId = myIdHelperService.getPidOrThrowException(theTarget);
|
||||
|
||||
Optional<EmpiLink> oEmpiLink = myEmpiLinkDaoSvc.getLinkByPersonPidAndTargetPid(personId, targetId);
|
||||
if (!oEmpiLink.isPresent()) {
|
||||
throw new InvalidRequestException("No link exists between " + thePerson.getIdElement().toVersionless() + " and " + theTarget.getIdElement().toVersionless());
|
||||
}
|
||||
|
||||
EmpiLink empiLink = oEmpiLink.get();
|
||||
if (!empiLink.isPossibleDuplicate()) {
|
||||
throw new InvalidRequestException(thePerson.getIdElement().toVersionless() + " and " + theTarget.getIdElement().toVersionless() + " are not linked as POSSIBLE_DUPLICATE.");
|
||||
}
|
||||
empiLink.setMatchResult(EmpiMatchResultEnum.NO_MATCH);
|
||||
empiLink.setLinkSource(EmpiLinkSourceEnum.MANUAL);
|
||||
myEmpiLinkDaoSvc.save(empiLink);
|
||||
|
||||
Parameters retval = (Parameters) ParametersUtil.newInstance(myFhirContext);
|
||||
retval.addParameter("success", true);
|
||||
return retval;
|
||||
}
|
||||
|
||||
private void validateNotDuplicatePersonRequest(IAnyResource thePerson, IAnyResource theTarget) {
|
||||
String personType = myFhirContext.getResourceType(thePerson);
|
||||
String targetType = myFhirContext.getResourceType(theTarget);
|
||||
if (!"Person".equals(personType)) {
|
||||
throw new InvalidRequestException("First argument to " + ProviderConstants.EMPI_UPDATE_LINK + " must be a Person. Was " + personType);
|
||||
}
|
||||
if (!"Person".equals(targetType)) {
|
||||
throw new InvalidRequestException("Second argument to " + ProviderConstants.EMPI_UPDATE_LINK + " must be a Person . Was " + targetType);
|
||||
}
|
||||
|
||||
if (!EmpiUtil.isEmpiManaged(thePerson) || !EmpiUtil.isEmpiManaged(theTarget)) {
|
||||
throw new InvalidRequestException("Only EMPI Managed Person resources may be updated via this operation. The Person resource provided is not tagged as managed by hapi-empi");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import ca.uhn.fhir.empi.api.EmpiLinkSourceEnum;
|
|||
import ca.uhn.fhir.empi.api.EmpiMatchResultEnum;
|
||||
import ca.uhn.fhir.jpa.entity.EmpiLink;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import org.hl7.fhir.r4.model.BooleanType;
|
||||
import org.hl7.fhir.r4.model.IdType;
|
||||
import org.hl7.fhir.r4.model.Parameters;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
|
@ -19,12 +21,15 @@ import java.util.List;
|
|||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class EmpiProviderQueryLinkR4Test extends BaseLinkR4Test {
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(EmpiProviderQueryLinkR4Test.class);
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(EmpiProviderQueryLinkR4Test.class);
|
||||
private StringType myLinkSource;
|
||||
private IdType myPerson1Id;
|
||||
private IdType myPerson2Id;
|
||||
private StringType myPerson1Id;
|
||||
private StringType myPerson2Id;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
|
@ -36,20 +41,20 @@ private static final Logger ourLog = LoggerFactory.getLogger(EmpiProviderQueryLi
|
|||
// Add a possible duplicate
|
||||
myLinkSource = new StringType(EmpiLinkSourceEnum.AUTO.name());
|
||||
Person person1 = createPerson();
|
||||
myPerson1Id = person1.getIdElement().toVersionless();
|
||||
myPerson1Id = new StringType(person1.getIdElement().toVersionless().getValue());
|
||||
Long person1Pid = myIdHelperService.getPidOrNull(person1);
|
||||
Person person2 = createPerson();
|
||||
myPerson2Id = person2.getIdElement().toVersionless();
|
||||
myPerson2Id = new StringType(person2.getIdElement().toVersionless().getValue());
|
||||
Long person2Pid = myIdHelperService.getPidOrNull(person2);
|
||||
EmpiLink empiLink = new EmpiLink().setPersonPid(person1Pid).setTargetPid(person2Pid).setMatchResult(EmpiMatchResultEnum.POSSIBLE_DUPLICATE).setLinkSource(EmpiLinkSourceEnum.AUTO);
|
||||
myEmpiLinkDaoSvc.save(empiLink);
|
||||
EmpiLink possibleDuplicateEmpiLink = new EmpiLink().setPersonPid(person1Pid).setTargetPid(person2Pid).setMatchResult(EmpiMatchResultEnum.POSSIBLE_DUPLICATE).setLinkSource(EmpiLinkSourceEnum.AUTO);
|
||||
myEmpiLinkDaoSvc.save(possibleDuplicateEmpiLink);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryLinkOneMatch() {
|
||||
|
||||
Parameters result = myEmpiProviderR4.queryLinks(myPersonId, myPatientId, null, null, myRequestDetails);
|
||||
ourLog.info(myFhirContext.newXmlParser().setPrettyPrint(true).encodeResourceToString(result));
|
||||
ourLog.info(myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(result));
|
||||
List<Parameters.ParametersParameterComponent> list = result.getParameter();
|
||||
assertThat(list, hasSize(1));
|
||||
List<Parameters.ParametersParameterComponent> part = list.get(0).getPart();
|
||||
|
@ -82,6 +87,34 @@ private static final Logger ourLog = LoggerFactory.getLogger(EmpiProviderQueryLi
|
|||
assertEmpiLink(2, part, myPerson1Id.getValue(), myPerson2Id.getValue(), EmpiMatchResultEnum.POSSIBLE_DUPLICATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotDuplicate() {
|
||||
{
|
||||
Parameters result = myEmpiProviderR4.getDuplicatePersons(myRequestDetails);
|
||||
List<Parameters.ParametersParameterComponent> list = result.getParameter();
|
||||
assertThat(list, hasSize(1));
|
||||
}
|
||||
{
|
||||
Parameters result = myEmpiProviderR4.notDuplicate(myPerson1Id, myPerson2Id, myRequestDetails);
|
||||
ourLog.info(myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(result));
|
||||
assertEquals("success", result.getParameterFirstRep().getName());
|
||||
assertTrue(((BooleanType) (result.getParameterFirstRep().getValue())).booleanValue());
|
||||
}
|
||||
Parameters result = myEmpiProviderR4.getDuplicatePersons(myRequestDetails);
|
||||
List<Parameters.ParametersParameterComponent> list = result.getParameter();
|
||||
assertThat(list, hasSize(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotDuplicateBadId() {
|
||||
try {
|
||||
myEmpiProviderR4.notDuplicate(myPerson1Id, new StringType("Person/notAnId123"), myRequestDetails);
|
||||
fail();
|
||||
} catch (ResourceNotFoundException e) {
|
||||
assertEquals("Resource Person/notAnId123 is not known", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void assertEmpiLink(int theExpectedSize, List<Parameters.ParametersParameterComponent> thePart, String thePersonId, String theTargetId, EmpiMatchResultEnum theMatchResult) {
|
||||
assertThat(thePart, hasSize(theExpectedSize));
|
||||
assertThat(thePart.get(0).getName(), is("personId"));
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
@ -30,6 +31,7 @@ public class EmpiLinkSvcTest extends BaseEmpiR4Test {
|
|||
myExpungeEverythingService.expungeEverythingByType(EmpiLink.class);
|
||||
super.after();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compareEmptyPatients() {
|
||||
Patient patient = new Patient();
|
||||
|
@ -61,6 +63,62 @@ public class EmpiLinkSvcTest extends BaseEmpiR4Test {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testPossibleDuplicate() {
|
||||
assertLinkCount(0);
|
||||
Person person = createPerson();
|
||||
Person target = createPerson();
|
||||
|
||||
myEmpiLinkSvc.updateLink(person, target, EmpiMatchResultEnum.POSSIBLE_DUPLICATE, EmpiLinkSourceEnum.AUTO, createContextForCreate());
|
||||
assertLinkCount(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoMatchBlocksPossibleDuplicate() {
|
||||
assertLinkCount(0);
|
||||
Person person = createPerson();
|
||||
Person target = createPerson();
|
||||
|
||||
Long personPid = myIdHelperService.getPidOrNull(person);
|
||||
Long targetPid = myIdHelperService.getPidOrNull(target);
|
||||
assertFalse(myEmpiLinkDaoSvc.getLinkByPersonPidAndTargetPid(personPid, targetPid).isPresent());
|
||||
assertFalse(myEmpiLinkDaoSvc.getLinkByPersonPidAndTargetPid(targetPid, personPid).isPresent());
|
||||
|
||||
saveNoMatchLink(personPid, targetPid);
|
||||
|
||||
myEmpiLinkSvc.updateLink(person, target, EmpiMatchResultEnum.POSSIBLE_DUPLICATE, EmpiLinkSourceEnum.AUTO, createContextForCreate());
|
||||
assertFalse(myEmpiLinkDaoSvc.getEmpiLinksByPersonPidTargetPidAndMatchResult(personPid, targetPid, EmpiMatchResultEnum.POSSIBLE_DUPLICATE).isPresent());
|
||||
assertLinkCount(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoMatchBlocksPossibleDuplicateReversed() {
|
||||
assertLinkCount(0);
|
||||
Person person = createPerson();
|
||||
Person target = createPerson();
|
||||
|
||||
Long personPid = myIdHelperService.getPidOrNull(person);
|
||||
Long targetPid = myIdHelperService.getPidOrNull(target);
|
||||
assertFalse(myEmpiLinkDaoSvc.getLinkByPersonPidAndTargetPid(personPid, targetPid).isPresent());
|
||||
assertFalse(myEmpiLinkDaoSvc.getLinkByPersonPidAndTargetPid(targetPid, personPid).isPresent());
|
||||
|
||||
saveNoMatchLink(targetPid, personPid);
|
||||
|
||||
myEmpiLinkSvc.updateLink(person, target, EmpiMatchResultEnum.POSSIBLE_DUPLICATE, EmpiLinkSourceEnum.AUTO, createContextForCreate());
|
||||
assertFalse(myEmpiLinkDaoSvc.getEmpiLinksByPersonPidTargetPidAndMatchResult(personPid, targetPid, EmpiMatchResultEnum.POSSIBLE_DUPLICATE).isPresent());
|
||||
assertLinkCount(1);
|
||||
}
|
||||
|
||||
private void saveNoMatchLink(Long thePersonPid, Long theTargetPid) {
|
||||
EmpiLink noMatchLink = new EmpiLink()
|
||||
.setPersonPid(thePersonPid)
|
||||
.setTargetPid(theTargetPid)
|
||||
.setLinkSource(EmpiLinkSourceEnum.MANUAL)
|
||||
.setMatchResult(EmpiMatchResultEnum.NO_MATCH);
|
||||
myEmpiLinkDaoSvc.save(noMatchLink);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManualEmpiLinksCannotBeModifiedBySystem() {
|
||||
Person person = createPerson(buildJanePerson());
|
||||
|
|
|
@ -22,7 +22,10 @@ package ca.uhn.fhir.empi.api;
|
|||
|
||||
import ca.uhn.fhir.empi.model.EmpiTransactionContext;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||
|
||||
public interface IEmpiLinkUpdaterSvc {
|
||||
IAnyResource updateLink(IAnyResource thePerson, IAnyResource theTarget, EmpiMatchResultEnum theMatchResult, EmpiTransactionContext theEmpiContext);
|
||||
|
||||
IBaseParameters notDuplicatePerson(IAnyResource thePerson, IAnyResource theTarget, EmpiTransactionContext theEmpiContext);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
|||
|
||||
public abstract class BaseEmpiProvider {
|
||||
|
||||
private final FhirContext myFhirContext;
|
||||
protected final FhirContext myFhirContext;
|
||||
private final IResourceLoader myResourceLoader;
|
||||
|
||||
public BaseEmpiProvider(FhirContext theFhirContext, IResourceLoader theResourceLoader) {
|
||||
|
@ -125,6 +125,11 @@ public abstract class BaseEmpiProvider {
|
|||
}
|
||||
}
|
||||
|
||||
protected void validateNotDuplicateParameters(IPrimitiveType<String> thePersonId, IPrimitiveType<String> theTargetId) {
|
||||
validateNotNull(ProviderConstants.EMPI_UPDATE_LINK_PERSON_ID, thePersonId);
|
||||
validateNotNull(ProviderConstants.EMPI_UPDATE_LINK_TARGET_ID, theTargetId);
|
||||
}
|
||||
|
||||
protected EmpiTransactionContext createEmpiContext(RequestDetails theRequestDetails) {
|
||||
TransactionLogMessages transactionLogMessages = TransactionLogMessages.createFromTransactionGuid(theRequestDetails.getTransactionGuid());
|
||||
return new EmpiTransactionContext(transactionLogMessages, EmpiTransactionContext.OperationType.MERGE_PERSONS);
|
||||
|
|
|
@ -134,4 +134,19 @@ public class EmpiProviderDstu3 extends BaseEmpiProvider {
|
|||
public Parameters getDuplicatePersons(ServletRequestDetails theRequestDetails) {
|
||||
return (Parameters) myEmpiLinkQuerySvc.getPossibleDuplicates(createEmpiContext(theRequestDetails));
|
||||
}
|
||||
|
||||
@Operation(name = ProviderConstants.EMPI_NOT_DUPLICATE)
|
||||
// TODO KHS can this return void?
|
||||
public Parameters notDuplicate(@OperationParam(name=ProviderConstants.EMPI_QUERY_LINKS_PERSON_ID, min = 1, max = 1) StringType thePersonId,
|
||||
@OperationParam(name=ProviderConstants.EMPI_QUERY_LINKS_TARGET_ID, min = 1, max = 1) StringType theTargetId,
|
||||
ServletRequestDetails theRequestDetails) {
|
||||
|
||||
validateNotDuplicateParameters(thePersonId, theTargetId);
|
||||
IAnyResource person = getLatestPersonFromIdOrThrowException(ProviderConstants.EMPI_UPDATE_LINK_PERSON_ID, thePersonId.getValue());
|
||||
IAnyResource target = getLatestPersonFromIdOrThrowException(ProviderConstants.EMPI_UPDATE_LINK_TARGET_ID, theTargetId.getValue());
|
||||
validateSameVersion(person, thePersonId);
|
||||
validateSameVersion(target, theTargetId);
|
||||
|
||||
return (Parameters) myEmpiLinkUpdaterSvc.notDuplicatePerson(person, target, createEmpiContext(theRequestDetails));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,4 +135,18 @@ public class EmpiProviderR4 extends BaseEmpiProvider {
|
|||
public Parameters getDuplicatePersons(ServletRequestDetails theRequestDetails) {
|
||||
return (Parameters) myEmpiLinkQuerySvc.getPossibleDuplicates(createEmpiContext(theRequestDetails));
|
||||
}
|
||||
|
||||
@Operation(name = ProviderConstants.EMPI_NOT_DUPLICATE)
|
||||
public Parameters notDuplicate(@OperationParam(name=ProviderConstants.EMPI_QUERY_LINKS_PERSON_ID, min = 1, max = 1) StringType thePersonId,
|
||||
@OperationParam(name=ProviderConstants.EMPI_QUERY_LINKS_TARGET_ID, min = 1, max = 1) StringType theTargetId,
|
||||
ServletRequestDetails theRequestDetails) {
|
||||
|
||||
validateNotDuplicateParameters(thePersonId, theTargetId);
|
||||
IAnyResource person = getLatestPersonFromIdOrThrowException(ProviderConstants.EMPI_UPDATE_LINK_PERSON_ID, thePersonId.getValue());
|
||||
IAnyResource target = getLatestPersonFromIdOrThrowException(ProviderConstants.EMPI_UPDATE_LINK_TARGET_ID, theTargetId.getValue());
|
||||
validateSameVersion(person, thePersonId);
|
||||
validateSameVersion(target, theTargetId);
|
||||
|
||||
return (Parameters) myEmpiLinkUpdaterSvc.notDuplicatePerson(person, target, createEmpiContext(theRequestDetails));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,4 +80,5 @@ public class ProviderConstants {
|
|||
public static final String EMPI_QUERY_LINKS_LINK_SOURCE = "linkSource";
|
||||
|
||||
public static final String EMPI_DUPLICATE_PERSONS = "$empi-duplicate-persons";
|
||||
public static final String EMPI_NOT_DUPLICATE = "$empi-not-duplicate";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue