Empi 56 link merged person (#1902)

This commit is contained in:
Ken Stevens 2020-06-05 15:50:50 -04:00 committed by GitHub
parent 558f419955
commit dd84846b94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 16 deletions

View File

@ -317,7 +317,11 @@ The operation returns the updated `Person` resource. Note that this is the only
## Merge Persons
The `$empi-merge-persons` operation can be used to merge one Person resource with another. When doing this, you will need to decide which resource to merge from and which one to merge to. In most cases, fields will be merged (e.g. names, identifiers, and links will be the union of two). However when there is a conflict (e.g. birthday), fields in the toPerson will take precedence over fields in the fromPerson. This operation takes the following parameters:
The `$empi-merge-persons` operation can be used to merge one Person resource with another. When doing this, you will need to decide which resource to merge from and which one to merge to. In most cases, fields will be merged (e.g. names, identifiers, and links will be the union of two). However when there is a conflict (e.g. birthday), fields in the toPerson will take precedence over fields in the fromPerson
After the merge is complete, `fromPerson.active` is set to `false`. Also, a new link with assurance level 4 (MANUAL MATCH) will be added pointing from the fromPerson to the toPerson.
This operation takes the following parameters:
<table class="table table-striped table-condensed">
<thead>
@ -334,7 +338,7 @@ The `$empi-merge-persons` operation can be used to merge one Person resource wit
<td>String</td>
<td>1..1</td>
<td>
The id of the Person resource to merge data from. "active" will be set to "false" on this resource after the merge.
The id of the Person resource to merge data from.
</td>
</tr>
<tr>

View File

@ -20,6 +20,8 @@ package ca.uhn.fhir.jpa.empi.svc;
* #L%
*/
import ca.uhn.fhir.empi.api.EmpiLinkSourceEnum;
import ca.uhn.fhir.empi.api.EmpiMatchResultEnum;
import ca.uhn.fhir.empi.api.IEmpiLinkSvc;
import ca.uhn.fhir.empi.api.IEmpiPersonMergerSvc;
import ca.uhn.fhir.empi.log.Logs;
@ -56,20 +58,38 @@ public class EmpiPersonMergerSvcImpl implements IEmpiPersonMergerSvc {
@Override
@Transactional
public IAnyResource mergePersons(IAnyResource theFromPerson, IAnyResource theToPerson, EmpiTransactionContext theEmpiTransactionContext) {
// TODO EMPI replace this with a post containing the manually merged fields
myPersonHelper.mergePersonFields(theFromPerson, theToPerson);
mergeLinks(theFromPerson, theToPerson, theEmpiTransactionContext);
myEmpiResourceDaoSvc.updatePerson(theToPerson);
log(theEmpiTransactionContext, "Merged " + theFromPerson.getIdElement().toVersionless() + " into " + theToPerson.getIdElement().toVersionless());
Long toPersonPid = myIdHelperService.getPidOrThrowException(theToPerson);
myPersonHelper.mergePersonFields(theFromPerson, theToPerson);
mergeLinks(theFromPerson, theToPerson, toPersonPid, theEmpiTransactionContext);
refreshLinksAndUpdatePerson(theToPerson, theEmpiTransactionContext);
Long fromPersonPid = myIdHelperService.getPidOrThrowException(theFromPerson);
addMergeLink(fromPersonPid, toPersonPid);
myPersonHelper.deactivatePerson(theFromPerson);
myEmpiResourceDaoSvc.updatePerson(theFromPerson);
log(theEmpiTransactionContext, "Deactivated " + theFromPerson.getIdElement().toVersionless());
refreshLinksAndUpdatePerson(theFromPerson, theEmpiTransactionContext);
log(theEmpiTransactionContext, "Merged " + theFromPerson.getIdElement().toVersionless() + " into " + theToPerson.getIdElement().toVersionless());
return theToPerson;
}
private void mergeLinks(IAnyResource theFromPerson, IAnyResource theToPerson, EmpiTransactionContext theEmpiTransactionContext) {
long toPersonPid = myIdHelperService.getPidOrThrowException(theToPerson);
private void addMergeLink(Long theFromPersonPid, Long theToPersonPid) {
EmpiLink empiLink = new EmpiLink()
.setPersonPid(theFromPersonPid)
.setTargetPid(theToPersonPid)
.setMatchResult(EmpiMatchResultEnum.MATCH)
.setLinkSource(EmpiLinkSourceEnum.MANUAL);
myEmpiLinkDaoSvc.save(empiLink);
}
private void refreshLinksAndUpdatePerson(IAnyResource theToPerson, EmpiTransactionContext theEmpiTransactionContext) {
myEmpiLinkSvc.syncEmpiLinksToPersonLinks(theToPerson, theEmpiTransactionContext);
myEmpiResourceDaoSvc.updatePerson(theToPerson);
}
private void mergeLinks(IAnyResource theFromPerson, IAnyResource theToPerson, Long theToPersonPid, EmpiTransactionContext theEmpiTransactionContext) {
List<EmpiLink> incomingLinks = myEmpiLinkDaoSvc.findEmpiLinksByPersonId(theFromPerson);
List<EmpiLink> origLinks = myEmpiLinkDaoSvc.findEmpiLinksByPersonId(theToPerson);
@ -97,13 +117,10 @@ public class EmpiPersonMergerSvcImpl implements IEmpiPersonMergerSvc {
}
}
// The original links didn't contain this target, so move it over to the toPerson
incomingLink.setPersonPid(toPersonPid);
incomingLink.setPersonPid(theToPersonPid);
ourLog.trace("Saving link {}", incomingLink);
myEmpiLinkDaoSvc.save(incomingLink);
}
myEmpiLinkSvc.syncEmpiLinksToPersonLinks(theFromPerson, theEmpiTransactionContext);
myEmpiLinkSvc.syncEmpiLinksToPersonLinks(theToPerson, theEmpiTransactionContext);
}
private Optional<EmpiLink> findLinkWithMatchingTarget(List<EmpiLink> theEmpiLinks, EmpiLink theLinkWithTargetToMatch) {

View File

@ -1,5 +1,8 @@
package ca.uhn.fhir.jpa.empi.provider;
import ca.uhn.fhir.empi.api.EmpiLinkSourceEnum;
import ca.uhn.fhir.empi.api.EmpiMatchResultEnum;
import ca.uhn.fhir.empi.util.AssuranceLevelUtil;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import org.hl7.fhir.r4.model.Bundle;
@ -9,6 +12,9 @@ import org.hl7.fhir.r4.model.StringType;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
@ -48,9 +54,16 @@ public class EmpiProviderMergePersonsR4Test extends BaseProviderR4Test {
public void testMerge() {
Person mergedPerson = myEmpiProviderR4.mergePersons(myFromPersonId, myToPersonId, myRequestDetails);
assertEquals(myToPerson.getIdElement(), mergedPerson.getIdElement());
assertThat(mergedPerson, is(samePersonAs(mergedPerson)));
assertThat(mergedPerson, is(samePersonAs(myToPerson)));
assertEquals(2, getAllPersons().size());
assertEquals(1, getAllActivePersons().size());
Person fromPerson = myPersonDao.read(myFromPerson.getIdElement().toUnqualifiedVersionless());
assertThat(fromPerson.getActive(), is(false));
List<Person.PersonLinkComponent> links = fromPerson.getLink();
assertThat(links, hasSize(1));
assertThat(links.get(0).getTarget().getReference(), is (myToPerson.getIdElement().toUnqualifiedVersionless().getValue()));
assertThat(links.get(0).getAssurance(), is (AssuranceLevelUtil.getAssuranceLevel(EmpiMatchResultEnum.MATCH, EmpiLinkSourceEnum.MANUAL).toR4()));
}
@Test