use of ca.uhn.hl7v2.model.v25.datatype.IS 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);
}
}
use of ca.uhn.hl7v2.model.v25.datatype.IS 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;
}
use of ca.uhn.hl7v2.model.v25.datatype.IS in project openmrs-core by openmrs.
the class ORUR01Handler method updateHealthCenter.
private void updateHealthCenter(Patient patient, PV1 pv1) {
// Update patient's location if it has changed
if (log.isDebugEnabled()) {
log.debug("Checking for discharge to location");
}
DLD dld = pv1.getDischargedToLocation();
log.debug("DLD = " + dld);
if (dld == null) {
return;
}
IS hl7DischargeToLocation = dld.getDischargeLocation();
log.debug("is = " + hl7DischargeToLocation);
if (hl7DischargeToLocation == null) {
return;
}
String dischargeToLocation = hl7DischargeToLocation.getValue();
log.debug("dischargeToLocation = " + dischargeToLocation);
if (dischargeToLocation != null && dischargeToLocation.length() > 0) {
if (log.isDebugEnabled()) {
log.debug("Patient discharged to " + dischargeToLocation);
}
// delimiter
for (int i = 0; i < dischargeToLocation.length(); i++) {
char ch = dischargeToLocation.charAt(i);
if (ch == '&' || ch == '^') {
dischargeToLocation = dischargeToLocation.substring(0, i);
break;
}
}
Integer newLocationId = Integer.parseInt(dischargeToLocation);
// Hydrate a full patient object from patient object containing only
// identifier
patient = Context.getPatientService().getPatient(patient.getPatientId());
PersonAttributeType healthCenterAttrType = Context.getPersonService().getPersonAttributeTypeByName("Health Center");
if (healthCenterAttrType == null) {
log.error("A person attribute type with name 'Health Center' is not defined but patient " + patient.getPatientId() + " is trying to change their health center to " + newLocationId);
return;
}
PersonAttribute currentHealthCenter = patient.getAttribute("Health Center");
if (currentHealthCenter == null || !newLocationId.toString().equals(currentHealthCenter.getValue())) {
PersonAttribute newHealthCenter = new PersonAttribute(healthCenterAttrType, newLocationId.toString());
log.debug("Updating patient's location from " + currentHealthCenter + " to " + newLocationId);
// add attribute (and void old if there is one)
patient.addAttribute(newHealthCenter);
// save the patient and their new attribute
Context.getPatientService().savePatient(patient);
}
}
log.debug("finished discharge to location method");
}
use of ca.uhn.hl7v2.model.v25.datatype.IS in project openmrs-core by openmrs.
the class HL7ServiceImpl method processHL7InQueue.
/**
* @see org.openmrs.hl7.HL7Service#processHL7InQueue(org.openmrs.hl7.HL7InQueue)
*/
@Override
public HL7InQueue processHL7InQueue(HL7InQueue hl7InQueue) throws HL7Exception {
if (hl7InQueue == null) {
throw new HL7Exception("hl7InQueue argument cannot be null");
}
// mark this queue object as processing so that it isn't processed twice
if (OpenmrsUtil.nullSafeEquals(HL7Constants.HL7_STATUS_PROCESSING, hl7InQueue.getMessageState())) {
throw new HL7Exception("The hl7InQueue message with id: " + hl7InQueue.getHL7InQueueId() + " is already processing. " + ",key=" + hl7InQueue.getHL7SourceKey() + ")");
} else {
hl7InQueue.setMessageState(HL7Constants.HL7_STATUS_PROCESSING);
}
if (log.isDebugEnabled()) {
log.debug("Processing HL7 inbound queue (id=" + hl7InQueue.getHL7InQueueId() + ",key=" + hl7InQueue.getHL7SourceKey() + ")");
}
// Parse the HL7 into an HL7Message or abort with failure
String hl7Message = hl7InQueue.getHL7Data();
try {
// Parse the inbound HL7 message using the parser
// NOT making a direct call here so that AOP can happen around this
// method
Message parsedMessage = Context.getHL7Service().parseHL7String(hl7Message);
// Send the parsed message to our receiver routine for processing
// into db
// NOT making a direct call here so that AOP can happen around this
// method
Context.getHL7Service().processHL7Message(parsedMessage);
// Move HL7 inbound queue entry into the archive before exiting
log.debug("Archiving HL7 inbound queue entry");
Context.getHL7Service().saveHL7InArchive(new HL7InArchive(hl7InQueue));
log.debug("Removing HL7 message from inbound queue");
Context.getHL7Service().purgeHL7InQueue(hl7InQueue);
} catch (HL7Exception e) {
boolean skipError = false;
log.debug("Unable to process hl7inqueue: " + hl7InQueue.getHL7InQueueId(), e);
log.debug("Hl7inqueue source: " + hl7InQueue.getHL7Source());
log.debug("hl7_processor.ignore_missing_patient_non_local? " + Context.getAdministrationService().getGlobalProperty(OpenmrsConstants.GLOBAL_PROPERTY_IGNORE_MISSING_NONLOCAL_PATIENTS, "false"));
if (e.getCause() != null && "Could not resolve patient".equals(e.getCause().getMessage()) && !"local".equals(hl7InQueue.getHL7Source().getName()) && "true".equals(Context.getAdministrationService().getGlobalProperty(OpenmrsConstants.GLOBAL_PROPERTY_IGNORE_MISSING_NONLOCAL_PATIENTS, "false"))) {
skipError = true;
}
if (!skipError) {
setFatalError(hl7InQueue, "Trouble parsing HL7 message (" + hl7InQueue.getHL7SourceKey() + ")", e);
}
} catch (Exception e) {
setFatalError(hl7InQueue, "Exception while attempting to process HL7 In Queue (" + hl7InQueue.getHL7SourceKey() + ")", e);
}
return hl7InQueue;
}
use of ca.uhn.hl7v2.model.v25.datatype.IS in project openmrs-core by openmrs.
the class ORUR01HandlerTest method parseObs_shouldAddCommentsToAnObservationFromNTESegments.
/**
* @see ORUR01Handler#parseObs(Encounter,OBX,OBR,String)
*/
@Test
public void parseObs_shouldAddCommentsToAnObservationFromNTESegments() throws Exception {
ObsService os = Context.getObsService();
String hl7string = "MSH|^~\\&|FORMENTRY|AMRS.ELD|HL7LISTENER|AMRS.ELD|20080226102656||ORU^R01|JqnfhKKtouEz8kzTk6Zo|P|2.5|1||||||||16^AMRS.ELD.FORMID\r" + "PID|||7^^^^||Collet^Test^Chebaskwony||\r" + "PV1||O|1^Unknown Location||||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||1|||||||||20080206\r" + "NTE|1|L|This is a comment";
// the expected question for the obs in the hl7 message has to be
// numeric
Assert.assertEquals("Numeric", Context.getConceptService().getConcept(5497).getDatatype().getName());
List<Obs> oldList = os.getObservationsByPersonAndConcept(new Person(7), new Concept(5497));
Message hl7message = parser.parse(hl7string);
router.processMessage(hl7message);
List<Obs> newList = os.getObservationsByPersonAndConcept(new Person(7), new Concept(5497));
Obs newObservation = null;
for (Obs newObs : newList) {
if (!oldList.contains(newObs) && !newObs.isObsGrouping()) {
newObservation = newObs;
}
}
Assert.assertEquals("This is a comment", newObservation.getComment());
}
Aggregations