use of org.openmrs.person.PersonMergeLog in project openmrs-core by openmrs.
the class PatientServiceImpl method mergePatients.
/**
* 1) Moves object (encounters/obs) pointing to <code>nonPreferred</code> to
* <code>preferred</code> 2) Copies data (gender/birthdate/names/ids/etc) from
* <code>nonPreferred</code> to <code>preferred</code> iff the data is missing or null in
* <code>preferred</code> 3) <code>notPreferred</code> is marked as voided
*
* @param preferred
* @param notPreferred
* @throws APIException
* @see org.openmrs.api.PatientService#mergePatients(org.openmrs.Patient, org.openmrs.Patient)
*/
@Override
public void mergePatients(Patient preferred, Patient notPreferred) throws APIException, SerializationException {
log.debug("Merging patients: (preferred)" + preferred.getPatientId() + ", (notPreferred) " + notPreferred.getPatientId());
if (preferred.getPatientId().equals(notPreferred.getPatientId())) {
log.debug("Merge operation cancelled: Cannot merge user" + preferred.getPatientId() + " to self");
throw new APIException("Patient.merge.cancelled", new Object[] { preferred.getPatientId() });
}
requireNoActiveOrderOfSameType(preferred, notPreferred);
PersonMergeLogData mergedData = new PersonMergeLogData();
mergeVisits(preferred, notPreferred, mergedData);
mergeEncounters(preferred, notPreferred, mergedData);
mergeProgramEnrolments(preferred, notPreferred, mergedData);
mergeRelationships(preferred, notPreferred, mergedData);
mergeObservationsNotContainedInEncounters(preferred, notPreferred, mergedData);
mergeIdentifiers(preferred, notPreferred, mergedData);
mergeNames(preferred, notPreferred, mergedData);
mergeAddresses(preferred, notPreferred, mergedData);
mergePersonAttributes(preferred, notPreferred, mergedData);
mergeGenderInformation(preferred, notPreferred, mergedData);
mergeDateOfBirth(preferred, notPreferred, mergedData);
mergeDateOfDeath(preferred, notPreferred, mergedData);
// void the non preferred patient
Context.getPatientService().voidPatient(notPreferred, "Merged with patient #" + preferred.getPatientId());
// void the person associated with not preferred patient
Context.getPersonService().voidPerson(notPreferred, "The patient corresponding to this person has been voided and Merged with patient #" + preferred.getPatientId());
// associate the Users associated with the not preferred person, to the preferred person.
changeUserAssociations(preferred, notPreferred, mergedData);
// Save the newly update preferred patient
// This must be called _after_ voiding the nonPreferred patient so that
// a "Duplicate Identifier" error doesn't pop up.
savePatient(preferred);
// save the person merge log
PersonMergeLog personMergeLog = new PersonMergeLog();
personMergeLog.setWinner(preferred);
personMergeLog.setLoser(notPreferred);
personMergeLog.setPersonMergeLogData(mergedData);
Context.getPersonService().savePersonMergeLog(personMergeLog);
}
use of org.openmrs.person.PersonMergeLog in project openmrs-core by openmrs.
the class PatientServiceImpl method mergeAddresses.
private void mergeAddresses(Patient preferred, Patient notPreferred, PersonMergeLogData mergedData) throws SerializationException {
// (must be done after all calls to services above so hbm doesn't try to save things prematurely (hacky)
for (PersonAddress newAddress : notPreferred.getAddresses()) {
boolean containsAddress = false;
for (PersonAddress currentAddress : preferred.getAddresses()) {
containsAddress = currentAddress.equalsContent(newAddress);
if (containsAddress) {
break;
}
}
if (!containsAddress) {
PersonAddress tmpAddress = (PersonAddress) newAddress.clone();
tmpAddress.setPersonAddressId(null);
tmpAddress.setVoided(false);
tmpAddress.setVoidedBy(null);
tmpAddress.setVoidReason(null);
// addresses from non-preferred patient shouldn't be marked as preferred
tmpAddress.setPreferred(false);
tmpAddress.setUuid(UUID.randomUUID().toString());
preferred.addAddress(tmpAddress);
mergedData.addCreatedAddress(tmpAddress.getUuid());
log.debug("Merging address " + newAddress.getPersonAddressId() + " to " + preferred.getPatientId());
}
}
// copy person attributes
for (PersonAttribute attr : notPreferred.getAttributes()) {
if (!attr.getVoided()) {
PersonAttribute tmpAttr = attr.copy();
tmpAttr.setPerson(null);
tmpAttr.setUuid(UUID.randomUUID().toString());
preferred.addAttribute(tmpAttr);
mergedData.addCreatedAttribute(tmpAttr.getUuid());
}
}
// move all other patient info
mergedData.setPriorGender(preferred.getGender());
if (!"M".equals(preferred.getGender()) && !"F".equals(preferred.getGender())) {
preferred.setGender(notPreferred.getGender());
}
mergedData.setPriorDateOfBirth(preferred.getBirthdate());
mergedData.setPriorDateOfBirthEstimated(preferred.getBirthdateEstimated());
if (preferred.getBirthdate() == null || (preferred.getBirthdateEstimated() && !notPreferred.getBirthdateEstimated())) {
preferred.setBirthdate(notPreferred.getBirthdate());
preferred.setBirthdateEstimated(notPreferred.getBirthdateEstimated());
}
mergedData.setPriorDateOfDeathEstimated(preferred.getDeathdateEstimated());
if (preferred.getDeathdateEstimated() == null) {
preferred.setDeathdateEstimated(notPreferred.getDeathdateEstimated());
}
mergedData.setPriorDateOfDeath(preferred.getDeathDate());
if (preferred.getDeathDate() == null) {
preferred.setDeathDate(notPreferred.getDeathDate());
}
if (preferred.getCauseOfDeath() != null) {
mergedData.setPriorCauseOfDeath(preferred.getCauseOfDeath().getUuid());
}
if (preferred.getCauseOfDeath() == null) {
preferred.setCauseOfDeath(notPreferred.getCauseOfDeath());
}
// void the non preferred patient
Context.getPatientService().voidPatient(notPreferred, "Merged with patient #" + preferred.getPatientId());
// void the person associated with not preferred patient
Context.getPersonService().voidPerson(notPreferred, "The patient corresponding to this person has been voided and Merged with patient #" + preferred.getPatientId());
// associate the Users associated with the not preferred person, to the preferred person.
changeUserAssociations(preferred, notPreferred, mergedData);
// Save the newly update preferred patient
// This must be called _after_ voiding the nonPreferred patient so that
// a "Duplicate Identifier" error doesn't pop up.
savePatient(preferred);
// save the person merge log
PersonMergeLog personMergeLog = new PersonMergeLog();
personMergeLog.setWinner(preferred);
personMergeLog.setLoser(notPreferred);
personMergeLog.setPersonMergeLogData(mergedData);
Context.getPersonService().savePersonMergeLog(personMergeLog);
}
use of org.openmrs.person.PersonMergeLog in project openmrs-core by openmrs.
the class PatientServiceTest method mergePatients_shouldAuditMovedIndependentObservations.
/**
* @see PatientService#mergePatients(Patient,Patient)
*/
@Test
public void mergePatients_shouldAuditMovedIndependentObservations() throws Exception {
// retrieve patients
Patient preferred = patientService.getPatient(999);
Patient notPreferred = patientService.getPatient(7);
voidOrders(Collections.singleton(notPreferred));
// get an observation for notPreferred and make it independent from any encounter
Obs obs = Context.getObsService().getObs(7);
obs.setEncounter(null);
obs.setComment("this observation is for testing the merge");
Context.getObsService().saveObs(obs, "Reason cannot be blank");
// merge the two patients and retrieve the audit object
PersonMergeLog audit = mergeAndRetrieveAudit(preferred, notPreferred);
String uuid = null;
List<Obs> observations = Context.getObsService().getObservationsByPerson(preferred);
for (Obs o : observations) {
if (obs.getComment().equals(o.getComment())) {
uuid = o.getUuid();
}
}
Assert.assertTrue("moving of independent observation was not audited", isValueInList(uuid, audit.getPersonMergeLogData().getMovedIndependentObservations()));
}
use of org.openmrs.person.PersonMergeLog in project openmrs-core by openmrs.
the class PatientServiceTest method mergePatients_shouldAuditPriorCauseOfDeath.
/**
* @see PatientService#mergePatients(Patient,Patient)
*/
@Test
public void mergePatients_shouldAuditPriorCauseOfDeath() throws Exception {
// retrieve preferred patient and set a cause of death
Patient preferred = patientService.getPatient(999);
preferred.setCauseOfDeath(Context.getConceptService().getConcept(3));
preferred.setDeathDate(new Date());
preferred.setDead(true);
preferred.addName(new PersonName("givenName", "middleName", "familyName"));
patientService.savePatient(preferred);
// merge with not preferred
Patient notPreferred = patientService.getPatient(7);
voidOrders(Collections.singleton(notPreferred));
PersonMergeLog audit = mergeAndRetrieveAudit(preferred, notPreferred);
Assert.assertEquals("prior cause of death was not audited", Context.getConceptService().getConcept(3).getUuid(), audit.getPersonMergeLogData().getPriorCauseOfDeath());
}
use of org.openmrs.person.PersonMergeLog in project openmrs-core by openmrs.
the class PatientServiceTest method mergePatients_shouldAuditPriorDateOfDeathEstimated.
/**
* @see PatientService#mergePatients(Patient,Patient)
*/
@Test
public void mergePatients_shouldAuditPriorDateOfDeathEstimated() throws Exception {
// retrieve preferred patient and set a date of death
GregorianCalendar cDate = new GregorianCalendar();
cDate.setTime(new Date());
Patient preferred = patientService.getPatient(999);
preferred.setDeathDate(cDate.getTime());
preferred.setDeathdateEstimated(true);
preferred.setCauseOfDeath(Context.getConceptService().getConcept(3));
preferred.addName(new PersonName("givenName", "middleName", "familyName"));
patientService.savePatient(preferred);
Patient notPreferred = patientService.getPatient(7);
voidOrders(Collections.singleton(notPreferred));
PersonMergeLog audit = mergeAndRetrieveAudit(preferred, notPreferred);
Assert.assertTrue("prior estimated date of death was not audited", audit.getPersonMergeLogData().getPriorDateOfDeathEstimated());
}
Aggregations