diff --git a/analyzers/pocH-100i/.vscode/settings.json b/analyzers/pocH-100i/.vscode/settings.json
new file mode 100644
index 0000000..890c247
--- /dev/null
+++ b/analyzers/pocH-100i/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+ "java.project.sourcePaths": [
+ "src/main/java"
+ ]
+}
\ No newline at end of file
diff --git a/analyzers/pocH-100i/pom.xml b/analyzers/pocH-100i/pom.xml
new file mode 100644
index 0000000..af30aac
--- /dev/null
+++ b/analyzers/pocH-100i/pom.xml
@@ -0,0 +1,89 @@
+
+ 4.0.0
+ org.openelisglobal.plugins
+ pocH-100iAnalyzer
+
+ org.openelisglobal
+ openelisglobal-plugins
+ 1.0
+ ../../pom.xml
+
+
+ 0.1
+
+ UTF-8
+ 2.3
+
+
+
+
+ javax.servlet
+ javax.servlet-api
+ 4.0.1
+ provided
+
+
+ commons-fileupload
+ commons-fileupload
+ 1.4
+
+
+ org.springframework
+ spring-webmvc
+ ${springframework.version}
+
+
+
+
+ src/main/java
+
+
+ src/main/filtered-resources
+ true
+
+
+ src/main/resources
+
+
+
+
+ maven-compiler-plugin
+ 3.8.0
+
+
+ 1.8
+
+
+
+ maven-resources-plugin
+ 2.4.3
+
+
+ copy-resources
+
+ install
+
+ copy-resources
+
+
+ ${project.basedir}/../../plugins
+
+
+
+ target/
+
+ ${project.build.finalName}.jar
+
+
+ false
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/analyzers/pocH-100i/src/main/java/oe/plugin/analyzer/PocH100iAnalyzer.java b/analyzers/pocH-100i/src/main/java/oe/plugin/analyzer/PocH100iAnalyzer.java
new file mode 100644
index 0000000..88d1658
--- /dev/null
+++ b/analyzers/pocH-100i/src/main/java/oe/plugin/analyzer/PocH100iAnalyzer.java
@@ -0,0 +1,167 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific language governing rights and limitations under
+ * the License.
+ *
+ * The Original Code is OpenELIS code.
+ *
+ * Copyright (C) ITECH, University of Washington, Seattle WA. All Rights Reserved.
+ */
+
+package oe.plugin.analyzer;
+
+import static org.openelisglobal.common.services.PluginAnalyzerService.getInstance;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerLineInserter;
+import org.openelisglobal.common.services.PluginAnalyzerService;
+import org.openelisglobal.plugin.AnalyzerImporterPlugin;
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerResponder;
+import org.openelisglobal.common.log.LogEvent;
+
+public class PocH100iAnalyzer implements AnalyzerImporterPlugin {
+
+ public static final String ANALYZER_NAME = "PocH100iAnalyzer";
+
+ @Override
+ public boolean connect() {
+ List nameMapping = new ArrayList<>();
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_WBC, "White Blood Cells Count (WBC)",
+ PocH100iAnalyzerImplementation.LOINC_WBC));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_RBC, "Red Blood Cells Count (RBC)",
+ PocH100iAnalyzerImplementation.LOINC_RBC));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_HGB, "Hemoglobin",
+ PocH100iAnalyzerImplementation.LOINC_HGB));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_HCT, "Hematocrit",
+ PocH100iAnalyzerImplementation.LOINC_HCT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_MCV, "Medium corpuscular volum",
+ PocH100iAnalyzerImplementation.LOINC_MCV));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_MCH, "",
+ PocH100iAnalyzerImplementation.LOINC_MCH));
+ nameMapping
+ .add(new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_MCHC, "",
+ PocH100iAnalyzerImplementation.LOINC_MCHC));
+ nameMapping
+ .add(new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_RDWSD, "",
+ PocH100iAnalyzerImplementation.LOINC_RDWSD));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_RDWCV, "",
+ PocH100iAnalyzerImplementation.LOINC_RDWCV));
+ nameMapping
+ .add(new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_PLT, "Platelets",
+ PocH100iAnalyzerImplementation.LOINC_PLT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_MPV, "",
+ PocH100iAnalyzerImplementation.LOINC_MPV));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_NEUT_COUNT, "Neutrophiles",
+ PocH100iAnalyzerImplementation.LOINC_NEUT_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_NEUT_PERCENT, "Neutrophiles (%)",
+ PocH100iAnalyzerImplementation.LOINC_NEUT_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_LYMPH_COUNT, "Lymphocytes (Abs)",
+ PocH100iAnalyzerImplementation.LOINC_LYMPH_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_LYMPH_PERCENT, "Lymphocytes (%)",
+ PocH100iAnalyzerImplementation.LOINC_LYMPH_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_MONO_COUNT, "Monocytes (Abs)",
+ PocH100iAnalyzerImplementation.LOINC_MONO_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_MONO_PERCENT, "Monocytes (%)",
+ PocH100iAnalyzerImplementation.LOINC_MONO_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_EO_COUNT, "Eosinophiles",
+ PocH100iAnalyzerImplementation.LOINC_EO_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_EO_PERCENT, "Eosinophiles (%)",
+ PocH100iAnalyzerImplementation.LOINC_EO_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_BASO_COUNT, "Basophiles",
+ PocH100iAnalyzerImplementation.LOINC_BASO_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_BASO_PERCENT, "Basophiles (%)",
+ PocH100iAnalyzerImplementation.LOINC_BASO_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_IG_COUNT, "",
+ PocH100iAnalyzerImplementation.LOINC_IG_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_IG_PERCENT, "",
+ PocH100iAnalyzerImplementation.LOINC_IG_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_MXD_COUNT, "",
+ PocH100iAnalyzerImplementation.LOINC_MXD_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_MXD_PERCENT, "",
+ PocH100iAnalyzerImplementation.LOINC_MXD_PERCENT));
+ getInstance().addAnalyzerDatabaseParts(ANALYZER_NAME, ANALYZER_NAME, nameMapping, true);
+ getInstance().registerAnalyzer(this);
+ return true;
+ }
+
+ @Override
+ public boolean isTargetAnalyzer(List lines) {
+ for (String line : lines) {
+ if (line.startsWith(PocH100iAnalyzerImplementation.HEADER_RECORD_IDENTIFIER)) {
+ String[] headerRecord = line.split(Pattern.quote(PocH100iAnalyzerImplementation.FD));
+ if (headerRecord.length < 5) {
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is not PocH100i: header record not long enough");
+ return false;
+ }
+ String[] senderNameFields = headerRecord[4].split(Pattern.quote(PocH100iAnalyzerImplementation.CD));
+ if (senderNameFields.length < 1) {
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is not PocH100i: sender name field not long enough");
+ return false;
+ }
+ String senderName = senderNameFields[0].trim();
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message analyzer name is " + senderName);
+ if (senderName.equalsIgnoreCase("pocH-100i")) {
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is PocH100i");
+ return true;
+ }
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is not PocH100i: sender name doesn't match");
+ return false;
+ }
+ }
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is not PocH100i: no header line");
+ return false;
+ }
+
+ @Override
+ public boolean isAnalyzerResult(List lines) {
+ for (String line : lines) {
+ if (line.startsWith(PocH100iAnalyzerImplementation.RESULT_RECORD_IDENTIFIER)) {
+ return true;
+ }
+ }
+ LogEvent.logDebug(this.getClass().getSimpleName(), "isAnalyzerResult", "no result recoord identifier located");
+ return false;
+ }
+
+ @Override
+ public AnalyzerLineInserter getAnalyzerLineInserter() {
+ return new PocH100iAnalyzerImplementation();
+ }
+
+ @Override
+ public AnalyzerResponder getAnalyzerResponder() {
+ return new PocH100iAnalyzerImplementation();
+ }
+
+}
diff --git a/analyzers/pocH-100i/src/main/java/oe/plugin/analyzer/PocH100iAnalyzerImplementation.java b/analyzers/pocH-100i/src/main/java/oe/plugin/analyzer/PocH100iAnalyzerImplementation.java
new file mode 100644
index 0000000..f5427af
--- /dev/null
+++ b/analyzers/pocH-100i/src/main/java/oe/plugin/analyzer/PocH100iAnalyzerImplementation.java
@@ -0,0 +1,441 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific language governing rights and limitations under
+ * the License.
+ *
+ * The Original Code is OpenELIS code.
+ *
+ * Copyright (C) ITECH, University of Washington, Seattle WA. All Rights Reserved.
+ */
+
+package oe.plugin.analyzer;
+
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Pattern;
+import java.util.Optional;
+
+import org.apache.commons.validator.GenericValidator;
+import org.openelisglobal.analyzer.service.AnalyzerService;
+import org.openelisglobal.analyzer.valueholder.Analyzer;
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerLineInserter;
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerReaderUtil;
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerResponder;
+import org.openelisglobal.analyzerimport.util.AnalyzerTestNameCache;
+import org.openelisglobal.analyzerimport.util.MappedTestName;
+import org.openelisglobal.analyzerresults.valueholder.AnalyzerResults;
+import org.openelisglobal.common.services.PluginAnalyzerService;
+import org.openelisglobal.spring.util.SpringContext;
+import org.openelisglobal.test.service.TestService;
+import org.openelisglobal.sample.service.SampleService;
+import org.openelisglobal.samplehuman.service.SampleHumanService;
+import org.openelisglobal.analysis.service.AnalysisService;
+import org.openelisglobal.test.valueholder.Test;
+import org.openelisglobal.analysis.valueholder.Analysis;
+import org.openelisglobal.person.valueholder.Person;
+import org.openelisglobal.patient.valueholder.Patient;
+import org.openelisglobal.sample.valueholder.Sample;
+import org.openelisglobal.common.util.DateUtil;
+import org.openelisglobal.common.log.LogEvent;
+
+public class PocH100iAnalyzerImplementation extends AnalyzerLineInserter implements AnalyzerResponder {
+
+ static final String ANALYZER_TEST_WBC = "WBC";
+ static final String ANALYZER_TEST_RBC = "RBC";
+ static final String ANALYZER_TEST_HGB = "HGB";
+ static final String ANALYZER_TEST_HCT = "HCT";
+ static final String ANALYZER_TEST_MCV = "MCV";
+ static final String ANALYZER_TEST_MCH = "MCH";
+ static final String ANALYZER_TEST_MCHC = "MCHC";
+ static final String ANALYZER_TEST_RDWSD = "RDW-SD";
+ static final String ANALYZER_TEST_RDWCV = "RDW-CV";
+ static final String ANALYZER_TEST_PLT = "PLT";
+ static final String ANALYZER_TEST_MPV = "MPV";
+ static final String ANALYZER_TEST_NEUT_COUNT = "NEUT#";
+ static final String ANALYZER_TEST_NEUT_PERCENT = "NEUT%";
+ static final String ANALYZER_TEST_LYMPH_COUNT = "LYMPH#";
+ static final String ANALYZER_TEST_LYMPH_PERCENT = "LYMPH%";
+ static final String ANALYZER_TEST_MONO_COUNT = "MONO#";
+ static final String ANALYZER_TEST_MONO_PERCENT = "MONO%";
+ static final String ANALYZER_TEST_EO_COUNT = "EO#";
+ static final String ANALYZER_TEST_EO_PERCENT = "EO%";
+ static final String ANALYZER_TEST_BASO_COUNT = "BASO#";
+ static final String ANALYZER_TEST_BASO_PERCENT = "BASO%";
+ static final String ANALYZER_TEST_IG_COUNT = "IG#";
+ static final String ANALYZER_TEST_IG_PERCENT = "IG%";
+ static final String ANALYZER_TEST_MXD_COUNT = "MXD#";
+ static final String ANALYZER_TEST_MXD_PERCENT = "MXD%";
+
+ static final String LOINC_WBC = "6690-2";
+ static final String LOINC_RBC = "789-8";
+ static final String LOINC_HGB = "718-7";
+ static final String LOINC_HCT = "4544-3";
+ static final String LOINC_MCV = "787-2";
+ static final String LOINC_MCH = "785-6";
+ static final String LOINC_MCHC = "786-4";
+ static final String LOINC_RDWSD = "21000-5";
+ static final String LOINC_RDWCV = "788-0";
+ static final String LOINC_PLT = "777-3";
+ static final String LOINC_MPV = "32623-1";
+ static final String LOINC_NEUT_COUNT = "751-8";
+ static final String LOINC_NEUT_PERCENT = "770-8";
+ static final String LOINC_LYMPH_COUNT = "731-0";;
+ static final String LOINC_LYMPH_PERCENT = "736-9";
+ static final String LOINC_MONO_COUNT = "742-7";
+ static final String LOINC_MONO_PERCENT = "5905-5";
+ static final String LOINC_EO_COUNT = "711-2";
+ static final String LOINC_EO_PERCENT = "713-8";
+ static final String LOINC_BASO_COUNT = "704-7";
+ static final String LOINC_BASO_PERCENT = "706-2";
+ static final String LOINC_IG_COUNT = "53115-2";
+ static final String LOINC_IG_PERCENT = "71695-1";
+ static final String LOINC_MXD_COUNT = "32154-7";
+ static final String LOINC_MXD_PERCENT = "32155-4";
+
+ protected static final String HEADER_RECORD_IDENTIFIER = "H";
+ protected static final String QUERY_RECORD_IDENTIFIER = "Q";
+ protected static final String PATIENT_RECORD_IDENTIFIER = "P";
+ protected static final String ORDER_RECORD_IDENTIFIER = "O";
+ protected static final String RESULT_RECORD_IDENTIFIER = "R";
+ protected static final String END_RECORD_IDENTIFIER = "L";
+ protected static final String FD = "|"; //DEFAULT_FIELD_DELIMITER
+ protected static final String CD = "^"; //DEFAULT_COMPONENT_DELIMITER
+ protected static final String RD = "\\"; //DEFAULT_REPEATER_DELIMITER
+ protected static final String ED = "&"; //DEFAULT_ESCAPE_DELIMITER
+ protected static final String TEST_COMMUNICATION_IDENTIFIER = "M|1|106";
+ private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
+ private SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyyMMddHHmmss");
+
+
+ private TestService testService = SpringContext.getBean(TestService.class);
+ private SampleService sampleService = SpringContext.getBean(SampleService.class);
+ private SampleHumanService sampleHumanService = SpringContext.getBean(SampleHumanService.class);
+ private AnalyzerService analyzerService = SpringContext.getBean(AnalyzerService.class);
+ private AnalysisService analysisService = SpringContext.getBean(AnalysisService.class);
+
+ private String ANALYZER_ID;
+ private Map testToLoincMap = new HashMap<>();
+ private Map loincToTestCodeMap = new HashMap<>();
+ private Map> testCodeToTestsMap = new HashMap<>();
+
+ private AnalyzerReaderUtil readerUtil = new AnalyzerReaderUtil();
+
+ public PocH100iAnalyzerImplementation() {
+
+ testToLoincMap.put(ANALYZER_TEST_WBC, LOINC_WBC);
+ testToLoincMap.put(ANALYZER_TEST_RBC, LOINC_RBC);
+ testToLoincMap.put(ANALYZER_TEST_HGB, LOINC_HGB);
+ testToLoincMap.put(ANALYZER_TEST_HCT, LOINC_HCT);
+ testToLoincMap.put(ANALYZER_TEST_MCV, LOINC_MCV);
+ testToLoincMap.put(ANALYZER_TEST_MCH, LOINC_MCH);
+ testToLoincMap.put(ANALYZER_TEST_MCHC, LOINC_MCHC);
+ testToLoincMap.put(ANALYZER_TEST_RDWSD, LOINC_RDWSD);
+ testToLoincMap.put(ANALYZER_TEST_RDWCV, LOINC_RDWCV);
+ testToLoincMap.put(ANALYZER_TEST_PLT, LOINC_PLT);
+ testToLoincMap.put(ANALYZER_TEST_MPV, LOINC_MPV);
+ testToLoincMap.put(ANALYZER_TEST_NEUT_COUNT, LOINC_NEUT_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_NEUT_PERCENT, LOINC_NEUT_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_LYMPH_COUNT, LOINC_LYMPH_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_LYMPH_PERCENT, LOINC_LYMPH_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_MONO_COUNT, LOINC_MONO_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_MONO_PERCENT, LOINC_MONO_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_EO_COUNT, LOINC_EO_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_EO_PERCENT, LOINC_EO_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_BASO_COUNT, LOINC_BASO_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_BASO_PERCENT, LOINC_BASO_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_IG_COUNT, LOINC_IG_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_IG_PERCENT, LOINC_IG_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_MXD_COUNT, LOINC_MXD_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_MXD_PERCENT, LOINC_MXD_PERCENT);
+
+ for (Entry entry : testToLoincMap.entrySet()) {
+ loincToTestCodeMap.put(entry.getValue(), entry.getKey());
+ testCodeToTestsMap.put(entry.getKey(), testService.getTestsByLoincCode(entry.getValue()));
+ }
+
+ Analyzer analyzer = analyzerService.getAnalyzerByName(PocH100iAnalyzer.ANALYZER_NAME);
+ ANALYZER_ID = analyzer.getId();
+ }
+
+ // example message:
+ // H|\^&|||pocH-100i^01-29^^^^ ^02318732||||||||E1394-97
+ // P|1
+ // O|1||^^ 12345ABCDE^B|^^^^WBC\^^^^RBC\^^^^HGB\^^^^HCT\ ^^^^MCV\^^^^MCH\^^^^MCHC\^^^^PLT\^^^^W-SCR\^^^^W-MCR\^^^^W-LCR\^^^^W-SCC\^^^^W-MCC\^^^^W-LCC\^^^^RDW-SD\^^^^RDW-CV\^^^^PDW\^^^^MPV\^^^^P-LCR|||||||N||||||||||||||F
+ // R|1|^^^^WBC^26|78|10*2/uL||N||||123456789012345||20011221163530
+ // R|2|^^^^RBC^26|350|10*4/uL||L||||123456789012345||20011221163530
+ // R|3|^^^^HGB^26|***.*|g/dL||A||||123456789012345||20011221163530
+ // ……
+ // R|19|^^^^P-LCR^26|50.0|%||H||||123456789012345||20011221163530
+ // L|1|N
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerLineInserter#insert
+ * (java.util.List, java.lang.String)
+ */
+ @Override
+ public boolean insert(List lines, String currentUserId) {
+
+ String patientRecord = null;
+ String orderRecord = null;
+
+ List results = new ArrayList<>();
+ for (String line : lines) {
+ if (line.startsWith(TEST_COMMUNICATION_IDENTIFIER)) {
+ LogEvent.logInfo(this.getClass().getName(), "insert", "this is a test communication record for PocH-100i");
+ }
+ if (line.startsWith(PATIENT_RECORD_IDENTIFIER)) {
+ if (patientRecord != null) {
+ patientRecord = null;
+ orderRecord = null;
+ }
+ patientRecord = line;
+ }
+ if (line.startsWith(ORDER_RECORD_IDENTIFIER)) {
+ orderRecord = line;
+ }
+ if (line.startsWith(RESULT_RECORD_IDENTIFIER)) {
+ LogEvent.logDebug(this.getClass().getName(), "insert", "adding result");
+
+ addRecordsToResults(patientRecord, orderRecord, line, results, currentUserId);
+ }
+ if (line.startsWith(END_RECORD_IDENTIFIER)) {
+ LogEvent.logDebug(this.getClass().getName(), "insert", "end Aquios of record");
+ break;
+ }
+ }
+ return persistImport(currentUserId, results);
+ }
+
+ @Override
+ public String getError() {
+ return PocH100iAnalyzer.ANALYZER_NAME + " analyzer unable to write to database";
+ }
+
+ private Test findMatchingTest(Sample sample, String resultTestCode) {
+ if (sample != null) {
+ for (Analysis curAnalysis : analysisService.getAnalysesBySampleId(sample.getId())) {
+ List possibleTests = testCodeToTestsMap.get(resultTestCode);
+ // if ((possibleTests == null || possibleTests.size() == 0) && resultTestCode.contains("+")) {
+ // possibleTests = testCodeToTestsMap.get(resultTestCode);
+ // }
+ if (possibleTests != null) {
+ for (Test curTest : possibleTests) {
+ if (curTest.getLoinc() != null && curTest.getLoinc().equals(curAnalysis.getTest().getLoinc())) {
+ LogEvent.logDebug(this.getClass().getSimpleName(), "findMatchingTest", "found test in sample for code: " + resultTestCode);
+ return curAnalysis.getTest();
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ //example patient record:
+ // P|1
+ // example order record:
+ // O|1||^^ 12345ABCDE^B|^^^^WBC\^^^^RBC\^^^^HGB\^^^^HCT\ ^^^^MCV\^^^^MCH\^^^^MCHC\^^^^PLT\^^^^W-SCR\^^^^W-MCR\^^^^W-LCR\^^^^W-SCC\^^^^W-MCC\^^^^W-LCC\^^^^RDW-SD\^^^^RDW-CV\^^^^PDW\^^^^MPV\^^^^P-LCR|||||||N||||||||||||||F
+ // example result records:
+ // R|1|^^^^WBC^26|78|10*2/uL||N||||123456789012345||20011221163530
+ private void addRecordsToResults(String patientRecord, String orderRecord, String resultRecord,
+ List results, String currentUserId) {
+ String[] patientRecordFields = patientRecord.split(Pattern.quote(FD));
+ String[] orderRecordFields = orderRecord.split(Pattern.quote(FD));
+ String[] orderTestIdFields = orderRecordFields[4].split(Pattern.quote(RD));
+ String[] orderIdFields = orderRecordFields[3].split(Pattern.quote(CD));
+ String[] resultRecordFields = resultRecord.split(Pattern.quote(FD));
+ String[] resultTestIdField = resultRecordFields[2].split(Pattern.quote(CD));
+ String resultRecordAbnormalFlag = resultRecordFields[6];
+ List orderTestIds = new ArrayList<>();
+ for (String orderIdField : orderTestIdFields) {
+ String[] orderIds = orderIdField.split(Pattern.quote(CD));
+ String orderTestId = orderIds.length >= 5 ? orderIds[4] : "";
+ if (GenericValidator.isBlankOrNull(orderTestId)) {
+ LogEvent.logWarn(this.getClass().getSimpleName(), "addRecordsToResults", "order analysis parameter name is not present");
+ }
+ orderTestIds.add(orderTestId);
+ }
+ if (orderTestIds.size() <= 0) {
+ LogEvent.logWarn(this.getClass().getSimpleName(), "addRecordsToResults", "order analysis has no tests specified");
+ }
+ String resultTestId = resultTestIdField.length >= 5 ? resultTestIdField[4] : "";
+
+ String currentAccessionNumber = orderIdFields[2].trim();
+ Sample sample = sampleService.getSampleByAccessionNumber(currentAccessionNumber);
+ Test test = findMatchingTest(sample, resultTestId);
+
+ if (test == null) {
+ LogEvent.logError(this.getClass().getName(), "addRecordsToResults",
+ "can't import a result if order does not have that test ordered");
+ LogEvent.logDebug(this.getClass().getSimpleName(), "", "resultTestId: " + resultTestId);
+ return;
+ }
+
+ switch (resultRecordAbnormalFlag) {
+ case "A": //masked data
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "masked data result");
+ break;
+ case ">": //out of assured linearity
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "out of assured linearity result");
+ break;
+ case "W": //low reliability
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "low reliability result");
+ break;
+ case "H": // higher than reference interval
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "higher than interval result");
+ break;
+ case "L": //lower than reference interval
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "lower than interval result");
+ break;
+ case "N": //normal
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "normal result");
+ break;
+ default:
+ LogEvent.logWarn(this.getClass().getSimpleName(), "addRecordsToResults", "abnormal flag not understood");
+ }
+
+ AnalyzerResults analyzerResults = addResult(results, null, "N", resultRecordFields[3],
+ DateUtil.convertStringDateToTimestampWithPattern(resultRecordFields[12], "yyyyMMddHHmmss"),
+ currentAccessionNumber, false, resultRecordFields[4], test);
+ LogEvent.logDebug(this.getClass().getName(), "addResultLine", "***" + analyzerResults.getAccessionNumber() + " "
+ + analyzerResults.getCompleteDate() + " " + analyzerResults.getResult());
+ }
+
+ public AnalyzerResults addResult(List resultList, List notMatchedResults, String resultType,
+ String resultValue, Date date, String accessionNumber, boolean isControl, String resultUnits,
+ Test test) {
+ LogEvent.logDebug(this.getClass().getName(), "addResult",
+ "adding result for lab Number: " + accessionNumber);
+ AnalyzerResults analyzerResults = createAnalyzerResult(resultType, resultValue, resultUnits, date,
+ accessionNumber, isControl, test);
+ if (analyzerResults.getTestId() != null) {
+ addValueToResults(resultList, analyzerResults);
+ } else {
+ LogEvent.logWarn(this.getClass().getName(), "addResult",
+ "no matching result for " + accessionNumber);
+ notMatchedResults.add(analyzerResults);
+ }
+ return analyzerResults;
+ }
+
+ private void addValueToResults(List resultList, AnalyzerResults result) {
+ resultList.add(result);
+ LogEvent.logDebug(this.getClass().getName(), "addValueToResults",
+ "searching for matching analysis for " + result.getAccessionNumber());
+ AnalyzerResults resultFromDB = readerUtil.createAnalyzerResultFromDB(result);
+ if (resultFromDB != null) {
+ LogEvent.logWarn(this.getClass().getName(), "addValueToResults",
+ "no resultFromDB for " + result.getAccessionNumber());
+ resultList.add(resultFromDB);
+ }
+
+ }
+
+ private AnalyzerResults createAnalyzerResult(String resultType, String resultValue, String resultUnits, Date date,
+ String accessionNumber, boolean isControl, Test test) {
+ LogEvent.logDebug(this.getClass().getName(), "createAnalyzerResult",
+ "creating analyzer result for " + accessionNumber);
+
+ AnalyzerResults analyzerResults = new AnalyzerResults();
+
+ analyzerResults.setAnalyzerId(ANALYZER_ID);
+ analyzerResults.setResult(resultValue);
+ analyzerResults.setUnits(resultUnits);
+ if (date != null) {
+ analyzerResults.setCompleteDate(new Timestamp(date.getTime()));
+ }
+ analyzerResults.setAccessionNumber(accessionNumber);
+ analyzerResults.setTestId(test.getId());
+ analyzerResults.setIsControl(isControl);
+ analyzerResults.setTestName(test.getLocalizedTestName().getLocalizedValue());
+ return analyzerResults;
+ }
+
+ public void persistImport(List resultList) {
+ this.persistImport("1", resultList);
+ }public String buildResponse(List lines) {
+
+ String queryRecord = null;
+
+ for (String line : lines) {
+ if (line.startsWith(TEST_COMMUNICATION_IDENTIFIER)) {
+ LogEvent.logInfo(this.getClass().getName(), "buildResponse", "this is a test communication record for " + PocH100iAnalyzer.ANALYZER_NAME);
+ }
+ if (line.startsWith(QUERY_RECORD_IDENTIFIER)) {
+ LogEvent.logDebug(this.getClass().getName(), "buildResponse", "request contains query record");
+ String response = generateQueryResponse(line);
+ return response;
+ }
+ }
+ LogEvent.logWarn(this.getClass().getName(), "buildResponse", "no response could be created, no query identifier supplied");
+ return "";
+ }
+
+ private String generateQueryResponse(String queryRecord) {
+ LogEvent.logDebug(this.getClass().getSimpleName(), "generateQueryResponse", "generating query response");
+ String[] queryRecordFields = queryRecord.split(Pattern.quote(FD));
+
+ String[] startingRangeIdNumber = queryRecordFields[2].split(Pattern.quote(CD));
+ String sampleIdNo = startingRangeIdNumber[2].trim();
+ String sampleNoAttribute = startingRangeIdNumber[3];
+
+ StringBuilder msgBuilder = new StringBuilder();
+ LogEvent.logDebug(this.getClass().getSimpleName(), "generateQueryResponse", "searching for sample with lab Number: " + sampleIdNo);
+
+ Sample sample = sampleService.getSampleByAccessionNumber(sampleIdNo.trim());
+ if (sample == null) {
+ LogEvent.logWarn(this.getClass().getSimpleName(), "generateQueryResponse", "no sample found with lab Number: " + sampleIdNo);
+ //return could not find sample messager
+ return msgBuilder.append("H|\\^&|\r\n")
+ .append("P|1|\r\n")
+ .append("O|1||||||||||||||||||||||||Y\r\n") //"Y" is no order exists marker
+ .append("L|1|N\r\n").toString();
+ }
+ Patient patient = sampleHumanService.getPatientForSample(sample);
+ Person person = patient.getPerson();
+ msgBuilder.append("H|\\^&|||||||||||E1394-97\r\n");
+ msgBuilder.append("P|1|||")
+ .append(patient.getNationalId()) //patient identifier
+ .append("|^").append(person.getFirstName()).append("^").append(person.getLastName()) //names
+ .append("||").append(patient.getBirthDate() == null ? "": dateFormat.format(patient.getBirthDate())) //birthdate
+ .append("|").append(patient.getGender()) //gender M F U
+ .append("|||||")
+ .append("")//DR id
+ .append("||||||||||||\r\n");
+
+ msgBuilder.append("O|1|").append(queryRecordFields[2]).append("||");
+
+ boolean first = true;
+ for (Analysis curAnalysis : analysisService.getAnalysesBySampleId(sample.getId())) {
+ Optional testCode = Optional.ofNullable(loincToTestCodeMap.get(curAnalysis.getTest().getLoinc()));
+ if (testCode.isPresent()) {
+ LogEvent.logDebug(this.getClass().getSimpleName(), "generateQueryResponse", "found supported test in sample with test code: " + testCode.get());
+ if (!first) {
+ msgBuilder.append("\\");
+ }
+ first = false;
+ msgBuilder.append("^^^^").append(testCode.get());
+ }
+ }
+ msgBuilder.append("||")
+ .append(sample.getEnteredDate() == null ? "" : dateTimeFormat.format(sample.getEnteredDate()))
+ .append("|||||N||||||||||||||Q\r\n");
+ msgBuilder.append("L|1|N\r\n");
+ return msgBuilder.toString();
+ }
+
+}
diff --git a/analyzers/pocH-100i/src/main/java/oe/plugin/analyzer/PocH100iAnalyzerMenu.java b/analyzers/pocH-100i/src/main/java/oe/plugin/analyzer/PocH100iAnalyzerMenu.java
new file mode 100644
index 0000000..1b3aa33
--- /dev/null
+++ b/analyzers/pocH-100i/src/main/java/oe/plugin/analyzer/PocH100iAnalyzerMenu.java
@@ -0,0 +1,57 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific language governing rights and limitations under
+ * the License.
+ *
+ * The Original Code is OpenELIS code.
+ *
+ * Copyright (C) ITECH, University of Washington, Seattle WA. All Rights Reserved.
+ */
+
+package oe.plugin.analyzer;
+
+import java.util.Locale;
+
+import org.openelisglobal.common.services.PluginMenuService;
+import org.openelisglobal.common.services.PluginMenuService.KnownMenu;
+import org.openelisglobal.menu.valueholder.Menu;
+import org.openelisglobal.plugin.MenuPlugin;
+
+public class PocH100iAnalyzerMenu extends MenuPlugin {
+
+ @Override
+ protected void insertMenu() {
+ PluginMenuService service = PluginMenuService.getInstance();
+ Menu menu = new Menu();
+
+ menu.setParent(PluginMenuService.getInstance().getKnownMenu(KnownMenu.ANALYZER, "menu_results"));
+ // The order this analyzer will show on the menu relative to other analyzers
+ menu.setPresentationOrder(10);
+ // The id needs to be unique in the system
+ menu.setElementId(PocH100iAnalyzer.ANALYZER_NAME + "_plugin");
+ // This will always be "/AnalyzerResults?type=Analyzer->" + PocH100iAnalyzer.ANALYZER_NAME);
+ Role role = service.getSystemRole( "Results" );
+ return service.bindRoleToModule( role, module );
+ }
+}
diff --git a/analyzers/pocH-100i/src/main/resources/PocH-100iAnalyzer.xml b/analyzers/pocH-100i/src/main/resources/PocH-100iAnalyzer.xml
new file mode 100644
index 0000000..e41e7d5
--- /dev/null
+++ b/analyzers/pocH-100i/src/main/resources/PocH-100iAnalyzer.xml
@@ -0,0 +1,22 @@
+
+
+ 1.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file