diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b11c5b2..844f750 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,29 +22,26 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - + - name: Checkout + uses: actions/checkout@v4 + - name: Set up JDK 1.8 - uses: actions/setup-java@v1 + uses: actions/setup-java@v4 with: - java-version: 8.0.232 + distribution: temurin + java-version: 8 + cache: 'maven' + - name: Set up Maven uses: stCarolas/setup-maven@v4 with: maven-version: 3.6.3 - - name: Cache Maven packages - uses: actions/cache@v2 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 - name: Build and Test run: mvn --batch-mode --update-snapshots clean package - name: Set settings.xml - uses: s4u/maven-settings-action@v2.6.0 + uses: s4u/maven-settings-action@v3.1.0 with: servers: | [{ diff --git a/api/pom.xml b/api/pom.xml index a51bac0..76a9987 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -17,5 +17,32 @@ org.openmrs.web openmrs-web + + org.openmrs.module + reporting-api + provided + + + org.openmrs.module + reporting-api-2.0 + provided + + + org.openmrs.module + calculation-api + provided + + + org.openmrs.module + serialization.xstream-api + ${serialization.xstreamVersion} + test + + + org.openmrs.module + serialization.xstream-api-2.0 + ${serialization.xstreamVersion} + test + diff --git a/api/src/main/java/org/openmrs/module/labintegration/ActivatedReportManager.java b/api/src/main/java/org/openmrs/module/labintegration/ActivatedReportManager.java new file mode 100644 index 0000000..d9458e0 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/labintegration/ActivatedReportManager.java @@ -0,0 +1,11 @@ +package org.openmrs.module.labintegration; + +import org.openmrs.module.reporting.report.manager.BaseReportManager; + +public abstract class ActivatedReportManager extends BaseReportManager { + + public boolean isActivated() { + return true; + } + +} diff --git a/api/src/main/java/org/openmrs/module/labintegration/LabIntegrationActivator.java b/api/src/main/java/org/openmrs/module/labintegration/LabIntegrationActivator.java index 4d0b118..2d13c91 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/LabIntegrationActivator.java +++ b/api/src/main/java/org/openmrs/module/labintegration/LabIntegrationActivator.java @@ -13,6 +13,7 @@ import org.openmrs.api.context.Context; import org.openmrs.module.BaseModuleActivator; import org.openmrs.module.labintegration.api.event.SaveEncounterAfterAdvice; +import org.openmrs.module.reporting.report.manager.ReportManagerUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,6 +31,18 @@ public class LabIntegrationActivator extends BaseModuleActivator { public void started() { LOGGER.info("Started Lab Integration"); Context.addAdvice(EncounterService.class, getFormSubmitAfterAdvice()); + //ReportManagerUtil.setupAllReports(ActivatedReportManager.class); + for (ActivatedReportManager reportManager : Context.getRegisteredComponents(ActivatedReportManager.class)) { + if (reportManager.isActivated()) { + LOGGER.info("Setting up report " + reportManager.getName() + "..."); + try { + ReportManagerUtil.setupReport(reportManager); + } + catch (Exception e) { + LOGGER.error("Failed to setup '" + reportManager.getName() + "' report because of: " + e.getMessage()); + } + } + } } /** @@ -42,7 +55,6 @@ public void stopped() { } private SaveEncounterAfterAdvice getFormSubmitAfterAdvice() { - return Context.getRegisteredComponent( - "labintegration.SaveEncounterAfterAdvice", SaveEncounterAfterAdvice.class); + return Context.getRegisteredComponent("labintegration.SaveEncounterAfterAdvice", SaveEncounterAfterAdvice.class); } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/PropertiesUtil.java b/api/src/main/java/org/openmrs/module/labintegration/PropertiesUtil.java index 6f95fef..590ac88 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/PropertiesUtil.java +++ b/api/src/main/java/org/openmrs/module/labintegration/PropertiesUtil.java @@ -5,26 +5,26 @@ import org.openmrs.api.context.Context; public final class PropertiesUtil { - - private static final String GP_LAB_ORDER_ENCOUNTER_TYPE_UUID = "labintegration.orderEncounterTypeUuid"; - - public static String getGlobalProperty(String propertyName) { - String propertyValue = Context.getAdministrationService().getGlobalProperty(propertyName); - if (StringUtils.isBlank(propertyValue)) { - throw new APIException(String.format("Property value for '%s' is not set", propertyName)); - } - return propertyValue; - } - - public static boolean isGlobalPropertySet(String propertyName) { - String propertyValue = Context.getAdministrationService().getGlobalProperty(propertyName); - return !StringUtils.isBlank(propertyValue); - } - - public static String getLabOrderEncounterTypeUuid() { - return getGlobalProperty(GP_LAB_ORDER_ENCOUNTER_TYPE_UUID); - } - - private PropertiesUtil() { - } + + private static final String GP_LAB_ORDER_ENCOUNTER_TYPE_UUID = "labintegration.orderEncounterTypeUuid"; + + public static String getGlobalProperty(String propertyName) { + String propertyValue = Context.getAdministrationService().getGlobalProperty(propertyName); + if (StringUtils.isBlank(propertyValue)) { + throw new APIException(String.format("Property value for '%s' is not set", propertyName)); + } + return propertyValue; + } + + public static boolean isGlobalPropertySet(String propertyName) { + String propertyValue = Context.getAdministrationService().getGlobalProperty(propertyName); + return !StringUtils.isBlank(propertyValue); + } + + public static String getLabOrderEncounterTypeUuid() { + return getGlobalProperty(GP_LAB_ORDER_ENCOUNTER_TYPE_UUID); + } + + private PropertiesUtil() { + } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/LabIntegrationReportService.java b/api/src/main/java/org/openmrs/module/labintegration/api/LabIntegrationReportService.java new file mode 100644 index 0000000..923f371 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/labintegration/api/LabIntegrationReportService.java @@ -0,0 +1,12 @@ +package org.openmrs.module.labintegration.api; + +import org.openmrs.Obs; +import org.openmrs.api.OpenmrsService; + +import java.util.Date; +import java.util.List; + +public interface LabIntegrationReportService extends OpenmrsService { + + List getLabResults(Date startDate, Date endDate); +} diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/LabIntegrationReportsConstants.java b/api/src/main/java/org/openmrs/module/labintegration/api/LabIntegrationReportsConstants.java new file mode 100644 index 0000000..27637b6 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/labintegration/api/LabIntegrationReportsConstants.java @@ -0,0 +1,18 @@ +package org.openmrs.module.labintegration.api; + +import org.openmrs.module.labintegration.api.hl7.ObsSelector; + +public final class LabIntegrationReportsConstants { + + public static final int TESTS_ORDERED_CONCEPT_ID = ObsSelector.TESTS_ORDERED_CONCEPT_ID; + + public static final int FREE_TEXT_RESULT_CONCEPT_ID = 165399; + + public static final String LOCATION_ISANTE_CODE_UUID = "0e52924e-4ebb-40ba-9b83-b198b532653b"; + + public static final String ISANTEPLUS_IDENDTIFIER_TYPE_UUID = "05a29f94-c0ed-11e2-94be-8c13b969e334"; + + private LabIntegrationReportsConstants() { + } + +} diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/alerts/AlertCreator.java b/api/src/main/java/org/openmrs/module/labintegration/api/alerts/AlertCreator.java index 21693a3..5d85a6f 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/alerts/AlertCreator.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/alerts/AlertCreator.java @@ -4,6 +4,6 @@ import org.openmrs.Obs; public interface AlertCreator { - - void createAlert(Encounter encounter, Obs obs, String status); + + void createAlert(Encounter encounter, Obs obs, String status); } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/alerts/OpenMrsAlertCreator.java b/api/src/main/java/org/openmrs/module/labintegration/api/alerts/OpenMrsAlertCreator.java index 61f691d..bb6094a 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/alerts/OpenMrsAlertCreator.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/alerts/OpenMrsAlertCreator.java @@ -21,40 +21,39 @@ @Component("alertCreator") public class OpenMrsAlertCreator implements AlertCreator { - - private static final Logger LOGGER = LoggerFactory.getLogger(OpenMrsAlertCreator.class); - - @Autowired - private AlertService alertService; - - @Autowired - private UserService userService; - - @Override - public void createAlert(Encounter encounter, Obs obs, String status) { - List users = findUsers(encounter); - if (CollectionUtils.isEmpty(users)) { - LOGGER.warn("No users found for encounter: {}", encounter.getUuid()); - } else { - registerAlerts(obs.getConcept(), encounter.getPatient(), users, status); - } - } - - - private List findUsers(Encounter encounter) { - List users = new ArrayList<>(); - for (EncounterProvider encProvider : encounter.getEncounterProviders()) { - Person person = encProvider.getProvider().getPerson(); - users.addAll(userService.getUsersByPerson(person, false)); - } - return users; - } - - private void registerAlerts(Concept concept, Patient patient, List users, String status) { - String text = String.format("Lab: %s received for %s test for patient %s", status, - concept.getName().getName(), patient.getPersonName().toString()); - Alert alert = new Alert(text, users); - alert.setCreator(users.get(0)); - alertService.saveAlert(alert); - } + + private static final Logger LOGGER = LoggerFactory.getLogger(OpenMrsAlertCreator.class); + + @Autowired + private AlertService alertService; + + @Autowired + private UserService userService; + + @Override + public void createAlert(Encounter encounter, Obs obs, String status) { + List users = findUsers(encounter); + if (CollectionUtils.isEmpty(users)) { + LOGGER.warn("No users found for encounter: {}", encounter.getUuid()); + } else { + registerAlerts(obs.getConcept(), encounter.getPatient(), users, status); + } + } + + private List findUsers(Encounter encounter) { + List users = new ArrayList<>(); + for (EncounterProvider encProvider : encounter.getEncounterProviders()) { + Person person = encProvider.getProvider().getPerson(); + users.addAll(userService.getUsersByPerson(person, false)); + } + return users; + } + + private void registerAlerts(Concept concept, Patient patient, List users, String status) { + String text = String.format("Lab: %s received for %s test for patient %s", status, concept.getName().getName(), + patient.getPersonName().toString()); + Alert alert = new Alert(text, users); + alert.setCreator(users.get(0)); + alertService.saveAlert(alert); + } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/event/SaveEncounterAfterAdvice.java b/api/src/main/java/org/openmrs/module/labintegration/api/event/SaveEncounterAfterAdvice.java index e1a500a..51b10a4 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/event/SaveEncounterAfterAdvice.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/event/SaveEncounterAfterAdvice.java @@ -24,18 +24,16 @@ public class SaveEncounterAfterAdvice implements AfterReturningAdvice { @Override public void afterReturning(Object savedObject, Method method, Object[] args, Object target) { - if (StringUtils.equals(method.getName(), SAVE_ENCOUNTER_METHOD_NAME) - && savedObject != null) { + if (StringUtils.equals(method.getName(), SAVE_ENCOUNTER_METHOD_NAME) && savedObject != null) { Encounter encounter = (Encounter) savedObject; - LOGGER.info("Invoked saveEncounter method in EncounterService. Saved encounter {}", - encounter.getUuid()); + LOGGER.info("Invoked saveEncounter method in EncounterService. Saved encounter {}", encounter.getUuid()); - if (StringUtils.equals(PropertiesUtil.getLabOrderEncounterTypeUuid(), - encounter.getEncounterType().getUuid())) { + if (StringUtils.equals(PropertiesUtil.getLabOrderEncounterTypeUuid(), encounter.getEncounterType().getUuid())) { LOGGER.info("Order encounter occurred {}", encounter.getUuid()); try { labIntegrationService.doOrder(encounter); - } catch (Exception e) { + } + catch (Exception e) { // TODO LOGGER.error("Unable to send order messages", e); } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/ObsSelector.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/ObsSelector.java index 90838e4..3dbd8d4 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/ObsSelector.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/ObsSelector.java @@ -11,61 +11,63 @@ @Component public class ObsSelector { - - private static final int TESTS_ORDERED_CONCEPT_ID = 1271; - private static volatile int viralLoadConceptId = -1; - private static volatile int earlyInfantDiagnosisConceptId = -1; - - private Set conceptIds = new HashSet<>(); - - public ObsSelector() { - - } - - public boolean isValidTestType(Obs obs) { - return TESTS_ORDERED_CONCEPT_ID == obs.getConcept().getConceptId() && obs.getValueCoded() != null && ( - (getViralLoadConceptId() != -1 && obs.getValueCoded().getConceptId() == getViralLoadConceptId()) - || (getEarlyInfantDiagnosisConceptId() != -1 && obs.getValueCoded().getConceptId() == getEarlyInfantDiagnosisConceptId()) - ); - } - - private int getViralLoadConceptId() { - if (viralLoadConceptId == -1) { - synchronized (ObsSelector.class) { - if (viralLoadConceptId == -1) { - ConceptService conceptService = Context.getService(ConceptService.class); - Concept concept = conceptService.getConceptByMapping("856", "CIEL"); - if (concept == null) { - concept = conceptService.getConceptByMapping("25836-8", "LOINC"); - } - - if (concept != null) { - viralLoadConceptId = concept.getConceptId(); - } - } - } - } - - return viralLoadConceptId; - } - - private int getEarlyInfantDiagnosisConceptId() { - if (earlyInfantDiagnosisConceptId == -1) { - synchronized (ObsSelector.class) { - if (earlyInfantDiagnosisConceptId == -1) { - ConceptService conceptService = Context.getService(ConceptService.class); - Concept concept = conceptService.getConceptByMapping("844", "CIEL"); - if (concept == null) { - concept = conceptService.getConceptByMapping("44871-2", "LOINC"); - } - - if (concept != null) { - earlyInfantDiagnosisConceptId = concept.getConceptId(); - } - } - } - } - - return earlyInfantDiagnosisConceptId; - } + + public static final int TESTS_ORDERED_CONCEPT_ID = 1271; + + private static volatile int viralLoadConceptId = -1; + + private static volatile int earlyInfantDiagnosisConceptId = -1; + + private Set conceptIds = new HashSet<>(); + + public ObsSelector() { + + } + + public boolean isValidTestType(Obs obs) { + return TESTS_ORDERED_CONCEPT_ID == obs.getConcept().getConceptId() && obs.getValueCoded() != null + && ((getViralLoadConceptId() != -1 && obs.getValueCoded().getConceptId() == getViralLoadConceptId()) + || (getEarlyInfantDiagnosisConceptId() != -1 + && obs.getValueCoded().getConceptId() == getEarlyInfantDiagnosisConceptId())); + } + + public int getViralLoadConceptId() { + if (viralLoadConceptId == -1) { + synchronized (ObsSelector.class) { + if (viralLoadConceptId == -1) { + ConceptService conceptService = Context.getService(ConceptService.class); + Concept concept = conceptService.getConceptByMapping("856", "CIEL"); + if (concept == null) { + concept = conceptService.getConceptByMapping("25836-8", "LOINC"); + } + + if (concept != null) { + viralLoadConceptId = concept.getConceptId(); + } + } + } + } + + return viralLoadConceptId; + } + + public int getEarlyInfantDiagnosisConceptId() { + if (earlyInfantDiagnosisConceptId == -1) { + synchronized (ObsSelector.class) { + if (earlyInfantDiagnosisConceptId == -1) { + ConceptService conceptService = Context.getService(ConceptService.class); + Concept concept = conceptService.getConceptByMapping("844", "CIEL"); + if (concept == null) { + concept = conceptService.getConceptByMapping("44871-2", "LOINC"); + } + + if (concept != null) { + earlyInfantDiagnosisConceptId = concept.getConceptId(); + } + } + } + } + + return earlyInfantDiagnosisConceptId; + } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/OrderConverter.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/OrderConverter.java index 3d7b6c4..9cda93b 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/OrderConverter.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/OrderConverter.java @@ -7,5 +7,6 @@ public interface OrderConverter { - String createMessage(Encounter encounter, OrderControl orderControl, HL7Config hl7Config) throws MessageCreationException; + String createMessage(Encounter encounter, OrderControl orderControl, HL7Config hl7Config) + throws MessageCreationException; } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/OrderGeneratorManager.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/OrderGeneratorManager.java index 16814d7..138e207 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/OrderGeneratorManager.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/OrderGeneratorManager.java @@ -11,18 +11,18 @@ @Component public class OrderGeneratorManager { - - @Autowired - private ORMO01OrderConverter orderConverter; - - @Autowired - private SCCHL7Config scchl7Config; - - public String generateORMO01Message(Encounter encounter, OrderDestination destination) throws MessageCreationException { - if (destination == OrderDestination.SCC) { - return orderConverter.createMessage(encounter, OrderControl.NEW_ORDER, scchl7Config); - } else { - throw new MessageCreationException("Message destination " + destination + "is not supported."); - } - } + + @Autowired + private ORMO01OrderConverter orderConverter; + + @Autowired + private SCCHL7Config scchl7Config; + + public String generateORMO01Message(Encounter encounter, OrderDestination destination) throws MessageCreationException { + if (destination == OrderDestination.SCC) { + return orderConverter.createMessage(encounter, OrderControl.NEW_ORDER, scchl7Config); + } else { + throw new MessageCreationException("Message destination " + destination + "is not supported."); + } + } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/OrderSenderManager.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/OrderSenderManager.java index 1f6293b..c0e2e9b 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/OrderSenderManager.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/OrderSenderManager.java @@ -8,13 +8,13 @@ @Component public class OrderSenderManager { - - @Autowired - private OpenElisOrderSender openElisOrderSender; - - public void sendOrders(Encounter encounter, OrderDestination destination) throws NewOrderException { - if (destination == OrderDestination.OPEN_ELIS) { - openElisOrderSender.sendNewOrder(encounter); - } - } + + @Autowired + private OpenElisOrderSender openElisOrderSender; + + public void sendOrders(Encounter encounter, OrderDestination destination) throws NewOrderException { + if (destination == OrderDestination.OPEN_ELIS) { + openElisOrderSender.sendNewOrder(encounter); + } + } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/config/AbstractHL7Config.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/config/AbstractHL7Config.java index 67874f0..7e4c0e5 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/config/AbstractHL7Config.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/config/AbstractHL7Config.java @@ -23,9 +23,9 @@ public abstract class AbstractHL7Config implements HL7Config { private static final String BIRTHPLACE_GROUP_CONCEPT = "labintegration.hl7.regForm.birthPlaceGroup"; private static final String BIRTHPLACE_CITY_CONCEPT = "labintegration.hl7.regForm.birthPlaceCity"; - + private static final String DEFAULT_DATE = "labintegration.hl7.dateFormat"; - + private static final String DEFAULT_MOTHER_NAME_ATTR_NAME = "First Name of Mother"; private static final String DEFAULT_PHONE_NUM_ATTR_NAME = "Telephone Number"; @@ -85,11 +85,12 @@ public Integer getBirthPlaceCityConceptId() { protected LabModulePropertySource getPropertySource() { return propertySource; } - + public String getDefaultDateFormat() { try { return PropertiesUtil.getGlobalProperty(DEFAULT_DATE); - } catch (APIException e) { + } + catch (APIException e) { return "yyyyMMddHHmmss"; } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/config/HL7Config.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/config/HL7Config.java index a9ef3ff..8f91a8b 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/config/HL7Config.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/config/HL7Config.java @@ -4,36 +4,36 @@ import org.openmrs.EncounterType; public interface HL7Config { - - String getReceivingApplication(); - - String getSendingApplication(); - - String getPatientIdentifierTypeUuid(); - - String getMotherNameAttrTypeName(); - - String getPhoneNumberAttrTypeName(); - - OrderIdentifier buildOrderIdentifier(Encounter encounter); - - EncounterType getRegistrationFormEncounterType(); - - Integer getReligionConceptId(); - - Integer getCivilStatusConceptId(); - - Integer getBirthPlaceGroupConceptId(); - - Integer getBirthPlaceCityConceptId(); - - String getSendingFacilityNamespaceID(); - - boolean isBillingNumberNeeded(); - - String getPatientDateOfBirthFormat(); - - String getAdmitDateFormat(); - - String getDefaultDateFormat(); + + String getReceivingApplication(); + + String getSendingApplication(); + + String getPatientIdentifierTypeUuid(); + + String getMotherNameAttrTypeName(); + + String getPhoneNumberAttrTypeName(); + + OrderIdentifier buildOrderIdentifier(Encounter encounter); + + EncounterType getRegistrationFormEncounterType(); + + Integer getReligionConceptId(); + + Integer getCivilStatusConceptId(); + + Integer getBirthPlaceGroupConceptId(); + + Integer getBirthPlaceCityConceptId(); + + String getSendingFacilityNamespaceID(); + + boolean isBillingNumberNeeded(); + + String getPatientDateOfBirthFormat(); + + String getAdmitDateFormat(); + + String getDefaultDateFormat(); } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/config/LabModulePropertySource.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/config/LabModulePropertySource.java index ee8ad45..25e9bae 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/config/LabModulePropertySource.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/config/LabModulePropertySource.java @@ -41,8 +41,8 @@ public Concept getConceptFromProperty(String propertyName, String defaultPropVal conceptDesignation.getSourceName()); if (concept == null) { - throw new LabHL7ConfigurationException("Concept " + conceptProp + " not found, " - + "proper concept must be configured"); + throw new LabHL7ConfigurationException( + "Concept " + conceptProp + " not found, " + "proper concept must be configured"); } return concept; diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/config/OrderIdentifier.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/config/OrderIdentifier.java index f0ec734..338b3d2 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/config/OrderIdentifier.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/config/OrderIdentifier.java @@ -8,20 +8,20 @@ import org.openmrs.module.labintegration.api.hl7.messages.util.ConceptUtil; public abstract class OrderIdentifier { - + public static final char ID_SEPARATOR = ';'; - + public abstract void updateORC(ORC orc, Obs obs) throws HL7Exception; public abstract void updateOBR(OBR obr, Obs obs) throws HL7Exception; - + public abstract void updatePlacerOrderNumber(ORC orc, Obs obs) throws DataTypeException; - + public abstract void updateUniversalServiceID(OBR obr, Obs obs) throws DataTypeException; protected void updateOrderTypeID(ORC orc, Obs obs) throws DataTypeException { String conceptCode = ConceptUtil.getLoincCode(obs); - + orc.getOrderType().getIdentifier().setValue(conceptCode); } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/handler/OruR01Handler.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/handler/OruR01Handler.java index ab3ebfe..6418bb4 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/handler/OruR01Handler.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/handler/OruR01Handler.java @@ -57,17 +57,20 @@ public class OruR01Handler implements Application { * */ private static final String DEFAULT_NUMERIC_VALUE = "39"; + private static final String DETECTED_CODED_VALUE = "1301"; + private static final String NOT_DETECTED_CODED_VALUE = "1302"; + private static final int TEST_RESULT_FREE_TEXT = 165399; - + private static final Logger LOGGER = LoggerFactory.getLogger(OruR01Handler.class); private static final String MESSAGE_VERSION = "2.5"; /** - * Always returns true, assuming that the router calling this handler will only call this - * handler with ORU_R01 messages. + * Always returns true, assuming that the router calling this handler will only call this handler + * with ORU_R01 messages. * * @return true */ @@ -95,7 +98,7 @@ public Message processMessage(Message message) throws HL7Exception { return response; } catch (ClassCastException ex) { - LOGGER.warn("Error casting {} to ORU_R01", message.getClass().getName(), ex); + LOGGER.warn("Error casting {} to ORU_R01", message.getClass().getName(), ex); throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.invalidMessageType ", new Object[] { message.getClass().getName() }, null), ex); } @@ -104,9 +107,10 @@ public Message processMessage(Message message) throws HL7Exception { throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.WhileProcessing"), ex); } catch (Exception ex) { - LOGGER.error("Could not process message! {}", ex.getMessage(), ex); + LOGGER.error("Could not process message! {}", ex.getMessage(), ex); throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.WhileProcessing"), ex); - } finally { + } + finally { Context.clearSession(); } } @@ -145,13 +149,13 @@ private Message processOruR01(ORU_R01 message) throws HL7Exception { LOGGER.debug("Location {}", pv1.getAssignedPatientLocation().getPointOfCare().getValue()); LOGGER.debug("Alternate Visit Id - ID {}", pv1.getAlternateVisitID().getIDNumber().getValue()); LOGGER.debug("Alternate Visit Id - Check digit {}", pv1.getAlternateVisitID().getCx2_CheckDigit().getValue()); - LOGGER.debug("Alternate Visit Id - Assigning Authority {}", pv1.getAlternateVisitID() - .getCx4_AssigningAuthority().getNamespaceID().getValue()); - LOGGER.debug("Alternate Visit Id - Identifier type code {}", pv1.getAlternateVisitID() - .getCx5_IdentifierTypeCode().getValue()); + LOGGER.debug("Alternate Visit Id - Assigning Authority {}", + pv1.getAlternateVisitID().getCx4_AssigningAuthority().getNamespaceID().getValue()); + LOGGER.debug("Alternate Visit Id - Identifier type code {}", + pv1.getAlternateVisitID().getCx5_IdentifierTypeCode().getValue()); for (int i = 0; i < numObr; i++) { LOGGER.debug("Processing OBR {} of {}", i + 1, numObr); - + ORU_R01_ORDER_OBSERVATION orderObs = patientResult.getORDER_OBSERVATION(i); OBR obr = orderObs.getOBR(); // OBR values @@ -161,7 +165,7 @@ private Message processOruR01(ORU_R01 message) throws HL7Exception { throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.InvalidOBR", new Object[] { messageControlId }, null)); } - + String encounterId = OruR01Util.getUuidFromPV1Segment(pv1); LOGGER.debug("Encounter UUID {}", encounterId); // Get the encounter @@ -175,16 +179,16 @@ private Message processOruR01(ORU_R01 message) throws HL7Exception { // Loop over the obs and create each object, adding it to the encounter int numObs = orderObs.getOBSERVATIONReps(); boolean encounterChanged = false; - + for (int j = 0; j < numObs; j++) { try { LOGGER.debug("Processing OBS {}", j); - + // OBX values OBX obx = orderObs.getOBSERVATION(j).getOBX(); LOGGER.debug("Parsing observation"); Obs obs = parseObs(encounter, obx, messageControlId); - + LOGGER.debug("Finished creating observation"); if (obs != null) { voidPreviousObs(encounter, obs); @@ -193,11 +197,12 @@ private Message processOruR01(ORU_R01 message) throws HL7Exception { createAlert(encounter, obs, message); encounterChanged = true; } - } catch (Exception e) { + } + catch (Exception e) { LOGGER.error("Could not process and add Obs!: {}", e, e); } } - + if (encounterChanged) { LOGGER.debug("Saving Encounter..."); try { @@ -206,7 +211,8 @@ private Message processOruR01(ORU_R01 message) throws HL7Exception { encounter.setEncounterDatetime(encounter.getVisit().getStartDatetime()); } Context.getEncounterService().saveEncounter(encounter); - } catch (Exception e) { + } + catch (Exception e) { LOGGER.error("Could not save encounter!", e); } } @@ -243,19 +249,19 @@ private Concept getConcept(CE codedElement, String uid) throws HL7Exception { String hl7ConceptId = codedElement.getIdentifier().getValue(); String codingSystem = codedElement.getNameOfCodingSystem().getValue(); - + if ("LN".equals(codingSystem)) { codingSystem = "LOINC"; } - + return getConcept(hl7ConceptId, codingSystem, uid); } /** * Get a concept object representing this conceptId and coding system.
* If codingSystem is 99DCT, then a new Concept with the given conceptId is returned.
- * Otherwise, the coding system is looked up in the ConceptMap for an openmrs concept mapped to - * that code. + * Otherwise, the coding system is looked up in the ConceptMap for an openmrs concept mapped to that + * code. * * @param hl7ConceptId the given hl7 conceptId * @param codingSystem the coding system for this conceptid (e.g. 99DCT) @@ -271,16 +277,17 @@ protected Concept getConcept(String hl7ConceptId, String codingSystem, String ui Integer conceptId = null; try { conceptId = Integer.valueOf(hl7ConceptId); - } catch (NumberFormatException e) { - if (hl7ConceptId.equals("Détecté")) { + } + catch (NumberFormatException e) { + if (hl7ConceptId.equals("Détecté")) { LOGGER.info("this is the value text 2 : " + hl7ConceptId); conceptId = Integer.valueOf(DETECTED_CODED_VALUE); - } else if (hl7ConceptId.equals("Non-Détecté")) { + } else if (hl7ConceptId.equals("Non-Détecté")) { LOGGER.info("this is the value text 3 : " + hl7ConceptId); conceptId = Integer.valueOf(NOT_DETECTED_CODED_VALUE); - } + } } - + return Context.getConceptService().getConcept(conceptId); } else { // the concept is not local, look it up in our mapping @@ -292,40 +299,40 @@ protected Concept getConcept(String hl7ConceptId, String codingSystem, String ui * Creates the Obs from the OBX message */ private Obs parseObs(Encounter encounter, OBX obx, String uid) throws HL7Exception { - + LOGGER.debug("parsing observation: {}", obx); Varies[] values = obx.getObservationValue(); if (values == null || values.length < 1) { return null; } - + String dataType = values[0].getName(); LOGGER.debug(" datatype = {}", dataType); - + Concept concept = getConcept(obx.getObservationIdentifier(), uid); LOGGER.debug(" concept = {}", concept); - + ConceptName conceptName = getConceptName(obx.getObservationIdentifier()); LOGGER.debug(" concept-name = {}", conceptName); - + Date datetime = getDatetime(obx); LOGGER.debug(" timestamp = {}", datetime); if (datetime == null) { datetime = encounter.getEncounterDatetime(); } - + // Conditional statement to discard results with LOINC 25836-8 && OBX[3,4] == LPLOG. // It typically comes as an additional result that accompanies Viral Load results. LOGGER.debug("Observation identifier {}", obx.getObservationIdentifier().getCe1_Identifier().getValue()); LOGGER.debug("Observation alternative identifier {}", - obx.getObservationIdentifier().getCe4_AlternateIdentifier().getValue()); - String[] obxIdentifiersToReject = {"LPLOG", "LBLOG"}; + obx.getObservationIdentifier().getCe4_AlternateIdentifier().getValue()); + String[] obxIdentifiersToReject = { "LPLOG", "LBLOG" }; if (("25836-8").equals(obx.getObservationIdentifier().getIdentifier().getValue()) - && Arrays.asList(obxIdentifiersToReject).contains( - (obx.getObservationIdentifier().getAlternateIdentifier().getValue()))) { + && Arrays.asList(obxIdentifiersToReject) + .contains((obx.getObservationIdentifier().getAlternateIdentifier().getValue()))) { return null; } - + Obs obs = new Obs(); obs.setPerson(encounter.getPatient()); obs.setConcept(concept); @@ -334,23 +341,23 @@ private Obs parseObs(Encounter encounter, OBX obx, String uid) throws HL7Excepti obs.setLocation(encounter.getLocation()); obs.setCreator(encounter.getCreator()); obs.setDateCreated(encounter.getDateCreated()); - + // Set comments if there are any ORU_R01_OBSERVATION parent = (ORU_R01_OBSERVATION) obx.getParent(); // Iterate over all OBX NTEs - List commentList = new ArrayList<>(); - for (int i = 0; i < parent.getNTEReps(); i++) { + List commentList = new ArrayList<>(); + for (int i = 0; i < parent.getNTEReps(); i++) { for (FT obxComment : parent.getNTE(i).getComment()) { commentList.add(obxComment.getValue()); } } String comments = org.apache.commons.lang3.StringUtils.join(commentList, " "); - + // Only set comments if there are any if (StringUtils.hasText(comments)) { obs.setComment(comments); } - + Type obx5 = values[0].getData(); if ("NM".equals(dataType)) { String value = ((NM) obx5).getValue(); @@ -358,8 +365,7 @@ private Obs parseObs(Encounter encounter, OBX obx, String uid) throws HL7Excepti } else if ("SN".equals(dataType)) { String value = ((SN) obx5).getNum1().getValue(); return processNumericValue(value, obs, concept, uid, conceptName); - } - else if ("CE".equals(dataType)) { + } else if ("CE".equals(dataType)) { CE value = (CE) obx5; String valueIdentifier = value.getIdentifier().getValue(); String valueName = value.getText().getValue(); @@ -378,16 +384,16 @@ else if ("CE".equals(dataType)) { obs.setValueText("Annulé Lab. Svp, contactez le LNSP pour plus d'information."); return obs; } - + return null; } - + Concept codedValue = getConcept(value, uid); if (codedValue == null) { LOGGER.error("Could not process coded response {}", uid); return null; } - + obs.setValueCoded(codedValue); obs.setValueCodedName(getConceptName(value)); } @@ -406,37 +412,36 @@ else if ("CE".equals(dataType)) { obs.setValueText("Annulé Lab. Svp, contactez le LNSP pour plus d'information."); return obs; } - + return null; } - + return obs; } LOGGER.warn("Not creating null valued obs for concept " + concept); return null; } - + // The exemption to the logic for saving Text results as obs.ValueText applies to VL results only. // If no numeric values are provided (i.e result is "indetectable"), then set the default minimum // value (i.e. 838 at the time of writing this code) // added mapping for PCR result when we receive Detecte 1301 will be send to the system, Non-Detecte will send 1302 // TODO: Make this logic a configurable one via Global Configurations - try { double val = Double.parseDouble(value.getValue()); obs = processNumericValue(Double.toString(val), obs, concept, uid, conceptName); - } catch (NumberFormatException e) { + } + catch (NumberFormatException e) { if (concept.isNumeric()) { LOGGER.info(value.getValue()); obs = processNumericValue(DEFAULT_NUMERIC_VALUE, obs, concept, uid, conceptName); } else { obs.setValueText(value.getValue()); } - + } - } else { // Unsupported data type throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.UpsupportedObsType", @@ -445,9 +450,9 @@ else if ("CE".equals(dataType)) { return obs; } - + private Obs processNumericValue(String value, Obs obs, Concept concept, String uid, ConceptName conceptName) - throws NoSuchMessageException, HL7Exception { + throws NoSuchMessageException, HL7Exception { if (value == null || value.length() == 0) { LOGGER.warn("Not creating null valued obs for concept {}", concept); return null; @@ -459,16 +464,14 @@ private Obs processNumericValue(String value, Obs obs, Concept concept, String u } 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); + } + 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(); + : Context.getConceptService().getFalseConcept(); boolean isValidAnswer = false; Collection conceptAnswers = concept.getAnswers(); if (conceptAnswers != null && !conceptAnswers.isEmpty()) { @@ -483,35 +486,35 @@ private Obs processNumericValue(String value, Obs obs, Concept concept, String u // 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)); + 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)); + new Object[] { obs.getConcept().getConceptId() }, null)); } } else { try { obs.setValueNumeric(Double.valueOf(value)); - } catch (NumberFormatException ex) { + } + catch (NumberFormatException ex) { throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.notnumericConcept", - new Object[] { value, concept.getConceptId(), conceptName.getName(), uid }, null), ex); + new Object[] { value, concept.getConceptId(), conceptName.getName(), uid }, null), ex); } } - + return obs; } - + private void voidPreviousObs(Encounter encounter, Obs newObs) { for (Obs obs : encounter.getObs()) { - if (obs.getConcept().getId().equals(newObs.getConcept().getId()) - && obs.getId() != null) { + if (obs.getConcept().getId().equals(newObs.getConcept().getId()) && obs.getId() != null) { obs.setVoided(true); obs.setDateVoided(new Date()); obs.setVoidReason("New result arrived from OpenELIS"); obs.setVoidedBy(getUserForEncounter(encounter)); - + Obs group = obs.getObsGroup(); if (group != null) { group.addGroupMember(newObs); @@ -519,7 +522,7 @@ private void voidPreviousObs(Encounter encounter, Obs newObs) { } } } - + private User getUserForEncounter(Encounter encounter) { for (EncounterProvider encProvider : encounter.getEncounterProviders()) { Person person = encProvider.getProvider().getPerson(); @@ -530,7 +533,7 @@ private User getUserForEncounter(Encounter encounter) { } return null; } - + private boolean isConceptProposal(String identifier) { return OpenmrsUtil.nullSafeEquals(identifier, OpenmrsConstants.PROPOSED_CONCEPT_IDENTIFIER); } @@ -597,8 +600,8 @@ private ConceptName getConceptName(ST altIdentifier, ID altCodingSystem) throws /** * Utility method to retrieve the openmrs ConceptName specified in an hl7 message observation - * segment. This method assumes that the check for 99NAM has been done already and is being - * given an openmrs conceptNameId + * segment. This method assumes that the check for 99NAM has been done already and is being given an + * openmrs conceptNameId * * @param hl7ConceptNameId internal ConceptNameId to look up * @return ConceptName from the database @@ -627,11 +630,10 @@ private MSH getMSH(ORU_R01 message) { private void validateMessageVersion(ORU_R01 message) throws HL7Exception { if (!message.getVersion().equals(MESSAGE_VERSION)) { - throw new HL7Exception(Context.getMessageSourceService() - .getMessage("ORUR01.error.invalidMessageVersion")); + throw new HL7Exception(Context.getMessageSourceService().getMessage("ORUR01.error.invalidMessageVersion")); } } - + private void createAlert(Encounter encounter, Obs obs, ORU_R01 oru) { AlertCreator alertCreator = Context.getRegisteredComponent("alertCreator", AlertCreator.class); alertCreator.createAlert(encounter, obs, OpenElisStatusHelper.getStatus(oru)); diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/OMLO21OrderConverter.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/OMLO21OrderConverter.java index dddde78..1a4db58 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/OMLO21OrderConverter.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/OMLO21OrderConverter.java @@ -37,22 +37,23 @@ public class OMLO21OrderConverter implements OrderConverter { @Autowired private ObrGenerator obrGenerator; - + @Autowired private ObsSelector obsSelector; @Override - public String createMessage(Encounter encounter, OrderControl orderControl, HL7Config hl7Config) throws MessageCreationException { + public String createMessage(Encounter encounter, OrderControl orderControl, HL7Config hl7Config) + throws MessageCreationException { try { OML_O21 message = new OML_O21(); message.initQuickstart("OML", "O21", labIntegrationProperties.getHL7ProcessingId()); - + mshGenerator.updateMsh(message.getMSH(), hl7Config); - + pidGenerator.updatePid(message.getPATIENT().getPID(), encounter, hl7Config); OrderIdentifier orderIdentifier = hl7Config.buildOrderIdentifier(encounter); - + int i = 0; for (Obs obs : encounter.getObs()) { if (obsSelector.isValidTestType(obs)) { @@ -63,7 +64,7 @@ public String createMessage(Encounter encounter, OrderControl orderControl, HL7C } String msg = message.toString(); - + return VersionSwitcher.switchVersion(msg); } catch (IOException e) { diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ORMO01OrderConverter.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ORMO01OrderConverter.java index 603fc83..5d0cf67 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ORMO01OrderConverter.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ORMO01OrderConverter.java @@ -30,21 +30,22 @@ public class ORMO01OrderConverter implements OrderConverter { @Autowired private Pv1Generator pv1Generator; - + @Autowired private OrcGenerator orcGenerator; - + @Autowired private ObrGenerator obrGenerator; - + @Autowired private LabIntegrationProperties labIntegrationProperties; - + @Autowired private ObsSelector obsSelector; @Override - public String createMessage(Encounter encounter, OrderControl orderControl, HL7Config hl7Config) throws MessageCreationException { + public String createMessage(Encounter encounter, OrderControl orderControl, HL7Config hl7Config) + throws MessageCreationException { try { ORM_O01 message = new ORM_O01(); @@ -52,9 +53,9 @@ public String createMessage(Encounter encounter, OrderControl orderControl, HL7C mshGenerator.updateMsh(message.getMSH(), hl7Config); pidGenerator.updatePid(message.getPATIENT().getPID(), encounter, hl7Config); pv1Generator.updatePv1(message.getPATIENT().getPATIENT_VISIT().getPV1(), hl7Config, encounter); - + OrderIdentifier orderIdentifier = hl7Config.buildOrderIdentifier(encounter); - + int i = 0; for (Obs obs : encounter.getObs()) { if (obsSelector.isValidTestType(obs)) { diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ack/AckGenerator.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ack/AckGenerator.java index 3eab6e0..5b36772 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ack/AckGenerator.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ack/AckGenerator.java @@ -1,6 +1,5 @@ package org.openmrs.module.labintegration.api.hl7.messages.ack; - import ca.uhn.hl7v2.HL7Exception; import ca.uhn.hl7v2.model.Message; import ca.uhn.hl7v2.model.v25.message.ACK; @@ -13,56 +12,58 @@ @Component public class AckGenerator { - - private PipeParser pipeParser = new PipeParser(); - - public ACK generateACK(Message msg) throws IOException, HL7Exception { - Message tmp = msg.getMessage().generateACK(); - return convert(tmp); - } - - public ACK generateACK(Message msg, HL7Exception e, String acknowledgementCode) throws MessageCreationException { - try { - Message tmp = msg.getMessage().generateACK(acknowledgementCode, getRootHL7Exception(e, e)); - return convert(tmp); - } catch (HL7Exception ex) { - throw new MessageCreationException("Unable to create ACK", ex); - } catch (IOException ex) { - throw new MessageCreationException("Unable to create ACK", ex); - } - } - - private ACK convert(Message msg) throws HL7Exception { - ACK ack = getACK(msg); - - ack.getMSH().getMsh9_MessageType().getMsg3_MessageStructure().setValue("ACK"); - - return convertVersion(ack); - } - - private ACK getACK(Message msg) throws HL7Exception { - ACK ack = new ACK(); - pipeParser.parse(ack, msg.getMessage().encode()); - return ack; - } - - private ACK convertVersion(ACK ack) throws HL7Exception { - String msg = ack.encode(); - msg = VersionSwitcher.switchVersion(msg); - - ACK newAck = new ACK(); - pipeParser.parse(newAck, msg); - return newAck; - } - - private HL7Exception getRootHL7Exception(Throwable ex, HL7Exception lastHl7ExInStack) { - Throwable cause = ex.getCause(); - if (cause instanceof HL7Exception) { - return getRootHL7Exception(cause, (HL7Exception) cause); - } else if (cause != null) { - return getRootHL7Exception(cause, lastHl7ExInStack); - } else { - return ex instanceof HL7Exception ? (HL7Exception) ex : lastHl7ExInStack; - } - } + + private PipeParser pipeParser = new PipeParser(); + + public ACK generateACK(Message msg) throws IOException, HL7Exception { + Message tmp = msg.getMessage().generateACK(); + return convert(tmp); + } + + public ACK generateACK(Message msg, HL7Exception e, String acknowledgementCode) throws MessageCreationException { + try { + Message tmp = msg.getMessage().generateACK(acknowledgementCode, getRootHL7Exception(e, e)); + return convert(tmp); + } + catch (HL7Exception ex) { + throw new MessageCreationException("Unable to create ACK", ex); + } + catch (IOException ex) { + throw new MessageCreationException("Unable to create ACK", ex); + } + } + + private ACK convert(Message msg) throws HL7Exception { + ACK ack = getACK(msg); + + ack.getMSH().getMsh9_MessageType().getMsg3_MessageStructure().setValue("ACK"); + + return convertVersion(ack); + } + + private ACK getACK(Message msg) throws HL7Exception { + ACK ack = new ACK(); + pipeParser.parse(ack, msg.getMessage().encode()); + return ack; + } + + private ACK convertVersion(ACK ack) throws HL7Exception { + String msg = ack.encode(); + msg = VersionSwitcher.switchVersion(msg); + + ACK newAck = new ACK(); + pipeParser.parse(newAck, msg); + return newAck; + } + + private HL7Exception getRootHL7Exception(Throwable ex, HL7Exception lastHl7ExInStack) { + Throwable cause = ex.getCause(); + if (cause instanceof HL7Exception) { + return getRootHL7Exception(cause, (HL7Exception) cause); + } else if (cause != null) { + return getRootHL7Exception(cause, lastHl7ExInStack); + } else { + return ex instanceof HL7Exception ? (HL7Exception) ex : lastHl7ExInStack; + } + } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ack/AckParser.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ack/AckParser.java index 442aa5f..1f864c7 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ack/AckParser.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ack/AckParser.java @@ -8,47 +8,48 @@ @Component public class AckParser { - - private static final String ACK_TYPE = "ACK"; - - private static final String ORL_O22_TYPE = "ORL_O22"; - + + private static final String ACK_TYPE = "ACK"; + + private static final String ORL_O22_TYPE = "ORL_O22"; + private PipeParser pipeParser = new PipeParser(); public Acknowledgement parse(String msg) throws InvalidAckException { - Acknowledgement result; - - try { - switch (getAckType(msg)) { - case ACK_TYPE: - ACK ack = new ACK(); - pipeParser.parse(ack, msg); - result = new Acknowledgement(ack); - break; - case ORL_O22_TYPE: - ORL_O22 orl = new ORL_O22(); - pipeParser.parse(orl, msg); - result = new Acknowledgement(orl); - break; - default: - throw new UnsupportedMessageTypeException("Message type is unsupported"); - } - - return result; - } + Acknowledgement result; + + try { + switch (getAckType(msg)) { + case ACK_TYPE: + ACK ack = new ACK(); + pipeParser.parse(ack, msg); + result = new Acknowledgement(ack); + break; + case ORL_O22_TYPE: + ORL_O22 orl = new ORL_O22(); + pipeParser.parse(orl, msg); + result = new Acknowledgement(orl); + break; + default: + throw new UnsupportedMessageTypeException("Message type is unsupported"); + } + + return result; + } catch (HL7Exception ex) { - throw new InvalidAckException("Error while parsing a message", ex); - } - } - - private String getAckType(String msg) throws InvalidAckException { - try { - ACK tmp = new ACK(); - pipeParser.parse(tmp, msg); - - return tmp.getMSH().getMessageType().getMsg3_MessageStructure().getValue(); - } catch (HL7Exception e) { - throw new InvalidAckException("Error while parsing a message", e); - } - } + throw new InvalidAckException("Error while parsing a message", ex); + } + } + + private String getAckType(String msg) throws InvalidAckException { + try { + ACK tmp = new ACK(); + pipeParser.parse(tmp, msg); + + return tmp.getMSH().getMessageType().getMsg3_MessageStructure().getValue(); + } + catch (HL7Exception e) { + throw new InvalidAckException("Error while parsing a message", e); + } + } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ack/Acknowledgement.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ack/Acknowledgement.java index e5ca413..99c157c 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ack/Acknowledgement.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ack/Acknowledgement.java @@ -20,23 +20,22 @@ public class Acknowledgement { Acknowledgement(ACK ack) { String ackCode = ack.getMSA().getAcknowledgmentCode().getValue(); this.success = APP_ACCEPT.equals(ackCode) || COMMIT_ACCEPT.equals(ackCode); - + this.msgId = ack.getMSH().getMessageControlID().getValue(); this.errorCode = ack.getERR().getHL7ErrorCode().getIdentifier().getValue(); - + this.errorDiagnosticsInformation = ack.getERR().getDiagnosticInformation().getValue(); - + } - + Acknowledgement(ORL_O22 orl) { String ackCode = orl.getMSA().getAcknowledgmentCode().getValue(); this.success = APP_ACCEPT.equals(ackCode) || COMMIT_ACCEPT.equals(ackCode); - + this.msgId = orl.getMSH().getMessageControlID().getValue(); this.errorCode = orl.getERR().getHL7ErrorCode().getIdentifier().getValue(); - - this.errorDiagnosticsInformation = orl.getERR().getErr3_HL7ErrorCode(). - getCwe9_OriginalText().getValue(); + + this.errorDiagnosticsInformation = orl.getERR().getErr3_HL7ErrorCode().getCwe9_OriginalText().getValue(); } public boolean isSuccess() { diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ack/UnsupportedMessageTypeException.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ack/UnsupportedMessageTypeException.java index face9b1..c85e39e 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ack/UnsupportedMessageTypeException.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/ack/UnsupportedMessageTypeException.java @@ -1,14 +1,14 @@ package org.openmrs.module.labintegration.api.hl7.messages.ack; public class UnsupportedMessageTypeException extends InvalidAckException { - - private static final long serialVersionUID = 4376585604635552460L; - - public UnsupportedMessageTypeException(String message) { - super(message); - } - - public UnsupportedMessageTypeException(String message, Throwable throwable) { - super(message, throwable); - } + + private static final long serialVersionUID = 4376585604635552460L; + + public UnsupportedMessageTypeException(String message) { + super(message); + } + + public UnsupportedMessageTypeException(String message, Throwable throwable) { + super(message, throwable); + } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/MshGenerator.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/MshGenerator.java index 4946220..d785d55 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/MshGenerator.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/MshGenerator.java @@ -15,14 +15,14 @@ public class MshGenerator { private static final String FIELD_SEPARATOR = "|"; + private static final String ENCODING_CHARS = "^~\\&"; - + @Autowired private DateSource dateSource; @Autowired private MessageControlIdSource controlIdSource; - public void updateMsh(MSH msh, HL7Config hl7Config) throws DataTypeException { SimpleDateFormat dateFormat = new SimpleDateFormat(hl7Config.getDefaultDateFormat()); diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/ObrGenerator.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/ObrGenerator.java index b776027..6f0f242 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/ObrGenerator.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/ObrGenerator.java @@ -12,16 +12,16 @@ @Component public class ObrGenerator { - + @Autowired private HL7Config hl7Config; - + public void updateObr(OBR obr, Obs obs, OrderIdentifier orderIdentifier) throws HL7Exception { SimpleDateFormat dateFormat = new SimpleDateFormat(hl7Config.getDefaultDateFormat()); - + //change OBR[6] to OBR[7] obr.getObservationDateTime().getTime().setValue(dateFormat.format(obs.getEncounter().getEncounterDatetime())); - + orderIdentifier.updateOBR(obr, obs); } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/OrcGenerator.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/OrcGenerator.java index c302a41..7295528 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/OrcGenerator.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/OrcGenerator.java @@ -8,11 +8,10 @@ @Component public class OrcGenerator { - - public void updateOrc(ORC orc, Obs obs, String orderControl, OrderIdentifier orderIdentifier) - throws HL7Exception { + + public void updateOrc(ORC orc, Obs obs, String orderControl, OrderIdentifier orderIdentifier) throws HL7Exception { orc.getOrderControl().setValue(orderControl); - + orderIdentifier.updateORC(orc, obs); } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/PidGenerator.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/PidGenerator.java index 729e4e5..519bc09 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/PidGenerator.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/PidGenerator.java @@ -39,7 +39,8 @@ public class PidGenerator { @Autowired private RegistrationDataHelper registrationObsHelper; - public void updatePid(PID pid, Encounter encounter, HL7Config hl7Config) throws DataTypeException, MessageCreationException { + public void updatePid(PID pid, Encounter encounter, HL7Config hl7Config) + throws DataTypeException, MessageCreationException { Patient patient = encounter.getPatient(); // add encounter on updateIdNumber idHelper.updateIdNumber(pid, patient, hl7Config, encounter); diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/Pv1Generator.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/Pv1Generator.java index 33ced81..476ad3c 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/Pv1Generator.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/Pv1Generator.java @@ -29,7 +29,7 @@ public void updatePv1(PV1 pv1, HL7Config hl7Config, Encounter encounter) throws assignedPatientLocationHelper.updateAssignedPatientLocation(pv1, hl7Config, encounter); assignedPatientLocationHelper.assignedAlternativeVisitId(pv1, hl7Config, encounter); - + if (hl7Config.getAdmitDateFormat() != null) { DateFormat df = new SimpleDateFormat(hl7Config.getAdmitDateFormat()); pv1.getAdmitDateTime().getTime().setValue(df.format(encounter.getEncounterDatetime())); @@ -41,7 +41,7 @@ public void updatePv1(PV1 pv1, HL7Config hl7Config, Encounter encounter) throws private void updateAttendingDoctor(PV1 pv1, Encounter encounter) throws HL7Exception { int quantity = pv1.getAttendingDoctorReps(); pv1.insertAttendingDoctor(quantity); - + Provider doctor = encounter.getEncounterProviders().iterator().next().getProvider(); XCN orderingProvider = pv1.getAttendingDoctor(quantity); providerInformationHelper.updateProviderInformation(orderingProvider, doctor, encounter); diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/helpers/LnspCodeHelper.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/helpers/LnspCodeHelper.java index 65c9b82..06fbc5f 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/helpers/LnspCodeHelper.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/helpers/LnspCodeHelper.java @@ -13,37 +13,37 @@ @Component public class LnspCodeHelper { - - @Autowired - private SCCHL7Config scchl7Config; - - public void updateUniversalServiceID(OBR obr, Obs obs) throws DataTypeException { - String conceptCode = ConceptUtil.getLoincCode(obs); - String lnspCode = findLnspCodeIfExist(obs, conceptCode); - - if (StringUtils.isNotBlank(lnspCode)) { - obr.getUniversalServiceIdentifier().getIdentifier().setValue(lnspCode); - } - } - - private String findLnspCodeIfExist(Obs obs, String conceptCode) { - String result = null; - String alternativeConceptUuid = scchl7Config.mapConceptToLnspTest(conceptCode); - - if (StringUtils.isNotBlank(alternativeConceptUuid)) { - Obs alternativeObs = EncounterUtil.findObsByConceptUuid(obs.getEncounter(), alternativeConceptUuid); - if (alternativeObs == null) { - throw new IllegalStateException("Wrong concept used for ordered test."); - } - - Concept alternativeConcept = alternativeObs.getValueCoded(); - if (alternativeConcept != null) { - result = ConceptUtil.getLnspCode(alternativeConcept); - if (StringUtils.isBlank(result)) { - throw new IllegalStateException("LNSP code is mandatory"); - } - } - } - return result; - } + + @Autowired + private SCCHL7Config scchl7Config; + + public void updateUniversalServiceID(OBR obr, Obs obs) throws DataTypeException { + String conceptCode = ConceptUtil.getLoincCode(obs); + String lnspCode = findLnspCodeIfExist(obs, conceptCode); + + if (StringUtils.isNotBlank(lnspCode)) { + obr.getUniversalServiceIdentifier().getIdentifier().setValue(lnspCode); + } + } + + private String findLnspCodeIfExist(Obs obs, String conceptCode) { + String result = null; + String alternativeConceptUuid = scchl7Config.mapConceptToLnspTest(conceptCode); + + if (StringUtils.isNotBlank(alternativeConceptUuid)) { + Obs alternativeObs = EncounterUtil.findObsByConceptUuid(obs.getEncounter(), alternativeConceptUuid); + if (alternativeObs == null) { + throw new IllegalStateException("Wrong concept used for ordered test."); + } + + Concept alternativeConcept = alternativeObs.getValueCoded(); + if (alternativeConcept != null) { + result = ConceptUtil.getLnspCode(alternativeConcept); + if (StringUtils.isBlank(result)) { + throw new IllegalStateException("LNSP code is mandatory"); + } + } + } + return result; + } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/helpers/OrderingProviderHelper.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/helpers/OrderingProviderHelper.java index 18dec89..596aca5 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/helpers/OrderingProviderHelper.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/helpers/OrderingProviderHelper.java @@ -11,27 +11,29 @@ @Component public class OrderingProviderHelper { - + @Autowired private ProviderInformationHelper providerInformationHelper; - + public void updateOrderingProvider(ORC orc, Obs obs) throws HL7Exception { int quantity = orc.getOrderingProviderReps(); orc.insertOrderingProvider(quantity); - + XCN orderingProvider = orc.getOrderingProvider(quantity); - providerInformationHelper.updateProviderInformation(orderingProvider, ProviderHelper.getProvider(obs), obs.getEncounter()); - + providerInformationHelper.updateProviderInformation(orderingProvider, ProviderHelper.getProvider(obs), + obs.getEncounter()); + orc.getOrderingProvider()[quantity] = orderingProvider; } - + public void updateOrderingProvider(OBR obr, Obs obs) throws HL7Exception { int quantity = obr.getOrderingProviderReps(); obr.insertOrderingProvider(quantity); - + XCN orderingProvider = obr.getOrderingProvider(quantity); - providerInformationHelper.updateProviderInformation(orderingProvider, ProviderHelper.getProvider(obs), obs.getEncounter()); - + providerInformationHelper.updateProviderInformation(orderingProvider, ProviderHelper.getProvider(obs), + obs.getEncounter()); + obr.getOrderingProvider()[quantity] = orderingProvider; } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/helpers/ProviderInformationHelper.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/helpers/ProviderInformationHelper.java index b3e5ee1..c39b431 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/helpers/ProviderInformationHelper.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/helpers/ProviderInformationHelper.java @@ -22,7 +22,7 @@ public void updateProviderInformation(XCN xcn, Provider provider, Encounter enco for (LocationAttribute locationAttribute : encounter.getLocation().getAttributes()) { - if (locationAttribute.getAttributeType().getUuid().equals(uuid)) { + if (locationAttribute.getAttributeType().getUuid().equals(uuid)) { siteCode = locationAttribute.getValueReference(); } } @@ -33,5 +33,3 @@ public void updateProviderInformation(XCN xcn, Provider provider, Encounter enco personNameHelper.updatePersonName(xcn, personName); } } - - diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/helpers/QuantityTimingHelper.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/helpers/QuantityTimingHelper.java index f00ebb9..95e469a 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/helpers/QuantityTimingHelper.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/helpers/QuantityTimingHelper.java @@ -13,36 +13,37 @@ @Component public class QuantityTimingHelper { + private static final String DATE_FORMAT = "yyyyMMddHHmmss"; - + @Autowired private HL7Config hl7Config; - + public void updateQuantityTiming(ORC orc, Obs obs) throws HL7Exception { int quantity = orc.getQuantityTimingReps(); orc.insertQuantityTiming(quantity); SimpleDateFormat dateFormat = new SimpleDateFormat(hl7Config.getDefaultDateFormat()); - + TQ quantityTiming = orc.getQuantityTiming(quantity); quantityTiming.getStartDateTime().getTime().setValue(dateFormat.format(obs.getEncounter().getEncounterDatetime())); - + // TODO //quantityTiming.getPriority().setValue(PriorityMapper.map(order.getUrgency())); - + orc.getQuantityTiming()[quantity] = quantityTiming; } - + public void updateQuantityTiming(OBR obr, Obs obs) throws HL7Exception { int quantity = obr.getQuantityTimingReps(); obr.insertQuantityTiming(quantity); SimpleDateFormat dateFormat = new SimpleDateFormat(hl7Config.getDefaultDateFormat()); - + TQ quantityTiming = obr.getQuantityTiming(quantity); quantityTiming.getStartDateTime().getTime().setValue(dateFormat.format(obs.getEncounter().getEncounterDatetime())); - + // TODO //quantityTiming.getPriority().setValue(PriorityMapper.map(order.getUrgency())); - + obr.getQuantityTiming()[quantity] = quantityTiming; } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/msh/MessageControlIdSource.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/msh/MessageControlIdSource.java index ac84f90..19064bc 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/msh/MessageControlIdSource.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/msh/MessageControlIdSource.java @@ -9,11 +9,11 @@ @Component public class MessageControlIdSource { - + private static final int RESET_BOUNDARY = 99999; - + private int rollingNumber; - + private HL7Config hl7Config = new SCCHL7Config(); public String generateId(Date date) { diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/pid/PidBillingNumberHelper.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/pid/PidBillingNumberHelper.java index f106121..cb19749 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/pid/PidBillingNumberHelper.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/pid/PidBillingNumberHelper.java @@ -12,7 +12,7 @@ public class PidBillingNumberHelper { public void updateBillingNumber(PID pid, Encounter encounter, HL7Config hl7Config) throws DataTypeException { pid.getPatientAccountNumber().getAssigningFacility().getNamespaceID() .setValue(hl7Config.getSendingFacilityNamespaceID()); - + if (hl7Config.isBillingNumberNeeded()) { /*Change encounter uuid to ID*/ pid.getPatientAccountNumber().getIDNumber().setValue(encounter.getId().toString()); diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/pid/PidIdHelper.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/pid/PidIdHelper.java index 20526be..f721751 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/pid/PidIdHelper.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/pid/PidIdHelper.java @@ -14,20 +14,20 @@ @Component public class PidIdHelper { - + private static final String OLD_SITE_CODE_UUID = "0e52924e-4ebb-40ba-9b83-b198b532653b"; - + private static final String NEW_SITE_CODE_UUID = "6242bf19-207e-4076-9d28-9290525b8ed9"; - + private static final String ISANTE_ID_UUID = "0e0c7cc2-3491-4675-b705-746e372ff346"; - public void updateIdNumber(PID pid, Patient patient, HL7Config hl7Config, Encounter encounter) throws DataTypeException, - MessageCreationException { - + public void updateIdNumber(PID pid, Patient patient, HL7Config hl7Config, Encounter encounter) + throws DataTypeException, MessageCreationException { + String oldSiteCode = null; String newSiteCode = null; PatientIdentifier isanteIdentifier = null; - + for (LocationAttribute locationAttribute : encounter.getLocation().getAttributes()) { if (locationAttribute.getAttributeType().getUuid().equals(OLD_SITE_CODE_UUID)) { oldSiteCode = locationAttribute.getValueReference(); @@ -35,31 +35,28 @@ public void updateIdNumber(PID pid, Patient patient, HL7Config hl7Config, Encoun newSiteCode = locationAttribute.getValueReference(); } } - + String siteCode = oldSiteCode != null ? oldSiteCode : newSiteCode != null ? newSiteCode : ""; - + PatientIdentifier id = PatientUtil.getPatientIdentifier(patient, hl7Config.getPatientIdentifierTypeUuid()); - + for (PatientIdentifier identifier : patient.getIdentifiers()) { if (StringUtils.equals(identifier.getIdentifierType().getUuid(), ISANTE_ID_UUID)) { isanteIdentifier = identifier; pid.getPatientID().getIDNumber().setValue(isanteIdentifier.toString()); - + break; } } - + if (isanteIdentifier == null) { pid.getPatientID().getIDNumber().setValue(siteCode + "4" + patient.getPatientId().toString()); } - - - + if (id.getLocation() != null) { - pid.getPatientID().getAssigningFacility().getNamespaceID() - .setValue(siteCode); + pid.getPatientID().getAssigningFacility().getNamespaceID().setValue(siteCode); } - - pid.getPatientID().getAssigningFacility().getNamespaceID().setValue(siteCode); - } + + pid.getPatientID().getAssigningFacility().getNamespaceID().setValue(siteCode); + } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/pv1/Pv1AssignedPatientLocationHelper.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/pv1/Pv1AssignedPatientLocationHelper.java index a6fec33..323b95b 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/pv1/Pv1AssignedPatientLocationHelper.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/generators/pv1/Pv1AssignedPatientLocationHelper.java @@ -12,53 +12,56 @@ @Component public class Pv1AssignedPatientLocationHelper { - + private static final Logger LOGGER = LoggerFactory.getLogger(Pv1AssignedPatientLocationHelper.class); - + public void updateAssignedPatientLocation(PV1 pv1, HL7Config hl7Config, Encounter encounter) throws DataTypeException { // Code added to set location id to siteCode String siteCode = ""; String uuid = "0e52924e-4ebb-40ba-9b83-b198b532653b"; - + for (LocationAttribute locationAttribute : encounter.getLocation().getAttributes()) { - + if (locationAttribute.getAttributeType().getUuid().equals(uuid)) { siteCode = locationAttribute.getValueReference(); } } - + if (siteCode != null) { pv1.getAssignedPatientLocation().getPl1_PointOfCare().setValue(siteCode); } } - + public void assignedAlternativeVisitId(PV1 pv1, HL7Config hl7Config, Encounter encounter) { - + //Code added to set location id to siteCode String siteCode = ""; String uuid = "0e52924e-4ebb-40ba-9b83-b198b532653b"; - + try { for (LocationAttribute locationAttribute : encounter.getLocation().getAttributes()) { if (locationAttribute.getAttributeType().getUuid().equals(uuid)) { siteCode = locationAttribute.getValueReference(); } } - + pv1.getAlternateVisitID().getIDNumber().setValue(encounter.getPatient().getUuid()); pv1.getAssignedPatientLocation().getPl1_PointOfCare().setValue(siteCode); - + // get encounter type uuid and encounter uuid pv1.getAlternateVisitID().getCheckDigit().setValue(encounter.getEncounterType().getUuid()); pv1.getAlternateVisitID().getIdentifierTypeCode().setValue(encounter.getUuid()); - + //get location location uuid 'To be tested' pv1.getAlternateVisitID().getAssigningAuthority().parse(encounter.getLocation().getUuid()); - } catch (DataTypeException ex) { + } + catch (DataTypeException ex) { LOGGER.error("Could not create PV1 message! \n" + ex.getLocalizedMessage()); - } catch (HL7Exception ex) { + } + catch (HL7Exception ex) { LOGGER.error("Could not create PV1 message! \n" + ex.getLocalizedMessage()); - } catch (Exception ex) { + } + catch (Exception ex) { LOGGER.error("Could not create PV1 message! \n" + ex.getLocalizedMessage()); } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/mappers/PriorityMapper.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/mappers/PriorityMapper.java index 20fad7a..21dbee0 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/mappers/PriorityMapper.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/mappers/PriorityMapper.java @@ -3,7 +3,7 @@ import org.openmrs.Order; public final class PriorityMapper { - + public static String map(Order.Urgency urgency) { switch (urgency) { case STAT: diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/ConceptUtil.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/ConceptUtil.java index 58f73c9..742b874 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/ConceptUtil.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/ConceptUtil.java @@ -10,8 +10,9 @@ public final class ConceptUtil { public static final String LOINC = "LOINC"; + public static final String LNSP_SOURCE_UUID = "f124da75-9f50-4b25-be97-13c029e3a65b"; - + public static String getLoincCode(Concept concept) { for (ConceptMap mapping : concept.getConceptMappings()) { ConceptReferenceTerm referenceTerm = mapping.getConceptReferenceTerm(); @@ -24,13 +25,13 @@ public static String getLoincCode(Concept concept) { return null; } - - public static String getLoincCode(Obs obs) { + + public static String getLoincCode(Obs obs) { Concept testConcept = obs.getValueCoded(); if (testConcept == null) { throw new IllegalStateException("Wrong concept used for ordered test: " + obs.getConcept().getId()); } - + String conceptCode = ConceptUtil.getLoincCode(testConcept); if (StringUtils.isBlank(conceptCode)) { throw new IllegalStateException("LOINC code is mandatory"); @@ -42,15 +43,15 @@ public static String getLnspCode(Concept concept) { for (ConceptMap mapping : concept.getConceptMappings()) { ConceptReferenceTerm referenceTerm = mapping.getConceptReferenceTerm(); ConceptSource conceptSource = referenceTerm.getConceptSource(); - + if (LNSP_SOURCE_UUID.equalsIgnoreCase(conceptSource.getUuid())) { return referenceTerm.getCode(); } } - + return null; } - + private ConceptUtil() { } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/EncounterUtil.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/EncounterUtil.java index e96cff5..deade77 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/EncounterUtil.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/EncounterUtil.java @@ -62,7 +62,7 @@ public static Obs findObs(Encounter encounter, int conceptId, Integer groupId) { return null; } - + public static Obs findObsByConceptUuid(Encounter encounter, String uuid) { for (Obs obs : encounter.getObs()) { Concept question = obs.getConcept(); @@ -70,7 +70,7 @@ public static Obs findObsByConceptUuid(Encounter encounter, String uuid) { return obs; } } - + return null; } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/OruR01Util.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/OruR01Util.java index 7ad1caf..c38196e 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/OruR01Util.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/OruR01Util.java @@ -10,53 +10,55 @@ import ca.uhn.hl7v2.model.v25.segment.PV1; public final class OruR01Util { - + public static final String ORUR01_ORU_R01 = "ORU\\^R01\\^ORU_R01"; - + public static final String ORU_R01 = "ORU^R01"; - + public static final String VERSION_25 = "2.5"; - + public static final String VERSION_251 = "2.5.1"; - + private static final Log LOGGER = LogFactory.getLog(OruR01Util.class); - + private static final Pattern ONLY_UUID = Pattern - .compile("[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"); - + .compile("[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"); + public static String changeMessageVersionFrom251To25(String message) { message = message.replaceFirst(ORUR01_ORU_R01, ORU_R01); message = message.replaceFirst(VERSION_251, VERSION_25); return message; } - + public static String getUuidFromOBRSegment4(OBR obr) { try { String segment4 = obr.getObr4_UniversalServiceIdentifier().getIdentifier().getValue(); Matcher matcher = ONLY_UUID.matcher(segment4); - + if (matcher.find()) { return matcher.group(); } else { return null; } - } catch (Exception e) { + } + catch (Exception e) { LOGGER.error("An error occured while getting uuid from OBR segment", e); return null; } } - + public static String getUuidFromPV1Segment(PV1 pv1) { try { String segment505 = pv1.getAlternateVisitID().getCx5_IdentifierTypeCode().getValue(); Matcher matcher = ONLY_UUID.matcher(segment505); - + if (matcher.find()) { return matcher.group(); } else { return null; } - } catch (Exception e) { + } + catch (Exception e) { LOGGER.error("An error occured while getting uuid from PV1 segment", e); return null; } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/PatientUtil.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/PatientUtil.java index 2a1a5ad..847c39f 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/PatientUtil.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/PatientUtil.java @@ -28,8 +28,8 @@ public static PatientIdentifier getPatientIdentifier(Patient patient, String typ } if (id == null) { - throw new MessageCreationException(String.format("Patient %s does not have an identifier with UUID: %s", - patient.getPatientId(), typeUuid)); + throw new MessageCreationException( + String.format("Patient %s does not have an identifier with UUID: %s", patient.getPatientId(), typeUuid)); } return id; diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/VersionSwitcher.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/VersionSwitcher.java index 726f8c5..8f62664 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/VersionSwitcher.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/VersionSwitcher.java @@ -1,15 +1,15 @@ package org.openmrs.module.labintegration.api.hl7.messages.util; /** - * Hack util for switching the versions of messages between 2.5 and 2.5.1 - * in order to keep using the HAPI version we have on our path. + * Hack util for switching the versions of messages between 2.5 and 2.5.1 in order to keep using the + * HAPI version we have on our path. */ public final class VersionSwitcher { - - public static String switchVersion(String msg) { - return msg.replace("|2.5\r", "|2.5.1\r"); - } - - private VersionSwitcher() { - } + + public static String switchVersion(String msg) { + return msg.replace("|2.5\r", "|2.5.1\r"); + } + + private VersionSwitcher() { + } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/VersionUpdater.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/VersionUpdater.java index 407e19a..0612853 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/VersionUpdater.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/messages/util/VersionUpdater.java @@ -10,16 +10,16 @@ @Component public class VersionUpdater { - - @Autowired - @Qualifier("hL7ServiceLabIntegration") - private HL7Service hl7Service; - - public ORU_R01 updateFrom25To251(String msg) throws HL7Exception { - msg = OruR01Util.changeMessageVersionFrom251To25(msg); - Message message = hl7Service.parseHL7String(msg); - - return (ORU_R01) message; - } - + + @Autowired + @Qualifier("hL7ServiceLabIntegration") + private HL7Service hl7Service; + + public ORU_R01 updateFrom25To251(String msg) throws HL7Exception { + msg = OruR01Util.changeMessageVersionFrom251To25(msg); + Message message = hl7Service.parseHL7String(msg); + + return (ORU_R01) message; + } + } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/openelis/OpenElisHL7Config.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/openelis/OpenElisHL7Config.java index 27cd802..07bdec6 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/openelis/OpenElisHL7Config.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/openelis/OpenElisHL7Config.java @@ -13,84 +13,85 @@ @Component("OpenElisHL7Config") public class OpenElisHL7Config extends AbstractHL7Config { - - private static final String RECEIVING_APP = "labintegration.openElis.receivingApplication"; - - private static final String SENDING_APP = "labintegration.openElis.sendingApplication"; - - private static final String PID_TYPE_UUID = "labintegration.openElis.pidTypeUuid"; - - private static final String OPENELIS_URL = "labintegration.openElis.url"; - - private static final String OPENELIS_INBOUND_HOST = "labintegration.openElis.inboundHost"; - - private static final String DEFAULT_RECEIVING_APP = "OpenELIS"; - - private static final String DEFAULT_SENDING_APP = "iSantePlus"; - - private static final String DEFAULT_PID_TYPE_UUID = "05a29f94-c0ed-11e2-94be-8c13b969e334"; - - @Override - public String getReceivingApplication() { - return getPropertySource().getProperty(RECEIVING_APP, DEFAULT_RECEIVING_APP); - } - - @Override - public String getSendingApplication() { - return getPropertySource().getProperty(SENDING_APP, DEFAULT_SENDING_APP); - } - - @Override - public String getPatientIdentifierTypeUuid() { - return getPropertySource().getProperty(PID_TYPE_UUID, DEFAULT_PID_TYPE_UUID); - } - - @Override - public OrderIdentifier buildOrderIdentifier(Encounter encounter) { - return new OpenElisOrderIdentifier(); - } - - @Override - public String getSendingFacilityNamespaceID() { - return null; - } - - @Override - public boolean isBillingNumberNeeded() { - return false; - } - - @Override - public String getPatientDateOfBirthFormat() { - return null; - } - - @Override - public String getAdmitDateFormat() { - return null; - } - - public String getOpenelisInboundHost() { - String inboundHost = getPropertySource().getProperty(OPENELIS_INBOUND_HOST, null); - if (StringUtils.isBlank(inboundHost)) { - URI uri = getOpenElisUrl(); - return uri.getHost(); - } else { - return inboundHost; - } - - } - - public URI getOpenElisUrl() { - String url = PropertiesUtil.getGlobalProperty(OPENELIS_URL); - try { - return new URI(url); - } catch (URISyntaxException e) { - throw new LabHL7ConfigurationException("Incorrect OpenELIS url: " + url, e); - } - } - - public boolean isOpenElisConfigured() { - return PropertiesUtil.isGlobalPropertySet(OPENELIS_URL); - } + + private static final String RECEIVING_APP = "labintegration.openElis.receivingApplication"; + + private static final String SENDING_APP = "labintegration.openElis.sendingApplication"; + + private static final String PID_TYPE_UUID = "labintegration.openElis.pidTypeUuid"; + + private static final String OPENELIS_URL = "labintegration.openElis.url"; + + private static final String OPENELIS_INBOUND_HOST = "labintegration.openElis.inboundHost"; + + private static final String DEFAULT_RECEIVING_APP = "OpenELIS"; + + private static final String DEFAULT_SENDING_APP = "iSantePlus"; + + private static final String DEFAULT_PID_TYPE_UUID = "05a29f94-c0ed-11e2-94be-8c13b969e334"; + + @Override + public String getReceivingApplication() { + return getPropertySource().getProperty(RECEIVING_APP, DEFAULT_RECEIVING_APP); + } + + @Override + public String getSendingApplication() { + return getPropertySource().getProperty(SENDING_APP, DEFAULT_SENDING_APP); + } + + @Override + public String getPatientIdentifierTypeUuid() { + return getPropertySource().getProperty(PID_TYPE_UUID, DEFAULT_PID_TYPE_UUID); + } + + @Override + public OrderIdentifier buildOrderIdentifier(Encounter encounter) { + return new OpenElisOrderIdentifier(); + } + + @Override + public String getSendingFacilityNamespaceID() { + return null; + } + + @Override + public boolean isBillingNumberNeeded() { + return false; + } + + @Override + public String getPatientDateOfBirthFormat() { + return null; + } + + @Override + public String getAdmitDateFormat() { + return null; + } + + public String getOpenelisInboundHost() { + String inboundHost = getPropertySource().getProperty(OPENELIS_INBOUND_HOST, null); + if (StringUtils.isBlank(inboundHost)) { + URI uri = getOpenElisUrl(); + return uri.getHost(); + } else { + return inboundHost; + } + + } + + public URI getOpenElisUrl() { + String url = PropertiesUtil.getGlobalProperty(OPENELIS_URL); + try { + return new URI(url); + } + catch (URISyntaxException e) { + throw new LabHL7ConfigurationException("Incorrect OpenELIS url: " + url, e); + } + } + + public boolean isOpenElisConfigured() { + return PropertiesUtil.isGlobalPropertySet(OPENELIS_URL); + } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/openelis/OpenElisOrderIdentifier.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/openelis/OpenElisOrderIdentifier.java index 8cbd0b1..dc47498 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/openelis/OpenElisOrderIdentifier.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/openelis/OpenElisOrderIdentifier.java @@ -10,38 +10,38 @@ import org.openmrs.module.labintegration.api.hl7.config.OrderIdentifier; public class OpenElisOrderIdentifier extends OrderIdentifier { - + @Override public void updateORC(ORC orc, Obs obs) throws HL7Exception { updateOrderTypeID(orc, obs); updatePlacerOrderNumber(orc, obs); } - + @Override public void updateOBR(OBR obr, Obs obs) throws DataTypeException { updateUniversalServiceID(obr, obs); } - + @Override public void updatePlacerOrderNumber(ORC orc, Obs obs) throws DataTypeException { Provider provider = obs.getEncounter().getEncounterProviders().iterator().next().getProvider(); - + String providerId = provider.getIdentifier(); orc.getPlacerOrderNumber().getEntityIdentifier().setValue(providerId); } - + @Override public void updateUniversalServiceID(OBR obr, Obs obs) throws DataTypeException { String encounterType = obs.getEncounter().getEncounterType().getName(); String encounterUuid = obs.getEncounter().getUuid(); - + if (StringUtils.isBlank(encounterType) || StringUtils.isBlank(encounterUuid)) { throw new IllegalStateException("Encounter type and encounter UUID are mandatory"); } - + String identifier = encounterType + ID_SEPARATOR + encounterUuid; - + obr.getUniversalServiceIdentifier().getIdentifier().setValue(identifier); } - + } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/openelis/OpenElisOrderSender.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/openelis/OpenElisOrderSender.java index db39ccf..45d95c9 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/openelis/OpenElisOrderSender.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/openelis/OpenElisOrderSender.java @@ -75,14 +75,14 @@ public boolean isEnabled() { return config.isOpenElisConfigured(); } - private Acknowledgement sendToOpenElis(Encounter encounter, OrderControl orderControl) throws MessageCreationException, - InvalidAckException { + private Acknowledgement sendToOpenElis(Encounter encounter, OrderControl orderControl) + throws MessageCreationException, InvalidAckException { String msg = orderConverter.createMessage(encounter, orderControl, config); - + HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.parseMediaType("application/hl7-v2")); HttpEntity request = new HttpEntity<>(msg, headers); - + ResponseEntity response = restTemplate.postForEntity(config.getOpenElisUrl(), request, String.class); return ackParser.parse(response.getBody()); diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/oru/OruRo1Receiver.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/oru/OruRo1Receiver.java index 4666d09..1e6a040 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/oru/OruRo1Receiver.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/oru/OruRo1Receiver.java @@ -17,30 +17,31 @@ @Component("OruRO1Receiver") public class OruRo1Receiver { - - @Autowired - @Qualifier("hL7ServiceLabIntegration") - private HL7Service hl7Service; - - @Autowired - private AckGenerator ackGenerator; - - public ACK receiveMsg(String msg) throws MessageCreationException, HL7Exception { - String parsedMsg = changeMessageVersionFrom251To25(msg); - Message message = hl7Service.parseHL7String(parsedMsg); - - try { - ORU_R01 oruMessage = (ORU_R01) message; - - Message res = hl7Service.processHL7Message(oruMessage); - - return ackGenerator.generateACK(res); - } catch (RuntimeException | IOException e) { - return ackGenerator.generateACK(message, new HL7Exception(e.getMessage(), e), "AE"); - } catch (HL7Exception e) { - return ackGenerator.generateACK(message, e, "AE"); - } - } - - + + @Autowired + @Qualifier("hL7ServiceLabIntegration") + private HL7Service hl7Service; + + @Autowired + private AckGenerator ackGenerator; + + public ACK receiveMsg(String msg) throws MessageCreationException, HL7Exception { + String parsedMsg = changeMessageVersionFrom251To25(msg); + Message message = hl7Service.parseHL7String(parsedMsg); + + try { + ORU_R01 oruMessage = (ORU_R01) message; + + Message res = hl7Service.processHL7Message(oruMessage); + + return ackGenerator.generateACK(res); + } + catch (RuntimeException | IOException e) { + return ackGenerator.generateACK(message, new HL7Exception(e.getMessage(), e), "AE"); + } + catch (HL7Exception e) { + return ackGenerator.generateACK(message, e, "AE"); + } + } + } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/scc/SCCHL7Config.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/scc/SCCHL7Config.java index 2ca1c7b..806b61b 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/scc/SCCHL7Config.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/scc/SCCHL7Config.java @@ -19,22 +19,22 @@ public class SCCHL7Config extends AbstractHL7Config { private static final String PID_TYPE_UUID = "labintegration.scc.pidTypeUuid"; private static final String DEFAULT_PID_TYPE_UUID = "05a29f94-c0ed-11e2-94be-8c13b969e334"; - + private static final String PATIENT_DATE_OF_BIRTH_FORMAT = "yyyyMMdd"; - + private static final String ADMIT_DATE_FORMAT = "yyyyMMdd"; - + private Map lnspCodeMapping; - + public SCCHL7Config() { lnspCodeMapping = new HashMap<>(); lnspCodeMapping.put("25836-8", "63cbd0ac-7b4d-477a-910d-8e75168275bf"); lnspCodeMapping.put("44871-2", "4f318d58-7647-47e2-92dd-7b568aa26360"); } - + @Autowired private SCCOrderIdentifier orderIdentifier; - + @Override public String getReceivingApplication() { return null; @@ -54,27 +54,27 @@ public String getPatientIdentifierTypeUuid() { public OrderIdentifier buildOrderIdentifier(Encounter encounter) { return orderIdentifier; } - + @Override public boolean isBillingNumberNeeded() { return true; } - + @Override public String getSendingFacilityNamespaceID() { return SENDING_FACILITY_NAMESPACE_ID; } - + @Override public String getPatientDateOfBirthFormat() { return PATIENT_DATE_OF_BIRTH_FORMAT; } - + @Override public String getAdmitDateFormat() { return ADMIT_DATE_FORMAT; } - + public String mapConceptToLnspTest(String code) { String result = ""; if (this.lnspCodeMapping.containsKey(code)) { @@ -82,6 +82,5 @@ public String mapConceptToLnspTest(String code) { } return result; } - - + } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/scc/SCCOrderIdentifier.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/scc/SCCOrderIdentifier.java index 8387bf2..d0fa95b 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/scc/SCCOrderIdentifier.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/scc/SCCOrderIdentifier.java @@ -20,74 +20,73 @@ @Component public class SCCOrderIdentifier extends OrderIdentifier { - + private static final String DEFAULT_ACTION_CODE = "O"; - + @Autowired private QuantityTimingHelper quantityTimingHelper; - + @Autowired private OrderingProviderHelper orderingProviderHelper; - + @Autowired private LnspCodeHelper lnspCodeHelper; - + @Autowired private HL7Config hl7Config; - + @Override public void updateORC(ORC orc, Obs obs) throws HL7Exception { SimpleDateFormat dateFormat = new SimpleDateFormat(hl7Config.getDefaultDateFormat()); updateOrderTypeID(orc, obs); updatePlacerOrderNumber(orc, obs); - + orderingProviderHelper.updateOrderingProvider(orc, obs); quantityTimingHelper.updateQuantityTiming(orc, obs); - + orc.getDateTimeOfTransaction().getTime().setValue(dateFormat.format(obs.getEncounter().getEncounterDatetime())); } - + @Override public void updatePlacerOrderNumber(ORC orc, Obs obs) throws DataTypeException { generatePlacerOrderNumber(obs, orc.getPlacerOrderNumber()); } - + @Override public void updateOBR(OBR obr, Obs obs) throws HL7Exception { updateUniversalServiceID(obr, obs); - + orderingProviderHelper.updateOrderingProvider(obr, obs); quantityTimingHelper.updateQuantityTiming(obr, obs); String encounterLocationUuid = obs.getEncounter().getLocation().getUuid(); obr.getPlacerOrderNumber().getEntityIdentifier().setValue(encounterLocationUuid); - + generatePlacerOrderNumber(obs, obr.getPlacerOrderNumber()); - + obr.getSpecimenActionCode().setValue(DEFAULT_ACTION_CODE); } - + @Override public void updateUniversalServiceID(OBR obr, Obs obs) throws DataTypeException { lnspCodeHelper.updateUniversalServiceID(obr, obs); } - + private void generatePlacerOrderNumber(Obs obs, EI placerOrderNumber) throws DataTypeException { //added site code to Placer Order number: site code + obs id - + Encounter encounter = obs.getEncounter(); - + String siteCode = ""; String uuid = "0e52924e-4ebb-40ba-9b83-b198b532653b"; - - + for (LocationAttribute locationAttribute : encounter.getLocation().getActiveAttributes()) { - + if (locationAttribute.getAttributeType().getUuid().equals(uuid)) { siteCode = locationAttribute.getValueReference(); } } - + placerOrderNumber.getEntityIdentifier().setValue(siteCode + '-' + encounter.getEncounterId() + '-' + obs.getObsId()); } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/util/OpenElisStatusHelper.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/util/OpenElisStatusHelper.java index 81b7eb8..b40fc4f 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/util/OpenElisStatusHelper.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/util/OpenElisStatusHelper.java @@ -5,31 +5,31 @@ import ca.uhn.hl7v2.model.v25.segment.OBR; public final class OpenElisStatusHelper { - - public static String getStatus(ORU_R01 oru) { - ORU_R01_ORDER_OBSERVATION orderObs = oru.getPATIENT_RESULT().getORDER_OBSERVATION(0); - OBR obr = orderObs.getOBR(); - String resultStatus = obr.getObr25_ResultStatus().getValue(); - - if ("O".equals(resultStatus)) { - return "Order Received"; - } else if ("I".equals(resultStatus)) { - return "Specimen Received"; - } else if ("P".equals(resultStatus)) { - return "Preliminary Result"; - } else if ("A".equals(resultStatus)) { - return "Result"; - } else if ("F".equals(resultStatus)) { - return "Final Result"; - } else if ("C".equals(resultStatus)) { - return "Correction"; - } else if ("X".equals(resultStatus)) { - return "Order Cancelled"; - } else { - return "Unknown"; - } - } - - private OpenElisStatusHelper() { - } + + public static String getStatus(ORU_R01 oru) { + ORU_R01_ORDER_OBSERVATION orderObs = oru.getPATIENT_RESULT().getORDER_OBSERVATION(0); + OBR obr = orderObs.getOBR(); + String resultStatus = obr.getObr25_ResultStatus().getValue(); + + if ("O".equals(resultStatus)) { + return "Order Received"; + } else if ("I".equals(resultStatus)) { + return "Specimen Received"; + } else if ("P".equals(resultStatus)) { + return "Preliminary Result"; + } else if ("A".equals(resultStatus)) { + return "Result"; + } else if ("F".equals(resultStatus)) { + return "Final Result"; + } else if ("C".equals(resultStatus)) { + return "Correction"; + } else if ("X".equals(resultStatus)) { + return "Order Cancelled"; + } else { + return "Unknown"; + } + } + + private OpenElisStatusHelper() { + } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/util/ProviderHelper.java b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/util/ProviderHelper.java index 34eeb7a..9d28abf 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/hl7/util/ProviderHelper.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/hl7/util/ProviderHelper.java @@ -9,20 +9,20 @@ import java.util.Set; public final class ProviderHelper { - - public static Provider getProvider(Obs obs) { - return getProvider(obs.getEncounter()); - } - - public static Provider getProvider(Encounter encounter) { - Set encProviders = encounter.getEncounterProviders(); - if (CollectionUtils.isNotEmpty(encProviders)) { - return encProviders.iterator().next().getProvider(); - } else { - return null; - } - } - - private ProviderHelper() { - } + + public static Provider getProvider(Obs obs) { + return getProvider(obs.getEncounter()); + } + + public static Provider getProvider(Encounter encounter) { + Set encProviders = encounter.getEncounterProviders(); + if (CollectionUtils.isNotEmpty(encProviders)) { + return encProviders.iterator().next().getProvider(); + } else { + return null; + } + } + + private ProviderHelper() { + } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/impl/LabIntegrationReportServiceImpl.java b/api/src/main/java/org/openmrs/module/labintegration/api/impl/LabIntegrationReportServiceImpl.java new file mode 100644 index 0000000..f08bee2 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/labintegration/api/impl/LabIntegrationReportServiceImpl.java @@ -0,0 +1,81 @@ +package org.openmrs.module.labintegration.api.impl; + +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Person; +import org.openmrs.api.ConceptService; +import org.openmrs.api.ObsService; +import org.openmrs.api.context.Context; +import org.openmrs.api.impl.BaseOpenmrsService; +import org.openmrs.module.labintegration.api.LabIntegrationReportService; +import org.openmrs.module.labintegration.api.hl7.ObsSelector; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import static org.openmrs.module.labintegration.api.LabIntegrationReportsConstants.FREE_TEXT_RESULT_CONCEPT_ID; +import static org.openmrs.module.labintegration.api.LabIntegrationReportsConstants.TESTS_ORDERED_CONCEPT_ID; + +@Component("labintegration.LabIntegrationReportServiceImpl") +public class LabIntegrationReportServiceImpl extends BaseOpenmrsService implements LabIntegrationReportService { + + @Override + public List getLabResults(Date startDate, Date endDate) { + ConceptService conceptService = Context.getConceptService(); + ObsService obsService = Context.getObsService(); + ObsSelector obsSelector = new ObsSelector(); + + Concept labOrderConcept = conceptService.getConcept(TESTS_ORDERED_CONCEPT_ID); + if (labOrderConcept == null) { + return Collections.emptyList(); + } + List orderConcepts = new ArrayList<>(); + if (obsSelector.getViralLoadConceptId() != -1) { + Concept viralLoad = conceptService.getConcept(obsSelector.getViralLoadConceptId()); + orderConcepts.add(viralLoad); + } + if (obsSelector.getEarlyInfantDiagnosisConceptId() != -1) { + Concept earlyChildDiagnosis = conceptService.getConcept(obsSelector.getEarlyInfantDiagnosisConceptId()); + orderConcepts.add(earlyChildDiagnosis); + } + if (orderConcepts.isEmpty()) { + return Collections.emptyList(); + } + + List orders = obsService.getObservations(null, null, orderConcepts, null, null, null, null, null, null, + startDate, endDate, false, null); + + Set persons = new LinkedHashSet<>(orders.size()); + Set orderedTests = new LinkedHashSet<>(orders.size()); + Set orderEncounters = new LinkedHashSet<>(orders.size()); + + for (Obs order : orders) { + persons.add(order.getPerson()); + orderedTests.add(order.getConcept()); + orderEncounters.add(order.getEncounter()); + } + + // freeTextResults are used to capture results with errors or other issues, so may not correspond + // directly to an ordered test + Concept freeTextResults = conceptService.getConcept(FREE_TEXT_RESULT_CONCEPT_ID); + if (freeTextResults != null) { + orderedTests.add(freeTextResults); + } + List testResults = obsService.getObservations(new ArrayList<>(persons), new ArrayList<>(orderEncounters), + new ArrayList<>(orderedTests), null, null, null, Arrays.asList("obsDatetime desc", "obsId asc"), null, null, + null, null, false); + + if (testResults != null) { + return testResults; + } + + return Collections.emptyList(); + } +} diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/impl/LabIntegrationServiceImpl.java b/api/src/main/java/org/openmrs/module/labintegration/api/impl/LabIntegrationServiceImpl.java index 8fe13b6..d948332 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/impl/LabIntegrationServiceImpl.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/impl/LabIntegrationServiceImpl.java @@ -23,7 +23,7 @@ public class LabIntegrationServiceImpl extends BaseOpenmrsService implements Lab @Autowired private OpenElisHL7Config openElisHL7Config; - + @Autowired private OrderSenderManager orderSenderManager; @@ -32,8 +32,8 @@ public void doOrder(Encounter encounter) throws NewOrderException { List orderDestinations = OrderDestination.getOrderDestinations(encounter); validateDestinations(orderDestinations); LOGGER.info("Started processing order (created or updated) in Encounter {} to {}", encounter.getUuid(), - StringUtils.join(orderDestinations, ',')); - + StringUtils.join(orderDestinations, ',')); + for (OrderDestination destination : orderDestinations) { if (destination.equals(OrderDestination.SCC)) { orderSenderManager.sendOrders(encounter, destination); @@ -44,8 +44,7 @@ public void doOrder(Encounter encounter) throws NewOrderException { } private void validateDestinations(List orderDestinations) { - if (orderDestinations.contains(OrderDestination.OPEN_ELIS) - && !openElisHL7Config.isOpenElisConfigured()) { + if (orderDestinations.contains(OrderDestination.OPEN_ELIS) && !openElisHL7Config.isOpenElisConfigured()) { throw new LabIntegrationException("Tried to order from OpenELIS that is not configured"); } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/model/OrderDestination.java b/api/src/main/java/org/openmrs/module/labintegration/api/model/OrderDestination.java index 8e5c04f..18b818c 100644 --- a/api/src/main/java/org/openmrs/module/labintegration/api/model/OrderDestination.java +++ b/api/src/main/java/org/openmrs/module/labintegration/api/model/OrderDestination.java @@ -8,54 +8,54 @@ import java.util.List; public enum OrderDestination { - SCC("SCC"), - OPEN_ELIS("OpenELIS"); - - public static final String ORDER_DESTINATION_CONCEPT_UUID = "160632AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - - private String name; - - OrderDestination(String text) { - this.name = text; - } - - public String getName() { - return this.name; - } - - public static OrderDestination fromString(String text) { - for (OrderDestination b : OrderDestination.values()) { - if (b.name.equalsIgnoreCase(text)) { - return b; - } - } - return null; - } - - public static List getOrderDestinations(Encounter encounter) { - List destinations = new ArrayList<>(); - - for (Obs obs : encounter.getAllObs()) { - if (ObjectUtils.equals(obs.getConcept().getUuid(), ORDER_DESTINATION_CONCEPT_UUID)) { - OrderDestination destination = OrderDestination.fromString(obs.getValueText()); - if (destination != null) { - destinations.add(destination); - } - } - } - - return destinations; - } - - public static boolean searchForExistence(Encounter encounter, OrderDestination... ods) { - List orderDestinations = OrderDestination.getOrderDestinations(encounter); - for (OrderDestination od : orderDestinations) { - for (OrderDestination searchedOd : ods) { - if (od.equals(searchedOd)) { - return true; - } - } - } - return false; - } + + SCC("SCC"), OPEN_ELIS("OpenELIS"); + + public static final String ORDER_DESTINATION_CONCEPT_UUID = "160632AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + private String name; + + OrderDestination(String text) { + this.name = text; + } + + public String getName() { + return this.name; + } + + public static OrderDestination fromString(String text) { + for (OrderDestination b : OrderDestination.values()) { + if (b.name.equalsIgnoreCase(text)) { + return b; + } + } + return null; + } + + public static List getOrderDestinations(Encounter encounter) { + List destinations = new ArrayList<>(); + + for (Obs obs : encounter.getAllObs()) { + if (ObjectUtils.equals(obs.getConcept().getUuid(), ORDER_DESTINATION_CONCEPT_UUID)) { + OrderDestination destination = OrderDestination.fromString(obs.getValueText()); + if (destination != null) { + destinations.add(destination); + } + } + } + + return destinations; + } + + public static boolean searchForExistence(Encounter encounter, OrderDestination... ods) { + List orderDestinations = OrderDestination.getOrderDestinations(encounter); + for (OrderDestination od : orderDestinations) { + for (OrderDestination searchedOd : ods) { + if (od.equals(searchedOd)) { + return true; + } + } + } + return false; + } } diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/reports/LabResultDataSetDefinition.java b/api/src/main/java/org/openmrs/module/labintegration/api/reports/LabResultDataSetDefinition.java new file mode 100644 index 0000000..339d071 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/labintegration/api/reports/LabResultDataSetDefinition.java @@ -0,0 +1,59 @@ +package org.openmrs.module.labintegration.api.reports; + +import org.openmrs.module.reporting.common.Localized; +import org.openmrs.module.reporting.common.TimeQualifier; +import org.openmrs.module.reporting.data.DataDefinition; +import org.openmrs.module.reporting.data.converter.DataConverter; +import org.openmrs.module.reporting.data.encounter.definition.EncounterDataDefinition; +import org.openmrs.module.reporting.data.obs.definition.EncounterToObsDataDefinition; +import org.openmrs.module.reporting.data.obs.definition.ObsDataDefinition; +import org.openmrs.module.reporting.data.obs.definition.PatientToObsDataDefinition; +import org.openmrs.module.reporting.data.obs.definition.PersonToObsDataDefinition; +import org.openmrs.module.reporting.data.patient.definition.PatientDataDefinition; +import org.openmrs.module.reporting.data.person.definition.PersonDataDefinition; +import org.openmrs.module.reporting.dataset.column.definition.RowPerObjectColumnDefinition; +import org.openmrs.module.reporting.dataset.definition.RowPerObjectDataSetDefinition; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Localized("labintegration.LabResultDataSetDefinition") +public class LabResultDataSetDefinition extends RowPerObjectDataSetDefinition { + + @Override + public List> getSupportedDataDefinitionTypes() { + List> l = new ArrayList>(); + l.add(ObsDataDefinition.class); + l.add(EncounterDataDefinition.class); + l.add(PatientDataDefinition.class); + l.add(PersonDataDefinition.class); + return l; + } + + @Override + public void addColumn(String name, DataDefinition dataDefinition, String mappings, DataConverter... converters) { + if (dataDefinition instanceof ObsDataDefinition) { + getColumnDefinitions().add(new RowPerObjectColumnDefinition(name, dataDefinition, mappings, converters)); + } else if (dataDefinition instanceof EncounterDataDefinition) { + ObsDataDefinition odd = new EncounterToObsDataDefinition((EncounterDataDefinition) dataDefinition); + getColumnDefinitions().add(new RowPerObjectColumnDefinition(name, odd, mappings, converters)); + } else if (dataDefinition instanceof PatientDataDefinition) { + ObsDataDefinition odd = new PatientToObsDataDefinition((PatientDataDefinition) dataDefinition); + getColumnDefinitions().add(new RowPerObjectColumnDefinition(name, odd, mappings, converters)); + } else if (dataDefinition instanceof PersonDataDefinition) { + ObsDataDefinition odd = new PersonToObsDataDefinition((PersonDataDefinition) dataDefinition); + getColumnDefinitions().add(new RowPerObjectColumnDefinition(name, odd, mappings, converters)); + } else { + throw new IllegalArgumentException( + "Unable to add data definition of type " + dataDefinition.getClass().getSimpleName()); + } + + } + + @Override + public void addColumns(String name, RowPerObjectDataSetDefinition dataSetDefinition, String mappings, + TimeQualifier whichValues, Integer numberOfValues, DataConverter... converters) { + + } +} diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/reports/LabResultDataSetEvaluator.java b/api/src/main/java/org/openmrs/module/labintegration/api/reports/LabResultDataSetEvaluator.java new file mode 100644 index 0000000..ccdb62c --- /dev/null +++ b/api/src/main/java/org/openmrs/module/labintegration/api/reports/LabResultDataSetEvaluator.java @@ -0,0 +1,158 @@ +package org.openmrs.module.labintegration.api.reports; + +import org.openmrs.Concept; +import org.openmrs.Location; +import org.openmrs.LocationAttribute; +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.PatientIdentifier; +import org.openmrs.PatientIdentifierType; +import org.openmrs.annotation.Handler; +import org.openmrs.api.PatientService; +import org.openmrs.api.context.Context; +import org.openmrs.module.labintegration.api.LabIntegrationReportService; +import org.openmrs.module.reporting.common.MessageUtil; +import org.openmrs.module.reporting.common.ObjectUtil; +import org.openmrs.module.reporting.data.converter.ObsValueConverter; +import org.openmrs.module.reporting.dataset.DataSet; +import org.openmrs.module.reporting.dataset.DataSetColumn; +import org.openmrs.module.reporting.dataset.SimpleDataSet; +import org.openmrs.module.reporting.dataset.definition.DataSetDefinition; +import org.openmrs.module.reporting.dataset.definition.evaluator.DataSetEvaluator; +import org.openmrs.module.reporting.evaluation.EvaluationContext; +import org.openmrs.module.reporting.evaluation.EvaluationException; + +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.openmrs.module.labintegration.api.LabIntegrationReportsConstants.LOCATION_ISANTE_CODE_UUID; +import static org.openmrs.module.labintegration.api.LabIntegrationReportsConstants.ISANTEPLUS_IDENDTIFIER_TYPE_UUID; + +@Handler(supports = LabResultDataSetDefinition.class) +public class LabResultDataSetEvaluator implements DataSetEvaluator { + + private final String COLUMN_NUMBER = "Number"; + + private final String COLUMN_CLINIC_CODE = "Clinic Code"; + + private final String COLUMN_ISANTEPLUS_ID = "ISantePlus ID"; + + private final String COLUMN_PATIENT_NAME = "Patient Name"; + + private final String COLUMN_DATE_ORDERED = "Date Ordered"; + + private final String COLUMN_TEST_ORDERED = "Test Ordered"; + + private final String COLUMN_DATE_RESULTED = "Date Resulted"; + + private final String COLUMN_RESULT = "Result"; + + @Override + public DataSet evaluate(DataSetDefinition dataSetDefinition, EvaluationContext evalContext) throws EvaluationException { + if (dataSetDefinition == null) { + throw new EvaluationException(null, new AssertionError("dataSetDefinition is null")); + } else if (!(dataSetDefinition instanceof LabResultDataSetDefinition)) { + throw new EvaluationException(null, + new AssertionError("Attempted to evaluate a LabResultDataSetDefinition but it was " + + dataSetDefinition.getClass().getSimpleName())); + } + + LabIntegrationReportService reportService = Context.getService(LabIntegrationReportService.class); + + SimpleDataSet simpleDataSet = new SimpleDataSet(dataSetDefinition, evalContext); + + List results = reportService.getLabResults((Date) evalContext.getParameterValue("startDate"), + (Date) evalContext.getParameterValue("endDate")); + + List columns = Arrays.asList( + new DataSetColumn(COLUMN_NUMBER, MessageUtil.translate("labintegration.results.clinic.no"), String.class), + new DataSetColumn(COLUMN_CLINIC_CODE, MessageUtil.translate("labintegration.results.clinic.code"), String.class), + new DataSetColumn(COLUMN_ISANTEPLUS_ID, MessageUtil.translate("labintegration.results.isanteplus.id"), + String.class), + new DataSetColumn(COLUMN_PATIENT_NAME, MessageUtil.translate("labintegration.results.patient.name"), + String.class), + new DataSetColumn(COLUMN_DATE_ORDERED, MessageUtil.translate("labintegration.results.date.ordered"), Date.class), + new DataSetColumn(COLUMN_TEST_ORDERED, MessageUtil.translate("labintegration.results.test.ordered"), + Concept.class), + new DataSetColumn(COLUMN_DATE_RESULTED, MessageUtil.translate("labintegration.results.date.resulted"), + Date.class), + new DataSetColumn(COLUMN_RESULT, MessageUtil.translate("labintegration.results.result"), String.class)); + + ObsValueConverter obsValueConverter = new ObsValueConverter(); + Map locationCodeCache = new HashMap<>(); + for (int i = 0; i < results.size(); i++) { + Obs obs = results.get(i); + for (DataSetColumn column : columns) { + Object value = null; + + switch (column.getName()) { + case COLUMN_NUMBER: + value = i + 1; + break; + case COLUMN_CLINIC_CODE: + value = extractLocationCode(obs, locationCodeCache); + break; + case COLUMN_PATIENT_NAME: + value = obs.getPerson().getPersonName().getFullName(); + break; + case COLUMN_ISANTEPLUS_ID: + value = getPatientIdentifier(obs.getPersonId()); + break; + case COLUMN_DATE_ORDERED: + value = obs.getEncounter().getEncounterDatetime(); + break; + case COLUMN_TEST_ORDERED: + value = ObjectUtil.format(obs.getConcept()); + break; + case COLUMN_DATE_RESULTED: + value = obs.getObsDatetime(); + break; + case COLUMN_RESULT: + value = obsValueConverter.convert(obs); + break; + } + if (value != null) { + simpleDataSet.addColumnValue(i, column, value); + } + } + } + if (results.isEmpty()) { + for (DataSetColumn column : columns) { + simpleDataSet.addColumnValue(0, column, ""); + } + + } + + return simpleDataSet; + } + + protected String extractLocationCode(Obs obs, Map locationCodeCache) { + Location location = obs.getEncounter().getLocation(); + + if (locationCodeCache.containsKey(location)) { + return locationCodeCache.get(location); + } + + for (LocationAttribute attribute : location.getAttributes()) { + if (attribute.getAttributeType().getUuid().equals(LOCATION_ISANTE_CODE_UUID)) { + String result = attribute.getValueReference(); + locationCodeCache.put(location, result); + return result; + } + } + + return null; + } + + protected String getPatientIdentifier(Integer personId) { + PatientService patientService = Context.getPatientService(); + Patient patient = patientService.getPatient(personId); + PatientIdentifierType pit = patientService.getPatientIdentifierTypeByUuid(ISANTEPLUS_IDENDTIFIER_TYPE_UUID); + patient.getPatientIdentifier(pit); + PatientIdentifier pid = patient.getPatientIdentifier(pit); + return pid != null ? pid.getIdentifier() : ""; + } +} diff --git a/api/src/main/java/org/openmrs/module/labintegration/api/reports/LabResultsReportManager.java b/api/src/main/java/org/openmrs/module/labintegration/api/reports/LabResultsReportManager.java new file mode 100644 index 0000000..45a8ffd --- /dev/null +++ b/api/src/main/java/org/openmrs/module/labintegration/api/reports/LabResultsReportManager.java @@ -0,0 +1,82 @@ +package org.openmrs.module.labintegration.api.reports; + +import org.openmrs.module.labintegration.ActivatedReportManager; +import org.openmrs.module.reporting.common.MessageUtil; +import org.openmrs.module.reporting.evaluation.parameter.Parameter; +import org.openmrs.module.reporting.report.ReportDesign; +import org.openmrs.module.reporting.report.definition.ReportDefinition; +import org.openmrs.module.reporting.report.manager.ReportManagerUtil; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class LabResultsReportManager extends ActivatedReportManager { + + @Override + public String getUuid() { + return "100db747-d65d-46d4-96dc-7e66fb672ab2"; + } + + public String getExcelDesignUuid() { + return "32639f66-1cc8-4ccc-93b3-20077ea33d7d"; + } + + @Override + public String getName() { + return MessageUtil.translate("labintegration.results.report.name"); + } + + public String getDataSetName() { + return MessageUtil.translate("labintegration.results.report.dataset"); + } + + @Override + public String getDescription() { + return MessageUtil.translate("labintegration.results.report.description"); + } + + @Override + public List getParameters() { + return Arrays.asList( + new Parameter("startDate", MessageUtil.translate("labintegration.results.parameter.startDate"), Date.class), + new Parameter("endDate", MessageUtil.translate("labintegration.results.parameter.endDate"), Date.class)); + } + + @Override + public ReportDefinition constructReportDefinition() { + ReportDefinition reportDefinition = new ReportDefinition(); + reportDefinition.setUuid(getUuid()); + reportDefinition.setName(getName()); + reportDefinition.setDescription(getDescription()); + reportDefinition.setParameters(getParameters()); + + LabResultDataSetDefinition dataSetDefinition = new LabResultDataSetDefinition(); + dataSetDefinition.setUuid(getUuid()); + dataSetDefinition.setName(getName()); + dataSetDefinition.setDescription(getDescription()); + dataSetDefinition.setParameters(getParameters()); + + Map parameterMappings = new HashMap(); + parameterMappings.put("startDate", "${startDate}"); + parameterMappings.put("endDate", "${endDate}"); + + reportDefinition.addDataSetDefinition(getDataSetName(), dataSetDefinition, parameterMappings); + + return reportDefinition; + } + + @Override + public List constructReportDesigns(ReportDefinition reportDefinition) { + return Arrays.asList(ReportManagerUtil.createExcelDesign(getExcelDesignUuid(), reportDefinition)); + } + + @Override + public String getVersion() { + return "1.0.0-SNAPSHOT"; + } +} diff --git a/api/src/main/resources/messages.properties b/api/src/main/resources/messages.properties index f7c0111..f267df1 100644 --- a/api/src/main/resources/messages.properties +++ b/api/src/main/resources/messages.properties @@ -21,3 +21,16 @@ ORUR01.error.UnresolvedEncounter=Could not resolve encounter ORUR01.error.UnresolvedLocation=Could not resolve location ORUR01.error.parseFormId=Error parsing form id from message ORUR01.error.UnresolvedEnterer=Could not resolve enterer +labintegration.results.parameter.startDate=Start Date +labintegration.results.parameter.endDate=End Date +labintegration.results.report.name=LNSP Results Report +labintegration.results.report.description=LNSP Report for Viral Load and EID Labs +labintegration.results.report.dataset=LNSP Results DataSet +labintegration.results.clinic.no=No. +labintegration.results.clinic.code=Clinic Code +labintegration.results.isanteplus.id=ISantePlus ID +labintegration.results.patient.name=Patient Name +labintegration.results.date.ordered=Date Ordered +labintegration.results.test.ordered=Test Ordered +labintegration.results.date.resulted=Date Resulted +labintegration.results.result=Result diff --git a/api/src/main/resources/messages_es.properties b/api/src/main/resources/messages_es.properties index f7c0111..9515fd1 100644 --- a/api/src/main/resources/messages_es.properties +++ b/api/src/main/resources/messages_es.properties @@ -21,3 +21,16 @@ ORUR01.error.UnresolvedEncounter=Could not resolve encounter ORUR01.error.UnresolvedLocation=Could not resolve location ORUR01.error.parseFormId=Error parsing form id from message ORUR01.error.UnresolvedEnterer=Could not resolve enterer +labintegration.results.parameter.startDate=Fecha de inicio +labintegration.results.parameter.endDate=Fecha de fin +labintegration.results.report.name=Informe de resultados de LNSP +labintegration.results.report.description=Informe LNSP para laboratorios de carga viral y detección temprana del VIH +labintegration.results.report.dataset=Conjunto de datos de resultados LNSP +labintegration.results.clinic.no=N.º +labintegration.results.clinic.code=Código de la clínica +labintegration.results.isanteplus.id=ID de ISantePlus +labintegration.results.patient.name=Nombre del paciente +labintegration.results.date.ordered=Fecha de solicitud +labintegration.results.test.ordered=Prueba solicitada +labintegration.results.date.resulted=Fecha del resultado +labintegration.results.result=Resultado diff --git a/api/src/main/resources/messages_fr.properties b/api/src/main/resources/messages_fr.properties index f7c0111..68c165d 100644 --- a/api/src/main/resources/messages_fr.properties +++ b/api/src/main/resources/messages_fr.properties @@ -21,3 +21,16 @@ ORUR01.error.UnresolvedEncounter=Could not resolve encounter ORUR01.error.UnresolvedLocation=Could not resolve location ORUR01.error.parseFormId=Error parsing form id from message ORUR01.error.UnresolvedEnterer=Could not resolve enterer +labintegration.results.parameter.startDate=Date de début +labintegration.results.parameter.endDate=Date de fin +labintegration.results.report.name=Rapport des résultats de LNSP +labintegration.results.report.description=Rapport LNSP pour les laboratoires de charge virale et de dépistage précoce du VIH +labintegration.results.report.dataset=Jeu de données des résultats LNSP +labintegration.results.clinic.no=N° +labintegration.results.clinic.code=Code de la clinique +labintegration.results.isanteplus.id=ID ISantePlus +labintegration.results.patient.name=Nom du patient +labintegration.results.date.ordered=Date de la commande +labintegration.results.test.ordered=Test demandé +labintegration.results.date.resulted=Date du résultat +labintegration.results.result=Résultat diff --git a/api/src/main/resources/moduleApplicationContext.xml b/api/src/main/resources/moduleApplicationContext.xml index eb5041e..90ab4b4 100644 --- a/api/src/main/resources/moduleApplicationContext.xml +++ b/api/src/main/resources/moduleApplicationContext.xml @@ -65,4 +65,12 @@ + + + + org.openmrs.module.labintegration.api.LabIntegrationReportService + + + + diff --git a/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/AbstractOrderConverterTest.java b/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/AbstractOrderConverterTest.java index cf3b32d..3772466 100644 --- a/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/AbstractOrderConverterTest.java +++ b/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/AbstractOrderConverterTest.java @@ -3,7 +3,6 @@ import org.openmrs.test.BaseModuleContextSensitiveTest; import org.springframework.test.context.ContextConfiguration; - @ContextConfiguration(classes = TestConfiguration.class, inheritLocations = false) public abstract class AbstractOrderConverterTest extends BaseModuleContextSensitiveTest { diff --git a/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/OMLO21OrderConverterTest.java b/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/OMLO21OrderConverterTest.java index 076139e..e358b4e 100644 --- a/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/OMLO21OrderConverterTest.java +++ b/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/OMLO21OrderConverterTest.java @@ -49,13 +49,13 @@ public class OMLO21OrderConverterTest extends AbstractOrderConverterTest { public void init() { OrderConverterTestUtils.mockRollingNumber(controlIdSource); } - + @Test public void dummyTest() { assertTrue(true); } -// @Test + // @Test public void shouldGenerateMessage() throws Exception { executeDataSet(DATASET); Patient patient = patientService.getPatient(PATIENT_ID); diff --git a/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/ORMO01OrderConverterTest.java b/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/ORMO01OrderConverterTest.java index 7b66c87..32f065b 100644 --- a/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/ORMO01OrderConverterTest.java +++ b/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/ORMO01OrderConverterTest.java @@ -23,50 +23,50 @@ import static org.junit.Assert.assertTrue; public class ORMO01OrderConverterTest extends AbstractOrderConverterTest { - + private static final String EXPECTED_FILE = "ORM_O01.hl7"; - + @Spy @Autowired private MessageControlIdSource controlIdSource; - + @Autowired @InjectMocks private MshGenerator mshGenerator; - + @Autowired private ORMO01OrderConverter orderConverter; - + @Autowired private PatientService patientService; - + @Autowired private ProviderService providerService; - + @Autowired private SCCHL7Config scchl7Config; - + @Before public void init() { OrderConverterTestUtils.mockRollingNumber(controlIdSource); } - + @Test public void dummyTest() { assertTrue(true); } - -// @Test + + // @Test public void shouldGenerateMessage() throws Exception { executeDataSet(DATASET); Patient patient = patientService.getPatient(PATIENT_ID); Provider provider = providerService.getProvider(PROVIDER_ID); HL7TestOrder order = new HL7TestOrder(patient, provider); - + Encounter e = order.value(); - + e.getEncounterType().setUuid("abcdefg1234567"); - + String msg = orderConverter.createMessage(e, OrderControl.NEW_ORDER, scchl7Config); String expected = HL7TestMsgUtil.readMsg(EXPECTED_FILE); diff --git a/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/TestConfiguration.java b/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/TestConfiguration.java index dd921db..cae83c9 100644 --- a/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/TestConfiguration.java +++ b/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/TestConfiguration.java @@ -1,11 +1,11 @@ package org.openmrs.module.labintegration.api.communication.hl7.messages; - import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportResource; @Configuration -@ImportResource({ "classpath:applicationContext-service.xml", "classpath*:moduleApplicationContext.xml" ,"classpath*:test-labContext.xml"}) +@ImportResource({ "classpath:applicationContext-service.xml", "classpath*:moduleApplicationContext.xml", + "classpath*:test-labContext.xml" }) public class TestConfiguration { - + } diff --git a/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/ack/AckParserTest.java b/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/ack/AckParserTest.java index 4226741..5ae1d76 100644 --- a/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/ack/AckParserTest.java +++ b/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/ack/AckParserTest.java @@ -22,15 +22,15 @@ public class AckParserTest { private static final String ACK_COMMIT_ACCEPT_FILE = "ACK_Commit_Accept.hl7"; private static final String ACK_COMMIT_ERROR_FILE = "ACK_Commit_Error.hl7"; - + private static final String ORL_O22_RECEIVED_FILE = "ORL_O22_RECEIVED.hl7"; - + private static final String ORL_O22_ERROR_FILE = "ORL_O22_ERROR.hl7"; - + private static final String MSG_ID = "20070701151010000018"; - + private static final String ORL_O22_RECEIVED_MSG_ID = "1"; - + private AckParser ackParser = new AckParser(); @Test @@ -58,30 +58,29 @@ public void shouldParseAckError() throws IOException, InvalidAckException { assertEquals(MSG_ID, ack.getMsgId()); assertEquals("103", ack.getErrorCode()); } - + @Test public void shouldParseORL_O22() throws IOException, InvalidAckException { String msg = HL7TestMsgUtil.readMsg(ORL_O22_RECEIVED_FILE); - + Acknowledgement ack = ackParser.parse(msg); - + assertNotNull(ack); assertTrue(ack.isSuccess()); assertNull(ack.getErrorDiagnosticsInformation()); assertEquals(ORL_O22_RECEIVED_MSG_ID, ack.getMsgId()); assertNull(ack.getErrorCode()); } - + @Test public void shouldParseORL_O22Error() throws IOException, InvalidAckException { String msg = HL7TestMsgUtil.readMsg(ORL_O22_ERROR_FILE); - + Acknowledgement ack = ackParser.parse(msg); - + assertNotNull(ack); assertFalse(ack.isSuccess()); - assertEquals("DUPLICATE_ORDER : ORDER_FOUND_QUEUED", - ack.getErrorDiagnosticsInformation()); + assertEquals("DUPLICATE_ORDER : ORDER_FOUND_QUEUED", ack.getErrorDiagnosticsInformation()); assertEquals(ORL_O22_RECEIVED_MSG_ID, ack.getMsgId()); assertEquals("207", ack.getErrorCode()); } diff --git a/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/orur01/OruRo1ReceiverTest.java b/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/orur01/OruRo1ReceiverTest.java index 05214c8..0fe4a0a 100644 --- a/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/orur01/OruRo1ReceiverTest.java +++ b/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/orur01/OruRo1ReceiverTest.java @@ -24,106 +24,98 @@ import static org.junit.Assert.assertNotNull; public class OruRo1ReceiverTest extends AbstractOrderConverterTest { - + private static final String DATASET = "lab-dataset.xml"; - + private static final String FINAL_RESULT_ORU_RO1 = "ORU_R01_Final_Result.hl7"; - + private static final String FINAL_RESULT_ERROR_ORU_RO1 = "ORU_R01_Final_Result_Error.hl7"; - + private static final String ENCOUNTER_UUID = "549c78dc-31da-11e8-acac-c3add5b19973"; + private static final int CONCEPT_ID = 678; - - + private PipeParser pipeParser = new PipeParser(); - + @Autowired @Qualifier("hL7ServiceLabIntegration") private HL7Service hl7Service; - + @Autowired private OruRo1Receiver oruRo1Receiver; - + @Autowired private EncounterService encounterService; - + @Before public void setUp() throws Exception { executeDataSet(DATASET); } - + @Test public void shouldParseOruRo1FinalMessage() throws IOException, MessageCreationException, HL7Exception { String hl7Msg = HL7TestMsgUtil.readMsg(FINAL_RESULT_ORU_RO1); oruRo1Receiver.receiveMsg(hl7Msg); - + Encounter encounter = encounterService.getEncounterByUuid(ENCOUNTER_UUID); Obs obs = EncounterUtil.findObs(encounter, CONCEPT_ID, null); - + assertNotNull(obs); assertEquals("This is a note about the result", obs.getComment()); assertEquals(12.0, obs.getValueNumeric(), 0.0); } - + @Test public void shouldParseOruRo1FinalMessageAndReturnACK() throws IOException, HL7Exception, MessageCreationException { - String hl7Msg = HL7TestMsgUtil.readMsg(FINAL_RESULT_ORU_RO1); - - ACK actual = oruRo1Receiver.receiveMsg(hl7Msg); - - ORU_R01 oruR01 = new ORU_R01(); - pipeParser.parse(oruR01, hl7Msg); - - assertEquals("^~\\&", actual.getMSH().getMsh2_EncodingCharacters().getValue()); - assertEquals("ACK", - actual.getMSH().getMsh9_MessageType().getMsg1_MessageCode().getValue()); - assertEquals(oruR01.getMSH().getMsh9_MessageType().getMsg2_TriggerEvent().getValue(), - actual.getMSH().getMsh9_MessageType().getMsg2_TriggerEvent().getValue()); - assertEquals("ACK", - actual.getMSH().getMsh9_MessageType().getMsg3_MessageStructure().getValue()); - assertNotNull(actual.getMSH().getMsh7_DateTimeOfMessage().getTime().getValue()); - assertNotNull(actual.getMSH().getMsh10_MessageControlID().getValue()); - // Result Status = Preliminary Result - assertEquals("P", - actual.getMSH().getMsh11_ProcessingID().getProcessingID().getValue()); - assertEquals("2.5.1", - actual.getMSH().getMsh12_VersionID().getVersionID().getValue()); - - // AA = Application Accept - assertEquals("AA", actual.getMSA().getMsa1_AcknowledgmentCode().getValue()); - assertEquals(oruR01.getMSH().getMsh10_MessageControlID().getValue(), - actual.getMSA().getMsa2_MessageControlID().getValue()); + String hl7Msg = HL7TestMsgUtil.readMsg(FINAL_RESULT_ORU_RO1); + + ACK actual = oruRo1Receiver.receiveMsg(hl7Msg); + + ORU_R01 oruR01 = new ORU_R01(); + pipeParser.parse(oruR01, hl7Msg); + + assertEquals("^~\\&", actual.getMSH().getMsh2_EncodingCharacters().getValue()); + assertEquals("ACK", actual.getMSH().getMsh9_MessageType().getMsg1_MessageCode().getValue()); + assertEquals(oruR01.getMSH().getMsh9_MessageType().getMsg2_TriggerEvent().getValue(), + actual.getMSH().getMsh9_MessageType().getMsg2_TriggerEvent().getValue()); + assertEquals("ACK", actual.getMSH().getMsh9_MessageType().getMsg3_MessageStructure().getValue()); + assertNotNull(actual.getMSH().getMsh7_DateTimeOfMessage().getTime().getValue()); + assertNotNull(actual.getMSH().getMsh10_MessageControlID().getValue()); + // Result Status = Preliminary Result + assertEquals("P", actual.getMSH().getMsh11_ProcessingID().getProcessingID().getValue()); + assertEquals("2.5.1", actual.getMSH().getMsh12_VersionID().getVersionID().getValue()); + + // AA = Application Accept + assertEquals("AA", actual.getMSA().getMsa1_AcknowledgmentCode().getValue()); + assertEquals(oruR01.getMSH().getMsh10_MessageControlID().getValue(), + actual.getMSA().getMsa2_MessageControlID().getValue()); + } + + @Test + public void shouldParseOruRo1ErrorMessageAndReturnACK() throws IOException, HL7Exception, MessageCreationException { + String hl7Msg = HL7TestMsgUtil.readMsg(FINAL_RESULT_ERROR_ORU_RO1); + + ACK actual = oruRo1Receiver.receiveMsg(hl7Msg); + + ORU_R01 oruR01 = new ORU_R01(); + pipeParser.parse(oruR01, hl7Msg); + + assertEquals("^~\\&", actual.getMSH().getMsh2_EncodingCharacters().getValue()); + assertEquals("ACK", actual.getMSH().getMsh9_MessageType().getMsg1_MessageCode().getValue()); + assertEquals(oruR01.getMSH().getMsh9_MessageType().getMsg2_TriggerEvent().getValue(), + actual.getMSH().getMsh9_MessageType().getMsg2_TriggerEvent().getValue()); + assertEquals("ACK", actual.getMSH().getMsh9_MessageType().getMsg3_MessageStructure().getValue()); + assertNotNull(actual.getMSH().getMsh7_DateTimeOfMessage().getTime().getValue()); + assertNotNull(actual.getMSH().getMsh10_MessageControlID().getValue()); + // Result Status = Preliminary Result + assertEquals("P", actual.getMSH().getMsh11_ProcessingID().getProcessingID().getValue()); + assertEquals("2.5.1", actual.getMSH().getMsh12_VersionID().getVersionID().getValue()); + + assertEquals("AE", actual.getMSA().getMsa1_AcknowledgmentCode().getValue()); + assertEquals(oruR01.getMSH().getMsh10_MessageControlID().getValue(), + actual.getMSA().getMsa2_MessageControlID().getValue()); + + assertEquals("ORUR01.error.InvalidEncounter", + actual.getERR().getErrorCodeAndLocation(0).getCodeIdentifyingError().getAlternateText().getValue()); } - - @Test - public void shouldParseOruRo1ErrorMessageAndReturnACK() throws IOException, HL7Exception, MessageCreationException { - String hl7Msg = HL7TestMsgUtil.readMsg(FINAL_RESULT_ERROR_ORU_RO1); - - ACK actual = oruRo1Receiver.receiveMsg(hl7Msg); - - ORU_R01 oruR01 = new ORU_R01(); - pipeParser.parse(oruR01, hl7Msg); - - assertEquals("^~\\&", actual.getMSH().getMsh2_EncodingCharacters().getValue()); - assertEquals("ACK", - actual.getMSH().getMsh9_MessageType().getMsg1_MessageCode().getValue()); - assertEquals(oruR01.getMSH().getMsh9_MessageType().getMsg2_TriggerEvent().getValue(), - actual.getMSH().getMsh9_MessageType().getMsg2_TriggerEvent().getValue()); - assertEquals("ACK", - actual.getMSH().getMsh9_MessageType().getMsg3_MessageStructure().getValue()); - assertNotNull(actual.getMSH().getMsh7_DateTimeOfMessage().getTime().getValue()); - assertNotNull(actual.getMSH().getMsh10_MessageControlID().getValue()); - // Result Status = Preliminary Result - assertEquals("P", - actual.getMSH().getMsh11_ProcessingID().getProcessingID().getValue()); - assertEquals("2.5.1", - actual.getMSH().getMsh12_VersionID().getVersionID().getValue()); - - assertEquals("AE", actual.getMSA().getMsa1_AcknowledgmentCode().getValue()); - assertEquals(oruR01.getMSH().getMsh10_MessageControlID().getValue(), - actual.getMSA().getMsa2_MessageControlID().getValue()); - - assertEquals("ORUR01.error.InvalidEncounter", - actual.getERR().getErrorCodeAndLocation(0).getCodeIdentifyingError().getAlternateText().getValue()); - } } diff --git a/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/testdata/HL7TestOrder.java b/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/testdata/HL7TestOrder.java index e460a29..9e6ff02 100644 --- a/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/testdata/HL7TestOrder.java +++ b/api/src/test/java/org/openmrs/module/labintegration/api/communication/hl7/messages/testdata/HL7TestOrder.java @@ -30,11 +30,11 @@ public class HL7TestOrder { public static final String CONCEPT_CODE = "44871-2"; public static final int SCHEDULED_DATE_MONTH = 2; - + public static final int ACTIVATED_DATE_MONTH = 3; - + public static final int EFFECTIVE_START_DATE_MONTH = 4; - + private final Encounter encounter; public HL7TestOrder(Patient patient, Provider provider) { @@ -45,11 +45,11 @@ public HL7TestOrder(Patient patient, Provider provider) { private static Date getScheduledDate() { return getDefaultDate(SCHEDULED_DATE_MONTH); } - + private static Date getActivatedDate() { return getDefaultDate(ACTIVATED_DATE_MONTH); } - + private static Date getEffectiveStartDate() { return getDefaultDate(EFFECTIVE_START_DATE_MONTH); } @@ -74,19 +74,19 @@ private Encounter mockEncounter(Patient patient, Provider provider) { EncounterType encounterType = new EncounterType(ENC_TYPE_NAME, "description"); when(encounter.getEncounterType()).thenReturn(encounterType); - + when(encounter.getPatient()).thenReturn(patient); - + EncounterProvider encProvider = mock(EncounterProvider.class); when(encProvider.getProvider()).thenReturn(provider); when(encounter.getEncounterProviders()).thenReturn(new HashSet<>(singletonList(encProvider))); - + when(encounter.getEncounterDatetime()).thenReturn(getScheduledDate()); - + Location location = new Location(); location.setUuid("LOCATION-UUID"); when(encounter.getLocation()).thenReturn(location); - + return encounter; } @@ -102,24 +102,24 @@ private void mockConceptAndObs() { ConceptReferenceTerm otherTerm = new ConceptReferenceTerm(otherSource, "XXXX", "other name"); ConceptMap otherMapping = new ConceptMap(otherTerm, new ConceptMapType()); - + Concept topConcept = new Concept(); topConcept.setId(1271); - + Concept concept = new Concept(); concept.setUuid("63cbd0ac-7b4d-477a-910d-8e75168275bf"); concept.addConceptMapping(otherMapping); concept.addConceptMapping(loincMapping); concept.setId(657); - + Obs obs = mock(Obs.class); when(obs.getEncounter()).thenReturn(encounter); when(obs.getConcept()).thenReturn(topConcept); when(obs.getValueCoded()).thenReturn(concept); - + when(encounter.getObs()).thenReturn(new HashSet<>(singletonList(obs))); } - + public Encounter value() { return encounter; } diff --git a/api/src/test/java/org/openmrs/module/labintegration/api/hl7/handler/OruR01HandlerTest.java b/api/src/test/java/org/openmrs/module/labintegration/api/hl7/handler/OruR01HandlerTest.java index 81bd0b7..e0d51d1 100644 --- a/api/src/test/java/org/openmrs/module/labintegration/api/hl7/handler/OruR01HandlerTest.java +++ b/api/src/test/java/org/openmrs/module/labintegration/api/hl7/handler/OruR01HandlerTest.java @@ -11,38 +11,34 @@ import static org.openmrs.module.labintegration.api.hl7.messages.util.OruR01Util.*; public class OruR01HandlerTest extends AbstractOrderConverterTest { - + private static final String DATASET = "lab-dataset.xml"; - + @Test public void processMessage_shouldParseObsAndNotReturnNull() throws HL7Exception, ApplicationException { - - try{ + + try { executeDataSet(DATASET); - } catch (Exception e) { + } + catch (Exception e) { return; } - + String hl7Message = "MSH|^~\\&|SOFTLAB|||LNSP|20210910132219-0400||ORU^R01|00000110|P|2.5\n" - + "PID||1310932929^^^^MR|1310932929^^^^MR||RAMON^RAZOR||19751201[0000]|M||U|^1??RE L'ARBRE^ANSE ROUGE^ART|||||||^549c78dc-31da-11e8-acac-c3add5b19973\n" - + "PV1||R|13109||||13109^HFSC^PRESTATAIRE^^^^^^^^^^L||||||||||^^^^^^^^^^^^L|||||||||||||||||||||||||||20210903||||||07d33a40-f185-11eb-ae5f-0242ac120009^f037e97b-471e-4898-a07c-b8e169e0ddc4^Indétectable^054edae9-1660-39e7-9920-6c814ed2df43^549c78dc-31da-11e8-acac-c3add5b19973\n" - + "ORC|RE|1310998951|1|77030005|||^^^202109031040-0400^^R||202109031040|HISTC||13109^HFSC^PRESTATAIRE^^^^^^^^^^L|13109\n" - + "OBR|1|1310998951|1|f037e97b-471e-4898-a07c-b8e169e0ddc4|||202109031040|||HISTC|N|||202109031046||13109^HFSC^PRESTATAIRE^^^^^^^^^^L||||||202109031128-0400|||F||^^^202109031040-0400^^R|||||||MCN\n" - + "OBX|1|SN|25836-8^^LN^LCV1P^Copies / ml (CVi-1)^L|0|^999||||||F|||202109031128||MCN|||202109031128\n" - + "OBX|2|ST|25836-8^^LN^LPLOG^Log (Copies / ml)^L|1|1,0||||||F|||202109031128||MCN|||202109031128\n" - + "NTE|1||Indétectable\n" - + "NTE|2\n" - + "NTE|3\n" - + "NTE|4\n" - + "NTE|5||Commentaire: <1000 copies/ml; patient en suppression virale.\n" - + "NTE|6|| Limite de détection sur plasma <150 Copies/ml.\n" - + "NTE|7||.\n" - + "NTE|8"; + + "PID||1310932929^^^^MR|1310932929^^^^MR||RAMON^RAZOR||19751201[0000]|M||U|^1??RE L'ARBRE^ANSE ROUGE^ART|||||||^549c78dc-31da-11e8-acac-c3add5b19973\n" + + "PV1||R|13109||||13109^HFSC^PRESTATAIRE^^^^^^^^^^L||||||||||^^^^^^^^^^^^L|||||||||||||||||||||||||||20210903||||||07d33a40-f185-11eb-ae5f-0242ac120009^f037e97b-471e-4898-a07c-b8e169e0ddc4^Indétectable^054edae9-1660-39e7-9920-6c814ed2df43^549c78dc-31da-11e8-acac-c3add5b19973\n" + + "ORC|RE|1310998951|1|77030005|||^^^202109031040-0400^^R||202109031040|HISTC||13109^HFSC^PRESTATAIRE^^^^^^^^^^L|13109\n" + + "OBR|1|1310998951|1|f037e97b-471e-4898-a07c-b8e169e0ddc4|||202109031040|||HISTC|N|||202109031046||13109^HFSC^PRESTATAIRE^^^^^^^^^^L||||||202109031128-0400|||F||^^^202109031040-0400^^R|||||||MCN\n" + + "OBX|1|SN|25836-8^^LN^LCV1P^Copies / ml (CVi-1)^L|0|^999||||||F|||202109031128||MCN|||202109031128\n" + + "OBX|2|ST|25836-8^^LN^LPLOG^Log (Copies / ml)^L|1|1,0||||||F|||202109031128||MCN|||202109031128\n" + + "NTE|1||Indétectable\n" + "NTE|2\n" + "NTE|3\n" + "NTE|4\n" + + "NTE|5||Commentaire: <1000 copies/ml; patient en suppression virale.\n" + + "NTE|6|| Limite de détection sur plasma <150 Copies/ml.\n" + "NTE|7||.\n" + "NTE|8"; hl7Message = hl7Message.replaceFirst(ORUR01_ORU_R01, ORU_R01); hl7Message = hl7Message.replaceFirst(VERSION_251, VERSION_25); hl7Message = hl7Message.replace("\n", Character.toString((char) 13)); hl7Message = hl7Message.replaceAll("\\[[0-9]{4}\\]", ""); - + PipeParser pipeParser = new PipeParser(); Message message = null; message = pipeParser.parse(hl7Message); @@ -50,97 +46,94 @@ public void processMessage_shouldParseObsAndNotReturnNull() throws HL7Exception, Message message1 = oruR01Handler.processMessage(message); assertNotNull(message); } - + @Test public void processMessage_shouldProcessMessageToObs() throws Exception { executeDataSet(DATASET); - - String hl7Message = "MSH|^~\\&|||||20241216090516-0500||ORU^R01|00000000|P|2.5\n" + - "PID||33118500^^^^MR^112123|33118500^^^^MR^112123||WASHINGTONN^GLENN||20000601|M||U|^4èME LA MONTAGNE^JEAN RABEL^NRO|||||||^7a732da7-f3a8-40fe-b9eb-c8a058de9497\n" + - "PV1||R|11223||||11223^OPAP^PRESTATAIRE^^^^^^^^^^L||||||||||^^^^^^^^^^^^L|||||||||||||||||||||||||||20241216||||||290fb4d0-2ae6-40bd-a058-436acea3d881^f037e97b-471e-4898-a07c-b8e169e0ddc4^^b181ab58-e4fb-4b47-bc69-f0c05dd473cd^7a732da7-f3a8-40fe-b9eb-c8a058de9497\n" + - "ORC|RE|11223-53-440|1|C8160001|||^^^202412160558-0500^^R||202412160558|HISTC||11223^OPAP^PRESTATAIRE^^^^^^^^^^L|11223\n" + - "OBR|1|11223-53-440|1|f037e97b-471e-4898-a07c-b8e169e0ddc4|||202412160558|||HISTC|N|||202412160600||11223^OPAP^PRESTATAIRE^^^^^^^^^^L||||||202412160905-0500|||F||^^^202412160558-0500^^R|||||||DIG\n" + - "OBX|1|CE|44871-2^^LN^LVH2P^ADN VIH-1, PCR-2^L|0|Détecté|||*|||F|||202412160601||DIG|||202412160905"; + + String hl7Message = "MSH|^~\\&|||||20241216090516-0500||ORU^R01|00000000|P|2.5\n" + + "PID||33118500^^^^MR^112123|33118500^^^^MR^112123||WASHINGTONN^GLENN||20000601|M||U|^4èME LA MONTAGNE^JEAN RABEL^NRO|||||||^7a732da7-f3a8-40fe-b9eb-c8a058de9497\n" + + "PV1||R|11223||||11223^OPAP^PRESTATAIRE^^^^^^^^^^L||||||||||^^^^^^^^^^^^L|||||||||||||||||||||||||||20241216||||||290fb4d0-2ae6-40bd-a058-436acea3d881^f037e97b-471e-4898-a07c-b8e169e0ddc4^^b181ab58-e4fb-4b47-bc69-f0c05dd473cd^7a732da7-f3a8-40fe-b9eb-c8a058de9497\n" + + "ORC|RE|11223-53-440|1|C8160001|||^^^202412160558-0500^^R||202412160558|HISTC||11223^OPAP^PRESTATAIRE^^^^^^^^^^L|11223\n" + + "OBR|1|11223-53-440|1|f037e97b-471e-4898-a07c-b8e169e0ddc4|||202412160558|||HISTC|N|||202412160600||11223^OPAP^PRESTATAIRE^^^^^^^^^^L||||||202412160905-0500|||F||^^^202412160558-0500^^R|||||||DIG\n" + + "OBX|1|CE|44871-2^^LN^LVH2P^ADN VIH-1, PCR-2^L|0|Détecté|||*|||F|||202412160601||DIG|||202412160905"; hl7Message = hl7Message.replaceFirst(ORUR01_ORU_R01, ORU_R01); hl7Message = hl7Message.replaceFirst(VERSION_251, VERSION_25); hl7Message = hl7Message.replace("\n", Character.toString((char) 13)); hl7Message = hl7Message.replaceAll("\\[[0-9]{4}\\]", ""); - + Message message = new PipeParser().parse(hl7Message); OruR01Handler oruR01Handler = new OruR01Handler(); - + Message ack = oruR01Handler.processMessage(message); } - + @Test public void processMessage_shouldProcessMessageToObsWithMinimalValue() throws Exception { executeDataSet(DATASET); - - String hl7Message = "MSH|^~\\&|||||20250110110400-0500||ORU^R01|00000076|P|2.5\n" + - "PID||b890^^^^MR^111600|b890^^^^MR^111600||IMELDA^ENGRID||20061107|F||U|^7èME MORNE L'HOPITAL^PORT-AU-PRINCE^OST|||||||^a26244c2-2319-41d2-b315-87a7d0e39191\n" + - "PV1||R|11100||||11100^HUEH^PRESTATAIRE^^^^^^^^^^L||||||||||^^^^^^^^^^^^L|||||||||||||||||||||||||||20250107||||||b0843976-2f60-4a2a-a7bd-12030531ed82^f037e97b-471e-4898-a07c-b8e169e0ddc4^Indétectable^03a89ca6-0717-455b-a30d-3f55be5b55dd^a26244c2-2319-41d2-b315-87a7d0e39191\n" + - "ORC|RE|11100-121-830|1|C9070041|||^^^202501072042-0500^^R||202501072042|HISTC||11100^HUEH^PRESTATAIRE^^^^^^^^^^L|11100\n" + - "OBR|1|11100-121-830|1|f037e97b-471e-4898-a07c-b8e169e0ddc4|||202501072042|||HISTC|N|||202501101044||11100^HUEH^PRESTATAIRE^^^^^^^^^^L||||||202501101103-0500|||F||^^^202501072042-0500^^R|||||||JSF\n" + - "OBX|1|ST|25836-8^^LN^LBCVA^Copies / ml (CVau)^L|0|voir ci-dessous||||||F|||202501101103||JSF|||202501101103\n" + - "NTE|1||Indétectable\n" + - "OBX|2|ST|25836-8^^LN^LBLOG^Log (Copies / ml)^L|1|voir ci-dessous||||||F|||202501101103||JSF|||202501101103\n" + - "NTE|1||Indétectable\n" + - "NTE|2\n" + - "NTE|3\n" + - "NTE|4\n" + - "NTE|5||Commentaire: <1000 copies/ml; patient en suppression virale.\n" + - "NTE|6|| Limite de détection du test sur DBS <839 copies/ml."; + + String hl7Message = "MSH|^~\\&|||||20250110110400-0500||ORU^R01|00000076|P|2.5\n" + + "PID||b890^^^^MR^111600|b890^^^^MR^111600||IMELDA^ENGRID||20061107|F||U|^7èME MORNE L'HOPITAL^PORT-AU-PRINCE^OST|||||||^a26244c2-2319-41d2-b315-87a7d0e39191\n" + + "PV1||R|11100||||11100^HUEH^PRESTATAIRE^^^^^^^^^^L||||||||||^^^^^^^^^^^^L|||||||||||||||||||||||||||20250107||||||b0843976-2f60-4a2a-a7bd-12030531ed82^f037e97b-471e-4898-a07c-b8e169e0ddc4^Indétectable^03a89ca6-0717-455b-a30d-3f55be5b55dd^a26244c2-2319-41d2-b315-87a7d0e39191\n" + + "ORC|RE|11100-121-830|1|C9070041|||^^^202501072042-0500^^R||202501072042|HISTC||11100^HUEH^PRESTATAIRE^^^^^^^^^^L|11100\n" + + "OBR|1|11100-121-830|1|f037e97b-471e-4898-a07c-b8e169e0ddc4|||202501072042|||HISTC|N|||202501101044||11100^HUEH^PRESTATAIRE^^^^^^^^^^L||||||202501101103-0500|||F||^^^202501072042-0500^^R|||||||JSF\n" + + "OBX|1|ST|25836-8^^LN^LBCVA^Copies / ml (CVau)^L|0|voir ci-dessous||||||F|||202501101103||JSF|||202501101103\n" + + "NTE|1||Indétectable\n" + + "OBX|2|ST|25836-8^^LN^LBLOG^Log (Copies / ml)^L|1|voir ci-dessous||||||F|||202501101103||JSF|||202501101103\n" + + "NTE|1||Indétectable\n" + "NTE|2\n" + "NTE|3\n" + "NTE|4\n" + + "NTE|5||Commentaire: <1000 copies/ml; patient en suppression virale.\n" + + "NTE|6|| Limite de détection du test sur DBS <839 copies/ml."; hl7Message = hl7Message.replaceFirst(ORUR01_ORU_R01, ORU_R01); hl7Message = hl7Message.replaceFirst(VERSION_251, VERSION_25); hl7Message = hl7Message.replace("\n", Character.toString((char) 13)); hl7Message = hl7Message.replaceAll("\\[[0-9]{4}\\]", ""); - + Message message = new PipeParser().parse(hl7Message); OruR01Handler oruR01Handler = new OruR01Handler(); - + Message ack = oruR01Handler.processMessage(message); } - + @Test public void processMessage_shouldProcessMessageToSkipObsForCancelledOrders() throws Exception { executeDataSet(DATASET); - - String hl7Message = "MSH|^~\\&|||||20250124005347-0500||ORU^R01|00000019|P|2.5\n" + - "PID||111001992^^^^MR^111600|111001992^^^^MR^111600||ASIMOV^ISAAC||20241217|M||U|^1èRE SANS SOUCI^MOMBIN CROCHU^NRE|||||||^4e7067cf-e964-46af-9fa6-e15858d3c0fc\n" + - "PV1||R|11100||||11100^HUEH^PRESTATAIRE^^^^^^^^^^L||||||||||^^^^^^^^^^^^L|||||||||||||||||||||||||||20250123||||||ecad04c3-dcef-4d5d-9075-ddaccab15d08^f037e97b-471e-4898-a07c-b8e169e0ddc4^^03a89ca6-0717-455b-a30d-3f55be5b55dd^4e7067cf-e964-46af-9fa6-e15858d3c0fc\n" + - "ORC|RE|11100-224-1988|1|C9230000|||^^^202501230924-0500^^R||202501230924|HISTC||11100^HUEH^PRESTATAIRE^^^^^^^^^^L|11100\n" + - "OBR|1|11100-224-1988|1|f037e97b-471e-4898-a07c-b8e169e0ddc4|||202501230924|||HISTC|N|||202501240043||11100^HUEH^PRESTATAIRE^^^^^^^^^^L||||||202501240053-0500|||F||^^^202501230924-0500^^R|||||||JSF\n" + - "OBX|1|ST|25836-8^^LN^LBCVR^Copies / ml (CVr)^L|0|Annulé Lab||||||F|||202501240051||JSF|||202501240053\n" + - "OBX|2|ST|25836-8^^LN^LBLOG^Log (Copies / ml)^L|1|Annulé Lab||||||F|||202501240051||JSF|||202501240053"; + + String hl7Message = "MSH|^~\\&|||||20250124005347-0500||ORU^R01|00000019|P|2.5\n" + + "PID||111001992^^^^MR^111600|111001992^^^^MR^111600||ASIMOV^ISAAC||20241217|M||U|^1èRE SANS SOUCI^MOMBIN CROCHU^NRE|||||||^4e7067cf-e964-46af-9fa6-e15858d3c0fc\n" + + "PV1||R|11100||||11100^HUEH^PRESTATAIRE^^^^^^^^^^L||||||||||^^^^^^^^^^^^L|||||||||||||||||||||||||||20250123||||||ecad04c3-dcef-4d5d-9075-ddaccab15d08^f037e97b-471e-4898-a07c-b8e169e0ddc4^^03a89ca6-0717-455b-a30d-3f55be5b55dd^4e7067cf-e964-46af-9fa6-e15858d3c0fc\n" + + "ORC|RE|11100-224-1988|1|C9230000|||^^^202501230924-0500^^R||202501230924|HISTC||11100^HUEH^PRESTATAIRE^^^^^^^^^^L|11100\n" + + "OBR|1|11100-224-1988|1|f037e97b-471e-4898-a07c-b8e169e0ddc4|||202501230924|||HISTC|N|||202501240043||11100^HUEH^PRESTATAIRE^^^^^^^^^^L||||||202501240053-0500|||F||^^^202501230924-0500^^R|||||||JSF\n" + + "OBX|1|ST|25836-8^^LN^LBCVR^Copies / ml (CVr)^L|0|Annulé Lab||||||F|||202501240051||JSF|||202501240053\n" + + "OBX|2|ST|25836-8^^LN^LBLOG^Log (Copies / ml)^L|1|Annulé Lab||||||F|||202501240051||JSF|||202501240053"; hl7Message = hl7Message.replaceFirst(ORUR01_ORU_R01, ORU_R01); hl7Message = hl7Message.replaceFirst(VERSION_251, VERSION_25); hl7Message = hl7Message.replace("\n", Character.toString((char) 13)); hl7Message = hl7Message.replaceAll("\\[[0-9]{4}\\]", ""); - + Message message = new PipeParser().parse(hl7Message); OruR01Handler oruR01Handler = new OruR01Handler(); - + Message ack = oruR01Handler.processMessage(message); } - + @Test public void processMessage_shouldProcessMessageToSkipObsForCancelledCodedOrders() throws Exception { executeDataSet(DATASET); - - String hl7Message = "MSH|^~\\&|||||20250124011234-0500||ORU^R01|00000051|P|2.5\n" + - "PID||131091227^^^^MR^131109|131091227^^^^MR^131109||BOA^VAL||20241116|M||U|^2èME VARREUX^CROIX-DES-BOUQUETS^OST|||||||^d65fc63e-9c0f-4c6c-b870-5d29410faeb9\n" + - "PV1||R|13109||||13109^HFSC^PRESTATAIRE^^^^^^^^^^L||||||||||^^^^^^^^^^^^L|||||||||||||||||||||||||||20250122||||||50c79a2d-e627-49ff-81a0-c3854a22b989^f037e97b-471e-4898-a07c-b8e169e0ddc4^^56684e1c-b23f-4269-8fb3-4dd80018a5e5^d65fc63e-9c0f-4c6c-b870-5d29410faeb9\n" + - "ORC|RE|13109-309-2776|1|C9220024|||^^^202501221301-0500^^R||202501221301|HISTC||13109^HFSC^PRESTATAIRE^^^^^^^^^^L|13109\n" + - "OBR|1|13109-309-2776|1|f037e97b-471e-4898-a07c-b8e169e0ddc4|||202501221301|||HISTC|N|||202501240105||13109^HFSC^PRESTATAIRE^^^^^^^^^^L||||||202501240112-0500|||F||^^^202501221301-0500^^R|||||||JSF\n" + - "OBX|1|CE|44871-2^^LN^LVHCD^ADN VIH-1, PCR-C^L|0|Annulé Lab||||||F|||202501240112||JSF|||202501240112"; + + String hl7Message = "MSH|^~\\&|||||20250124011234-0500||ORU^R01|00000051|P|2.5\n" + + "PID||131091227^^^^MR^131109|131091227^^^^MR^131109||BOA^VAL||20241116|M||U|^2èME VARREUX^CROIX-DES-BOUQUETS^OST|||||||^d65fc63e-9c0f-4c6c-b870-5d29410faeb9\n" + + "PV1||R|13109||||13109^HFSC^PRESTATAIRE^^^^^^^^^^L||||||||||^^^^^^^^^^^^L|||||||||||||||||||||||||||20250122||||||50c79a2d-e627-49ff-81a0-c3854a22b989^f037e97b-471e-4898-a07c-b8e169e0ddc4^^56684e1c-b23f-4269-8fb3-4dd80018a5e5^d65fc63e-9c0f-4c6c-b870-5d29410faeb9\n" + + "ORC|RE|13109-309-2776|1|C9220024|||^^^202501221301-0500^^R||202501221301|HISTC||13109^HFSC^PRESTATAIRE^^^^^^^^^^L|13109\n" + + "OBR|1|13109-309-2776|1|f037e97b-471e-4898-a07c-b8e169e0ddc4|||202501221301|||HISTC|N|||202501240105||13109^HFSC^PRESTATAIRE^^^^^^^^^^L||||||202501240112-0500|||F||^^^202501221301-0500^^R|||||||JSF\n" + + "OBX|1|CE|44871-2^^LN^LVHCD^ADN VIH-1, PCR-C^L|0|Annulé Lab||||||F|||202501240112||JSF|||202501240112"; hl7Message = hl7Message.replaceFirst(ORUR01_ORU_R01, ORU_R01); hl7Message = hl7Message.replaceFirst(VERSION_251, VERSION_25); hl7Message = hl7Message.replace("\n", Character.toString((char) 13)); hl7Message = hl7Message.replaceAll("\\[[0-9]{4}\\]", ""); - + Message message = new PipeParser().parse(hl7Message); OruR01Handler oruR01Handler = new OruR01Handler(); - + Message ack = oruR01Handler.processMessage(message); } } diff --git a/omod/pom.xml b/omod/pom.xml index 1ac2a71..e3aac9d 100644 --- a/omod/pom.xml +++ b/omod/pom.xml @@ -14,9 +14,9 @@ - org.openmrs.module - labintegration-api - ${parent.version} + ${project.parent.groupId} + ${project.parent.artifactId}-api + ${project.parent.version} org.openmrs.web @@ -29,6 +29,11 @@ provided tests + + org.openmrs.module + reporting-api + provided + @@ -65,10 +70,10 @@ target/${project.parent.artifactId}-${project.version}.omod github-packages omod + ${project.parent.groupId} false ${project.parent.artifactId} ${project.version} - ${groupId} diff --git a/omod/src/main/java/org/openmrs/module/labintegration/web/OruR01MessageController.java b/omod/src/main/java/org/openmrs/module/labintegration/web/OruR01MessageController.java index dd99ebf..dbb0318 100644 --- a/omod/src/main/java/org/openmrs/module/labintegration/web/OruR01MessageController.java +++ b/omod/src/main/java/org/openmrs/module/labintegration/web/OruR01MessageController.java @@ -14,12 +14,13 @@ @Controller @RequestMapping(value = "api/message/orders/results") public class OruR01MessageController { - + @Autowired private OruRo1Receiver receiver; - + @RequestMapping(method = RequestMethod.GET) - @ResponseBody public String parseOruR01Message(@RequestBody String msg) throws MessageCreationException, HL7Exception { + @ResponseBody + public String parseOruR01Message(@RequestBody String msg) throws MessageCreationException, HL7Exception { ACK ack = receiver.receiveMsg(msg); return ack.encode(); } diff --git a/omod/src/main/java/org/openmrs/module/labintegration/web/ResultServlet.java b/omod/src/main/java/org/openmrs/module/labintegration/web/ResultServlet.java index f6073e1..1be121e 100644 --- a/omod/src/main/java/org/openmrs/module/labintegration/web/ResultServlet.java +++ b/omod/src/main/java/org/openmrs/module/labintegration/web/ResultServlet.java @@ -17,61 +17,63 @@ import java.io.IOException; public class ResultServlet extends HttpServlet { - - private static final long serialVersionUID = -236230490819244022L; - - private static final Logger LOGGER = LoggerFactory.getLogger(ResultServlet.class); - - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { - if (!allowMsg(req)) { - resp.sendError(HttpServletResponse.SC_FORBIDDEN, req.getRemoteAddr() - + " is not allowed to send inbound messages"); - return; - } - - OruRo1Receiver receiver = Context.getRegisteredComponent("OruRO1Receiver", OruRo1Receiver.class); - - String msg = IOUtils.toString(req.getInputStream()); - - try { - addProxyPermissions(); - - ACK ack = receiver.receiveMsg(msg); - String ackMsg = ack.encode(); - - resp.setStatus(HttpServletResponse.SC_OK); - resp.setContentType("application/hl7-v2"); - resp.setContentLength(ackMsg.length()); - resp.getWriter().write(ackMsg); - - } catch (MessageCreationException e) { - LOGGER.error("Unable to create an HL7v2 message", e); - resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); - } catch (HL7Exception e) { - LOGGER.error("HL7 Error", e); - resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage()); - } - } - - private void addProxyPermissions() { - Context.addProxyPrivilege("Get Encounters"); - Context.addProxyPrivilege("Get Concepts"); - Context.addProxyPrivilege("Get Users"); - Context.addProxyPrivilege("Manage Alerts"); - Context.addProxyPrivilege("Edit Encounters"); - Context.addProxyPrivilege("Add Encounters"); - Context.addProxyPrivilege("Get Locations"); - Context.addProxyPrivilege("Edit Observations"); - Context.addProxyPrivilege("Add Observations"); - Context.addProxyPrivilege("Get Observations"); - } - - private boolean allowMsg(HttpServletRequest req) { - OpenElisHL7Config config = Context.getRegisteredComponent("OpenElisHL7Config", OpenElisHL7Config.class); - - String expectedHost = config.getOpenelisInboundHost(); - - return StringUtils.equals(req.getRemoteAddr(), expectedHost); - } + + private static final long serialVersionUID = -236230490819244022L; + + private static final Logger LOGGER = LoggerFactory.getLogger(ResultServlet.class); + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { + if (!allowMsg(req)) { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, + req.getRemoteAddr() + " is not allowed to send inbound messages"); + return; + } + + OruRo1Receiver receiver = Context.getRegisteredComponent("OruRO1Receiver", OruRo1Receiver.class); + + String msg = IOUtils.toString(req.getInputStream()); + + try { + addProxyPermissions(); + + ACK ack = receiver.receiveMsg(msg); + String ackMsg = ack.encode(); + + resp.setStatus(HttpServletResponse.SC_OK); + resp.setContentType("application/hl7-v2"); + resp.setContentLength(ackMsg.length()); + resp.getWriter().write(ackMsg); + + } + catch (MessageCreationException e) { + LOGGER.error("Unable to create an HL7v2 message", e); + resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + } + catch (HL7Exception e) { + LOGGER.error("HL7 Error", e); + resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage()); + } + } + + private void addProxyPermissions() { + Context.addProxyPrivilege("Get Encounters"); + Context.addProxyPrivilege("Get Concepts"); + Context.addProxyPrivilege("Get Users"); + Context.addProxyPrivilege("Manage Alerts"); + Context.addProxyPrivilege("Edit Encounters"); + Context.addProxyPrivilege("Add Encounters"); + Context.addProxyPrivilege("Get Locations"); + Context.addProxyPrivilege("Edit Observations"); + Context.addProxyPrivilege("Add Observations"); + Context.addProxyPrivilege("Get Observations"); + } + + private boolean allowMsg(HttpServletRequest req) { + OpenElisHL7Config config = Context.getRegisteredComponent("OpenElisHL7Config", OpenElisHL7Config.class); + + String expectedHost = config.getOpenelisInboundHost(); + + return StringUtils.equals(req.getRemoteAddr(), expectedHost); + } } diff --git a/omod/src/main/resources/apps/lnspreports_extension.json b/omod/src/main/resources/apps/lnspreports_extension.json new file mode 100644 index 0000000..df594f9 --- /dev/null +++ b/omod/src/main/resources/apps/lnspreports_extension.json @@ -0,0 +1,11 @@ +[ + { + "id" : "${project.parent.artifactId}.lnsp-report", + "extensionPointId": "org.openmrs.module.reportingui.reports.overview", + "type" : "link", + "label" : "labintegration.results.report.name", + "url": "reportingui/runReport.page?reportDefinition=100db747-d65d-46d4-96dc-7e66fb672ab2", + "order" : 300, + "requiredPrivilege": "App: reportingui.reports" + } +] \ No newline at end of file diff --git a/omod/src/main/resources/config.xml b/omod/src/main/resources/config.xml index c2e2622..965fac3 100644 --- a/omod/src/main/resources/config.xml +++ b/omod/src/main/resources/config.xml @@ -27,8 +27,21 @@ org.openmrs.module.legacyui + org.openmrs.module.reporting + + + /lib/labintegration-api-reporting-${project.parent.version}.jar + + + org.openmrs.module.reporting + ${reportingVersion} + + + + +