/** * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * 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. * * The Original Code is OpenELIS code. * * Copyright (C) ITECH, University of Washington, Seattle WA. All Rights Reserved. * */ package us.mn.state.health.lims.dataexchange.order.action; import java.util.ArrayList; import java.util.List; import org.apache.commons.validator.GenericValidator; import us.mn.state.health.lims.common.services.ITestIdentityService; import us.mn.state.health.lims.common.services.TestIdentityService; import us.mn.state.health.lims.common.util.DateUtil; import ca.uhn.hl7v2.HL7Exception; import ca.uhn.hl7v2.model.Message; import ca.uhn.hl7v2.model.v251.datatype.CX; import ca.uhn.hl7v2.model.v251.group.OML_O21_OBSERVATION_REQUEST; import ca.uhn.hl7v2.model.v251.group.OML_O21_ORDER_PRIOR; import ca.uhn.hl7v2.model.v251.message.OML_O21; import ca.uhn.hl7v2.model.v251.segment.OBR; import ca.uhn.hl7v2.model.v251.segment.ORC; import ca.uhn.hl7v2.model.v251.segment.PID; public class HL7OrderInterpreter implements IOrderInterpreter{ public enum IdentityType{ GUID("GU"), ST_NUMBER("ST"), NATIONAL_ID("NA"), OB_NUMBER("OB"), PC_NUMBER("PC"); private String tag; private IdentityType(String tag){ this.tag = tag; } public String getIdentifier(){ return tag; } } public enum Gender{ MALE("M"), FEMALE("F"); private String tag; private Gender(String tag){ this.tag = tag; } public String getIdentifier(){ return tag; } } public enum ServiceIdentifier{ PANEL("P"), TEST("T"); private String tag; ServiceIdentifier(String tag){ this.tag = tag; } public String getIdentifier(){ return tag; } } private String labOrderNumber; private OrderType orderType; private OML_O21 orderMessage; private MessagePatient patient; private List<InterpreterResults> results = new ArrayList<InterpreterResults>(); private List<String> unsupportedTests = new ArrayList<String>(); private List<String> unsupportedPanels = new ArrayList<String>(); private ITestIdentityService testIdentityService; @Override public List<InterpreterResults> interpret(Message orderMessage){ this.orderMessage = (OML_O21)orderMessage; // try{ // System.out.println(this.orderMessage.printStructure()); // LogEvent.logError( "Debugging", "hl7", this.orderMessage.printStructure()); // }catch(HL7Exception e1){ // // TODO Auto-generated catch block // e1.printStackTrace(); // } try{ patient = createPatientFromHL7(); extractOrderInformation(); }catch(HL7Exception e){ e.printStackTrace(); return buildResultList(true); } return buildResultList(false); } private void extractOrderInformation() throws HL7Exception{ ORC orcSegment = (ORC)orderMessage.getORDER().get("ORC"); labOrderNumber = orcSegment.getPlacerOrderNumber().encode(); if(OrderType.REQUEST.getIdentifier().equals(orcSegment.getOrderControl().getValue())){ orderType = OrderType.REQUEST; }else if(OrderType.CANCEL.getIdentifier().equals(orcSegment.getOrderControl().getValue())){ orderType = OrderType.CANCEL; }else{ orderType = OrderType.UNKNOWN; } } private MessagePatient createPatientFromHL7() throws HL7Exception{ MessagePatient patient = new MessagePatient(); PID pid = (PID)orderMessage.getPATIENT().get("PID"); CX[] patientIdentities = pid.getPatientIdentifierList(); for(CX identity : patientIdentities){ String value = identity.getCx1_IDNumber().getValue(); String code = identity.getIdentifierTypeCode().getValue(); if(IdentityType.GUID.getIdentifier().equals(code)){ patient.setGuid(value); }else if(IdentityType.ST_NUMBER.getIdentifier().equals(code)){ patient.setStNumber(value); }else if(IdentityType.NATIONAL_ID.getIdentifier().equals(code)){ patient.setNationalId(value); }else if(IdentityType.OB_NUMBER.getIdentifier().equals(code)){ patient.setObNumber(value); }else if(IdentityType.PC_NUMBER.getIdentifier().equals(code)){ patient.setPcNumber(value); } } if( Gender.MALE.getIdentifier().equals(pid.getAdministrativeSex().getValue())){ patient.setGender("M"); }else if( Gender.FEMALE.getIdentifier().equals(pid.getAdministrativeSex().getValue())){ patient.setGender("F"); } setDOB(patient, pid); patient.setLastName(pid.getPatientName(0).getFamilyName().getSurname().getValue()); patient.setFirstName(pid.getPatientName(0).getGivenName().getValue()); patient.setAddressStreet(pid.getPatientAddress(0).getStreetAddress().getStreetOrMailingAddress().getValue()); patient.setAddressVillage(pid.getPatientAddress(0).getCity().getValue()); patient.setAddressDepartment(pid.getPatientAddress(0).getStateOrProvince().getValue()); return patient; } private void setDOB(MessagePatient patient, PID pid) throws HL7Exception{ String dob = pid.getDateTimeOfBirth().encode(); if( dob.length() >= 4){ String year = null; String month = DateUtil.AMBIGUOUS_DATE_SEGMENT; String date = DateUtil.AMBIGUOUS_DATE_SEGMENT; year = dob.substring(0, 4); if( dob.length() >= 6){ month = dob.substring(4, 6); } if( dob.length() >= 8){ date = dob.substring(6, 8); } patient.setDisplayDOB(date + "/" + month + "/" + year); } } private List<InterpreterResults> buildResultList(boolean exceptionThrown){ results = new ArrayList<InterpreterResults>(); if(exceptionThrown){ results.add(InterpreterResults.INTERPRET_ERROR); }else{ if( orderType == OrderType.UNKNOWN){ results.add(InterpreterResults.UNKNOWN_REQUEST_TYPE); } if(GenericValidator.isBlankOrNull(getReferringOrderNumber())){ results.add(InterpreterResults.MISSING_ORDER_NUMBER); } if(orderType == OrderType.REQUEST){ if(GenericValidator.isBlankOrNull(getMessagePatient().getGuid())){ results.add(InterpreterResults.MISSING_PATIENT_GUID); } //These are being commented out until we get confirmation on the desired policy. Either the request should be rejected or the user should be required to // fill the missing information in at the time of sample entry. Commenting these out supports the latter // if(GenericValidator.isBlankOrNull(getMessagePatient().getGender())){ // results.add(InterpreterResults.MISSING_PATIENT_GENDER); // } // // if(getMessagePatient().getDob() == null){ // results.add(InterpreterResults.MISSING_PATIENT_DOB); // } if(getMessagePatient().getNationalId() == null && getMessagePatient().getObNumber() == null && getMessagePatient().getPcNumber() == null && getMessagePatient().getStNumber() == null){ results.add(InterpreterResults.MISSING_PATIENT_IDENTIFIER); } try{ OML_O21_OBSERVATION_REQUEST orderRequest = orderMessage.getORDERAll().get(0).getOBSERVATION_REQUEST(); checkOBR( orderRequest.getOBR()); List<OML_O21_ORDER_PRIOR> priorOrders = orderRequest.getPRIOR_RESULT().getORDER_PRIORAll(); for(OML_O21_ORDER_PRIOR priorOrder : priorOrders){ checkOBR(priorOrder.getOBR()); } }catch(HL7Exception e){ e.printStackTrace(); results.add(InterpreterResults.INTERPRET_ERROR); } } } if(results.isEmpty()){ results.add(InterpreterResults.OK); } return results; } private void checkOBR( OBR obr) throws HL7Exception{ if( obr.isEmpty() ){ results.add(InterpreterResults.MISSING_TESTS); }else{ String name = obr.getUniversalServiceIdentifier().getText().getValue(); String identifier = obr.getUniversalServiceIdentifier().getIdentifier().getValue(); if( identifier.startsWith(ServiceIdentifier.TEST.getIdentifier() + "-")){ if(!getTestIdentityService().doesTestExist(name)){ if( !results.contains(InterpreterResults.UNSUPPORTED_TESTS)){ results.add(InterpreterResults.UNSUPPORTED_TESTS); } unsupportedTests.add( name ); } }else if( identifier.startsWith(ServiceIdentifier.PANEL.getIdentifier() + "-")){ if(!getTestIdentityService().doesPanelExist(name)){ if( !results.contains(InterpreterResults.UNSUPPORTED_PANELS)){ results.add(InterpreterResults.UNSUPPORTED_PANELS); } unsupportedPanels.add( name ); } }else{ results.add(InterpreterResults.OTHER_THAN_PANEL_OR_TEST_REQUESTED); } } } @Override public String getReferringOrderNumber(){ return labOrderNumber; } @Override public String getMessage(){ if(orderMessage == null){ return null; } try{ return orderMessage.encode(); }catch(HL7Exception e){ e.printStackTrace(); } return null; } @Override public MessagePatient getMessagePatient(){ return patient; } @Override public List<InterpreterResults> getResultStatus(){ return results; } @Override public OrderType getOrderType(){ return orderType; } @Override public List<String> getUnsupportedTests(){ return unsupportedTests; } @Override public List<String> getUnsupportedPanels(){ return unsupportedPanels; } private ITestIdentityService getTestIdentityService(){ if( testIdentityService == null){ testIdentityService = TestIdentityService.getInstance(); } return testIdentityService; } public void setTestIdentityService(ITestIdentityService testIdentityService){ this.testIdentityService = testIdentityService; } }