Java tutorial
/** * The contents of this file are subject to the OpenMRS Public License * Version 1.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://license.openmrs.org * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * Copyright (C) OpenMRS, LLC. All Rights Reserved. */ package org.openmrs.module.rheapocadapter.impl; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; import ca.uhn.hl7v2.model.Varies; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openmrs.Concept; import org.openmrs.ConceptAnswer; import org.openmrs.ConceptDatatype; import org.openmrs.ConceptMap; import org.openmrs.ConceptName; import org.openmrs.ConceptNumeric; import org.openmrs.ConceptSource; import org.openmrs.Drug; import org.openmrs.Encounter; import org.openmrs.EncounterType; import org.openmrs.Location; import org.openmrs.Obs; import org.openmrs.Patient; import org.openmrs.PatientIdentifier; import org.openmrs.PatientIdentifierType; import org.openmrs.Person; import org.openmrs.PersonAttribute; import org.openmrs.PersonAttributeType; import org.openmrs.PersonName; import org.openmrs.User; import org.openmrs.api.ConceptService; import org.openmrs.api.context.Context; import org.openmrs.hl7.handler.ProposingConceptException; import org.openmrs.module.rheapocadapter.RHEAConstants; import org.openmrs.module.rheapocadapter.RHEAHL7Constants; import org.openmrs.module.rheapocadapter.service.MessageTransformer; import org.openmrs.module.rheapocadapter.service.TransactionService; import org.openmrs.util.OpenmrsConstants; import org.openmrs.util.OpenmrsUtil; import org.springframework.util.StringUtils; import ca.uhn.hl7v2.HL7Exception; import ca.uhn.hl7v2.app.Application; import ca.uhn.hl7v2.app.ApplicationException; import ca.uhn.hl7v2.model.DataTypeException; import ca.uhn.hl7v2.model.Message; import ca.uhn.hl7v2.model.Type; import ca.uhn.hl7v2.model.v25.segment.NK1; import ca.uhn.hl7v2.model.v25.datatype.CE; import ca.uhn.hl7v2.model.v25.datatype.CWE; import ca.uhn.hl7v2.model.v25.datatype.CX; import ca.uhn.hl7v2.model.v25.datatype.DT; import ca.uhn.hl7v2.model.v25.datatype.DTM; import ca.uhn.hl7v2.model.v25.datatype.FT; import ca.uhn.hl7v2.model.v25.datatype.ID; import ca.uhn.hl7v2.model.v25.datatype.NM; import ca.uhn.hl7v2.model.v25.datatype.ST; import ca.uhn.hl7v2.model.v25.datatype.TM; import ca.uhn.hl7v2.model.v25.datatype.TS; import ca.uhn.hl7v2.model.v25.datatype.XAD; import ca.uhn.hl7v2.model.v25.datatype.XCN; import ca.uhn.hl7v2.model.v25.group.ORU_R01_OBSERVATION; import ca.uhn.hl7v2.model.v25.group.ORU_R01_ORDER_OBSERVATION; import ca.uhn.hl7v2.model.v25.group.ORU_R01_PATIENT_RESULT; import ca.uhn.hl7v2.model.v25.message.ADT_A05; import ca.uhn.hl7v2.model.v25.message.ORU_R01; import ca.uhn.hl7v2.model.v25.segment.MSH; import ca.uhn.hl7v2.model.v25.segment.OBR; import ca.uhn.hl7v2.model.v25.segment.OBX; import ca.uhn.hl7v2.model.v25.segment.ORC; import ca.uhn.hl7v2.model.v25.segment.PD1; import ca.uhn.hl7v2.model.v25.segment.PID; import ca.uhn.hl7v2.model.v25.segment.PV1; import ca.uhn.hl7v2.parser.EncodingNotSupportedException; import ca.uhn.hl7v2.parser.GenericParser; import ca.uhn.hl7v2.parser.Parser; /** * */ public class HL7MessageTransformer implements MessageTransformer, Application { private Log log = LogFactory.getLog(HL7MessageTransformer.class); private TransactionService service = Context.getService(TransactionService.class); private static Integer obxCount = 0; int orderObsCount = 0; int counter = 0; private ORU_R01 r01 = new ORU_R01(); List<Encounter> encounterList = new ArrayList<Encounter>(); public List<Encounter> getEncounterList() { return encounterList; } public void setEncounterList(List<Encounter> encounterList) { this.encounterList = encounterList; } public boolean canProcess(Message message) { return message != null && "ORU_R01".equals(message.getName()); } public Message processMessage(Message message) throws ApplicationException { if (message instanceof ORU_R01) { try { ORU_R01 oru = (ORU_R01) message; return oru; } catch (ClassCastException e) { log.error("Error casting " + message.getClass().getName() + " to ORU_R01", e); throw new ApplicationException("Invalid message type for handler"); } } else if (message instanceof ADT_A05) { try { ADT_A05 adt = (ADT_A05) message; log.info("ADT Message"); return adt; } catch (ClassCastException e) { log.error("Error casting " + message.getClass().getName() + " to ADT_A05 : " + e.getMessage()); throw new ApplicationException("Invalid message type for handler"); } } else { throw new ApplicationException("Invalid message sent to ORU_R01/ADT_A05 handler"); } } /** * Auto generated method comment * * @param adt * @return */ public Patient patientFromADT_A051(ADT_A05 adt) throws HL7Exception { PID pid = adt.getPID(); log.info("PID =" + pid.toString()); Patient patient = getPatient(pid); setParentsNames(patient, adt); return patient; } public List<Obs> fromORU_R01toObs(ORU_R01 oru) throws HL7Exception { // validate message validate(oru); List<Obs> obses = new ArrayList<Obs>(); // extract segments for convenient use below MSH msh = getMSH(oru); PID pid = getPID(oru); String messageControlId = msh.getMessageControlID().getValue(); if (log.isDebugEnabled()) log.debug("Found HL7 message in inbound queue with control id = " + messageControlId); Patient patient = getPatient(pid); if (log.isDebugEnabled()) log.debug("Processing HL7 message for patient " + patient.getPatientId()); // create observations if (log.isDebugEnabled()) log.debug("Creating observations for message " + messageControlId + "..."); ORU_R01_PATIENT_RESULT patientResult = oru.getPATIENT_RESULT(); int numObr = patientResult.getORDER_OBSERVATIONReps(); for (int i = 0; i < numObr; i++) { if (log.isDebugEnabled()) log.debug("Processing OBR (" + i + " of " + numObr + ")"); ORU_R01_ORDER_OBSERVATION orderObs = patientResult.getORDER_OBSERVATION(i); // the parent obr OBR obr = orderObs.getOBR(); int numObs = orderObs.getOBSERVATIONReps(); for (int j = 0; j < numObs; j++) { if (log.isDebugEnabled()) log.debug("Processing OBS (" + j + " of " + numObs + ")"); OBX obx = orderObs.getOBSERVATION(j).getOBX(); PV1 pv1 = oru.getPATIENT_RESULT().getPATIENT().getVISIT().getPV1(); Obs obs; try { obs = parseObs(obx, obr, pid, pv1); if (!obs.getValueText().equals(null)) obs.setValueText(obs.getValueText() + "/" + oru.toString()); else obs.setValueText(oru.toString()); obses.add(obs); } catch (ParseException e) { log.error("Unable to parse" + e.getMessage()); } } } return (obses.isEmpty()) ? obses : null; } private void validate(Message message) throws HL7Exception { // TODO: check version, etc. } private MSH getMSH(ORU_R01 oru) { return oru.getMSH(); } private PID getPID(ORU_R01 oru) { return oru.getPATIENT_RESULT().getPATIENT().getPID(); } private Obs parseObs(OBX obx, OBR obr, PID pid, PV1 pv1) throws HL7Exception, ParseException { if (log.isDebugEnabled()) log.debug("parsing observation: " + obx); Encounter encounter = new Encounter(); if (pv1 != null) { encounter.setEncounterDatetime( DateFormat.getDateTimeInstance().parse(pv1.getAdmitDateTime().getTime().getValue())); } Varies[] values = obx.getObservationValue(); // bail out if no values were found if (values == null || values.length < 1) return null; String hl7Datatype = values[0].getName(); if (log.isDebugEnabled()) log.debug(" datatype = " + hl7Datatype); Concept concept = getConcept(obx.getObservationIdentifier()); if (log.isDebugEnabled()) log.debug(" concept = " + concept.getConceptId()); ConceptName conceptName = getConceptName(obx.getObservationIdentifier()); if (log.isDebugEnabled()) log.debug(" concept-name = " + conceptName); Date datetime = getDatetime(obx); if (log.isDebugEnabled()) log.debug(" timestamp = " + datetime); if (datetime == null) datetime = new Date(); Obs obs = new Obs(); Patient patient = getPatient(pid); obs.setPerson(patient); obs.setConcept(concept); obs.setEncounter(encounter); obs.setObsDatetime(datetime); obs.setLocation(null); obs.setCreator(Context.getAuthenticatedUser()); obs.setDateCreated(getDatetime(obr)); Type obx5 = values[0].getData(); if ("NM".equals(hl7Datatype)) { String value = ((NM) obx5).getValue(); if (value == null || value.length() == 0) { log.warn("Not creating null valued obs for concept " + concept); return null; } else if (value.equals("0") || value.equals("1")) { obs.setConcept(concept); if (concept.getDatatype().isBoolean()) { obs.setValueAsString(value.equals("1") ? "true" : "false"); } else if (concept.getDatatype().isNumeric()) try { obs.setValueNumeric(Double.valueOf(value)); } catch (NumberFormatException e) { throw new HL7Exception("numeric (NM) value '" + value + "' is not numeric for concept #" + concept.getConceptId() + " (" + conceptName.getName() + ") ", e); } else if (concept.getDatatype().isCoded()) { Concept answer = value.equals("1") ? Context.getConceptService().getConceptByName("true") : Context.getConceptService().getConceptByName("false"); boolean isValidAnswer = false; Collection<ConceptAnswer> conceptAnswers = concept.getAnswers(); if (conceptAnswers != null && conceptAnswers.size() > 0) { for (ConceptAnswer conceptAnswer : conceptAnswers) { if (conceptAnswer.getAnswerConcept().equals(answer)) { obs.setValueCoded(answer); isValidAnswer = true; break; } } } // answer the boolean answer concept was't found if (!isValidAnswer) throw new HL7Exception(answer.toString() + " is not a valid answer for obs with uuid "); } else { // throw this exception to make sure that the handler // doesn't silently ignore bad hl7 message throw new HL7Exception("Can't set boolean concept answer for concept with id " + obs.getConcept().getConceptId()); } } else { try { obs.setValueNumeric(Double.valueOf(value)); } catch (NumberFormatException e) { throw new HL7Exception("numeric (NM) value '" + value + "' is not numeric for concept #" + concept.getConceptId() + " (" + conceptName.getName() + ") in message ", e); } } } else if ("CWE".equals(hl7Datatype)) { log.debug(" CWE observation"); CWE value = (CWE) obx5; String valueIdentifier = value.getIdentifier().getValue(); log.debug(" value id = " + valueIdentifier); String valueName = value.getText().getValue(); log.debug(" value name = " + valueName); try { Concept valueConcept = getConcept(value); obs.setValueCoded(valueConcept); } catch (NumberFormatException e) { throw new HL7Exception( "Invalid concept ID '" + valueIdentifier + "' for OBX-5 value '" + valueName + "'"); } if (log.isDebugEnabled()) log.debug(" Done with CWE"); } else if ("CE".equals(hl7Datatype)) { CE value = (CE) obx5; String valueIdentifier = value.getIdentifier().getValue(); String valueName = value.getText().getValue(); try { obs.setValueCoded(getConcept(value)); } catch (NumberFormatException e) { throw new HL7Exception( "Invalid concept ID '" + valueIdentifier + "' for OBX-5 value '" + valueName + "'"); } } else if ("DT".equals(hl7Datatype)) { DT value = (DT) obx5; Date valueDate = getDate(value.getYear(), value.getMonth(), value.getDay(), 0, 0, 0); if (value == null || valueDate == null) { log.warn("Not creating null valued obs for concept " + concept); return null; } obs.setValueDatetime(valueDate); } else if ("TS".equals(hl7Datatype)) { DTM value = ((TS) obx5).getTime(); Date valueDate = getDate(value.getYear(), value.getMonth(), value.getDay(), value.getHour(), value.getMinute(), value.getSecond()); if (value == null || valueDate == null) { log.warn("Not creating null valued obs for concept " + concept); return null; } obs.setValueDatetime(valueDate); } else if ("TM".equals(hl7Datatype)) { TM value = (TM) obx5; Date valueTime = getDate(0, 0, 0, value.getHour(), value.getMinute(), value.getSecond()); if (value == null || valueTime == null) { log.warn("Not creating null valued obs for concept " + concept); return null; } obs.setValueDatetime(valueTime); } else if ("ST".equals(hl7Datatype)) { ST value = (ST) obx5; if (value == null || value.getValue() == null || value.getValue().trim().length() == 0) { log.warn("Not creating null valued obs for concept " + concept); return null; } obs.setValueText(value.getValue()); } else { // unsupported data type throw new HL7Exception("Unsupported observation datatype '" + hl7Datatype + "'"); } return obs; } private ConceptName getConceptName(CE ce) throws HL7Exception { ST altIdentifier = ce.getAlternateIdentifier(); ID altCodingSystem = ce.getNameOfAlternateCodingSystem(); return getConceptName(altIdentifier, altCodingSystem); } private ConceptName getConceptName(CWE cwe) throws HL7Exception { ST altIdentifier = cwe.getAlternateIdentifier(); ID altCodingSystem = cwe.getNameOfAlternateCodingSystem(); return getConceptName(altIdentifier, altCodingSystem); } private ConceptName getConceptName(ST altIdentifier, ID altCodingSystem) throws HL7Exception { if (altIdentifier != null) { String hl7ConceptNameId = altIdentifier.getValue(); return getConceptName(hl7ConceptNameId); } return null; } private ConceptName getConceptName(String hl7ConceptNameId) throws HL7Exception { ConceptName specifiedConceptName = null; if (hl7ConceptNameId != null) { // get the exact concept name specified by the id try { Integer conceptNameId = new Integer(hl7ConceptNameId); specifiedConceptName = new ConceptName(); specifiedConceptName.setConceptNameId(conceptNameId); } catch (NumberFormatException e) { // if it is not a valid number, more than likely it is a bad hl7 // message log.debug("Invalid concept name ID '" + hl7ConceptNameId + "'", e); } } return specifiedConceptName; } private Date getDate(int year, int month, int day, int hour, int minute, int second) { Calendar cal = Calendar.getInstance(); // Calendar.set(MONTH, int) is zero-based, Hl7 is not cal.set(year, month - 1, day, hour, minute, second); return cal.getTime(); } private Concept getConcept(CE codedElement) throws HL7Exception { String hl7ConceptId = codedElement.getIdentifier().getValue(); String codingSystem = codedElement.getNameOfCodingSystem().getValue(); return getConcept(hl7ConceptId, codingSystem); } private Concept getConcept(CWE codedElement) throws HL7Exception { String hl7ConceptId = codedElement.getIdentifier().getValue(); String codingSystem = codedElement.getNameOfCodingSystem().getValue(); return getConcept(hl7ConceptId, codingSystem); } protected Concept getConcept(String hl7ConceptId, String codingSystem) throws HL7Exception { Concept concept = Context.getConceptService().getConceptByMapping(hl7ConceptId, codingSystem); if (concept == null) { log.error("Unable to find concept with code: " + hl7ConceptId + " and mapping: " + codingSystem + " in hl7 message, a new one created "); concept = new Concept(); ConceptMap conceptMap = new ConceptMap(); conceptMap.setConcept(concept); conceptMap.setSourceCode(hl7ConceptId); conceptMap.setSource(new ConceptSource()); Context.getConceptService().saveConcept(concept); return null; } return concept; } private Date getDatetime(OBX obx) throws HL7Exception { TS ts = obx.getDateTimeOfTheObservation(); return getDatetime(ts); } private Date getDatetime(OBR obr) throws HL7Exception { TS ts = obr.getObservationDateTime(); return getDatetime(ts); } private Date getDatetime(TS ts) throws HL7Exception { Date datetime = null; DTM value = ts.getTime(); if (value.getYear() == 0 || value.getValue() == null) return null; try { datetime = getDate(value.getYear(), value.getMonth(), value.getDay(), value.getHour(), value.getMinute(), value.getSecond()); } catch (DataTypeException e) { } return datetime; } private Patient getPatient(PID pid) throws HL7Exception { log.info("get ID " + pid.getPatientID().getIDNumber()); log.info("get Name " + pid.getPatientName().toString()); Patient patient = resolvePatientId(pid); if (patient == null) throw new HL7Exception("Could not resolve patient"); return patient; } private Patient getPatientORUR01(PID pid) throws HL7Exception { Patient patient; String patId = pid.getPatientIdentifierList(0).getIDNumber().toString(); String idType = pid.getPatientIdentifierList(0).getIdentifierTypeCode().getValue(); PatientIdentifierType patientIdentifierType = Context.getPatientService() .getPatientIdentifierTypeByName(idType); List<PatientIdentifierType> identifierTypeList = new ArrayList<PatientIdentifierType>(); identifierTypeList.add(patientIdentifierType); List<Patient> patients = Context.getPatientService().getPatients(null, patId, identifierTypeList, false); // I am not checking the identifier type here. Need to come back and add // a check for this if (patients.size() == 1) { patient = patients.get(0); } else { throw new HL7Exception("Could not resolve patient"); } return patient; } private Message changeStringToMessage(String mess) throws EncodingNotSupportedException, HL7Exception { Parser genericParser = new GenericParser(); Message message = genericParser.parse(mess); return message; } public void processMessage(String mess) throws ApplicationException, EncodingNotSupportedException, HL7Exception { processMessage(changeStringToMessage(mess)); } private Patient resolvePatientId(PID pid) throws HL7Exception { String patId = pid.getPatientID().getIDNumber().getValue(); log.info("the Id = " + patId); String idType = pid.getPatientID().getIdentifierTypeCode().getValue(); List<PatientIdentifierType> patientIdTypes = Context.getPatientService().getAllPatientIdentifierTypes(); if (!patientIdTypes.contains(idType)) { log.error("Type of the Id not in the list for this site " + idType); return null; } else { Patient patient = new Patient(); // Populate the PID Segment patient.getPersonName().setFamilyName(pid.getPatientName(0).getFamilyName().getSurname().getValue()); patient.getPersonName().setGivenName(pid.getPatientName(0).getGivenName().getValue()); PatientIdentifier patientIdentifier = null; for (CX cx : pid.getPatientIdentifierList()) { patientIdentifier.setIdentifier(cx.getIDNumber().getValue()); patientIdentifier.getIdentifierType().setName(cx.getIdentifierTypeCode().getValue()); patient.getIdentifiers().add(patientIdentifier); } return patient; } } private void setParentsNames(Patient patient, ADT_A05 adt) throws HL7Exception { PD1 pd1 = adt.getPD1(); pd1.getStudentIndicator().setTable(0); pd1.getHandicap().setTable(0); Set<PersonAttribute> att = new TreeSet<PersonAttribute>(); NK1 nk1 = null; for (int i = 0; i < adt.getNK1Reps(); i++) { PersonAttributeType mother = Context.getPersonService() .getPersonAttributeTypeByName(RHEAConstants.MOTHER_NAME_ATTRIBUTE_TYPE); PersonAttributeType father = Context.getPersonService() .getPersonAttributeTypeByName(RHEAConstants.FATHER_NAME_ATTRIBUTE_TYPE); nk1 = adt.getNK1(i); if (nk1.getRelationship().getText().getValue().equalsIgnoreCase("MTH")) { PersonAttribute mom = new PersonAttribute(mother, nk1.getNKName(0).getFamilyName().getSurname().getValue()); att.add(mom); } else if (nk1.getRelationship().getText().getValue().equalsIgnoreCase("FTH")) { PersonAttribute dad = new PersonAttribute(father, nk1.getNKName(0).getFamilyName().getSurname().getValue()); att.add(dad); } } } @Override public String encodingEncounterToMessage(Encounter encounter) { ArrayList<Encounter> encounters = new ArrayList<Encounter>(); encounters.add(encounter); String message = ""; try { message = getMessage(generateORU_R01Message(encounter.getPatient(), encounters)); log.info("after parsing " + message); } catch (HL7Exception e) { // TODO Auto-generated catch block log.error("Error generated", e); } return message; } // private String getConceptMappingId(Concept concept) { // for (ConceptMap conMap : concept.getConceptMappings()) { // if (conMap.getSource().getName().equalsIgnoreCase("LOINC")) { // return conMap.getSourceCode(); // } // } // return null; // // } // // private String getConceptMappingCodingSys(Concept concept) { // for (ConceptMap conMap : concept.getConceptMappings()) { // if (conMap.getSource().getName().equalsIgnoreCase("LOINC")) { // return conMap.getSource().getName(); // } // } // return null; // // } /** * @throws HL7Exception * @throws ApplicationException * @throws EncodingNotSupportedException * @see org.openmrs.module.rheapocadapter.service.MessageTransformer#translateMessage(java.lang.String) */ @Override public Message translateMessage(String message) { try { return processMessage(changeStringToMessage(message)); } catch (EncodingNotSupportedException e) { log.error("Error generated" + e.getMessage()); } catch (ApplicationException e) { log.error("Error generated" + e.getMessage()); } catch (HL7Exception e) { log.error("Error generated" + e.getMessage()); } return null; } private PatientIdentifier getPatientIdentifierByIdentifierType(Patient patient, PatientIdentifierType idType) { return ((patient.getPatientIdentifier(idType) != null) && (patient.getPatientIdentifier(idType).getIdentifierType().equals(idType))) ? (patient.getPatientIdentifier(idType)) : null; } /** * @throws DataTypeException * @see org.openmrs.module.rheapocadapter.service.MessageTransformer#generateMessage(org.openmrs.Patient) */ @Override public String generateMessage(Patient patient, String eventType) { try { log.info("Start Creating message"); String implementationId = ""; try { implementationId = (Context.getAdministrationService().getImplementationId() .getImplementationId() != null) ? Context.getAdministrationService().getImplementationId().getImplementationId() : "rwanda000"; } catch (NullPointerException e) { log.error("No Implementation Id set;"); implementationId = "rwanda000"; } String fosaid = implementationId.substring(implementationId.indexOf("rwanda") + 6); log.info("fosaid" + fosaid); ADT_A05 adt = new ADT_A05(); // Populate the MSH Segment MSH mshSegment = adt.getMSH(); mshSegment.getFieldSeparator().setValue("|"); mshSegment.getEncodingCharacters().setValue("^~\\&"); mshSegment.getDateTimeOfMessage().getTime() .setValue(new SimpleDateFormat("yyyyMMdd").format(new Date())); mshSegment.getSendingApplication().getNamespaceID().setValue(fosaid); mshSegment.getSequenceNumber().setValue("123"); mshSegment.getMessageType().getMessageCode().setValue("ADT"); mshSegment.getMessageType().getMessageStructure().setValue("ADT_A05"); if (eventType.equalsIgnoreCase("Update")) { mshSegment.getMessageType().getTriggerEvent().setValue("A31"); } else if (eventType.equalsIgnoreCase("Create")) { mshSegment.getMessageType().getTriggerEvent().setValue("A28"); } mshSegment.getVersionID().getVersionID().setValue("2.5"); // Populate the PID Segment PID pid = adt.getPID(); pid.getPatientName(0).getFamilyName().getSurname().setValue(patient.getFamilyName()); pid.getPatientName(0).getGivenName().setValue(patient.getGivenName()); { PatientIdentifierType nid = Context.getPatientService().getPatientIdentifierTypeByName("NID"); PatientIdentifierType mutuelle = Context.getPatientService() .getPatientIdentifierTypeByName("Mutuelle"); PatientIdentifierType rama = Context.getPatientService().getPatientIdentifierTypeByName("RAMA"); PatientIdentifierType primaryCare = Context.getPatientService() .getPatientIdentifierTypeByName("Primary Care ID Type"); String id = ""; String idType = ""; int i = 0; if (getPatientIdentifierByIdentifierType(patient, nid) != null) { log.info("Get NID"); id = ""; idType = ""; idType = RHEAHL7Constants.NID_ID_TYPE; id = getPatientIdentifierByIdentifierType(patient, nid).getIdentifier(); if (id != "" && idType != "") { pid.getPatientIdentifierList(i).getIDNumber().setValue(id); pid.getPatientIdentifierList(i).getIdentifierTypeCode().setValue(idType); i++; } } if (getPatientIdentifierByIdentifierType(patient, rama) != null) { log.info("Get Rama"); id = ""; idType = ""; idType = RHEAHL7Constants.RAMA_ID_TYPE; id = getPatientIdentifierByIdentifierType(patient, rama).getIdentifier(); if (id != "" && idType != "") { pid.getPatientIdentifierList(i).getIDNumber().setValue(id); pid.getPatientIdentifierList(i).getIdentifierTypeCode().setValue(idType); i++; } } if (getPatientIdentifierByIdentifierType(patient, mutuelle) != null) { log.info("Get Mutuelle"); id = ""; idType = ""; idType = RHEAHL7Constants.MUTUELLE_ID_TYPE; id = getPatientIdentifierByIdentifierType(patient, mutuelle).getIdentifier(); if (id != "" && idType != "") { pid.getPatientIdentifierList(i).getIDNumber().setValue(id); pid.getPatientIdentifierList(i).getIdentifierTypeCode().setValue(idType); i++; } } if (getPatientIdentifierByIdentifierType(patient, primaryCare) != null) { log.info("Get OMRS"); id = ""; idType = ""; implementationId = implementationId.toLowerCase(); fosaid = implementationId.substring(implementationId.indexOf("rwanda") + 6); idType = RHEAHL7Constants.OMRS_ID_TYPE_PREFIX + fosaid; id = getPatientIdentifierByIdentifierType(patient, primaryCare).getIdentifier(); log.info("idType " + idType); if (id != "" && idType != "") { pid.getPatientIdentifierList(i).getIDNumber().setValue(id); pid.getPatientIdentifierList(i).getIdentifierTypeCode().setValue(idType); i++; } } if (!patient.getPatientIdentifier().getIdentifierType().equals(nid) && !patient.getPatientIdentifier().getIdentifierType().equals(rama) && !patient.getPatientIdentifier().getIdentifierType().equals(mutuelle) && !patient.getPatientIdentifier().getIdentifierType().equals(primaryCare)) { id = ""; idType = ""; log.info("Get " + patient.getPatientIdentifier().getIdentifier()); idType = patient.getPatientIdentifier().getIdentifierType().getName(); id = patient.getPatientIdentifier().getIdentifier(); if (id != "" && idType != "") { pid.getPatientIdentifierList(i).getIDNumber().setValue(id); pid.getPatientIdentifierList(i).getIdentifierTypeCode().setValue(idType); i++; } } } SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd"); Date dob = patient.getBirthdate(); Date dod = patient.getDeathDate(); String dobStr = ""; String dodStr = ""; if (dob != null) dobStr = df.format(dob); if (dod != null) dodStr = df.format(dod); // Address XAD add = pid.getPatientAddress(0); add.getCountry().setValue(patient.getPersonAddress().getCountry()); add.getStateOrProvince().setValue(patient.getPersonAddress().getStateProvince()); add.getCity().setValue(patient.getPersonAddress().getCountyDistrict()); add.getCensusTract().setValue(patient.getPersonAddress().getAddress1()); add.getCountyParishCode().setValue(patient.getPersonAddress().getCityVillage()); add.getOtherGeographicDesignation().setValue(patient.getPersonAddress().getNeighborhoodCell()); // gender pid.getAdministrativeSex().setValue(patient.getGender()); // dob pid.getDateTimeOfBirth().getTime().setValue(dobStr); // Death // pid.getPatientDeathIndicator().setValue( // patient.getDead().toString()); // pid.getPatientDeathDateAndTime().getTime().setValue(dodStr); PD1 pd1 = adt.getPD1(); pd1.getStudentIndicator().setTable(0); pd1.getHandicap().setTable(0); // set mother and father name int n = 0; NK1 nk1 = adt.getNK1(n); PersonAttributeType mother = Context.getPersonService() .getPersonAttributeTypeByName(RHEAConstants.MOTHER_NAME_ATTRIBUTE_TYPE); PersonAttribute mom = patient.getAttribute(mother); if (mom != null) { n++; String mom_str = mom.getValue(); nk1.getSetIDNK1().setValue("1"); nk1.getRelationship().getIdentifier().setValue("MTH"); nk1.getRelationship().getText().setValue("mother"); nk1.getRelationship().getNameOfCodingSystem().setValue("REL_RTS"); nk1.getNKName(0).getFamilyName().getSurname().setValue(mom_str); } nk1 = adt.getNK1(n); PersonAttributeType father = Context.getPersonService() .getPersonAttributeTypeByName(RHEAConstants.FATHER_NAME_ATTRIBUTE_TYPE); PersonAttribute dad = patient.getAttribute(father); if (dad != null) { n++; String dad_str = dad.getValue(); nk1.getSetIDNK1().setValue("2"); nk1.getRelationship().getIdentifier().setValue("FTH"); nk1.getRelationship().getText().setValue("father"); nk1.getRelationship().getNameOfCodingSystem().setValue("REL_RTS"); nk1.getNKName(0).getFamilyName().getSurname().setValue(dad_str); } PV1 pv1 = adt.getPV1(); pv1.getSetIDPV1().setValue("1"); pv1.getPatientClass().setValue("U"); return new GenericParser().encode(adt, "XML"); } catch (DataTypeException e) { log.error("Error generated" + e.getMessage()); return ""; } catch (HL7Exception e) { log.error("Error generated" + e.getMessage()); return ""; } } private PV1 getPV1(ORU_R01 oru) { return oru.getPATIENT_RESULT().getPATIENT().getVISIT().getPV1(); } private ORC getORC(ORU_R01 oru) { return oru.getPATIENT_RESULT().getORDER_OBSERVATION().getORC(); } private boolean isConceptProposal(String identifier) { return OpenmrsUtil.nullSafeEquals(identifier, OpenmrsConstants.PROPOSED_CONCEPT_IDENTIFIER); } private Concept getConcept(CE codedElement, String uid) throws HL7Exception { String hl7ConceptId = codedElement.getIdentifier().getValue(); String codingSystem = codedElement.getNameOfCodingSystem().getValue().toString(); Concept concept = Context.getConceptService().getConceptByMapping(hl7ConceptId, codingSystem); return concept; } private Concept getConcept(CWE codedElement, String uid) throws HL7Exception { String hl7ConceptId = codedElement.getIdentifier().getValue(); String codingSystem = codedElement.getNameOfCodingSystem().getValue(); return getConcept(hl7ConceptId, codingSystem, uid); } protected Concept getConcept(String hl7ConceptId, String codingSystem, String uid) throws HL7Exception { if (codingSystem == null || "99DCT".equals(codingSystem)) { // the concept is local try { Integer conceptId = new Integer(hl7ConceptId); Concept concept = new Concept(conceptId); return concept; } catch (NumberFormatException e) { throw new HL7Exception("Invalid concept ID '" + hl7ConceptId + "' in hl7 message with uid: " + uid); } } else { // the concept is not local, look it up in our mapping Concept concept = Context.getConceptService().getConceptByMapping(hl7ConceptId, codingSystem); if (concept == null) { log.error("Unable to find concept with code: " + hl7ConceptId + " and mapping: " + codingSystem + " in hl7 message with uid: " + uid); } return concept; } } private Obs parseObs(Encounter encounter, OBX obx, OBR obr, String uid) throws HL7Exception, ProposingConceptException { if (log.isDebugEnabled()) log.debug("parsing observation: " + obx); Varies[] values = obx.getObservationValue(); // bail out if no values were found if (values == null || values.length < 1) return null; String hl7Datatype = values[0].getName(); if (log.isDebugEnabled()) log.debug(" datatype = " + hl7Datatype); Concept concept = getConcept(obx.getObservationIdentifier(), uid); if (log.isDebugEnabled()) log.debug(" concept = " + concept.getConceptId()); ConceptName conceptName = getConceptName(obx.getObservationIdentifier()); if (log.isDebugEnabled()) log.debug(" concept-name = " + conceptName); Date datetime = getDatetime(obx); if (log.isDebugEnabled()) log.debug(" timestamp = " + datetime); if (datetime == null) datetime = encounter.getEncounterDatetime(); Obs obs = new Obs(); obs.setUuid(UUID.randomUUID().toString()); obs.setPerson(encounter.getPatient()); obs.setConcept(concept); obs.setEncounter(encounter); obs.setObsDatetime(datetime); obs.setLocation(encounter.getLocation()); obs.setCreator(encounter.getCreator()); obs.setDateCreated(new Date()); // set comments if there are any StringBuilder comments = new StringBuilder(); ORU_R01_OBSERVATION parent = (ORU_R01_OBSERVATION) obx.getParent(); // iterate over all OBX NTEs for (int i = 0; i < parent.getNTEReps(); i++) for (FT obxComment : parent.getNTE(i).getComment()) { if (comments.length() > 0) comments.append(" "); comments = comments.append(obxComment.getValue()); } // only set comments if there are any if (StringUtils.hasText(comments.toString())) obs.setComment(comments.toString()); Type obx5 = values[0].getData(); if ("NM".equals(hl7Datatype)) { String value = ((NM) obx5).getValue(); if (value == null || value.length() == 0) { log.warn("Not creating null valued obs for concept " + concept); return null; } else if (value.equals("0") || value.equals("1")) { concept = concept.hydrate(concept.getConceptId().toString()); obs.setConcept(concept); if (concept.getDatatype().isNumeric()) try { obs.setValueNumeric(Double.valueOf(value)); } catch (NumberFormatException e) { throw new HL7Exception("numeric (NM) value '" + value + "' is not numeric for concept #" + concept.getConceptId() + " (" + conceptName.getName() + ") in message " + uid, e); } else { // throw this exception to make sure that the handler // doesn't silently ignore bad hl7 message throw new HL7Exception("Can't set boolean concept answer for concept with id " + obs.getConcept().getConceptId()); } } else { try { obs.setValueNumeric(Double.valueOf(value)); } catch (NumberFormatException e) { throw new HL7Exception( "numeric (NM) value '" + value + "' is not numeric for concept #" + concept.getConceptId() + " (" + conceptName.getName() + ") in message " + uid, e); } } } else if ("CWE".equals(hl7Datatype)) { log.debug(" CWE observation"); CWE value = (CWE) obx5; String valueIdentifier = value.getIdentifier().getValue(); log.debug(" value id = " + valueIdentifier); String valueName = value.getText().getValue(); log.debug(" value name = " + valueName); if (isConceptProposal(valueIdentifier)) { if (log.isDebugEnabled()) log.debug("Proposing concept"); throw new ProposingConceptException(concept, valueName); } else { log.debug(" not proposal"); try { Concept valueConcept = getConcept(value, uid); obs.setValueCoded(valueConcept); if ("99RX".equals(value.getNameOfAlternateCodingSystem().getValue())) { Drug valueDrug = new Drug(); valueDrug.setDrugId(new Integer(value.getAlternateIdentifier().getValue())); obs.setValueDrug(valueDrug); } else { ConceptName valueConceptName = getConceptName(value); if (valueConceptName != null) { if (log.isDebugEnabled()) { log.debug(" value concept-name-id = " + valueConceptName.getConceptNameId()); log.debug(" value concept-name = " + valueConceptName.getName()); } obs.setValueCodedName(valueConceptName); } } } catch (NumberFormatException e) { throw new HL7Exception( "Invalid concept ID '" + valueIdentifier + "' for OBX-5 value '" + valueName + "'"); } } if (log.isDebugEnabled()) log.debug(" Done with CWE"); } else if ("CE".equals(hl7Datatype)) { CE value = (CE) obx5; String valueIdentifier = value.getIdentifier().getValue(); String valueName = value.getText().getValue(); if (isConceptProposal(valueIdentifier)) { throw new ProposingConceptException(concept, valueName); } else { try { Concept c = getConcept(value, uid); obs.setValueCoded(c); ConceptName name = c.getName(); obs.setValueCodedName(name); } catch (NumberFormatException e) { throw new HL7Exception( "Invalid concept ID '" + valueIdentifier + "' for OBX-5 value '" + valueName + "'"); } } } else if ("DT".equals(hl7Datatype)) { DT value = (DT) obx5; Date valueDate = getDate(value.getYear(), value.getMonth(), value.getDay(), 0, 0, 0); if (value == null || valueDate == null) { log.warn("Not creating null valued obs for concept " + concept); return null; } obs.setValueDatetime(valueDate); } else if ("TS".equals(hl7Datatype)) { DTM value = ((TS) obx5).getTime(); Date valueDate = getDate(value.getYear(), value.getMonth(), value.getDay(), value.getHour(), value.getMinute(), value.getSecond()); if (value == null || valueDate == null) { log.warn("Not creating null valued obs for concept " + concept); return null; } obs.setValueDatetime(valueDate); } else if ("TM".equals(hl7Datatype)) { TM value = (TM) obx5; Date valueTime = getDate(0, 0, 0, value.getHour(), value.getMinute(), value.getSecond()); if (value == null || valueTime == null) { log.warn("Not creating null valued obs for concept " + concept); return null; } obs.setValueDatetime(valueTime); } else if ("ST".equals(hl7Datatype)) { ST value = (ST) obx5; if (value == null || value.getValue() == null || value.getValue().trim().length() == 0) { log.warn("Not creating null valued obs for concept " + concept); return null; } obs.setValueText(value.getValue()); } else { // unsupported data type // TODO: support RP (report), SN (structured numeric) // do we need to support BIT just in case it slips thru? throw new HL7Exception("Unsupported observation datatype '" + hl7Datatype + "'"); } return obs; } public List<Encounter> messageToEncounter(ORU_R01 message) throws HL7Exception { // List<Encounter> encList = new ArrayList<Encounter>(); // log.info("Starting creating enc from message"); // Encounter enc = null; // // ORU_R01_PATIENT_RESULT result = message.getPATIENT_RESULT(); // int orderNo = result.getORDER_OBSERVATIONReps(); // // Encounter previousEnc = null; // boolean preFlag = false; // log.info("Before loop"); // for (int i = 0; i < orderNo; i++) { // log.info("inside loop " + i); // ORU_R01_ORDER_OBSERVATION order = result.getORDER_OBSERVATION(i); // log.info("order length " + order.getOBSERVATIONReps()); // String id = order.getOBR().getFillerOrderNumber() // .getEntityIdentifier().getValue(); // log.info("before if"); // if (id != null) { // log.info("id!=null"); // enc = parseEncounter(i, result, message, previousEnc); // log.info("after getting enc"); // encList.add(enc); // previousEnc = enc; // preFlag = true; // } else if (preFlag == false) { // log.info("id==null and preflag==false"); // if (previousEnc != null) { // log.info("id==null and preflag==false and previousEnc!=null"); // enc = parseEncounter(i, result, message, previousEnc); // previousEnc = enc; // } // } else { // log.info("id==null and preflag==true"); // preFlag = false; // } // } // log.info(encList.size() + " Size of the list"); // return encList; // return parseEncounter(result, message, null); log.info(">>>>Creating encs"); List<Encounter> encs = null; try { RHEA_ORU_R01Handler rHEA_ORU_R01Handler = new RHEA_ORU_R01Handler(null); // String mess = // // "<?xml version=\"1.0\"?> <ORU_R01 xmlns=\"urn:hl7-org:v2xml\"> <MSH> <MSH.1>|</MSH.1> <MSH.2>^~\\&</MSH.2> <MSH.6> <HD.1>Point of Care</HD.1> </MSH.6> <MSH.7> <TS.1>20121005084254</TS.1> </MSH.7> <MSH.9> <MSG.1>ORU</MSG.1> <MSG.2>R01</MSG.2> <MSG.3>ORU_R01</MSG.3> </MSH.9> <MSH.10>a70d7108-5a0c-4818-8360-f73a22f7fd65</MSH.10> <MSH.11> <PT.1>D</PT.1> <PT.2>C</PT.2> </MSH.11> <MSH.12> <VID.1>2.5</VID.1> <VID.2> <CE.1>RWA</CE.1> </VID.2> </MSH.12> <MSH.21> <EI.1>CLSM_V0.83</EI.1> </MSH.21> </MSH> <ORU_R01.PATIENT_RESULT> <ORU_R01.PATIENT> <PID> <PID.3> <CX.1>1199170003455088</CX.1> <CX.5>NID</CX.5> </PID.3> <PID.5> <XPN.1> <FN.1>ALICE</FN.1> </XPN.1> <XPN.2>MUKAMURIGO</XPN.2> </PID.5> <PID.7> <TS.1>19910430</TS.1> </PID.7> </PID> </ORU_R01.PATIENT> <ORU_R01.ORDER_OBSERVATION> <ORC> <ORC.1>RE</ORC.1> <ORC.9> <TS.1>201210050842</TS.1> </ORC.9> <ORC.12> <XCN.1>38</XCN.1> </ORC.12> <ORC.16> <CE.1>Identifier</CE.1> <CE.2>Text</CE.2> <CE.3>Name of Coding System</CE.3> </ORC.16> </ORC> <OBR> <OBR.1>0</OBR.1> <OBR.3> <EI.1>5</EI.1> </OBR.3> <OBR.4> <CE.2>ANC Physical</CE.2> </OBR.4> <OBR.7> <TS.1>201210010000</TS.1> </OBR.7> <OBR.16> <XCN.1>1198080018198077 </XCN.1> <XCN.2> <FN.1>MUSABWA</FN.1> </XCN.2> <XCN.3>JACQUES</XCN.3> <XCN.13>NID</XCN.13> </OBR.16> <OBR.20>363</OBR.20> <OBR.21>OMRS-Ruhunda</OBR.21> </OBR> </ORU_R01.ORDER_OBSERVATION> <ORU_R01.ORDER_OBSERVATION> <OBR> <OBR.1>1</OBR.1> <OBR.18>0</OBR.18> <OBR.29> <EIP.2> <EI.3>5</EI.3> </EIP.2> </OBR.29> </OBR> <ORU_R01.OBSERVATION> <OBX> <OBX.1>0</OBX.1> <OBX.2>NM</OBX.2> <OBX.3> <CE.1>84862-4</CE.1> <CE.2>DIASTOLIC BLOOD PRESSURE</CE.2> <CE.3>LOINC</CE.3> </OBX.3> <OBX.5>68.0</OBX.5> <OBX.6> <CE.1>mmHg</CE.1> <CE.3>ucum</CE.3> </OBX.6> <OBX.14> <TS.1>20121001161045</TS.1> </OBX.14> </OBX> </ORU_R01.OBSERVATION> <ORU_R01.OBSERVATION> <OBX> <OBX.1>1</OBX.1> <OBX.2>NM</OBX.2> <OBX.3> <CE.1>29463-7</CE.1> <CE.2>WEIGHT (KG)</CE.2> <CE.3>LOINC</CE.3> </OBX.3> <OBX.5>50.0</OBX.5> <OBX.6> <CE.1>kg</CE.1> <CE.3>ucum</CE.3> </OBX.6> <OBX.14> <TS.1>20121001161047</TS.1> </OBX.14> </OBX> </ORU_R01.OBSERVATION> <ORU_R01.OBSERVATION> <OBX> <OBX.1>2</OBX.1> <OBX.2>NM</OBX.2> <OBX.3> <CE.1>11885-1</CE.1> <CE.2>NUMBER OF WEEKS PREGNANT</CE.2> <CE.3>LOINC</CE.3> </OBX.3> <OBX.5>10.0</OBX.5> <OBX.6> <CE.1>weeks</CE.1> <CE.3>ucum</CE.3> </OBX.6> <OBX.14> <TS.1>20121001161046</TS.1> </OBX.14> </OBX> </ORU_R01.OBSERVATION> <ORU_R01.OBSERVATION> <OBX> <OBX.1>3</OBX.1> <OBX.2>NM</OBX.2> <OBX.3> <CE.1>8310-5</CE.1> <CE.2>TEMPERATURE (C)</CE.2> <CE.3>LOINC</CE.3> </OBX.3> <OBX.5>37.0</OBX.5> <OBX.6> <CE.1>DEG C</CE.1> <CE.3>ucum</CE.3> </OBX.6> <OBX.14> <TS.1>20121001161046</TS.1> </OBX.14> </OBX> </ORU_R01.OBSERVATION> <ORU_R01.OBSERVATION> <OBX> <OBX.1>4</OBX.1> <OBX.2>NM</OBX.2> <OBX.3> <CE.1>11881-0</CE.1> <CE.2>Length of the uterus (fundal height) in cm</CE.2> <CE.3>LOINC</CE.3> </OBX.3> <OBX.5>8.0</OBX.5> <OBX.6> <CE.1>cm</CE.1> <CE.3>ucum</CE.3> </OBX.6> <OBX.14> <TS.1>20121001161046</TS.1> </OBX.14> </OBX> </ORU_R01.OBSERVATION> <ORU_R01.OBSERVATION> <OBX> <OBX.1>5</OBX.1> <OBX.2>NM</OBX.2> <OBX.3> <CE.1>55283-6</CE.1> <CE.2>Heart rate of fetus</CE.2> <CE.3>LOINC</CE.3> </OBX.3> <OBX.5>120.0</OBX.5> <OBX.6> <CE.1>BPM</CE.1> <CE.3>ucum</CE.3> </OBX.6> <OBX.14> <TS.1>20121001161048</TS.1> </OBX.14> </OBX> </ORU_R01.OBSERVATION> <ORU_R01.OBSERVATION> <OBX> <OBX.1>6</OBX.1> <OBX.3> <CE.1>46040-2</CE.1> <CE.2>WEIGHT CHANGE</CE.2> <CE.3>LOINC</CE.3> </OBX.3> </OBX> </ORU_R01.OBSERVATION> <ORU_R01.OBSERVATION> <OBX> <OBX.1>7</OBX.1> <OBX.2>NM</OBX.2> <OBX.3> <CE.1>8480-6</CE.1> <CE.2>SYSTOLIC BLOOD PRESSURE</CE.2> <CE.3>LOINC</CE.3> </OBX.3> <OBX.5>124.0</OBX.5> <OBX.6> <CE.1>mmHg</CE.1> <CE.3>ucum</CE.3> </OBX.6> <OBX.14> <TS.1>20121001161047</TS.1> </OBX.14> </OBX> </ORU_R01.OBSERVATION> </ORU_R01.ORDER_OBSERVATION> <ORU_R01.ORDER_OBSERVATION> <OBR> <OBR.1>2</OBR.1> <OBR.3> <EI.1>18</EI.1> </OBR.3> <OBR.4> <CE.2>ANC Maternal Treatments and Interventions</CE.2> </OBR.4> <OBR.7> <TS.1>201210010000</TS.1> </OBR.7> <OBR.16> <XCN.1>b6d79622-9cfe-1031-84cf-bd846ceebe61</XCN.1> <XCN.2> <FN.1>MUSABWA</FN.1> </XCN.2> <XCN.3>JACQUES</XCN.3> <XCN.13>EPID</XCN.13> </OBR.16> <OBR.20>363</OBR.20> <OBR.21>OMRS-Ruhunda</OBR.21> </OBR> </ORU_R01.ORDER_OBSERVATION> <ORU_R01.ORDER_OBSERVATION> <OBR> <OBR.1>3</OBR.1> <OBR.18>2</OBR.18> <OBR.29> <EIP.2> <EI.3>18</EI.3> </EIP.2> </OBR.29> </OBR> <ORU_R01.OBSERVATION> <OBX> <OBX.1>0</OBX.1> <OBX.2>CE</OBX.2> <OBX.3> <CE.1>72180-3</CE.1> <CE.2>Was the woman given iron and folic acid?</CE.2> <CE.3>LOINC</CE.3> </OBX.3> <OBX.5> <CE.1>1066</CE.1> <CE.2>NO</CE.2> <CE.3>RWCS</CE.3> </OBX.5> <OBX.14> <TS.1>20121001163939</TS.1> </OBX.14> </OBX> </ORU_R01.OBSERVATION> <ORU_R01.OBSERVATION> <OBX> <OBX.1>1</OBX.1> <OBX.2>CE</OBX.2> <OBX.3> <CE.1>72178-7</CE.1> <CE.2>Given Mosquito Nets</CE.2> <CE.3>LOINC</CE.3> </OBX.3> <OBX.5> <CE.1>1065</CE.1> <CE.2>YES</CE.2> <CE.3>RWCS</CE.3> </OBX.5> <OBX.14> <TS.1>20121001163940</TS.1> </OBX.14> </OBX> </ORU_R01.OBSERVATION> <ORU_R01.OBSERVATION> <OBX> <OBX.1>2</OBX.1> <OBX.2>CE</OBX.2> <OBX.3> <CE.1>72179-5</CE.1> <CE.2>Given Sulfadoxin Pyrimethamine</CE.2> <CE.3>LOINC</CE.3> </OBX.3> <OBX.5> <CE.1>1066</CE.1> <CE.2>NO</CE.2> <CE.3>RWCS</CE.3> </OBX.5> <OBX.14> <TS.1>20121001163940</TS.1> </OBX.14> </OBX> </ORU_R01.OBSERVATION> <ORU_R01.OBSERVATION> <OBX> <OBX.1>3</OBX.1> <OBX.2>CE</OBX.2> <OBX.3> <CE.1>72187-8</CE.1> <CE.2>given tetanus vaccine</CE.2> <CE.3>LOINC</CE.3> </OBX.3> <OBX.5> <CE.1>1065</CE.1> <CE.2>YES</CE.2> <CE.3>RWCS</CE.3> </OBX.5> <OBX.14> <TS.1>20121001163938</TS.1> </OBX.14> </OBX> </ORU_R01.OBSERVATION> <ORU_R01.OBSERVATION> <OBX> <OBX.1>4</OBX.1> <OBX.2>CE</OBX.2> <OBX.3> <CE.1>8406</CE.1> <CE.2>Given Mebendazole</CE.2> <CE.3>RWCS</CE.3> </OBX.3> <OBX.5> <CE.1>1066</CE.1> <CE.2>NO</CE.2> <CE.3>RWCS</CE.3> </OBX.5> <OBX.14> <TS.1>20121001163938</TS.1> </OBX.14> </OBX> </ORU_R01.OBSERVATION> </ORU_R01.ORDER_OBSERVATION> </ORU_R01.PATIENT_RESULT> </ORU_R01>"; // // String ms = EncodedMessageComparator.standardize(mess); // Message message = // rHEA_ORU_R01Handler.changeStringToMessage(mess); encs = rHEA_ORU_R01Handler.processORU_R01((ORU_R01) rHEA_ORU_R01Handler.processMessage(message)); log.info("<<<<<<Encs size >>>>> " + encs.size()); } catch (HL7Exception e) { log.error(e.getMessage()); } catch (ApplicationException e) { log.error(e.getMessage()); } return encs; } public synchronized Encounter parseEncounter(int num, ORU_R01_PATIENT_RESULT result, ORU_R01 message, Encounter previousEnc) throws HL7Exception { MSH msh = getMSH(message); PID pid = getPID(message); ORC orc = getORC(message); // List<Encounter> encounters = new ArrayList<Encounter>(); log.info(num + " Encounter"); ORU_R01_ORDER_OBSERVATION order2 = result.getORDER_OBSERVATION(num); ORU_R01_ORDER_OBSERVATION order = null; OBR childObr = null; OBR encOBR = null; if (previousEnc == null) { encOBR = order2.getOBR(); // the child obr order = result.getORDER_OBSERVATION(num); childObr = order.getOBR(); } else { order = result.getORDER_OBSERVATION(num); childObr = order.getOBR(); } String messageControlId = msh.getMessageControlID().getValue(); // create the encounter // Patient is retrieved by enterpriseId only Patient patient = getPatientORUR01(pid); if (previousEnc == null) { previousEnc = createEncounter(msh, patient, orc, childObr, encOBR); } if (childObr.getParentNumber().getFillerAssignedIdentifier().getUniversalID().getValue() != null) { // boolean flag = false; // create observations ORU_R01_PATIENT_RESULT patientResult = message.getPATIENT_RESULT(); log.info(message.getPATIENT_RESULTReps() + "Number of results"); int numObr = patientResult.getORDER_OBSERVATIONReps(); ORU_R01_ORDER_OBSERVATION orderObs = null; for (int i = 1; i < numObr; i++) { log.info(">>>>>>>>>>>Processing OBR (" + i + " of " + numObr + ")"); orderObs = patientResult.getORDER_OBSERVATION(i); // the parent obr OBR obr = orderObs.getOBR(); if (obr.getPlacerField1() != null) { // if we're not ignoring this obs group, create an // Obs grouper object that the underlying obs objects // will // use Obs obsGrouper = null; if (childObr.getUniversalServiceIdentifier().getIdentifier().getValue() != null) { Concept obrConcept = getConcept(childObr.getUniversalServiceIdentifier(), messageControlId); // create an obs for this obs group too obsGrouper = new Obs(); obsGrouper.setConcept(obrConcept); obsGrouper.setPerson(previousEnc.getPatient()); obsGrouper.setEncounter(previousEnc); Date datetime = getDatetime(obr); if (datetime == null) datetime = previousEnc.getEncounterDatetime(); obsGrouper.setObsDatetime(datetime); obsGrouper.setLocation(previousEnc.getLocation()); obsGrouper.setCreator(previousEnc.getCreator()); obsGrouper.setDateCreated(new Date()); obsGrouper.setUuid(UUID.randomUUID().toString()); // add this obs as another row in the obs table previousEnc.addObs(obsGrouper); } // loop over the obs and create each object, adding it // to // the encounter int numObs = orderObs.getOBSERVATIONReps(); HL7Exception errorInHL7Queue = null; for (int j = 0; j < numObs; j++) { if (log.isDebugEnabled()) log.debug("Processing OBS (" + j + " of " + numObs + ")"); OBX obx = orderObs.getOBSERVATION(j).getOBX(); try { log.debug("Parsing observation"); Obs obs = parseObs(previousEnc, obx, obr, messageControlId); if (obs != null) { // if we're backfilling an encounter, don't // use // the creator/dateCreated from the // encounter if (previousEnc.getEncounterId() != null) { obs.setCreator(Context.getAuthenticatedUser()); obs.setDateCreated(new Date()); } // set the obsGroup on this obs if (obsGrouper != null) { // set the obs to the group. This // assumes // the group is already // on the encounter and that when the // encounter is saved it will // propagate to the children obs obsGrouper.addGroupMember(obs); previousEnc.addObs(obs); } else { // set this obs on the encounter object // that // we // will be saving later log.debug("Obs is not null. Adding to encounter object"); previousEnc.addObs(obs); } } else { } } catch (ProposingConceptException proposingException) { } catch (HL7Exception e) { errorInHL7Queue = e; } } } } } // encounters.add(previousEnc); return previousEnc; } private Date getEncounterDate(OBR obr) throws HL7Exception { return tsToDate(obr.getObservationDateTime()); } private Date tsToDate(TS ts) throws HL7Exception { // need to handle timezone String dtm = ts.getTime().getValue(); int year = Integer.parseInt(dtm.substring(0, 4)); int month = (dtm.length() >= 6 ? Integer.parseInt(dtm.substring(4, 6)) - 1 : 0); int day = (dtm.length() >= 8 ? Integer.parseInt(dtm.substring(6, 8)) : 1); int hour = (dtm.length() >= 10 ? Integer.parseInt(dtm.substring(8, 10)) : 0); int min = (dtm.length() >= 12 ? Integer.parseInt(dtm.substring(10, 12)) : 0); int sec = (dtm.length() >= 14 ? Integer.parseInt(dtm.substring(12, 14)) : 0); Calendar cal = Calendar.getInstance(); cal.set(year, month, day, hour, min, sec); /* * if (cal.getTimeZone().getRawOffset() != timeZoneOffsetMillis) { * TimeZone tz = (TimeZone)TimeZone.getDefault().clone(); * tz.setRawOffset(timeZoneOffsetMillis); cal.setTimeZone(tz); } */ return cal.getTime(); } private Person getProviderORUR01(OBR encObr) throws HL7Exception { XCN hl7Provider = encObr.getOrderingProvider(0); Person p = service.getPersonByNID(hl7Provider.getIDNumber().getValue()); // Integer providerId = service.getPersonByNID(NID); if (p == null) { log.info( "ID extracted from the HL7 message does not match with PoC records, a basic patient will be created..."); Person providerCandidate = new Person(); providerCandidate.setGender("N/A"); PersonName name = new PersonName(); if (hl7Provider.getGivenName().getValue() != null) { name.setGivenName(hl7Provider.getGivenName().getValue()); } else { name.setGivenName("BLANK"); } if (hl7Provider.getFamilyName().getSurname().getValue() != null) { name.setFamilyName(hl7Provider.getFamilyName().getSurname().getValue()); } else { name.setFamilyName("BLANK"); } SortedSet<PersonName> names = new TreeSet<PersonName>(); names.add(name); providerCandidate.setNames(names); PersonAttributeType NIDAttributeType = Context.getPersonService().getPersonAttributeTypeByName("NID"); if (NIDAttributeType == null) { log.info("Creating a PersonAttributeType for NID since it does not exsist"); NIDAttributeType = new PersonAttributeType(); NIDAttributeType.setName("NID"); NIDAttributeType.setDescription("Stores the NID of the Person object"); Context.getPersonService().savePersonAttributeType(NIDAttributeType); } PersonAttribute NIDAtrribute = new PersonAttribute(); NIDAtrribute.setAttributeType(NIDAttributeType); NIDAtrribute.setValue(hl7Provider.getIDNumber().getValue()); PersonAttributeType roleAttributeType = Context.getPersonService().getPersonAttributeType("Role"); // We need to mark this patient as a potential provider. // The ideal way to do this would be to create a user object and set // its Role to Provider. // However, this would result in the creation and storage of an // additional object in the database. // Furthermore, we would be forced to define an username and // password for each of the new users. // Therefore, I am merely creating a person attribute of type Role, // and setting it to "Provider" (for now). if (roleAttributeType == null) { log.info("Creating a PersonAttributeType for Role since it does not exsist"); roleAttributeType = new PersonAttributeType(); roleAttributeType.setName("Role"); roleAttributeType.setDescription("Stores the Role of the Person object"); Context.getPersonService().savePersonAttributeType(roleAttributeType); } PersonAttribute roledAtrribute = new PersonAttribute(); roledAtrribute.setAttributeType(roleAttributeType); roledAtrribute.setValue("Provider"); SortedSet<PersonAttribute> attributes = new TreeSet<PersonAttribute>(); attributes.add(NIDAtrribute); attributes.add(roledAtrribute); providerCandidate.setAttributes(attributes); Person candidate = Context.getPersonService().savePerson(providerCandidate); p = candidate; } return p; } private Location getLocation(OBR obr) throws HL7Exception { String hl7Location = obr.getFillerField1().getValue(); Location location = null; List<Location> locationsList = Context.getLocationService().getAllLocations(); Context.getLocationService().getLocation(hl7Location); for (Location l : locationsList) { String des = l.getDescription(); String fosaid = null; if (des != null) { fosaid = des.toString(); } String elid = null; if (fosaid != null) { final Matcher matcher = Pattern.compile(":").matcher(fosaid); if (matcher.find()) { elid = fosaid.substring(matcher.end()).trim(); if (elid.equals(hl7Location)) { location = l; } } } } return (location == null) ? Context.getLocationService().getDefaultLocation() : location; } private EncounterType getEncounterType(OBR obr) { String admissionType = obr.getUniversalServiceIdentifier().getText().getValue().toString(); EncounterType encounterType = Context.getEncounterService().getEncounterType(admissionType); if (encounterType == null) { log.info("EncounterType does not exsist, creating a new one for :" + admissionType); EncounterType newEncounterType = new EncounterType(); newEncounterType.setName(admissionType); newEncounterType.setDescription("CREATED BY POC Adapter MODULE"); Context.getEncounterService().saveEncounterType(newEncounterType); log.info("Saved newly created encounter type"); return newEncounterType; } else { return encounterType; } } private Date getDate(OBR obr) { try { String str_date = obr.getObservationDateTime().getTime().getValue(); DateFormat formatter; Date date; formatter = new SimpleDateFormat("yyyyMMddhhmm"); date = (Date) formatter.parse(str_date); return date; } catch (ParseException e) { return new Date(); } } private Encounter createEncounter(MSH msh, Patient patient, ORC orc, OBR obr, OBR encObr) throws HL7Exception { // the encounter we will return Encounter encounter = null; encounter = new Encounter(); Date encounterDate = getEncounterDate(encObr); Person provider = getProviderORUR01(encObr); Location location = getLocation(encObr); EncounterType encounterType = getEncounterType(encObr); User enterer = Context.getAuthenticatedUser(); Date date = getDate(encObr); encounter.setEncounterDatetime(encounterDate); encounter.setProvider(provider); encounter.setPatient(patient); encounter.setLocation(location); encounter.setEncounterType(encounterType); encounter.setCreator(enterer); encounter.setDateCreated(date); return encounter; } public ORU_R01 generateORU_R01Message(Patient pat, List<Encounter> encounterList) throws HL7Exception { MSH msh = r01.getMSH(); String implementationId = ""; String fosaid = ""; // Get current date String dateFormat = "yyyyMMddHHmmss"; SimpleDateFormat formatter = new SimpleDateFormat(dateFormat); String formattedDate = formatter.format(new Date()); msh.getFieldSeparator().setValue(RHEAHL7Constants.FIELD_SEPARATOR);// msh.getEncodingCharacters().setValue(RHEAHL7Constants.ENCODING_CHARACTERS);// msh.getVersionID().getInternationalizationCode().getIdentifier() .setValue(RHEAHL7Constants.INTERNATIONALIZATION_CODE);// msh.getVersionID().getVersionID().setValue(RHEAHL7Constants.VERSION);// msh.getDateTimeOfMessage().getTime().setValue(formattedDate);// try { implementationId = (Context.getAdministrationService().getImplementationId() .getImplementationId() != null) ? Context.getAdministrationService().getImplementationId().getImplementationId() : "rwanda000"; } catch (NullPointerException e) { log.error("No Implementation Id set;"); implementationId = "rwanda000"; } implementationId = implementationId.toLowerCase(); fosaid = implementationId.substring(implementationId.indexOf("rwanda") + 6); msh.getSendingFacility().getNamespaceID().setValue(fosaid);// msh.getMessageType().getMessageCode().setValue(RHEAHL7Constants.MESSAGE_TYPE);// msh.getMessageType().getTriggerEvent().setValue(RHEAHL7Constants.TRIGGER_EVENT);// msh.getMessageType().getMessageStructure().setValue(RHEAHL7Constants.MESSAGE_STRUCTURE);// msh.getReceivingFacility().getNamespaceID().setValue(RHEAHL7Constants.RECEIVING_FACILITY);// msh.getProcessingID().getProcessingID().setValue(RHEAHL7Constants.PROCESSING_ID);// msh.getProcessingID().getProcessingMode().setValue(RHEAHL7Constants.PROCESSING_MODE);// msh.getMessageControlID().setValue(UUID.randomUUID().toString());// msh.getAcceptAcknowledgmentType().setValue(RHEAHL7Constants.ACK_TYPE); msh.getApplicationAcknowledgmentType().setValue(RHEAHL7Constants.APPLICATION_ACK_TYPE); msh.getMessageProfileIdentifier(0).getEntityIdentifier().setValue(RHEAHL7Constants.MSG_PROFILE_IDENTIFIER); PID pid = r01.getPATIENT_RESULT().getPATIENT().getPID(); Patient patient = pat; int i = 0; String id = ""; String idType = ""; try { { PatientIdentifierType nid = Context.getPatientService().getPatientIdentifierTypeByName("NID"); PatientIdentifierType mutuelle = Context.getPatientService() .getPatientIdentifierTypeByName("Mutuelle"); PatientIdentifierType rama = Context.getPatientService().getPatientIdentifierTypeByName("RAMA"); PatientIdentifierType primaryCare = Context.getPatientService() .getPatientIdentifierTypeByName("Primary Care ID Type"); if (getPatientIdentifierByIdentifierType(patient, nid) != null) { log.info("Get NID"); id = ""; idType = ""; idType = nid.getName(); id = getPatientIdentifierByIdentifierType(patient, nid).getIdentifier(); if (id != "" && idType != "") { pid.getPatientIdentifierList(i).getIDNumber().setValue(id); pid.getPatientIdentifierList(i).getIdentifierTypeCode().setValue(idType); i++; } } if (getPatientIdentifierByIdentifierType(patient, rama) != null) { log.info("Get Rama"); id = ""; idType = ""; idType = rama.getName(); id = getPatientIdentifierByIdentifierType(patient, rama).getIdentifier(); if (id != "" && idType != "") { pid.getPatientIdentifierList(i).getIDNumber().setValue(id); pid.getPatientIdentifierList(i).getIdentifierTypeCode().setValue(idType); i++; } } if (getPatientIdentifierByIdentifierType(patient, mutuelle) != null) { log.info("Get Mutuelle"); id = ""; idType = ""; idType = mutuelle.getName(); id = getPatientIdentifierByIdentifierType(patient, mutuelle).getIdentifier(); if (id != "" && idType != "") { pid.getPatientIdentifierList(i).getIDNumber().setValue(id); pid.getPatientIdentifierList(i).getIdentifierTypeCode().setValue(idType); i++; } } if (getPatientIdentifierByIdentifierType(patient, primaryCare) != null) { log.info("Get OMRS"); id = ""; idType = ""; try { implementationId = (Context.getAdministrationService().getImplementationId() .getImplementationId() != null) ? Context.getAdministrationService().getImplementationId() .getImplementationId() : "rwanda000"; } catch (NullPointerException e) { log.error("No Implementation Id set;"); implementationId = "rwanda000"; } implementationId = implementationId.toLowerCase(); fosaid = implementationId.substring(implementationId.indexOf("rwanda") + 6); idType = "OMRS" + fosaid; id = getPatientIdentifierByIdentifierType(patient, primaryCare).getIdentifier(); if (id != "" && idType != "") { pid.getPatientIdentifierList(i).getIDNumber().setValue(id); pid.getPatientIdentifierList(i).getIdentifierTypeCode().setValue(idType); i++; } } if (!patient.getPatientIdentifier().getIdentifierType().equals(nid) && !patient.getPatientIdentifier().getIdentifierType().equals(rama) && !patient.getPatientIdentifier().getIdentifierType().equals(mutuelle) && !patient.getPatientIdentifier().getIdentifierType().equals(primaryCare)) { id = ""; idType = ""; log.info("Get " + patient.getPatientIdentifier().getIdentifier()); idType = patient.getPatientIdentifier().getIdentifierType().getName(); id = patient.getPatientIdentifier().getIdentifier(); if (id != "" && idType != "") { pid.getPatientIdentifierList(i).getIDNumber().setValue(id); pid.getPatientIdentifierList(i).getIdentifierTypeCode().setValue(idType); i++; } } } } catch (Exception e) { log.info(e.getMessage()); idType = patient.getPatientIdentifier().getIdentifierType().getName(); id = patient.getPatientIdentifier().getIdentifier(); pid.getPatientIdentifierList(i).getIDNumber().setValue(id); pid.getPatientIdentifierList(i).getIdentifierTypeCode().setValue(idType); } // Cohort singlePatientCohort = new Cohort(); // singlePatientCohort.addMember(pat.getId()); // // Map<Integer, PatientIdentifier> patientIdentifierMap = Context // .getPatientSetService().getPatientIdentifiersByType( // singlePatientCohort, // Context.getPatientService() // .getPatientIdentifierTypeByName( // RHEAHL7Constants.IDENTIFIER_TYPE)); // // PID pid = r01.getPATIENT_RESULT().getPATIENT().getPID(); // // pid.getSetIDPID().setValue(RHEAHL7Constants.IDPID); // pid.getPatientIdentifierList(0) // .getIDNumber() // .setValue( // patientIdentifierMap // .get(patientIdentifierMap.keySet().iterator() // .next()).getIdentifier()); // // pid.getPatientIdentifierList(0).getIdentifierTypeCode() // .setValue(RHEAHL7Constants.IDENTIFIER_TYPE); pid.getPatientName(0).getFamilyName().getSurname().setValue(pat.getFamilyName()); pid.getPatientName(0).getGivenName().setValue(pat.getGivenName()); PV1 pv1 = r01.getPATIENT_RESULT().getPATIENT().getVISIT().getPV1(); pv1.getPatientClass().setValue(RHEAHL7Constants.PATIENT_CLASS); pv1.getAssignedPatientLocation().getFacility().getNamespaceID() .setValue(encounterList.get(0).getLocation().getName()); pv1.getAssignedPatientLocation().getPointOfCare() .setValue(encounterList.get(0).getLocation().getLocationId().toString()); pv1.getAdmissionType().setValue(encounterList.get(0).getEncounterType().getName()); pv1.getPatientClass().setValue(RHEAHL7Constants.PATIENT_CLASS); pv1.getAssignedPatientLocation().getFacility().getNamespaceID() .setValue(encounterList.get(0).getLocation().getName()); pv1.getAssignedPatientLocation().getPointOfCare() .setValue(encounterList.get(0).getLocation().getLocationId().toString()); pv1.getAdmissionType().setValue(encounterList.get(0).getEncounterType().getName()); Person provider = encounterList.get(0).getProvider(); TransactionService service = Context.getService(TransactionService.class); // Cohort singleProviderCohort = new Cohort(); // singleProviderCohort.addMember(provider.getId()); // // Map<Integer, PatientIdentifier> providerIdentifierMap = Context // .getPatientSetService().getPatientIdentifiersByType( // singleProviderCohort, // Context.getPatientService() // .getPatientIdentifierTypeByName("NID")); // // String providerNID = providerIdentifierMap.get( // providerIdentifierMap.keySet().iterator().next()) // .getIdentifier(); String providerNID = service.getPersonAttributesByPerson(provider, "NID"); log.info(providerNID + " Provider NID"); pv1.getAttendingDoctor(0).getFamilyName().getSurname() .setValue(encounterList.get(0).getProvider().getFamilyName()); pv1.getAttendingDoctor(0).getGivenName().setValue(encounterList.get(0).getProvider().getGivenName()); pv1.getAttendingDoctor(0).getIdentifierTypeCode().setValue("NID"); pv1.getAttendingDoctor(0).getIDNumber().setValue(providerNID); pv1.getAdmitDateTime().getTime() .setValue(new SimpleDateFormat("yyyyMMddhhmm").format(encounterList.get(0).getDateCreated())); // populate ORC segments try { createORC(r01, encounterList); } catch (Exception e) { log.error("Error generated", e); } // populate OBR segments try { createOBREnc(r01, encounterList); } catch (Exception e) { // TODO Auto-generated catch block log.error("Error generated", e); } // populate OBX segments ConceptService cs = Context.getConceptService(); int counter = 1; return r01; } public String getMessage(ORU_R01 roi) { Parser parser = new GenericParser(); String msg = null; try { msg = parser.encode(roi, "XML"); } catch (HL7Exception e) { log.error("Exception parsing constructed message."); } return msg; } private static void createORC(ORU_R01 r01, List<Encounter> encounterList) throws Exception { int orderORCCount = 0; ORC orc = null; orc = r01.getPATIENT_RESULT().getORDER_OBSERVATION(orderORCCount).getORC(); orc.getOrderControl().setValue(RHEAHL7Constants.ORDER_CONTROL); orc.getOrderingProvider(0).getIDNumber().setValue(encounterList.get(0).getProvider().getId().toString()); orc.getOrderControlCodeReason().getIdentifier().setValue("Identifier"); orc.getOrderControlCodeReason().getText().setValue("Text"); orc.getOrderControlCodeReason().getNameOfCodingSystem().setValue("Name of Coding System"); SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmm"); String dateStr = ""; Date d = new Date(); dateStr = df.format(d); orc.getDateTimeOfTransaction().getTime().setValue(dateStr); orderORCCount++; } private void createOBREnc(ORU_R01 r01, List<Encounter> encounterList) throws Exception { for (Encounter e : encounterList) { OBR obr = null; obr = r01.getPATIENT_RESULT().getORDER_OBSERVATION(orderObsCount).getOBR(); int reps = r01.getPATIENT_RESULT().getORDER_OBSERVATIONReps(); Date encDt = e.getEncounterDatetime(); SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmm"); SimpleDateFormat dayFormat = new SimpleDateFormat("yyyyMMdd"); String encDateStr = ""; String encDateOnly = ""; if (encDt != null) { encDateStr = df.format(encDt); encDateOnly = dayFormat.format(encDt); } obr.getObservationDateTime().getTime().setValue(encDateStr); obr.getSetIDOBR().setValue(String.valueOf(orderObsCount)); obr.getUniversalServiceIdentifier().getText().setValue(e.getEncounterType().getName()); // Accession number String accessionNumber = String.valueOf(e.getEncounterId()); obr.getFillerOrderNumber().getEntityIdentifier().setValue(accessionNumber); obr.getFillerField1().setValue(e.getLocation().getId().toString()); obr.getFillerField2().setValue(e.getLocation().getName()); orderObsCount++; createOBRGroup(r01, orderObsCount, e); orderObsCount++; } } private void createOBRGroup(ORU_R01 r01, int orderObsCount, Encounter encounter) throws HL7Exception { Set<Obs> allObs = encounter.getAllObs(); Set<Obs> rejectedObs = new HashSet<Obs>(); Set<Obs> unrelatedObs = new HashSet<Obs>(); Set<Obs> acceptedObs = new HashSet<Obs>(); Iterator<Obs> it = allObs.iterator(); while (it.hasNext()) { Obs obs = it.next(); if (obs.getObsGroup() != null && !rejectedObs.contains(obs)) { Obs parentObs = obs.getObsGroup(); Set<Obs> childObs = parentObs.getGroupMembers(); acceptedObs.add(parentObs); acceptedObs.addAll(childObs); it.remove(); rejectedObs.addAll(childObs); parentObs.setVoided(true); createOBRGroupSegment(r01, encounter, parentObs, childObs, orderObsCount); orderObsCount++; } } allObs.removeAll(acceptedObs); if (allObs.size() > 0) { createOBRGroupSegment(r01, encounter, null, allObs, orderObsCount); } } private void createOBRGroupSegment(ORU_R01 r01, Encounter encounter, Obs parentObs, Set<Obs> childObs, int orderObsCount) throws HL7Exception { OBR obr = null; obr = r01.getPATIENT_RESULT().getORDER_OBSERVATION(orderObsCount).getOBR(); Date encDt = encounter.getEncounterDatetime(); SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmm"); SimpleDateFormat dayFormat = new SimpleDateFormat("yyyyMMdd"); String encDateStr = ""; String encDateOnly = ""; if (encDt != null) { encDateStr = df.format(encDt); encDateOnly = dayFormat.format(encDt); } obr.getSetIDOBR().setValue(String.valueOf(orderObsCount)); if (parentObs != null) { if (parentObs.isObsGrouping()) { Collection<ConceptMap> conceptMappings = parentObs.getConcept().getConceptMappings(); Iterator<ConceptMap> itr = conceptMappings.iterator(); boolean hasMapping = false; while (itr.hasNext() && hasMapping == false) { ConceptMap map = itr.next(); if (map.getSource().getName().toString().equals("RWCS") || map.getSource().getName().toString().equals("ICD10") || map.getSource().getName().toString().equals("LOINC")) { obr.getUniversalServiceIdentifier().getIdentifier().setValue(map.getSourceCode()); obr.getUniversalServiceIdentifier().getText() .setValue(parentObs.getConcept().getName().toString()); obr.getUniversalServiceIdentifier().getNameOfCodingSystem() .setValue(map.getSource().getName()); hasMapping = true; } } } } // Accession number String accessionNumber = String.valueOf(encounter.getEncounterId()); obr.getParentNumber().getFillerAssignedIdentifier().getUniversalID().setValue(accessionNumber); int x = orderObsCount - 1; obr.getPlacerField1().setValue(Integer.toString(x)); for (Obs ob : childObs) { boolean successful = createOBXSegment(ob, orderObsCount, counter); if (successful) counter++; } orderObsCount = orderObsCount + 1; } private boolean createOBXSegment(Obs ob, int orderObsCount, int counter) throws HL7Exception, DataTypeException { ConceptService cs = Context.getConceptService(); OBX obx = r01.getPATIENT_RESULT().getORDER_OBSERVATION(orderObsCount).getOBSERVATION(counter).getOBX(); obx.getSetIDOBX().setValue(counter + ""); Collection<ConceptMap> conceptMappings = ob.getConcept().getConceptMappings(); Iterator<ConceptMap> itr = conceptMappings.iterator(); boolean hasMapping = false; while (itr.hasNext() && hasMapping == false) { ConceptMap map = itr.next(); if (map.getSource().getName().toString().equals("RWCS") || map.getSource().getName().toString().equals("ICD10") || map.getSource().getName().toString().equals("LOINC")) { obx.getObservationIdentifier().getIdentifier().setValue(map.getSourceCode()); obx.getObservationIdentifier().getText().setValue(ob.getConcept().getName().toString()); obx.getObservationIdentifier().getNameOfCodingSystem().setValue(map.getSource().getName()); hasMapping = true; } } ConceptDatatype datatype = ob.getConcept().getDatatype(); if (ob.getConcept().isNumeric()) { obx.getValueType().setValue(RHEAHL7Constants.HL7_NUMERIC); NM nm = new NM(r01); nm.setValue(ob.getValueNumeric() + ""); Concept concept = ob.getConcept(); if (concept.isNumeric()) { ConceptNumeric conceptNumeric = cs.getConceptNumeric(concept.getId()); if (conceptNumeric.getUnits() != null && !conceptNumeric.getUnits().equals("")) { obx.getUnits().getIdentifier().setValue(conceptNumeric.getUnits()); obx.getUnits().getNameOfCodingSystem().setValue(RHEAHL7Constants.UNIT_CODING_SYSTEM); } } obx.getObservationValue(0).setData(nm); TS ts = new TS(r01); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); ts.getTime().setValue(sdf.format(ob.getDateCreated())); obx.getDateTimeOfTheObservation().getTime().setValue(sdf.format(ob.getDateCreated())); } else if (datatype.equals(cs.getConceptDatatypeByName(RHEAHL7Constants.CONCEPT_DATATYPE_DATETIME)) || datatype.equals(cs.getConceptDatatypeByName(RHEAHL7Constants.CONCEPT_DATATYPE_DATE))) { obx.getValueType().setValue(RHEAHL7Constants.HL7_DATETIME); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); TS ts = new TS(r01); ts.getTime().setValue(sdf.format(ob.getValueDatetime())); obx.getObservationValue(0).setData(ts); SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMddHHmmss"); ts.getTime().setValue(sdf1.format(ob.getValueDatetime())); obx.getDateTimeOfTheObservation().getTime().setValue(sdf.format(ob.getDateCreated())); } else if (datatype.equals(cs.getConceptDatatypeByName(RHEAHL7Constants.CONCEPT_DATATYPE_TEXT))) { obx.getValueType().setValue(RHEAHL7Constants.HL7_TEXT); ST st = new ST(r01); st.setValue(ob.getValueText()); obx.getObservationValue(0).setData(st); TS ts = new TS(r01); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); ts.getTime().setValue(sdf.format(ob.getDateCreated())); obx.getDateTimeOfTheObservation().getTime().setValue(sdf.format(ob.getDateCreated())); } else if (datatype.equals(cs.getConceptDatatypeByName(RHEAHL7Constants.CONCEPT_DATATYPE_CODED))) { obx.getValueType().setValue(RHEAHL7Constants.HL7_CODED); CE ce = new CE(r01); Concept concept = ob.getValueCoded(); Collection<ConceptMap> conceptValueMappings = concept.getConceptMappings(); Iterator<ConceptMap> itr2 = conceptValueMappings.iterator(); boolean hasValueMapping = false; while (itr2.hasNext() && hasValueMapping == false) { ConceptMap map = itr2.next(); if (map.getSource().getName().toString().equals("RWCS") || map.getSource().getName().toString().equals("ICD10") || map.getSource().getName().toString().equals("LOINC")) { ce.getNameOfCodingSystem().setValue(map.getSource().getName()); String nameStr = concept.getName().toString(); ce.getText().setValue(nameStr); ce.getIdentifier().setValue(map.getSourceCode()); hasValueMapping = true; } } obx.getObservationValue(0).setData(ce); TS ts = new TS(r01); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); ts.getTime().setValue(sdf.format(ob.getDateCreated())); obx.getDateTimeOfTheObservation().getTime().setValue(sdf.format(ob.getDateCreated())); } obxCount++; return true; } @Override public Object encodingEncounterToMessage(Patient patient, List<Encounter> encounters) { // TODO Auto-generated method stub return null; } }