/**
* Copyright (c) 2009-2010 Misys Open Source Solutions (MOSS) and others
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* Contributors:
* Misys Open Source Solutions - initial API and implementation
* -
*/
package org.openhealthtools.openxds.registry.patient;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openhealthexchange.openpixpdq.data.Patient;
import org.openhealthtools.openxds.dao.XdsRegistryPatientDao;
import org.openhealthtools.openxds.registry.PersonIdentifier;
import org.openhealthexchange.openpixpdq.data.PatientIdentifier;
import org.openhealthtools.openxds.registry.api.RegistryPatientContext;
import org.openhealthtools.openxds.registry.api.RegistryPatientException;
import org.openhealthtools.openxds.registry.api.XdsRegistryPatientService;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
* The class is the core of XDS Registry Patient Manager and
* provides the patient life cycle operations such as createPatient,
* updatePatient, mergePatients and unmergePatients.
*
* @author <a href="mailto:Rasakannu.Palaniyandi@misys.com">Raja</a>
*
*/
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class XdsRegistryPatientServiceImpl implements XdsRegistryPatientService
{
private static Log log = LogFactory.getLog(XdsRegistryPatientServiceImpl.class);
public XdsRegistryPatientDao xdsRegistryPatientDao;
@Transactional(propagation = Propagation.REQUIRES_NEW)
public boolean isValidPatient(PatientIdentifier pid, RegistryPatientContext context) throws RegistryPatientException {
try {
PersonIdentifier identifier = getPersonIdentifier(pid);
PersonIdentifier personIdentifier = xdsRegistryPatientDao.getPersonById(identifier);
if (personIdentifier == null) {
return false;
}
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("Failed while trying to determine if the patient with the given identifier is known." + e, e);
throw new RegistryPatientException(e.getMessage());
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void createPatient(Patient patient, RegistryPatientContext context) throws RegistryPatientException {
try {
for (PatientIdentifier pid : patient.getPatientIds()) {
PersonIdentifier identifier = getPersonIdentifier(pid,patient.isDeathIndicator());
PersonIdentifier personIdentifier = xdsRegistryPatientDao.getPersonById(identifier);
if(personIdentifier != null){
if(personIdentifier.getMerge().equals("Y")){
personIdentifier.setMerge("N");
xdsRegistryPatientDao.updatePersonIdentifier(personIdentifier);
}
}else{
xdsRegistryPatientDao.savePersonIdentifier(identifier);
}
}
}
catch (Exception e) {
log.error("Failed while trying to save a new patient record in the patient registry." + e, e);
throw new RegistryPatientException(e.getMessage());
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updatePatient(Patient patient, RegistryPatientContext context) throws RegistryPatientException {
for (PatientIdentifier pid : patient.getPatientIds()) {
PersonIdentifier identifier = getPersonIdentifier(pid);
PersonIdentifier personIdentifier = xdsRegistryPatientDao.getPersonById(identifier);
PersonIdentifier updateidentifier = getPersonIdentifier(personIdentifier,pid,patient.isDeathIndicator());
try {
xdsRegistryPatientDao.updatePersonIdentifier(updateidentifier);
} catch (Exception e) {
log.error("Failed while trying to update a patient record in the patient registry." + e, e);
throw new RegistryPatientException(e.getMessage());
}
}
}
@Transactional(propagation = Propagation.REQUIRED)
public void mergePatients(Patient survivingPatient, Patient mergePatient, RegistryPatientContext context) throws RegistryPatientException {
PatientIdentifier survivingId = survivingPatient.getPatientIds().get(0);
PersonIdentifier personIdentifier = getPersonIdentifier(survivingId);
PersonIdentifier survivingPersonId = xdsRegistryPatientDao.getPersonById(personIdentifier);
for (PatientIdentifier pid : mergePatient.getPatientIds()) {
PersonIdentifier retiredId = getPersonIdentifier(pid);
PersonIdentifier retiredPersonId = xdsRegistryPatientDao.getPersonById(retiredId);
if (retiredPersonId == null || survivingPersonId == null) {
log.error("Unable to locate one of the two patient records that need to be merged.");
throw new RegistryPatientException("Unable to identify the two patient records that need to be merged.");
}
retiredPersonId.setSurvivingPatientId(survivingPersonId.getPatientId());
retiredPersonId.setMerge("Y");
try {
xdsRegistryPatientDao.mergePersonIdentifier(retiredPersonId);
} catch (Exception e) {
log.error("Failed while trying to merge two patient records in the patient registry." + e, e);
throw new RegistryPatientException(e.getMessage());
}
}
}
@Transactional(propagation = Propagation.REQUIRED)
public void unmergePatients(Patient survivingPatient, Patient mergePatient, RegistryPatientContext context) throws RegistryPatientException {
PatientIdentifier survivingId = survivingPatient.getPatientIds().get(0);
PersonIdentifier personIdentifier = getPersonIdentifier(survivingId);
PersonIdentifier survivingPersonId = xdsRegistryPatientDao.getPersonById(personIdentifier);
for (PatientIdentifier pid : mergePatient.getPatientIds()) {
PersonIdentifier retiredId = getPersonIdentifier(pid);
PersonIdentifier retiredPersonId = xdsRegistryPatientDao.getPersonById(retiredId);
if (retiredPersonId == null || survivingPersonId == null) {
log.error("Unable to locate one of the two patient records that need to be unmerged.");
throw new RegistryPatientException("Unable to identify the two patient records that need to be unmerged.");
}
if(retiredPersonId.getSurvivingPatientId().equals(survivingPersonId.getPatientId())){
retiredPersonId.setSurvivingPatientId("");
retiredPersonId.setMerge("N");
}else{
log.error("Unable to unmerge the patient because surviving_patient_id of merge patient is not matched with surviving patient");
throw new RegistryPatientException("Unable to unmerge the patient because surviving_patient_id of merge patient is not matched with surviving patient");
}
try {
xdsRegistryPatientDao.mergePersonIdentifier(retiredPersonId);
} catch (Exception e) {
log.error("Failed while trying to unmerge two patient records in the patient registry." + e, e);
throw new RegistryPatientException(e.getMessage());
}
}
}
public XdsRegistryPatientDao getXdsRegistryPatientDao() {
return xdsRegistryPatientDao;
}
public void setXdsRegistryPatientDao(XdsRegistryPatientDao xdsRegistryPatientDao) {
this.xdsRegistryPatientDao = xdsRegistryPatientDao;
}
public static PersonIdentifier getPersonIdentifier(PatientIdentifier patientIdentifier,boolean deleted) {
PersonIdentifier pi = getPersonIdentifier(patientIdentifier);
pi.setDelete(deleted ? "Y" : "N");
pi.setMerge("N");
return pi;
}
public static PersonIdentifier getPersonIdentifier(PatientIdentifier patientIdentifier){
PersonIdentifier pi = new PersonIdentifier();
pi.setPatientId(patientIdentifier.getId());
String assignAuth = getAssigningAuthority(patientIdentifier);
pi.setAssigningAuthority(assignAuth);
return pi;
}
public static PersonIdentifier getPersonIdentifier(PersonIdentifier pi, PatientIdentifier patientIdentifier,boolean deleted) {
pi.setPatientId(patientIdentifier.getId());
String assignAuth = getAssigningAuthority(patientIdentifier);
pi.setAssigningAuthority(assignAuth);
pi.setDelete(deleted ? "Y" : "N");
return pi;
}
/**
* @param patientIdentifier The patient identifier object.
* @return The assigning authority for this patient identifier, formatted as a String
*/
private static String getAssigningAuthority(PatientIdentifier patientIdentifier){
if (patientIdentifier.getAssigningAuthority() == null)
{
return null;
}
String assignFacNam = patientIdentifier.getAssigningAuthority().getNamespaceId();
String assignFacUniversal = patientIdentifier.getAssigningAuthority().getUniversalId();
String assignFacUniversaltype = patientIdentifier.getAssigningAuthority().getUniversalIdType();
if(assignFacNam != null && assignFacUniversal != null && assignFacUniversaltype !=null)
return assignFacNam +"&"+ assignFacUniversal + "&"+ assignFacUniversaltype;
else if(assignFacNam == null && assignFacUniversal != null && assignFacUniversaltype !=null){
return "&"+ assignFacUniversal + "&"+ assignFacUniversaltype;
}else if(assignFacNam != null && assignFacUniversaltype == null){
return assignFacNam + "&"+ assignFacUniversal + "&";
}
return null;
}
}