Search in sources :

Example 46 with Message

use of ca.uhn.hl7v2.model.Message in project openmrs-core by openmrs.

the class ORUR01Handler method processMessage.

/**
 * Processes an ORU R01 event message
 *
 * @should create encounter and obs from hl7 message
 * @should create basic concept proposal
 * @should create concept proposal and with obs alongside
 * @should not create problem list observation with concept proposals
 * @should append to an existing encounter
 * @should create obs group for OBRs
 * @should create obs valueCodedName
 * @should fail on empty concept proposals
 * @should fail on empty concept answers
 * @should set value_Coded matching a boolean concept for obs if the answer is 0 or 1 and
 *         Question datatype is coded
 * @should set value as boolean for obs if the answer is 0 or 1 and Question datatype is Boolean
 * @should set value_Numeric for obs if Question datatype is Numeric and the answer is either 0
 *         or 1
 * @should set value_Numeric for obs if Question datatype is Numeric
 * @should fail if question datatype is coded and a boolean is not a valid answer
 * @should fail if question datatype is neither Boolean nor numeric nor coded
 * @should create an encounter and find the provider by identifier
 * @should create an encounter and find the provider by personId
 * @should create an encounter and find the provider by uuid
 * @should create an encounter and find the provider by providerId
 * @should fail if the provider name type code is not specified and is not a personId
 * @should understand form uuid if present
 * @should prefer form uuid over id if both are present
 * @should prefer form id if uuid is not found
 * @should set complex data for obs with complex concepts
 */
@Override
public Message processMessage(Message message) throws ApplicationException {
    if (!(message instanceof ORU_R01)) {
        throw new ApplicationException(Context.getMessageSourceService().getMessage("ORUR01.error.invalidMessage"));
    }
    log.debug("Processing ORU_R01 message");
    Message response;
    try {
        ORU_R01 oru = (ORU_R01) message;
        response = processORU_R01(oru);
    } catch (ClassCastException e) {
        log.warn("Error casting " + message.getClass().getName() + " to ORU_R01", e);
        throw new ApplicationException(Context.getMessageSourceService().getMessage("ORUR01.error.invalidMessageType ", new Object[] { message.getClass().getName() }, null), e);
    } catch (HL7Exception e) {
        log.warn("Error while processing ORU_R01 message", e);
        throw new ApplicationException(Context.getMessageSourceService().getMessage("ORUR01.error.WhileProcessing"), e);
    }
    log.debug("Finished processing ORU_R01 message");
    return response;
}
Also used : ApplicationException(ca.uhn.hl7v2.app.ApplicationException) Message(ca.uhn.hl7v2.model.Message) ORU_R01(ca.uhn.hl7v2.model.v25.message.ORU_R01) HL7Exception(ca.uhn.hl7v2.HL7Exception)

Example 47 with Message

use of ca.uhn.hl7v2.model.Message in project openmrs-core by openmrs.

the class ORUR01Handler method parseObs.

/**
 * Creates the Obs pojo from the OBX message
 *
 * @param encounter The Encounter object this Obs is a member of
 * @param obx The hl7 obx message
 * @param obr The parent hl7 or message
 * @param uid unique string for this message for any error reporting purposes
 * @return Obs pojo with all values filled in
 * @throws HL7Exception if there is a parsing exception
 * @throws ProposingConceptException if the answer to this obs is a proposed concept
 * @should add comments to an observation from NTE segments
 * @should add multiple comments for an observation as one comment
 * @should add comments to an observation group
 */
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.setPerson(encounter.getPatient());
    obs.setConcept(concept);
    obs.setEncounter(encounter);
    obs.setObsDatetime(datetime);
    obs.setLocation(encounter.getLocation());
    obs.setCreator(encounter.getCreator());
    obs.setDateCreated(encounter.getDateCreated());
    // 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 ("0".equals(value) || "1".equals(value)) {
            concept = concept.hydrate(concept.getConceptId().toString());
            obs.setConcept(concept);
            if (concept.getDatatype().isBoolean()) {
                obs.setValueBoolean("1".equals(value));
            } else if (concept.getDatatype().isNumeric()) {
                try {
                    obs.setValueNumeric(Double.valueOf(value));
                } catch (NumberFormatException e) {
                    throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.notnumericConcept", new Object[] { value, concept.getConceptId(), conceptName.getName(), uid }, null), e);
                }
            } else if (concept.getDatatype().isCoded()) {
                Concept answer = "1".equals(value) ? Context.getConceptService().getTrueConcept() : Context.getConceptService().getFalseConcept();
                boolean isValidAnswer = false;
                Collection<ConceptAnswer> conceptAnswers = concept.getAnswers();
                if (conceptAnswers != null && !conceptAnswers.isEmpty()) {
                    for (ConceptAnswer conceptAnswer : conceptAnswers) {
                        if (conceptAnswer.getAnswerConcept().getId().equals(answer.getId())) {
                            obs.setValueCoded(answer);
                            isValidAnswer = true;
                            break;
                        }
                    }
                }
                // answer the boolean answer concept was't found
                if (!isValidAnswer) {
                    throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.invalidAnswer", new Object[] { answer.toString(), uid }, null));
                }
            } else {
                // throw this exception to make sure that the handler doesn't silently ignore bad hl7 message
                throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.CannotSetBoolean", new Object[] { obs.getConcept().getConceptId() }, null));
            }
        } else {
            try {
                obs.setValueNumeric(Double.valueOf(value));
            } catch (NumberFormatException e) {
                throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.notnumericConcept", new Object[] { value, concept.getConceptId(), conceptName.getName(), uid }, null), 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 (HL7Constants.HL7_LOCAL_DRUG.equals(value.getNameOfAlternateCodingSystem().getValue())) {
                    Drug valueDrug = new Drug();
                    valueDrug.setDrugId(Integer.valueOf(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(Context.getMessageSourceService().getMessage("ORUR01.error.InvalidConceptId", new Object[] { valueIdentifier, valueName }, null));
            }
        }
        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 {
                obs.setValueCoded(getConcept(value, uid));
                obs.setValueCodedName(getConceptName(value));
            } catch (NumberFormatException e) {
                throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.InvalidConceptId", new Object[] { valueIdentifier, valueName }, null));
            }
        }
    } else if ("DT".equals(hl7Datatype)) {
        DT value = (DT) obx5;
        if (value != null) {
            Date valueDate = getDate(value.getYear(), value.getMonth(), value.getDay(), 0, 0, 0);
            obs.setValueDatetime(valueDate);
        } else {
            log.warn("Not creating null valued obs for concept " + concept);
            return null;
        }
    } else if ("TS".equals(hl7Datatype)) {
        DTM value = ((TS) obx5).getTime();
        if (value != null) {
            Date valueDate = getDate(value.getYear(), value.getMonth(), value.getDay(), value.getHour(), value.getMinute(), value.getSecond());
            obs.setValueDatetime(valueDate);
        } else {
            log.warn("Not creating null valued obs for concept " + concept);
            return null;
        }
    } else if ("TM".equals(hl7Datatype)) {
        TM value = (TM) obx5;
        if (value != null) {
            Date valueTime = getDate(0, 0, 0, value.getHour(), value.getMinute(), value.getSecond());
            obs.setValueDatetime(valueTime);
        } else {
            log.warn("Not creating null valued obs for concept " + concept);
            return null;
        }
    } 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 if ("ED".equals(hl7Datatype)) {
        ED value = (ED) obx5;
        if (value == null || value.getData() == null || !StringUtils.hasText(value.getData().getValue())) {
            log.warn("Not creating null valued obs for concept " + concept);
            return null;
        }
        // we need to hydrate the concept so that the EncounterSaveHandler
        // doesn't fail since it needs to check if it is a concept numeric
        Concept c = Context.getConceptService().getConcept(obs.getConcept().getConceptId());
        obs.setConcept(c);
        String title = null;
        if (obs.getValueCodedName() != null) {
            title = obs.getValueCodedName().getName();
        }
        if (!StringUtils.hasText(title)) {
            title = c.getName().getName();
        }
        obs.setComplexData(new ComplexData(title, value.getData().getValue()));
    } else {
        // do we need to support BIT just in case it slips thru?
        throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.UpsupportedObsType", new Object[] { hl7Datatype }, null));
    }
    return obs;
}
Also used : FT(ca.uhn.hl7v2.model.v25.datatype.FT) CWE(ca.uhn.hl7v2.model.v25.datatype.CWE) DT(ca.uhn.hl7v2.model.v25.datatype.DT) ComplexData(org.openmrs.obs.ComplexData) ConceptName(org.openmrs.ConceptName) ED(ca.uhn.hl7v2.model.v25.datatype.ED) Concept(org.openmrs.Concept) ORU_R01_OBSERVATION(ca.uhn.hl7v2.model.v25.group.ORU_R01_OBSERVATION) Drug(org.openmrs.Drug) Obs(org.openmrs.Obs) ST(ca.uhn.hl7v2.model.v25.datatype.ST) CE(ca.uhn.hl7v2.model.v25.datatype.CE) ConceptAnswer(org.openmrs.ConceptAnswer) Date(java.util.Date) RelationshipType(org.openmrs.RelationshipType) EncounterType(org.openmrs.EncounterType) Type(ca.uhn.hl7v2.model.Type) PersonAttributeType(org.openmrs.PersonAttributeType) HL7Exception(ca.uhn.hl7v2.HL7Exception) Collection(java.util.Collection) TM(ca.uhn.hl7v2.model.v25.datatype.TM) DTM(ca.uhn.hl7v2.model.v25.datatype.DTM) DTM(ca.uhn.hl7v2.model.v25.datatype.DTM) Varies(ca.uhn.hl7v2.model.Varies) NM(ca.uhn.hl7v2.model.v25.datatype.NM) TS(ca.uhn.hl7v2.model.v25.datatype.TS)

Example 48 with Message

use of ca.uhn.hl7v2.model.Message in project openmrs-core by openmrs.

the class ADTA28Handler method processADT_A28.

private Message processADT_A28(ADT_A05 adt) throws HL7Exception {
    // validate HL7 version
    validate(adt);
    // extract segments for convenient use below
    MSH msh = getMSH(adt);
    PID pid = getPID(adt);
    // Obtain message control id (unique ID for message from sending
    // application). Eventually avoid replaying the same message.
    String messageControlId = msh.getMessageControlID().getValue();
    log.debug("Found HL7 message in inbound queue with control id = " + messageControlId);
    // Add creator of the patient to application
    String sendingApp = msh.getSendingApplication().getComponent(0).toString();
    log.debug("SendingApplication = " + sendingApp);
    // Search for the patient
    Integer patientId = findPatientId(pid);
    // Create new patient if the patient id doesn't exist yet
    if (patientId == null) {
        log.info("Creating new patient in response to ADT_A28 " + messageControlId);
        Patient patient = createPatient(pid, sendingApp);
        if (patient == null) {
            throw new HL7Exception("Couldn't create Patient object from PID");
        }
        Context.getPatientService().savePatient(patient);
    } else {
        log.info("Ignoring ADT_A28 message because patient (" + patientId + ") already exists.");
    }
    return adt;
}
Also used : MSH(ca.uhn.hl7v2.model.v25.segment.MSH) HL7Exception(ca.uhn.hl7v2.HL7Exception) Patient(org.openmrs.Patient) PID(ca.uhn.hl7v2.model.v25.segment.PID)

Example 49 with Message

use of ca.uhn.hl7v2.model.Message in project openmrs-core by openmrs.

the class HL7ServiceTest method resolveUserId_shouldReturnUserUsingUsername.

/**
 * @throws HL7Exception
 * @see HL7Service#resolveUserId(ca.uhn.hl7v2.model.v25.datatype.XCN)
 */
@Test
public void resolveUserId_shouldReturnUserUsingUsername() throws HL7Exception {
    HL7Service hl7service = Context.getHL7Service();
    // construct a message such that id Number at ORC is null
    Message message = hl7service.parseHL7String("MSH|^~\\&|FORMENTRY|AMRS.ELD|HL7LISTENER|AMRS.ELD|20080226102656||ORU^R01|JqnfhKKtouEz8kzTk6Zo|P|2.5|1||||||||16^AMRS.ELD.FORMID\r" + "PID|||3^^^^||John3^Doe^||\r" + "NK1|1|Hornblower^Horatio^L|2B^Sibling^99REL||||||||||||M|19410501|||||||||||||||||1000^^^L^PN||||\r" + "ORC|RE||||||||20080226102537|^butch\r" + "OBR|1|||1238^MEDICAL RECORD OBSERVATIONS^99DCT\r" + "OBX|1|NM|5497^CD4, BY FACS^99DCT||450|||||||||20080206\r" + "OBX|2|DT|5096^RETURN VISIT DATE^99DCT||20080229|||||||||20080212");
    ORU_R01 oru = (ORU_R01) message;
    ORC orc = oru.getPATIENT_RESULT().getORDER_OBSERVATION().getORC();
    XCN xcn = orc.getEnteredBy(0);
    Integer userId = hl7service.resolveUserId(xcn);
    assertThat(userId, is(502));
}
Also used : ORC(ca.uhn.hl7v2.model.v25.segment.ORC) XCN(ca.uhn.hl7v2.model.v25.datatype.XCN) Message(ca.uhn.hl7v2.model.Message) ORU_R01(ca.uhn.hl7v2.model.v25.message.ORU_R01) Test(org.junit.Test) BaseContextSensitiveTest(org.openmrs.test.BaseContextSensitiveTest)

Example 50 with Message

use of ca.uhn.hl7v2.model.Message in project openmrs-core by openmrs.

the class HL7ServiceTest method resolveLocationId_shouldReturnNullIfLocationIdAndNameAreIncorrect.

/**
 * @throws HL7Exception
 * @see HL7Service#resolveLocationId(ca.uhn.hl7v2.model.v25.datatype.PL)
 */
@Test
public void resolveLocationId_shouldReturnNullIfLocationIdAndNameAreIncorrect() throws HL7Exception {
    executeDataSet("org/openmrs/hl7/include/ORUTest-initialData.xml");
    HL7Service hl7service = Context.getHL7Service();
    Message message = hl7service.parseHL7String("MSH|^~\\&|FORMENTRY|AMRS.ELD|HL7LISTENER|AMRS.ELD|20080226102656||ORU^R01|JqnfhKKtouEz8kzTk6Zo|P|2.5|1||||||||16^AMRS.ELD.FORMID\r" + "PID|||3^^^^||John3^Doe^||\r" + "NK1|1|Hornblower^Horatio^L|2B^Sibling^99REL||||||||||||M|19410501|||||||||||||||||1000^^^L^PN||||\r" + "PV1||O|99999^0^0^0&Unknown&0||||1^Super User (1-8)|||||||||||||||||||||||||||||||||||||20080212|||||||V\r" + "ORC|RE||||||||20080226102537|1^Super User\r" + "OBR|1|||1238^MEDICAL RECORD OBSERVATIONS^99DCT\r" + "OBX|1|NM|5497^CD4, BY FACS^99DCT||450|||||||||20080206\r" + "OBX|2|DT|5096^RETURN VISIT DATE^99DCT||20080229|||||||||20080212");
    ORU_R01 oru = (ORU_R01) message;
    PV1 pv1 = oru.getPATIENT_RESULT().getPATIENT().getVISIT().getPV1();
    Assert.assertNotNull("PV1 parsed as null", pv1);
    PL hl7Location = pv1.getAssignedPatientLocation();
    Integer locationId = hl7service.resolveLocationId(hl7Location);
    Assert.assertNull(locationId);
}
Also used : Message(ca.uhn.hl7v2.model.Message) ORU_R01(ca.uhn.hl7v2.model.v25.message.ORU_R01) PV1(ca.uhn.hl7v2.model.v25.segment.PV1) PL(ca.uhn.hl7v2.model.v25.datatype.PL) Test(org.junit.Test) BaseContextSensitiveTest(org.openmrs.test.BaseContextSensitiveTest)

Aggregations

Message (ca.uhn.hl7v2.model.Message)114 Test (org.junit.Test)82 BaseContextSensitiveTest (org.openmrs.test.BaseContextSensitiveTest)60 ORU_R01 (ca.uhn.hl7v2.model.v25.message.ORU_R01)30 Patient (org.openmrs.Patient)24 NK1 (ca.uhn.hl7v2.model.v25.segment.NK1)22 HL7Exception (ca.uhn.hl7v2.HL7Exception)20 QRD (ca.uhn.hl7v2.model.v24.segment.QRD)19 ArrayList (java.util.ArrayList)19 MockEndpoint (org.apache.camel.component.mock.MockEndpoint)18 ORUR01Handler (org.openmrs.hl7.handler.ORUR01Handler)15 Concept (org.openmrs.Concept)14 Obs (org.openmrs.Obs)14 Person (org.openmrs.Person)14 MSH (ca.uhn.hl7v2.model.v24.segment.MSH)13 ObsService (org.openmrs.api.ObsService)11 ADR_A19 (ca.uhn.hl7v2.model.v24.message.ADR_A19)9 MSA (ca.uhn.hl7v2.model.v24.segment.MSA)9 Encounter (org.openmrs.Encounter)9 Structure (ca.uhn.hl7v2.model.Structure)8