Search in sources :

Example 26 with PersonMergeLog

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);
}
Also used : APIException(org.openmrs.api.APIException) PersonMergeLog(org.openmrs.person.PersonMergeLog) PersonMergeLogData(org.openmrs.person.PersonMergeLogData)

Example 27 with 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);
}
Also used : PersonAddress(org.openmrs.PersonAddress) PersonMergeLog(org.openmrs.person.PersonMergeLog) PersonAttribute(org.openmrs.PersonAttribute)

Example 28 with 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()));
}
Also used : Obs(org.openmrs.Obs) Patient(org.openmrs.Patient) PersonMergeLog(org.openmrs.person.PersonMergeLog) BaseContextSensitiveTest(org.openmrs.test.BaseContextSensitiveTest) PatientServiceImplTest(org.openmrs.api.impl.PatientServiceImplTest) Test(org.junit.Test)

Example 29 with PersonMergeLog

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());
}
Also used : PersonName(org.openmrs.PersonName) Patient(org.openmrs.Patient) PersonMergeLog(org.openmrs.person.PersonMergeLog) Date(java.util.Date) BaseContextSensitiveTest(org.openmrs.test.BaseContextSensitiveTest) PatientServiceImplTest(org.openmrs.api.impl.PatientServiceImplTest) Test(org.junit.Test)

Example 30 with PersonMergeLog

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());
}
Also used : PersonName(org.openmrs.PersonName) GregorianCalendar(java.util.GregorianCalendar) Patient(org.openmrs.Patient) PersonMergeLog(org.openmrs.person.PersonMergeLog) Date(java.util.Date) BaseContextSensitiveTest(org.openmrs.test.BaseContextSensitiveTest) PatientServiceImplTest(org.openmrs.api.impl.PatientServiceImplTest) Test(org.junit.Test)

Aggregations

PersonMergeLog (org.openmrs.person.PersonMergeLog)41 Test (org.junit.Test)37 BaseContextSensitiveTest (org.openmrs.test.BaseContextSensitiveTest)37 Patient (org.openmrs.Patient)18 PatientServiceImplTest (org.openmrs.api.impl.PatientServiceImplTest)18 Person (org.openmrs.Person)9 PersonName (org.openmrs.PersonName)8 PersonMergeLogData (org.openmrs.person.PersonMergeLogData)8 Date (java.util.Date)6 BindException (org.springframework.validation.BindException)6 Errors (org.springframework.validation.Errors)6 GregorianCalendar (java.util.GregorianCalendar)4 Location (org.openmrs.Location)2 Obs (org.openmrs.Obs)2 PatientIdentifier (org.openmrs.PatientIdentifier)2 PersonAddress (org.openmrs.PersonAddress)2 PersonAttribute (org.openmrs.PersonAttribute)2 ArrayList (java.util.ArrayList)1 Encounter (org.openmrs.Encounter)1 PatientIdentifierType (org.openmrs.PatientIdentifierType)1