/** * 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) CIRG, University of Washington, Seattle WA. All Rights Reserved. * */ package us.mn.state.health.lims.resultvalidation.util; import org.apache.commons.validator.GenericValidator; import us.mn.state.health.lims.analysis.dao.AnalysisDAO; import us.mn.state.health.lims.analysis.daoimpl.AnalysisDAOImpl; import us.mn.state.health.lims.analysis.valueholder.Analysis; import us.mn.state.health.lims.analyte.dao.AnalyteDAO; import us.mn.state.health.lims.analyte.daoimpl.AnalyteDAOImpl; import us.mn.state.health.lims.analyte.valueholder.Analyte; import us.mn.state.health.lims.common.exception.LIMSRuntimeException; import us.mn.state.health.lims.common.formfields.FormFields; import us.mn.state.health.lims.common.formfields.FormFields.Field; import us.mn.state.health.lims.common.services.*; import us.mn.state.health.lims.common.services.NoteService.NoteType; import us.mn.state.health.lims.common.services.QAService.QAObservationType; import us.mn.state.health.lims.common.services.StatusService.AnalysisStatus; import us.mn.state.health.lims.common.services.StatusService.RecordStatus; import us.mn.state.health.lims.common.tools.StopWatch; import us.mn.state.health.lims.common.util.ConfigurationProperties; import us.mn.state.health.lims.common.util.ConfigurationProperties.Property; import us.mn.state.health.lims.common.util.IdValuePair; import us.mn.state.health.lims.common.util.StringUtil; import us.mn.state.health.lims.dictionary.dao.DictionaryDAO; import us.mn.state.health.lims.dictionary.daoimpl.DictionaryDAOImpl; import us.mn.state.health.lims.dictionary.valueholder.Dictionary; import us.mn.state.health.lims.observationhistory.dao.ObservationHistoryDAO; import us.mn.state.health.lims.observationhistory.daoimpl.ObservationHistoryDAOImpl; import us.mn.state.health.lims.observationhistory.valueholder.ObservationHistory; import us.mn.state.health.lims.observationhistorytype.dao.ObservationHistoryTypeDAO; import us.mn.state.health.lims.observationhistorytype.daoImpl.ObservationHistoryTypeDAOImpl; import us.mn.state.health.lims.observationhistorytype.valueholder.ObservationHistoryType; import us.mn.state.health.lims.result.action.util.ResultsLoadUtility; import us.mn.state.health.lims.result.dao.ResultDAO; import us.mn.state.health.lims.result.daoimpl.ResultDAOImpl; import us.mn.state.health.lims.result.valueholder.Result; import us.mn.state.health.lims.resultvalidation.action.util.ResultValidationItem; import us.mn.state.health.lims.resultvalidation.bean.AnalysisItem; import us.mn.state.health.lims.sample.dao.SampleDAO; import us.mn.state.health.lims.sample.daoimpl.SampleDAOImpl; import us.mn.state.health.lims.sample.valueholder.Sample; import us.mn.state.health.lims.sampleqaevent.dao.SampleQaEventDAO; import us.mn.state.health.lims.sampleqaevent.daoimpl.SampleQaEventDAOImpl; import us.mn.state.health.lims.sampleqaevent.valueholder.SampleQaEvent; import us.mn.state.health.lims.statusofsample.util.StatusRules; import us.mn.state.health.lims.test.dao.TestDAO; import us.mn.state.health.lims.test.dao.TestSectionDAO; import us.mn.state.health.lims.test.daoimpl.TestDAOImpl; import us.mn.state.health.lims.test.daoimpl.TestSectionDAOImpl; import us.mn.state.health.lims.test.valueholder.Test; import us.mn.state.health.lims.test.valueholder.TestSection; import us.mn.state.health.lims.testresult.dao.TestResultDAO; import us.mn.state.health.lims.testresult.daoimpl.TestResultDAOImpl; import us.mn.state.health.lims.testresult.valueholder.TestResult; import java.util.*; public class ResultsValidationRetroCIUtility { // private static String VIRAL_LOAD_ID = ""; private static String ANALYTE_CD4_CT_GENERATED_ID; private static String CONCLUSION_ID; private final DictionaryDAO dictionaryDAO = new DictionaryDAOImpl(); private final AnalysisDAO analysisDAO = new AnalysisDAOImpl(); private final TestSectionDAO testSectionDAO = new TestSectionDAOImpl(); private final ResultDAO resultDAO = new ResultDAOImpl(); private final TestResultDAO testResultDAO = new TestResultDAOImpl(); private final TestDAO testDAO = new TestDAOImpl(); private final SampleDAO sampleDAO = new SampleDAOImpl(); private final ObservationHistoryDAO observationHistoryDAO = new ObservationHistoryDAOImpl(); private static String SAMPLE_STATUS_OBSERVATION_HISTORY_TYPE_ID; private static String CD4_COUNT_SORT_NUMBER; private ResultsLoadUtility resultsLoadUtility = new ResultsLoadUtility(); private static List<Integer> notValidStatus = new ArrayList<Integer>(); private Map<String, String> testIdToUnits = new HashMap<String, String>(); private Map<String, Boolean> accessionToValidMap; private String totalTestName = ""; static { notValidStatus.add(Integer.parseInt(StatusService.getInstance().getStatusID(AnalysisStatus.Finalized))); notValidStatus.add(Integer.parseInt(StatusService.getInstance().getStatusID(AnalysisStatus.TechnicalRejected))); AnalyteDAO analyteDAO = new AnalyteDAOImpl(); Analyte analyte = new Analyte(); analyte.setAnalyteName("Conclusion"); analyte = analyteDAO.getAnalyteByName(analyte, false); CONCLUSION_ID = analyte.getId(); analyte.setAnalyteName("generated CD4 Count"); analyte = analyteDAO.getAnalyteByName(analyte, false); ANALYTE_CD4_CT_GENERATED_ID = analyte == null ? "" : analyte.getId(); TestDAO testDAO = new TestDAOImpl(); Test test = testDAO.getTestByName("CD4 absolute count"); if( test != null){ CD4_COUNT_SORT_NUMBER = test.getSortOrder(); } ObservationHistoryTypeDAO ohTypeDAO = new ObservationHistoryTypeDAOImpl(); ObservationHistoryType oht = ohTypeDAO.getByName("SampleRecordStatus"); if( oht != null){ SAMPLE_STATUS_OBSERVATION_HISTORY_TYPE_ID = oht.getId(); } } StopWatch sw; public List<AnalysisItem> getResultValidationList(String testSectionName, String testName, List<Integer> statusList) { accessionToValidMap = new HashMap<String, Boolean>(); sw = new StopWatch(); sw.disable(true); List<ResultValidationItem> testList = new ArrayList<ResultValidationItem>(); List<AnalysisItem> resultList = new ArrayList<AnalysisItem>(); if (!(GenericValidator.isBlankOrNull(testSectionName) || testSectionName.equals("0"))) { sw.start("Result Validation " + testSectionName); String testSectionId; // unique serology department format for RetroCI if (testSectionName.equals("Serology")) { testSectionId = getTestSectionId(testSectionName); testList = getUnValidatedElisaResultItemsInTestSection(testSectionId); Collections.sort(testList, new Comparator<ResultValidationItem>() { @Override public int compare(ResultValidationItem o1, ResultValidationItem o2) { return o1.getAccessionNumber().compareTo(o2.getAccessionNumber()); } }); resultList = testResultListToELISAAnalysisList(testList, statusList); // default department format } else { // unique virology department format if ((!GenericValidator.isBlankOrNull(testName) && testSectionName.equals("Virology"))) { if (testName.equals("Genotyping")) { testName = "Génotypage"; } testList.addAll(getUnValidatedTestResultItemsByTest(testName, statusList)); } else { testSectionId = getTestSectionId(testSectionName); testList = getUnValidatedTestResultItemsInTestSection(testSectionId, statusList); // Immunology and Hematology are together //Not sure if this is the correct way to judge this business rule if (ConfigurationProperties.getInstance().isPropertyValueEqual(Property.configurationName, "CI_GENERAL") && testSectionName.equals("Immunology")) { sw.setMark("Immuno time"); // add Hematology tests to list totalTestName = StringUtil.getMessageForKey("test.validation.total.percent"); List<ResultValidationItem> hematologyResults = getUnValidatedTestResultItemsInTestSection(getTestSectionId("Hematology"), statusList); addPrecentageResultsTotal(hematologyResults); testList.addAll(hematologyResults); sw.setMark("Hemo time"); } } resultList = testResultListToAnalysisItemList(testList); sw.setMark("conversion done for " + resultList.size()); } sortByAccessionNumberAndOrder(resultList); sw.setMark("sorting done"); setGroupingNumbers(resultList); sw.setMark("Grouping done"); } sw.setMark("end"); sw.report(); return resultList; } private void addPrecentageResultsTotal(List<ResultValidationItem> hematologyResults) { Map<String, ResultValidationItem> accessionToTotalMap = new HashMap<String, ResultValidationItem>(); for (ResultValidationItem resultItem : hematologyResults) { if (isItemToBeTotaled(resultItem)) { ResultValidationItem totalItem = accessionToTotalMap.get(resultItem.getAccessionNumber()); if (totalItem == null) { totalItem = createTotalItem(resultItem); accessionToTotalMap.put(resultItem.getAccessionNumber(), totalItem); } totalItem.getResult().setValue(totalValues(totalItem, resultItem)); totalItem.setTestSortNumber(greaterSortNumber(totalItem, resultItem)); } } roundTotalItemValue(accessionToTotalMap); hematologyResults.addAll(accessionToTotalMap.values()); } private String greaterSortNumber(ResultValidationItem totalItem, ResultValidationItem resultItem) { return String.valueOf(Math.max(Integer.parseInt(totalItem.getTestSortNumber()), Integer.parseInt(resultItem.getTestSortNumber()))); } private boolean isItemToBeTotaled(ResultValidationItem resultItem) { String name = resultItem.getTestName(); // This is totally un-wholesome it is to specific to RetroCI if (name.equals("Lymph %")) { Result result = resultDAO.getResultById(resultItem.getResultId()); return result == null || result.getAnalyte() == null || !ANALYTE_CD4_CT_GENERATED_ID.equals( result.getAnalyte().getId() ); } else { return name.equals("Neut %") || name.equals("Mono %") || name.equals("Eo %") || name.equals("Baso %"); } } private ResultValidationItem createTotalItem(ResultValidationItem resultItem) { ResultValidationItem item = new ResultValidationItem(); item.setTestName(totalTestName); item.setUnitsOfMeasure( "%" ); item.setAccessionNumber( resultItem.getAccessionNumber() ); item.setResult( new Result() ); item.getResult().setValue( "0" ); item.setResultType( TypeOfTestResultService.ResultType.NUMERIC.getCharacterValue() ); item.setTestSortNumber( "0" ); return item; } private String totalValues(ResultValidationItem totalItem, ResultValidationItem additionalItem) { try { return String.valueOf(Double.parseDouble(totalItem.getResult().getValue()) + Double.parseDouble(additionalItem.getResult().getValue())); } catch (NumberFormatException e) { return totalItem.getResult().getValue(); } } private void roundTotalItemValue(Map<String, ResultValidationItem> accessionToTotalMap) { for (ResultValidationItem totalItem : accessionToTotalMap.values()) { String total = totalItem.getResult().getValue(); if (total.startsWith("99.9999")) { totalItem.getResult().setValue("100.0"); } else { int separatorIndex = total.indexOf('.'); if (separatorIndex > 0) { totalItem.getResult().setValue(total.substring(0, separatorIndex + 2)); } } } } private void sortByAccessionNumberAndOrder(List<AnalysisItem> resultItemList) { Collections.sort(resultItemList, new Comparator<AnalysisItem>() { public int compare(AnalysisItem a, AnalysisItem b) { int accessionComp = a.getAccessionNumber().compareTo(b.getAccessionNumber()); return ((accessionComp == 0) ? Integer.parseInt(a.getTestSortNumber()) - Integer.parseInt(b.getTestSortNumber()) : accessionComp); } }); } private void setGroupingNumbers(List<AnalysisItem> resultList) { String currentAccessionNumber = null; AnalysisItem headItem = null; int groupingCount = 1; for (AnalysisItem analysisResultItem : resultList) { if (!analysisResultItem.getAccessionNumber().equals(currentAccessionNumber)) { currentAccessionNumber = analysisResultItem.getAccessionNumber(); headItem = analysisResultItem; groupingCount++; } else { headItem.setMultipleResultForSample(true); analysisResultItem.setMultipleResultForSample(true); } analysisResultItem.setSampleGroupingNumber(groupingCount); } } @SuppressWarnings("unchecked") public List<ResultValidationItem> getUnValidatedElisaResultItemsInTestSection(String id) { List<Analysis> analysisList = new ArrayList<Analysis>(); List<Test> tests = resultsLoadUtility.getTestsInSection(id); for (Test test : tests) { List<Analysis> analysisTestList = analysisDAO.getAllAnalysisByTestAndExcludedStatus(test.getId(), notValidStatus); analysisList.addAll(analysisTestList); } return getGroupedTestsForAnalysisList(analysisList, false); } @SuppressWarnings("unchecked") public List<ResultValidationItem> getUnValidatedTestResultItemsInTestSection(String sectionId, List<Integer> statusList) { List<Analysis> analysisList = analysisDAO.getAllAnalysisByTestSectionAndStatus(sectionId, statusList, false); sw.setMark("analysis returned " + analysisList.size()); return getGroupedTestsForAnalysisList(analysisList, !StatusRules.useRecordStatusForValidation()); } @SuppressWarnings("unchecked") public List<ResultValidationItem> getUnValidatedTestResultItemsByTest(String testName, List<Integer> statusList) { List<Analysis> analysisList = analysisDAO.getAllAnalysisByTestAndStatus(getTestId(testName), statusList); return getGroupedTestsForAnalysisList(analysisList, false); } /* * N.B. The ignoreRecordStatus is an abomination and should be removed. It * is a quick and dirty fix for workplan and validation using the same code * but having different rules */ public List<ResultValidationItem> getGroupedTestsForAnalysisList(Collection<Analysis> filteredAnalysisList, boolean ignoreRecordStatus) throws LIMSRuntimeException { List<ResultValidationItem> selectedTestList = new ArrayList<ResultValidationItem>(); Dictionary dictionary; for (Analysis analysis : filteredAnalysisList) { if (ignoreRecordStatus || sampleReadyForValidation(analysis.getSampleItem().getSample())) { List<ResultValidationItem> testResultItemList = getResultItemFromAnalysis(analysis); //NB. The resultValue is filled in during getResultItemFromAnalysis as a side effect of setResult for (ResultValidationItem validationItem : testResultItemList) { if (TypeOfTestResultService.ResultType.isDictionaryVariant( validationItem.getResultType() )) { dictionary = new Dictionary(); String resultValue = null; try { dictionary.setId(validationItem.getResultValue()); dictionaryDAO.getData(dictionary); resultValue = GenericValidator.isBlankOrNull(dictionary.getLocalAbbreviation()) ? dictionary.getDictEntry() : dictionary.getLocalAbbreviation(); } catch (Exception e) { //no-op } validationItem.setResultValue(resultValue); } validationItem.setAnalysis( analysis ); validationItem.setNonconforming( QAService.isAnalysisParentNonConforming( analysis ) || StatusService.getInstance().matches( analysis.getStatusId(), AnalysisStatus.TechnicalRejected ) ); if(FormFields.getInstance().useField(Field.QaEventsBySection) ) validationItem.setNonconforming(getQaEventByTestSection(analysis)); selectedTestList.add(validationItem); } } } return selectedTestList; } private boolean sampleReadyForValidation(Sample sample) { Boolean valid = accessionToValidMap.get(sample.getAccessionNumber()); if (valid == null) { valid = getSampleRecordStatus( sample ) != RecordStatus.NotRegistered; accessionToValidMap.put(sample.getAccessionNumber(), valid); } return valid; } public List<ResultValidationItem> getResultItemFromAnalysis(Analysis analysis) throws LIMSRuntimeException { List<ResultValidationItem> testResultList = new ArrayList<ResultValidationItem>(); List<Result> resultList = resultDAO.getResultsByAnalysis(analysis); NoteType[] noteTypes = { NoteType.EXTERNAL, NoteType.INTERNAL, NoteType.REJECTION_REASON, NoteType.NON_CONFORMITY}; String notes = new NoteService( analysis ).getNotesAsString( true, true, "<br/>", noteTypes, false ); if (resultList == null) { return testResultList; } // For historical reasons we add a null member to the collection if it // is empty // this should be refactored. // The result list are results associated with the analysis, if there is // none we want // to present the user with a blank one if (resultList.isEmpty()) { resultList.add(null); } ResultValidationItem parentItem = null; for (Result result : resultList) { if( parentItem != null && result.getParentResult() != null && parentItem.getResultId().equals(result.getParentResult().getId())){ parentItem.setQualifiedResultValue(result.getValue()); parentItem.setHasQualifiedResult( true ); parentItem.setQualificationResultId(result.getId()); continue; } ResultValidationItem resultItem = createTestResultItem(analysis, analysis.getTest(), analysis.getSampleItem().getSortOrder(), result, analysis.getSampleItem().getSample().getAccessionNumber(), notes); notes = null;//we only want it once if( resultItem.getQualifiedDictionaryId() != null){ parentItem = resultItem; } testResultList.add(resultItem); } return testResultList; } private ResultValidationItem createTestResultItem(Analysis analysis, Test test, String sequenceNumber, Result result, String accessionNumber, String notes) { List<TestResult> testResults = getPossibleResultsForTest(test); String displayTestName = TestService.getLocalizedTestNameWithType( test ); // displayTestName = augmentTestNameWithRange(displayTestName, result); ResultValidationItem testItem = new ResultValidationItem(); testItem.setAccessionNumber(accessionNumber); testItem.setAnalysis( analysis ); testItem.setSequenceNumber(sequenceNumber); testItem.setTestName(displayTestName); testItem.setTestId(test.getId()); testItem.setAnalysisMethod(analysis.getAnalysisType()); testItem.setResult(result); testItem.setDictionaryResults(getAnyDictonaryValues(testResults)); testItem.setResultType(getTestResultType(testResults )); testItem.setTestSortNumber(test.getSortOrder()); testItem.setReflexGroup(analysis.getTriggeredReflex()); testItem.setChildReflex(analysis.getTriggeredReflex() && isConclusion(result, analysis)); testItem.setQualifiedDictionaryId(getQualifiedDictionaryId(testResults)); testItem.setPastNotes( notes ); return testItem; } private String getQualifiedDictionaryId(List<TestResult> testResults){ String qualDictionaryIds = ""; for( TestResult testResult : testResults){ if( testResult.getIsQuantifiable()){ if( !"".equals(qualDictionaryIds )){ qualDictionaryIds += ","; } qualDictionaryIds += testResult.getValue(); } } return "".equals(qualDictionaryIds) ? null : "[" + qualDictionaryIds + "]"; } private String augmentUOMWithRange(String uom, Result result) { if( result == null){return uom;} String range = new ResultService( result ).getDisplayReferenceRange( true ); uom = StringUtil.blankIfNull( uom ); return GenericValidator.isBlankOrNull( range ) ? uom : (uom + " ( " + range + " )"); } private boolean isConclusion(Result testResult, Analysis analysis) { List<Result> results = resultDAO.getResultsByAnalysis(analysis); if (results.size() == 1) { return false; } Long testResultId = Long.parseLong(testResult.getId()); // This based on the fact that the conclusion is always added // after the shared result so if there is a result with a larger id // then this is not a conclusion for (Result result : results) { if (Long.parseLong(result.getId()) > testResultId) { return false; } } return true; } @SuppressWarnings("unchecked") private List<TestResult> getPossibleResultsForTest(Test test) { return testResultDAO.getAllActiveTestResultsPerTest( test ); } private List<IdValuePair> getAnyDictonaryValues(List<TestResult> testResults) { List<IdValuePair> values = null; Dictionary dictionary; if (testResults != null && testResults.size() > 0 && TypeOfTestResultService.ResultType.isDictionaryVariant( testResults.get( 0 ).getTestResultType() )) { values = new ArrayList<IdValuePair>(); values.add(new IdValuePair("0", "")); for (TestResult testResult : testResults) { // Note: result group use to be a criteria but was removed, if // results are not as expected investigate if ( TypeOfTestResultService.ResultType.isDictionaryVariant( testResult.getTestResultType() )) { dictionary = dictionaryDAO.getDataForId(testResult.getValue()); String displayValue = dictionary.getLocalizedName(); if ("unknown".equals(displayValue)) { displayValue = GenericValidator.isBlankOrNull(dictionary.getLocalAbbreviation()) ? dictionary.getDictEntry() : dictionary.getLocalAbbreviation(); } values.add(new IdValuePair(testResult.getValue(), displayValue)); } } } return values; } private String getTestResultType(List<TestResult> testResults) { String testResultType = TypeOfTestResultService.ResultType.NUMERIC.getCharacterValue(); if (testResults != null && testResults.size() > 0) { testResultType = testResults.get(0).getTestResultType(); } return testResultType; } public List<AnalysisItem> testResultListToELISAAnalysisList(List<ResultValidationItem> testResultList, List<Integer> statusList) { List<AnalysisItem> analysisItemList = new ArrayList<AnalysisItem>(); AnalysisItem analysisResultItem = new AnalysisItem(); String currentAccessionNumber = ""; String currentInvalidAccessionNumber = ""; boolean readyForValidation = true; for (int i = 0; i < testResultList.size(); i++) { ResultValidationItem tResultItem = testResultList.get(i); // create new bean if (!tResultItem.getAccessionNumber().equals(currentAccessionNumber)) { if (tResultItem.getAccessionNumber().equals(currentInvalidAccessionNumber)) { continue; } Sample sample = sampleDAO.getSampleByAccessionNumber(tResultItem.getAccessionNumber()); if (sampleReadyForValidation(sample)) { if (!GenericValidator.isBlankOrNull(analysisResultItem.getFinalResult()) && readyForValidation) { analysisItemList.add(analysisResultItem); } readyForValidation = true; analysisResultItem = testResultItemToELISAAnalysisItem(tResultItem); currentAccessionNumber = analysisResultItem.getAccessionNumber(); currentInvalidAccessionNumber = ""; } else { // record status not valid currentInvalidAccessionNumber = tResultItem.getAccessionNumber(); continue; } // or just add test result to elisaAlgorithm bean } else { analysisResultItem.setResult(tResultItem.getResultValue()); analysisResultItem = addTestResultToELISAAnalysisItem(tResultItem, analysisResultItem); } if (!GenericValidator.isBlankOrNull(analysisResultItem.getStatusId()) && !statusList.contains(Integer.parseInt(analysisResultItem.getStatusId()))) { readyForValidation = false; } String finalResult = checkIfFinalResult(tResultItem.getAnalysis().getId()); if (!GenericValidator.isBlankOrNull(finalResult)) { analysisResultItem.setFinalResult(finalResult); } // final time through if (i == (testResultList.size() - 1) && readyForValidation && !GenericValidator.isBlankOrNull(analysisResultItem.getFinalResult())) { analysisItemList.add(analysisResultItem); } } return analysisItemList; } public String checkIfFinalResult(String analysisId) { String finalResult = null; Analysis analysis = new Analysis(); analysis.setId(analysisId); List<Result> resultList = resultDAO.getResultsByAnalysis(analysis); String conclusion = null; if (resultList.size() > 1) { for (Result result : resultList) { if (result.getAnalyte() != null && result.getAnalyte().getId().equals(CONCLUSION_ID)) { conclusion = result.getValue(); } } } if (conclusion != null) { Dictionary dictionary = new Dictionary(); dictionary.setId(conclusion); dictionaryDAO.getData(dictionary); finalResult = (dictionary.getDictEntry()); } return finalResult; } public AnalysisItem testResultItemToELISAAnalysisItem(ResultValidationItem testResultItem) { AnalysisItem elisaResultItem = new AnalysisItem(); elisaResultItem.setAccessionNumber(testResultItem.getAccessionNumber()); elisaResultItem.setTestName(testResultItem.getTestName()); elisaResultItem.setResult(testResultItem.getResultValue()); elisaResultItem.setSampleGroupingNumber(testResultItem.getSampleGroupingNumber()); elisaResultItem.setAnalysisId(testResultItem.getAnalysis().getId()); elisaResultItem.setStatusId(testResultItem.getAnalysis().getStatusId()); elisaResultItem.setNote(testResultItem.getNote()); elisaResultItem.setNoteId(testResultItem.getNoteId()); elisaResultItem.setResultId(testResultItem.getResultId()); elisaResultItem.setNonconforming(testResultItem.isNonconforming() ); // elisaResultItem.setResult(testResultItem.getResult().getValue()); // set elisa test to result elisaResultItem = setElisaTestResult(testResultItem.getTestName(), elisaResultItem); return elisaResultItem; } public AnalysisItem addTestResultToELISAAnalysisItem(ResultValidationItem testResultItem, AnalysisItem eItem) { eItem.setAnalysisId(testResultItem.getAnalysis().getId()); eItem.setStatusId(testResultItem.getAnalysis().getStatusId()); if( testResultItem.isNonconforming()){ eItem.setNonconforming(true); } // set elisa test to result eItem = setElisaTestResult(testResultItem.getTestName(), eItem); return eItem; } public AnalysisItem setElisaTestResult(String testName, AnalysisItem eItem) { String result = eItem.getResult(); String analysisId = eItem.getAnalysisId(); if (testName.equals("Murex")) { eItem.setMurexResult(result); eItem.setMurexAnalysisId(analysisId); } else if (testName.equals("Integral")) { eItem.setIntegralResult(result); eItem.setIntegralAnalysisId(analysisId); } else if (testName.equals("Vironostika")) { eItem.setVironostikaResult(result); eItem.setVironostikaAnalysisId(analysisId); } else if (testName.equals("Genie II")) { eItem.setGenieIIResult(result); eItem.setGenieIIAnalysisId(analysisId); } else if (testName.equals("Genie II 10")) { eItem.setGenieII10Result(result); eItem.setGenieII10AnalysisId(analysisId); } else if (testName.equals("Genie II 100")) { eItem.setGenieII100Result(result); eItem.setGenieII100AnalysisId(analysisId); } else if (testName.equals("Western Blot 1")) { eItem.setWesternBlot1Result(result); eItem.setWesternBlot1AnalysisId(analysisId); } else if (testName.equals("Western Blot 2")) { eItem.setWesternBlot2Result(result); eItem.setWesternBlot2AnalysisId(analysisId); } else if (testName.equals("p24 Ag")) { eItem.setP24AgResult(result); eItem.setP24AgAnalysisId(analysisId); } else if (testName.equals("Bioline")) { eItem.setBiolineResult(result); eItem.setBiolineAnalysisId(analysisId); } else if (testName.equals("Innolia")) { eItem.setInnoliaResult(result); eItem.setInnoliaAnalysisId(analysisId); } return eItem; } public List<AnalysisItem> testResultListToAnalysisItemList(List<ResultValidationItem> testResultList) { List<AnalysisItem> analysisResultList = new ArrayList<AnalysisItem>(); /* The issue with multiselect results is that each selection is one ResultValidationItem but they all need to be condensed into one AnalysisItem. There is a many to one mapping. The first multiselect result we have gets rolled into one AnalysisItem and the rest are skipped but we want to capture any qualified results */ boolean multiResultEntered = false; String currentAccession = null; AnalysisItem currentMultiSelectAnalysisItem = null; for (ResultValidationItem testResultItem : testResultList) { if( !testResultItem.getAccessionNumber().equals(currentAccession)){ currentAccession = testResultItem.getAccessionNumber(); currentMultiSelectAnalysisItem = null; multiResultEntered = false; } if( !multiResultEntered){ AnalysisItem convertedItem = testResultItemToAnalysisItem(testResultItem); analysisResultList.add(convertedItem); if( TypeOfTestResultService.ResultType.isMultiSelectVariant( testResultItem.getResultType() )){ multiResultEntered = true; currentMultiSelectAnalysisItem = convertedItem; } } if(currentMultiSelectAnalysisItem != null && testResultItem.isHasQualifiedResult() ){ currentMultiSelectAnalysisItem.setQualifiedResultValue(testResultItem.getQualifiedResultValue()); currentMultiSelectAnalysisItem.setQualifiedDictionaryId(testResultItem.getQualifiedDictionaryId()); currentMultiSelectAnalysisItem.setHasQualifiedResult(true); } } return analysisResultList; } private RecordStatus getSampleRecordStatus(Sample sample) { List<ObservationHistory> ohList = observationHistoryDAO.getAll(null, sample, SAMPLE_STATUS_OBSERVATION_HISTORY_TYPE_ID); if (ohList.isEmpty()) { return null; } return StatusService.getInstance().getRecordStatusForID(ohList.get(0).getValue()); } public AnalysisItem testResultItemToAnalysisItem(ResultValidationItem testResultItem) { AnalysisItem analysisResultItem = new AnalysisItem(); String testUnits = getUnitsByTestId(testResultItem.getTestId()); String testName = testResultItem.getTestName(); String sortOrder = testResultItem.getTestSortNumber(); Result result = testResultItem.getResult(); if (result != null && result.getAnalyte() != null && ANALYTE_CD4_CT_GENERATED_ID.equals(testResultItem.getResult().getAnalyte().getId())) { testUnits = ""; testName = StringUtil.getMessageForKey("result.conclusion.cd4"); analysisResultItem.setShowAcceptReject(false); analysisResultItem.setReadOnly(true); sortOrder = CD4_COUNT_SORT_NUMBER; } else if (testResultItem.getTestName().equals(totalTestName)) { analysisResultItem.setShowAcceptReject(false); analysisResultItem.setReadOnly(true); testUnits = testResultItem.getUnitsOfMeasure(); analysisResultItem.setIsHighlighted(!"100.0".equals(testResultItem.getResult().getValue())); } testUnits = augmentUOMWithRange(testUnits, testResultItem.getResult()); analysisResultItem.setAccessionNumber(testResultItem.getAccessionNumber()); analysisResultItem.setTestName(testName); analysisResultItem.setUnits(testUnits); if (!(testResultItem.getAnalysis() == null)) { analysisResultItem.setAnalysisId(testResultItem.getAnalysis().getId()); } analysisResultItem.setPastNotes(testResultItem.getPastNotes()); analysisResultItem.setResultId(testResultItem.getResultId()); analysisResultItem.setResultType(testResultItem.getResultType()); analysisResultItem.setTestId(testResultItem.getTestId()); analysisResultItem.setTestSortNumber(sortOrder); analysisResultItem.setDictionaryResults(testResultItem.getDictionaryResults()); analysisResultItem.setDisplayResultAsLog(TestIdentityService.isTestNumericViralLoad(testResultItem.getTestId())); if( result != null){ if( TypeOfTestResultService.ResultType.isMultiSelectVariant( testResultItem.getResultType() ) && !(testResultItem.getAnalysis() == null) ){ analysisResultItem.setMultiSelectResultValues( new AnalysisService( testResultItem.getAnalysis() ).getJSONMultiSelectResults() ); }else{ analysisResultItem.setResult( getFormattedResult( testResultItem ) ); } if( TypeOfTestResultService.ResultType.NUMERIC.matches( testResultItem.getResultType() )){ if (result.getMinNormal() == null || result.getMaxNormal() == null) { analysisResultItem.setSignificantDigits(result.getSignificantDigits()); } else { analysisResultItem.setSignificantDigits( result.getMinNormal().equals( result.getMaxNormal())? -1 : result.getSignificantDigits()); } } } analysisResultItem.setReflexGroup(testResultItem.isReflexGroup()); analysisResultItem.setChildReflex(testResultItem.isChildReflex()); if (!(testResultItem.getAnalysis() == null)) { analysisResultItem.setNonconforming( testResultItem.isNonconforming() || StatusService.getInstance().matches( testResultItem.getAnalysis().getStatusId(), AnalysisStatus.TechnicalRejected )); } analysisResultItem.setQualifiedDictionaryId(testResultItem.getQualifiedDictionaryId()); analysisResultItem.setQualifiedResultValue(testResultItem.getQualifiedResultValue()); analysisResultItem.setQualifiedResultId(testResultItem.getQualificationResultId()); analysisResultItem.setHasQualifiedResult( testResultItem.isHasQualifiedResult() ); return analysisResultItem; } private String getFormattedResult(ResultValidationItem testResultItem) { String result = testResultItem.getResult().getValue(); if( TestIdentityService.isTestNumericViralLoad(testResultItem.getTestId()) && !GenericValidator.isBlankOrNull(result)){ return result.split("\\(")[0].trim(); }else{ return new ResultService(testResultItem.getResult()).getResultValue( false ); } } public String getUnitsByTestId(String testId) { String uomName = null; if (testId != null) { uomName = testIdToUnits.get(testId); if (uomName == null) { Test test = new Test(); test.setId(testId); test = testDAO.getTestById(test); if (test.getUnitOfMeasure() != null) { uomName = test.getUnitOfMeasure().getName(); testIdToUnits.put(testId, uomName); } else { testIdToUnits.put(testId, ""); } } } return uomName; } public String getTestSectionId(String testSectionName) { TestSection testSection = new TestSection(); testSection.setTestSectionName(testSectionName); testSection = testSectionDAO.getTestSectionByName(testSection); return testSection.getId(); } private String getTestId(String testName) { Test test = testDAO.getTestByName(testName); return test.getId(); } private boolean getQaEventByTestSection(Analysis analysis){ if (analysis.getTestSection()!=null && analysis.getSampleItem().getSample()!=null) { Sample sample=analysis.getSampleItem().getSample(); List<SampleQaEvent> sampleQaEventsList=getSampleQaEvents(sample); for(SampleQaEvent event : sampleQaEventsList){ QAService qa = new QAService(event); if(!GenericValidator.isBlankOrNull(qa.getObservationValue( QAObservationType.SECTION )) && qa.getObservationValue( QAObservationType.SECTION ).equals(analysis.getTestSection().getNameKey())) return true; } } return false; } public List<SampleQaEvent> getSampleQaEvents(Sample sample){ SampleQaEventDAO sampleQaEventDAO = new SampleQaEventDAOImpl(); return sampleQaEventDAO.getSampleQaEventsBySample(sample); } }