Search in sources :

Example 21 with NK1

use of ca.uhn.hl7v2.model.v25.segment.NK1 in project openmrs-core by openmrs.

the class ORUR01HandlerTest method processNK1_shouldCreateARelationshipFromANK1Segment.

/**
 * @see ORUR01Handler#processNK1(Patient,NK1)
 */
@Test
public void processNK1_shouldCreateARelationshipFromANK1Segment() throws Exception {
    PersonService personService = Context.getPersonService();
    // the patient that is the focus of
    Patient patient = new Patient(3);
    // this hl7 message
    // the patient that is related to
    Patient relative = new Patient(2);
    // patientA
    // process a message with a single NK1 segment
    // defines relative as patient's Parent
    String hl7String = "MSH|^~\\&|FORMENTRY|AMRS.ELD|HL7LISTENER|AMRS.ELD|20090728170332||ORU^R01|gu99yBh4loLX2mh9cHaV|P|2.5|1||||||||4^AMRS.ELD.FORMID\r" + "PID|||3^^^^||Beren^John^Bondo||\r" + "NK1|1|Jones^Jane^Lee^^RN|3A^Parent^99REL||||||||||||F|19751016|||||||||||||||||2^^^L^PI\r" + "PV1||O|1^Unknown||||1^Super User (admin)|||||||||||||||||||||||||||||||||||||20090714|||||||V\r" + "ORC|RE||||||||20090728165937|1^Super User\r" + "OBR|1|||1238^MEDICAL RECORD OBSERVATIONS^99DCT\r" + "OBX|2|NM|5497^CD4 COUNT^99DCT||123|||||||||20090714\r" + "OBR|3|||23^FOOD CONSTRUCT^99DCT\r" + "OBX|1|CWE|21^FOOD ASSISTANCE FOR ENTIRE FAMILY^99DCT||22^UNKNOWN^99DCT^2471^UNKNOWN^99NAM|||||||||20090714";
    ORUR01Handler oruHandler = new ORUR01Handler();
    Message hl7message = parser.parse(hl7String);
    ORU_R01 oru = (ORU_R01) hl7message;
    List<NK1> nk1List = oruHandler.getNK1List(oru);
    for (NK1 nk1 : nk1List) oruHandler.processNK1(patient, nk1);
    // verify relationship was created
    List<Relationship> rels = personService.getRelationships(relative, patient, new RelationshipType(3));
    Assert.assertTrue("new relationship was not created", !rels.isEmpty() && rels.size() == 1);
}
Also used : Message(ca.uhn.hl7v2.model.Message) ORU_R01(ca.uhn.hl7v2.model.v25.message.ORU_R01) NK1(ca.uhn.hl7v2.model.v25.segment.NK1) PersonService(org.openmrs.api.PersonService) Relationship(org.openmrs.Relationship) RelationshipType(org.openmrs.RelationshipType) Patient(org.openmrs.Patient) Test(org.junit.Test) BaseContextSensitiveTest(org.openmrs.test.BaseContextSensitiveTest)

Example 22 with NK1

use of ca.uhn.hl7v2.model.v25.segment.NK1 in project openmrs-core by openmrs.

the class ORUR01HandlerTest method processNK1_shouldCreateAPersonIfTheRelativeIsNotFound.

/**
 * @see ORUR01Handler#processNK1(Patient,NK1)
 */
@Test
public void processNK1_shouldCreateAPersonIfTheRelativeIsNotFound() throws Exception {
    // process a message with an invalid relative identifier
    PersonService personService = Context.getPersonService();
    // the patient that is the focus of
    Patient patient = new Patient(3);
    // this hl7 message
    String hl7String = "MSH|^~\\&|FORMENTRY|AMRS.ELD|HL7LISTENER|AMRS.ELD|20090728170332||ORU^R01|gu99yBh4loLX2mh9cHaV|P|2.5|1||||||||4^AMRS.ELD.FORMID\r" + "PID|||3^^^^||Beren^John^Bondo||\r" + "NK1|1|Jones^Jane^Lee^^RN|3A^Parent^99REL||||||||||||F|19751016|||||||||||||||||2178037d-f86b-4f12-8d8b-be3ebc220029^^^UUID^v4\r" + "PV1||O|1^Unknown||||1^Super User (admin)|||||||||||||||||||||||||||||||||||||20090714|||||||V\r" + "ORC|RE||||||||20090728165937|1^Super User\r" + "OBR|1|||1238^MEDICAL RECORD OBSERVATIONS^99DCT\r" + "OBX|2|NM|5497^CD4 COUNT^99DCT||123|||||||||20090714\r" + "OBR|3|||23^FOOD CONSTRUCT^99DCT\r" + "OBX|1|CWE|21^FOOD ASSISTANCE FOR ENTIRE FAMILY^99DCT||22^UNKNOWN^99DCT^2471^UNKNOWN^99NAM|||||||||20090714";
    ORUR01Handler oruHandler = new ORUR01Handler();
    Message hl7message = parser.parse(hl7String);
    ORU_R01 oru = (ORU_R01) hl7message;
    List<NK1> nk1List = oruHandler.getNK1List(oru);
    for (NK1 nk1 : nk1List) oruHandler.processNK1(patient, nk1);
    // find the relative in the database
    Person relative = personService.getPersonByUuid("2178037d-f86b-4f12-8d8b-be3ebc220029");
    Assert.assertNotNull("a new person was not created", relative);
    // see if the relative made it into the relationship properly
    List<Relationship> rels = personService.getRelationships(relative, patient, new RelationshipType(3));
    Assert.assertTrue("new relationship was not created", !rels.isEmpty() && rels.size() == 1);
}
Also used : Message(ca.uhn.hl7v2.model.Message) ORU_R01(ca.uhn.hl7v2.model.v25.message.ORU_R01) NK1(ca.uhn.hl7v2.model.v25.segment.NK1) PersonService(org.openmrs.api.PersonService) Relationship(org.openmrs.Relationship) RelationshipType(org.openmrs.RelationshipType) Patient(org.openmrs.Patient) Person(org.openmrs.Person) Test(org.junit.Test) BaseContextSensitiveTest(org.openmrs.test.BaseContextSensitiveTest)

Example 23 with NK1

use of ca.uhn.hl7v2.model.v25.segment.NK1 in project openmrs-core by openmrs.

the class ORUR01HandlerTest method processNK1_shouldFailIfTheRelationshipIdentifierIsFormattedImproperly.

/**
 * @see ORUR01Handler#processNK1(Patient,NK1)
 */
@Test(expected = HL7Exception.class)
public void processNK1_shouldFailIfTheRelationshipIdentifierIsFormattedImproperly() throws Exception {
    // process a message with an invalid relationship identifier format
    // the patient that is the focus of
    Patient patient = new Patient(3);
    // this hl7 message
    String hl7String = "MSH|^~\\&|FORMENTRY|AMRS.ELD|HL7LISTENER|AMRS.ELD|20090728170332||ORU^R01|gu99yBh4loLX2mh9cHaV|P|2.5|1||||||||4^AMRS.ELD.FORMID\r" + "PID|||3^^^^||Beren^John^Bondo||\r" + "NK1|1|Jones^Jane^Lee^^RN|3C^Parent^99REL||||||||||||F|19751016|||||||||||||||||2^^^L^PI\r" + "PV1||O|1^Unknown||||1^Super User (admin)|||||||||||||||||||||||||||||||||||||20090714|||||||V\r" + "ORC|RE||||||||20090728165937|1^Super User\r" + "OBR|1|||1238^MEDICAL RECORD OBSERVATIONS^99DCT\r" + "OBX|2|NM|5497^CD4 COUNT^99DCT||123|||||||||20090714\r" + "OBR|3|||23^FOOD CONSTRUCT^99DCT\r" + "OBX|1|CWE|21^FOOD ASSISTANCE FOR ENTIRE FAMILY^99DCT||22^UNKNOWN^99DCT^2471^UNKNOWN^99NAM|||||||||20090714";
    ORUR01Handler oruHandler = new ORUR01Handler();
    Message hl7message = parser.parse(hl7String);
    ORU_R01 oru = (ORU_R01) hl7message;
    List<NK1> nk1List = oruHandler.getNK1List(oru);
    for (NK1 nk1 : nk1List) oruHandler.processNK1(patient, nk1);
}
Also used : Message(ca.uhn.hl7v2.model.Message) ORU_R01(ca.uhn.hl7v2.model.v25.message.ORU_R01) NK1(ca.uhn.hl7v2.model.v25.segment.NK1) Patient(org.openmrs.Patient) Test(org.junit.Test) BaseContextSensitiveTest(org.openmrs.test.BaseContextSensitiveTest)

Example 24 with NK1

use of ca.uhn.hl7v2.model.v25.segment.NK1 in project openmrs-core by openmrs.

the class ORUR01Handler method processNK1.

/**
 * process an NK1 segment and add relationships if needed
 *
 * @param patient
 * @param nk1
 * @throws HL7Exception
 * @should create a relationship from a NK1 segment
 * @should not create a relationship if one exists
 * @should create a person if the relative is not found
 * @should fail if the coding system is not 99REL
 * @should fail if the relationship identifier is formatted improperly
 * @should fail if the relationship type is not found
 */
protected void processNK1(Patient patient, NK1 nk1) throws HL7Exception {
    // guarantee we are working with our custom coding system
    String relCodingSystem = nk1.getRelationship().getNameOfCodingSystem().getValue();
    if (!relCodingSystem.equals(HL7Constants.HL7_LOCAL_RELATIONSHIP)) {
        throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.relationshipCoding", new Object[] { relCodingSystem }, null));
    }
    // get the relationship type identifier
    String relIdentifier = nk1.getRelationship().getIdentifier().getValue();
    // validate the format of the relationship identifier
    if (!Pattern.matches("[0-9]+[AB]", relIdentifier)) {
        throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.relationshipType", new Object[] { relIdentifier }, null));
    }
    // get the type ID
    Integer relTypeId;
    try {
        relTypeId = Integer.parseInt(relIdentifier.substring(0, relIdentifier.length() - 1));
    } catch (NumberFormatException e) {
        throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.relationshipType", new Object[] { relIdentifier }, null));
    }
    // find the relationship type
    RelationshipType relType = Context.getPersonService().getRelationshipType(relTypeId);
    if (relType == null) {
        throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.relationshipTypeNotFound", new Object[] { relTypeId }, null));
    }
    // find the relative
    Person relative = getRelative(nk1);
    // determine if the patient is person A or B; the relIdentifier indicates
    // the relative's side of the relationship, so the patient is the inverse
    boolean patientIsPersonA = relIdentifier.endsWith("B");
    boolean patientCanBeEitherPerson = relType.getbIsToA().equals(relType.getaIsToB());
    // look at existing relationships to determine if a new one is needed
    Set<Relationship> rels = new HashSet<>();
    if (relative != null) {
        if (patientCanBeEitherPerson || patientIsPersonA) {
            rels.addAll(Context.getPersonService().getRelationships(patient, relative, relType));
        }
        if (patientCanBeEitherPerson || !patientIsPersonA) {
            rels.addAll(Context.getPersonService().getRelationships(relative, patient, relType));
        }
    }
    // create a relationship if none is found
    if (rels.isEmpty()) {
        // check the relative's existence
        if (relative == null) {
            // create one based on NK1 information
            relative = Context.getHL7Service().createPersonFromNK1(nk1);
            if (relative == null) {
                throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.relativeNotCreated"));
            }
        }
        // create the relationship
        Relationship relation = new Relationship();
        if (patientCanBeEitherPerson || patientIsPersonA) {
            relation.setPersonA(patient);
            relation.setPersonB(relative);
        } else {
            relation.setPersonA(relative);
            relation.setPersonB(patient);
        }
        relation.setRelationshipType(relType);
        Context.getPersonService().saveRelationship(relation);
    }
}
Also used : Relationship(org.openmrs.Relationship) HL7Exception(ca.uhn.hl7v2.HL7Exception) RelationshipType(org.openmrs.RelationshipType) Person(org.openmrs.Person) HashSet(java.util.HashSet)

Example 25 with NK1

use of ca.uhn.hl7v2.model.v25.segment.NK1 in project openmrs-core by openmrs.

the class ORUR01Handler method processORU_R01.

/**
 * Bulk of the processing done here. Called by the main processMessage method
 *
 * @param oru the message to process
 * @return the processed message
 * @throws HL7Exception
 * @should process multiple NK1 segments
 */
private Message processORU_R01(ORU_R01 oru) throws HL7Exception {
    // TODO: ideally, we would branch or alter our behavior based on the
    // sending application.
    // validate message
    validate(oru);
    // extract segments for convenient use below
    MSH msh = getMSH(oru);
    PID pid = getPID(oru);
    List<NK1> nk1List = getNK1List(oru);
    PV1 pv1 = getPV1(oru);
    // we're using the ORC assoc with first OBR to
    ORC orc = getORC(oru);
    // hold data enterer and date entered for now
    // Obtain message control id (unique ID for message from sending
    // application)
    String messageControlId = msh.getMessageControlID().getValue();
    if (log.isDebugEnabled()) {
        log.debug("Found HL7 message in inbound queue with control id = " + messageControlId);
    }
    // create the encounter
    Patient patient = getPatient(pid);
    if (log.isDebugEnabled()) {
        log.debug("Processing HL7 message for patient " + patient.getPatientId());
    }
    Encounter encounter = createEncounter(msh, patient, pv1, orc);
    // do the discharge to location logic
    try {
        updateHealthCenter(patient, pv1);
    } catch (Exception e) {
        log.error("Error while processing Discharge To Location (" + messageControlId + ")", e);
    }
    // process NK1 (relationship) segments
    for (NK1 nk1 : nk1List) {
        processNK1(patient, nk1);
    }
    // list of concepts proposed in the obs of this encounter.
    // these proposals need to be created after the encounter
    // has been created
    List<ConceptProposal> conceptProposals = new ArrayList<>();
    // create observations
    if (log.isDebugEnabled()) {
        log.debug("Creating observations for message " + messageControlId + "...");
    }
    // we ignore all MEDICAL_RECORD_OBSERVATIONS that are OBRs.  We do not
    // create obs_groups for them
    List<Integer> ignoredConceptIds = new ArrayList<>();
    String obrConceptId = Context.getAdministrationService().getGlobalProperty(OpenmrsConstants.GLOBAL_PROPERTY_MEDICAL_RECORD_OBSERVATIONS, "1238");
    if (StringUtils.hasLength(obrConceptId)) {
        ignoredConceptIds.add(Integer.valueOf(obrConceptId));
    }
    // we also ignore all PROBLEM_LIST that are OBRs
    String obrProblemListConceptId = Context.getAdministrationService().getGlobalProperty(OpenmrsConstants.GLOBAL_PROPERTY_PROBLEM_LIST, "1284");
    if (StringUtils.hasLength(obrProblemListConceptId)) {
        ignoredConceptIds.add(Integer.valueOf(obrProblemListConceptId));
    }
    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();
        if (!StringUtils.hasText(obr.getUniversalServiceIdentifier().getIdentifier().getValue())) {
            throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.errorInvalidOBR ", new Object[] { messageControlId }, null));
        }
        // if we're not ignoring this obs group, create an
        // Obs grouper object that the underlying obs objects will use
        Obs obsGrouper = null;
        Concept obrConcept = getConcept(obr.getUniversalServiceIdentifier(), messageControlId);
        if (obrConcept != null && !ignoredConceptIds.contains(obrConcept.getId())) {
            // maybe check for a parent obs group from OBR-29 Parent ?
            // create an obs for this obs group too
            obsGrouper = new Obs();
            obsGrouper.setConcept(obrConcept);
            obsGrouper.setPerson(encounter.getPatient());
            obsGrouper.setEncounter(encounter);
            Date datetime = getDatetime(obr);
            if (datetime == null) {
                datetime = encounter.getEncounterDatetime();
            }
            obsGrouper.setObsDatetime(datetime);
            obsGrouper.setLocation(encounter.getLocation());
            obsGrouper.setCreator(encounter.getCreator());
            // set comments if there are any
            StringBuilder comments = new StringBuilder();
            ORU_R01_ORDER_OBSERVATION parent = (ORU_R01_ORDER_OBSERVATION) obr.getParent();
            int totalNTEs = parent.getNTEReps();
            for (int iNTE = 0; iNTE < totalNTEs; iNTE++) {
                for (FT obxComment : parent.getNTE(iNTE).getComment()) {
                    if (comments.length() > 0) {
                        comments.append(" ");
                    }
                    comments.append(obxComment.getValue());
                }
            }
            // only set comments if there are any
            if (StringUtils.hasText(comments.toString())) {
                obsGrouper.setComment(comments.toString());
            }
            // add this obs as another row in the obs table
            encounter.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(encounter, obx, obr, messageControlId);
                if (obs != null) {
                    // the creator/dateCreated from the encounter
                    if (encounter.getEncounterId() != null) {
                        obs.setCreator(getEnterer(orc));
                        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);
                    } else {
                        // set this obs on the encounter object that we
                        // will be saving later
                        log.debug("Obs is not null. Adding to encounter object");
                        encounter.addObs(obs);
                        log.debug("Done with this obs");
                    }
                }
            } catch (ProposingConceptException proposingException) {
                Concept questionConcept = proposingException.getConcept();
                String value = proposingException.getValueName();
                // if the sender never specified any text for the proposed concept
                if (!StringUtils.isEmpty(value)) {
                    conceptProposals.add(createConceptProposal(encounter, questionConcept, value));
                } else {
                    errorInHL7Queue = new HL7Exception(Context.getMessageSourceService().getMessage("Hl7.proposed.concept.name.empty"), proposingException);
                    // stop any further processing of current message
                    break;
                }
            } catch (HL7Exception e) {
                errorInHL7Queue = e;
            } finally {
                // Handle obs-level exceptions
                if (errorInHL7Queue != null) {
                    throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.improperlyFormattedOBX", new Object[] { PipeParser.encode(obx, new EncodingCharacters('|', "^~\\&")) }, null), HL7Exception.DATA_TYPE_ERROR, errorInHL7Queue);
                }
            }
        }
    }
    if (log.isDebugEnabled()) {
        log.debug("Finished creating observations");
        log.debug("Current thread: " + Thread.currentThread());
        log.debug("Creating the encounter object");
    }
    Context.getEncounterService().saveEncounter(encounter);
    // now that the encounter is saved
    for (ConceptProposal proposal : conceptProposals) {
        Context.getConceptService().saveConceptProposal(proposal);
    }
    return oru;
}
Also used : ORC(ca.uhn.hl7v2.model.v25.segment.ORC) ArrayList(java.util.ArrayList) FT(ca.uhn.hl7v2.model.v25.datatype.FT) NK1(ca.uhn.hl7v2.model.v25.segment.NK1) Encounter(org.openmrs.Encounter) OBR(ca.uhn.hl7v2.model.v25.segment.OBR) EncodingCharacters(ca.uhn.hl7v2.parser.EncodingCharacters) Concept(org.openmrs.Concept) Obs(org.openmrs.Obs) MSH(ca.uhn.hl7v2.model.v25.segment.MSH) ORU_R01_PATIENT_RESULT(ca.uhn.hl7v2.model.v25.group.ORU_R01_PATIENT_RESULT) OBX(ca.uhn.hl7v2.model.v25.segment.OBX) Patient(org.openmrs.Patient) PID(ca.uhn.hl7v2.model.v25.segment.PID) PV1(ca.uhn.hl7v2.model.v25.segment.PV1) DataTypeException(ca.uhn.hl7v2.model.DataTypeException) HL7Exception(ca.uhn.hl7v2.HL7Exception) ApplicationException(ca.uhn.hl7v2.app.ApplicationException) Date(java.util.Date) ORU_R01_ORDER_OBSERVATION(ca.uhn.hl7v2.model.v25.group.ORU_R01_ORDER_OBSERVATION) ConceptProposal(org.openmrs.ConceptProposal) HL7Exception(ca.uhn.hl7v2.HL7Exception)

Aggregations

Message (ca.uhn.hl7v2.model.Message)30 Test (org.junit.Test)30 BaseContextSensitiveTest (org.openmrs.test.BaseContextSensitiveTest)30 ORU_R01 (ca.uhn.hl7v2.model.v25.message.ORU_R01)29 NK1 (ca.uhn.hl7v2.model.v25.segment.NK1)22 ORUR01Handler (org.openmrs.hl7.handler.ORUR01Handler)15 Patient (org.openmrs.Patient)11 Person (org.openmrs.Person)10 CX (ca.uhn.hl7v2.model.v25.datatype.CX)7 Relationship (org.openmrs.Relationship)5 RelationshipType (org.openmrs.RelationshipType)5 HL7Exception (ca.uhn.hl7v2.HL7Exception)4 ORC (ca.uhn.hl7v2.model.v25.segment.ORC)4 PV1 (ca.uhn.hl7v2.model.v25.segment.PV1)4 PersonService (org.openmrs.api.PersonService)4 ApplicationException (ca.uhn.hl7v2.app.ApplicationException)3 PL (ca.uhn.hl7v2.model.v25.datatype.PL)3 XCN (ca.uhn.hl7v2.model.v25.datatype.XCN)3 PID (ca.uhn.hl7v2.model.v25.segment.PID)2 EncodingNotSupportedException (ca.uhn.hl7v2.parser.EncodingNotSupportedException)2