package ch.elexis.hl7.v2x; import java.text.MessageFormat; import java.text.ParseException; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ca.uhn.hl7v2.HL7Exception; import ca.uhn.hl7v2.model.AbstractPrimitive; import ca.uhn.hl7v2.model.Message; import ca.uhn.hl7v2.model.v23.datatype.CE; import ca.uhn.hl7v2.model.v26.datatype.CWE; import ca.uhn.hl7v2.model.v26.datatype.ED; import ca.uhn.hl7v2.model.v26.datatype.FT; import ca.uhn.hl7v2.model.v26.datatype.NM; import ca.uhn.hl7v2.model.v26.datatype.SN; import ca.uhn.hl7v2.model.v26.datatype.ST; import ca.uhn.hl7v2.model.v26.datatype.TX; import ca.uhn.hl7v2.model.v26.datatype.XAD; import ca.uhn.hl7v2.model.v26.group.ORU_R01_OBSERVATION; import ca.uhn.hl7v2.model.v26.group.ORU_R01_ORDER_OBSERVATION; import ca.uhn.hl7v2.model.v26.message.ORU_R01; import ca.uhn.hl7v2.model.v26.segment.MSH; import ca.uhn.hl7v2.model.v26.segment.NTE; import ca.uhn.hl7v2.model.v26.segment.OBR; import ca.uhn.hl7v2.model.v26.segment.OBX; import ca.uhn.hl7v2.model.v26.segment.PID; import ch.elexis.core.constants.StringConstants; import ch.elexis.core.exceptions.ElexisException; import ch.elexis.core.model.IPatient; import ch.elexis.core.types.Country; import ch.elexis.core.types.Gender; import ch.elexis.hl7.HL7PatientResolver; import ch.elexis.hl7.HL7Reader; import ch.elexis.hl7.model.EncapsulatedData; import ch.elexis.hl7.model.LabResultData; import ch.elexis.hl7.model.ObservationMessage; import ch.elexis.hl7.model.TextData; import ch.elexis.hl7.v26.HL7Constants; import ch.elexis.hl7.v26.HL7_ORU_R01; import ch.elexis.hl7.v26.Messages; import ch.rgw.tools.StringTool; public class HL7ReaderV26 extends HL7Reader { static Logger logger = LoggerFactory.getLogger(HL7ReaderV26.class); public HL7ReaderV26(Message message){ super(message); } @Override public String getSender() throws ElexisException{ String sender; try { MSH msh = (MSH) message.get("MSH"); sender = msh.getMsh4_SendingFacility().getNamespaceID().getValue(); if (sender == null) { sender = msh.getMsh3_SendingApplication().getNamespaceID().getValue(); if (sender == null) { sender = ""; } } } catch (HL7Exception e) { throw new ElexisException(e.getMessage(), e); } return sender; } @Override public ObservationMessage readObservation(HL7PatientResolver patientResolver, boolean createIfNotFound) throws ElexisException{ observation = null; ORU_R01 oru = (ORU_R01) message; try { this.patientResolver = patientResolver; setPatient(oru, createIfNotFound); int obsCount = oru.getPATIENT_RESULT().getORDER_OBSERVATIONReps(); for (int idx = 0; idx < obsCount; idx++) { OBR obr = oru.getPATIENT_RESULT().getORDER_OBSERVATION(idx).getOBR(); String obrObservationDateTime = obr.getObr7_ObservationDateTime().getValue(); setOrderComment(oru, idx, obrObservationDateTime); for (int i = 0; i < oru.getPATIENT_RESULT().getORDER_OBSERVATION(idx) .getOBSERVATIONReps(); i++) { ORU_R01_ORDER_OBSERVATION obs = oru.getPATIENT_RESULT().getORDER_OBSERVATION(idx); // get notes and comments String commentNTE = getComments(obs, i); // groupe and sequence String group = ""; String sequence = ""; for (int k = 0; k < 2; k++) { CWE cwe = obr.getObr47_FillerSupplementalServiceInformation(k); if (cwe != null) { String code = ""; if (cwe.getCwe3_NameOfCodingSystem() != null) code = cwe.getCwe3_NameOfCodingSystem().getValue(); group = getGroup(code, cwe); sequence = getSequence(code, cwe); } } // result readOBXResults(obs.getOBSERVATION(i), commentNTE, group, sequence, obrObservationDateTime); } } } catch (HL7Exception | ParseException e) { throw new ElexisException(e.getMessage(), e); } return observation; } private String getGroup(String code, CWE cwe){ if (HL7_ORU_R01.CODINGSYSTEM_DORNER_GROUP_CODE.equalsIgnoreCase(code)) { if (cwe.getCwe2_Text() != null) { return cwe.getCwe2_Text().getValue(); } } return ""; } private String getSequence(String code, CWE cwe){ if (HL7_ORU_R01.CODINGSYSTEM_DORNER_GROUP_POSITION.equalsIgnoreCase(code)) { if (cwe.getCwe1_Identifier() != null) { return cwe.getCwe1_Identifier().getValue(); } } return ""; } private void setPatient(ORU_R01 oru, final boolean createIfNotFound) throws ParseException, HL7Exception{ List<? extends IPatient> list = new ArrayList<IPatient>(); String lastName = ""; //$NON-NLS-1$ String firstName = ""; //$NON-NLS-1$ String birthDate = ""; //$NON-NLS-1$ String sex = Gender.FEMALE.value(); pat = null; if (pat == null) { String sendingApplication = oru.getMSH().getMsh3_SendingApplication().getHd1_NamespaceID().getValue(); String sendingFacility = oru.getMSH().getMsh4_SendingFacility().getHd1_NamespaceID().getValue(); String dateTimeOfMessage = oru.getMSH().getMsh7_DateTimeOfMessage().getValue(); PID pid = oru.getPATIENT_RESULT().getPATIENT().getPID(); String patid = pid.getPatientID().getIDNumber().getValue(); String patid_alternative = pid.getPid4_AlternatePatientIDPID(0).getCx1_IDNumber().getValue(); if (StringTool.isNothing(patid)) { patid = pid.getPatientID().getCx1_IDNumber().getValue(); if (StringTool.isNothing(patid)) { patid = pid.getPid2_PatientID().getIDNumber().getValue(); if (StringTool.isNothing(patid)) { patid = pid.getAlternatePatientIDPID(0).getCx1_IDNumber().getValue(); if (StringTool.isNothing(patid)) { patid = patid_alternative; if (patid == null) { patid = ""; } } } } } if (patid != null) { list = patientResolver.getPatientById(patid); } // String[] pidflds = patid.split("[\\^ ]+"); //$NON-NLS-1$ // String pid = ""; // if (pidflds.length > 0) // pid = pidflds[pidflds.length - 1]; // place order number String orderNumber = oru.getPATIENT_RESULT().getORDER_OBSERVATION().getORC().getOrc2_PlacerOrderNumber() .getEi1_EntityIdentifier().getValue(); if (pid.getPid5_PatientName(0).getFamilyName().getFn1_Surname().getValue() != null) lastName = pid.getPid5_PatientName(0).getFamilyName().getFn1_Surname().getValue(); if (pid.getPid5_PatientName(0).getGivenName().getValue() != null) firstName = pid.getPid5_PatientName(0).getGivenName().getValue(); String patientName = firstName + " " + lastName; observation = new ObservationMessage(sendingApplication, sendingFacility, dateTimeOfMessage, patid, patientName, patid_alternative, orderNumber); birthDate = pid.getDateTimeOfBirth().getValue(); sex = pid.getAdministrativeSex().getValue(); if ((patid == null) || (list.size() != 1)) { // We did not find the patient using the PatID, so we try the // name and birthdate list = patientResolver.findPatientByNameAndBirthdate(lastName, firstName, birthDate); if ((list != null) && (list.size() == 1)) { pat = list.get(0); } else { if (createIfNotFound) { String phone = StringConstants.EMPTY; XAD adr = pid.getPatientAddress(0); phone = pid.getPhoneNumberHome(0).getTelephoneNumber().getValue(); pat = patientResolver.createPatient(lastName, firstName, birthDate, sex); pat.setPatientNr(patid); if (adr != null) { if (adr.getStreetAddress() != null) { pat.setStreet(adr.getStreetAddress().getComponent(0).toString()); } if (adr.getZipOrPostalCode() != null) { pat.setZip(adr.getZipOrPostalCode().getValue()); } if (adr.getCity() != null) { pat.setCity(adr.getCity().getValue()); } if (adr.getCountry() != null) { try { Country cc = Country.valueOf(adr.getCountry().getValue()); pat.setCountry(cc); } catch (Exception e) { // unknown country, just move on } } } pat.setPhone1(phone); } else { resolvePatient(firstName, lastName, birthDate); } } } else { // if the patient with the given ID was found, we verify, if it // is the correct name pat = list.get(0); if (lastName.length() != 0 && firstName.length() != 0) { checkConflict(firstName, lastName, birthDate, sex); } } } } private void setOrderComment(ORU_R01 oru, int idx, String obsDate) throws ParseException{ String orderCommentNTE = getComments(oru.getPATIENT_RESULT().getORDER_OBSERVATION(idx), -1); if (orderCommentNTE != null) { observation.add(new TextData(HL7Constants.COMMENT_NAME, orderCommentNTE, obsDate, HL7Constants.COMMENT_GROUP, null)); } } private String getComments(ORU_R01_ORDER_OBSERVATION oobs, int i){ String commentNTE = null; int size = oobs.getNTEReps(); if (i > -1) { size = oobs.getOBSERVATION(i).getNTEReps(); } for (int n = 0; n < size; n++) { NTE nte = oobs.getNTE(n); if (i > -1) { nte = oobs.getOBSERVATION(i).getNTE(n); } AbstractPrimitive comment = nte.getNte3_Comment(0); if (comment != null) { if (commentNTE != null) { commentNTE += "\n"; } else { commentNTE = ""; } commentNTE += comment.getValue(); } } return commentNTE; } private void readOBXResults(ORU_R01_OBSERVATION obs, String commentNTE, String group, String sequence, String defaultDateTime) throws ParseException{ OBX obx = obs.getOBX(); String valueType = obx.getObx2_ValueType().getValue(); String name = ""; String itemCode = ""; String unit = ""; String range = ""; String observationTime = ""; String status = ""; boolean flag = false; if (valueType.equals(HL7Constants.OBX_VALUE_TYPE_ED)) { String observationId = obx.getObx3_ObservationIdentifier().getCwe1_Identifier().getValue(); if (!"DOCUMENT".equals(observationId)) { logger.warn(MessageFormat.format( Messages.getString("HL7_ORU_R01.Error_WrongObsIdentifier"), observationId)); } ED ed = (ED) obx.getObx5_ObservationValue(0).getData(); String filename = ed.getEd3_DataSubtype().getValue(); String encoding = ed.getEd4_Encoding().getValue(); String data = ed.getEd5_Data().getValue(); sequence = obx.getSetIDOBX().getValue(); observationTime = obx.getObx14_DateTimeOfTheObservation().getValue(); observation.add(new EncapsulatedData(filename, encoding, data, observationTime, commentNTE, group, sequence)); } else if (isTextOrNumeric(valueType)) { name = obx.getObx4_ObservationSubID().getValue(); if (name == null) { name = obx.getObx3_ObservationIdentifier().getCwe2_Text().getValue(); if (name == null) { name = obx.getObx3_ObservationIdentifier().getCwe1_Identifier().getValue(); } } String value = ""; Object tmp = obx.getObx5_ObservationValue(0).getData(); if (tmp instanceof ST) { value = ((ST) tmp).getValue(); } else if (tmp instanceof TX) { value = ((TX) tmp).getValue(); if (value.contains("\\.br")) { value = parseTextValue(value); } } else if (tmp instanceof FT) { value = parseFormattedTextValue(((FT) tmp).getValue()); } else if (tmp instanceof NM) { value = ((NM) tmp).getValue(); } else if (tmp instanceof SN) { value = ((SN) tmp).getSn2_Num1().getValue(); } else if (tmp instanceof CE) { value = ((CE) tmp).getCe2_Text().getValue(); } itemCode = obx.getObx3_ObservationIdentifier().getCwe1_Identifier().getValue(); unit = obx.getObx6_Units().getCwe1_Identifier().getValue(); range = obx.getObx7_ReferencesRange().getValue(); flag = isPathologic(obx.getObx8_AbnormalFlags(0).getValue()); observationTime = obx.getObx14_DateTimeOfTheObservation().getValue(); status = obx.getObx11_ObservationResultStatus().getValue(); LabResultData lrd = new LabResultData(itemCode, name, unit, value, range, flag, defaultDateTime, observationTime, commentNTE, group, sequence, status); if (valueType.equals(HL7Constants.OBX_VALUE_TYPE_NM) || valueType.equals(HL7Constants.OBX_VALUE_TYPE_SN)) { lrd.setIsNumeric(true); } else if (valueType.equals(HL7Constants.OBX_VALUE_TYPE_TX)) { lrd.setIsPlainText(true); } else if (valueType.equals(HL7Constants.OBX_VALUE_TYPE_FT)) { lrd.setIsFormatedText(true); } observation.add(lrd); } else { logger.error(MessageFormat.format("Value type {0} is not implemented!", valueType)); } } }