/**
* 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.reports.action.implementation;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import us.mn.state.health.lims.analysis.valueholder.Analysis;
import us.mn.state.health.lims.common.action.BaseActionForm;
import us.mn.state.health.lims.common.services.AnalysisService;
import us.mn.state.health.lims.common.services.StatusService;
import us.mn.state.health.lims.common.services.StatusService.AnalysisStatus;
import us.mn.state.health.lims.common.services.TestService;
import us.mn.state.health.lims.common.util.StringUtil;
import us.mn.state.health.lims.reports.action.implementation.reportBeans.HaitiAggregateReportData;
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 java.util.*;
/**
* 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.
*
*/
public abstract class IndicatorAllTest extends IndicatorReport implements IReportCreator,
IReportParameterSetter {
private List<HaitiAggregateReportData> reportItems;
private Map<String, TestBucket> testNameToBucketList;
private Map<String, TestBucket> concatSection_TestToBucketMap;
private List<TestBucket> testBucketList;
private static final String USER_TEST_SECTION_ID;
static {
USER_TEST_SECTION_ID = new TestSectionDAOImpl().getTestSectionByName("user").getId();
}
@Override
protected String reportFileName() {
return "LabAggregate";
}
public JRDataSource getReportDataSource() throws IllegalStateException {
return errorFound ? new JRBeanCollectionDataSource(errorMsgs) : new JRBeanCollectionDataSource(reportItems);
}
public void initializeReport(BaseActionForm dynaForm) {
super.initializeReport();
setDateRange(dynaForm);
createReportParameters();
setTestMapForAllTests();
setAnalysisForDateRange();
mergeLists();
setTestAggregates();
}
private void setTestMapForAllTests() {
testNameToBucketList = new HashMap<String, TestBucket>();
concatSection_TestToBucketMap = new HashMap<String, TestBucket>();
testBucketList = new ArrayList<TestBucket>();
List<Test> testList = TestService.getAllActiveTests();
for (Test test : testList) {
TestBucket bucket = new TestBucket();
bucket.testName = TestService.getUserLocalizedReportingTestName(test );
bucket.testSort = Integer.parseInt(test.getSortOrder());
bucket.testSection = test.getTestSection().getLocalizedName();
bucket.sectionSort = test.getTestSection().getSortOrderInt();
testNameToBucketList.put( TestService.getUserLocalizedReportingTestName( test ), bucket);
testBucketList.add(bucket);
}
}
private void setAnalysisForDateRange(){
HashMap<String, ArrayList<Analysis>> sampleToPanelAnalysisMap = new HashMap<String, ArrayList<Analysis>>();
List<Analysis> rawAnalysisList = AnalysisService.getAnalysisStartedOrCompletedInDateRange( lowDate, highDate );
ArrayList<Analysis> analysisList = new ArrayList<Analysis>();
//group analysis w/ panels by samples (sampleItem)
for( Analysis analysis : rawAnalysisList ){
extractAnalysisInPanels( sampleToPanelAnalysisMap, analysisList, analysis );
}
//for each sample we will break it down into panels with list of analysis
for( String sampleId : sampleToPanelAnalysisMap.keySet() ){
HashMap<String, ArrayList<Analysis>> panelIdToAnalysisMap = new HashMap<String, ArrayList<Analysis>>();
for( Analysis sampleAnalysis : sampleToPanelAnalysisMap.get( sampleId ) ){
ArrayList<Analysis> panelAnalysisList = panelIdToAnalysisMap.get( sampleAnalysis.getPanel().getId() );
if( panelAnalysisList == null ){
panelAnalysisList = new ArrayList<Analysis>();
panelIdToAnalysisMap.put( sampleAnalysis.getPanel().getId(), panelAnalysisList );
}
panelAnalysisList.add( sampleAnalysis );
}
//we will now go through each panel and either throw out all analysis if any one is canceled
// or create the correct analysis thingy
for( String panelId : panelIdToAnalysisMap.keySet() ){
Analysis templateAnalysis = panelIdToAnalysisMap.get( panelId ).get( 0 );
String panelName = templateAnalysis.getPanel().getLocalizedName();
boolean canceled = false;
boolean notStarted = false;
boolean finished = false;
boolean inProgress = false;
for( Analysis panelAnalysis : panelIdToAnalysisMap.get( panelId ) ){
if( StatusService.getInstance().matches( panelAnalysis.getStatusId(), AnalysisStatus.Canceled ) ){
canceled = true;
break;
}else if( StatusService.getInstance().matches( panelAnalysis.getStatusId(), AnalysisStatus.NotStarted ) ){
notStarted = true;
}else if( StatusService.getInstance().matches( panelAnalysis.getStatusId(), AnalysisStatus.Finalized ) ){
finished = true;
}else{
inProgress = true;
}
}
if( canceled ){
//all analysis are treated as being out of the panel
for( Analysis analysis : panelIdToAnalysisMap.get( panelId ) ){
analysisList.add( analysis );
}
}else{
//we will create a fake analysis and add it to the analysisList
// and make sure the panel name is in the bucket list
String status;
if( inProgress || (notStarted && finished)){
status = StatusService.getInstance().getStatusID( AnalysisStatus.TechnicalAcceptance );
}else if( notStarted){
status = StatusService.getInstance().getStatusID( AnalysisStatus.NotStarted );
}else{
status = StatusService.getInstance().getStatusID( AnalysisStatus.Finalized );
}
Analysis proxyAnalysis = getProxyAnalysis( templateAnalysis, panelName, status );
analysisList.add( proxyAnalysis );
createAndAddBucketIfNeeded( panelName, proxyAnalysis );
}
}
}
//go through map and both classify panels and return sets with any canceled analysis
for( Analysis analysis : analysisList ){
addStatusToBuckets( analysis );
}
}
private void extractAnalysisInPanels( HashMap<String, ArrayList<Analysis>> sampleToPanalAnalysisMap, ArrayList<Analysis> analysisList, Analysis analysis ){
if( analysis.getPanel() == null ){
analysisList.add( analysis );
}else{
ArrayList<Analysis> itemAnalysisList = sampleToPanalAnalysisMap.get( analysis.getSampleItem().getId() );
if( itemAnalysisList == null ){
itemAnalysisList = new ArrayList<Analysis>();
sampleToPanalAnalysisMap.put( analysis.getSampleItem().getId(), itemAnalysisList );
}
itemAnalysisList.add( analysis );
}
}
private void addStatusToBuckets( Analysis analysis ){
Test test = analysis.getTest();
if( test != null ){
TestBucket testBucket;
//N.B. We need to look at the test->test section because the analysis test section reflects the user selection for the test section
//that entry will not be in the test to test section map
if( USER_TEST_SECTION_ID.equals( analysis.getTest().getTestSection().getId() ) ){
String concatedName = analysis.getTestSection().getLocalizedName()
+ TestService.getUserLocalizedTestName( analysis.getTest() );
testBucket = concatSection_TestToBucketMap.get( concatedName );
if( testBucket == null ){
testBucket = new TestBucket();
testBucket.testName = TestService.getUserLocalizedReportingTestName( test );
testBucket.testSort = Integer.parseInt( test.getSortOrder() );
testBucket.testSection = analysis.getTestSection().getLocalizedName();
testBucket.sectionSort = analysis.getTestSection().getSortOrderInt();
concatSection_TestToBucketMap.put( concatedName, testBucket );
}
}else if(test.getLocalizedTestName() == null) {
testBucket = testNameToBucketList.get( test.getTestName());
}else{
testBucket = testNameToBucketList.get( TestService.getUserLocalizedReportingTestName( test ));
}
if( testBucket != null ){
if( StatusService.getInstance().matches( analysis.getStatusId(), AnalysisStatus.NotStarted ) ){
testBucket.notStartedCount++;
}else if( inProgress( analysis ) ){
testBucket.inProgressCount++;
}else if( StatusService.getInstance().matches( analysis.getStatusId(), AnalysisStatus.Finalized ) ){
testBucket.finishedCount++;
}
}
}
}
private void createAndAddBucketIfNeeded( String panelName, Analysis proxyAnalysis ){
TestBucket panelBucket = testNameToBucketList.get( panelName );
if( panelBucket == null ){
panelBucket = new TestBucket();
panelBucket.testName = panelName;
panelBucket.testSort = -1;
panelBucket.testSection = proxyAnalysis.getTestSection().getLocalizedName();
panelBucket.sectionSort = proxyAnalysis.getTestSection().getSortOrderInt();
testNameToBucketList.put( panelName, panelBucket );
testBucketList.add( panelBucket );
}
}
private Analysis getProxyAnalysis( Analysis templateAnalysis, String panelName, String status ){
Analysis proxyAnalysis = new Analysis();
TestSection proxyTestSection = new TestSection();
Test proxyTest = new Test();
proxyAnalysis.setStatusId( status );
proxyAnalysis.setTest( proxyTest );
proxyAnalysis.setTestSection( proxyTestSection );
proxyTestSection.setTestSectionName( templateAnalysis.getTestSection().getLocalizedName() );
proxyTestSection.setSortOrderInt( templateAnalysis.getTestSection().getSortOrderInt() );
proxyTestSection.setId( templateAnalysis.getTestSection().getId() );
proxyTest.setTestSection( proxyTestSection );
proxyTest.setTestName( panelName );
return proxyAnalysis;
}
private boolean inProgress(Analysis analysis) {
return StatusService.getInstance().matches( analysis.getStatusId(), AnalysisStatus.TechnicalAcceptance ) ||
StatusService.getInstance().matches( analysis.getStatusId(), AnalysisStatus.TechnicalRejected ) ||
StatusService.getInstance().matches( analysis.getStatusId(), AnalysisStatus.BiologistRejected );
}
private void mergeLists() {
Map<String, TestSection> testSectionMap = getTestSectionNameMap();
//get rid of empty buckets, make sorting faster
List<TestBucket> fullBucketList = new ArrayList<TestBucket>( );
for( TestBucket bucket : testBucketList){
if((bucket.finishedCount + bucket.notStartedCount + bucket.inProgressCount) > 0){
fullBucketList.add( bucket );
testSectionMap.remove( bucket.testSection);
}
}
testBucketList = fullBucketList;
addEmptySectionsToBucketList(testSectionMap, testBucketList );
for (TestBucket bucket : concatSection_TestToBucketMap.values()) {
testBucketList.add(bucket);
}
Collections.sort(testBucketList, new Comparator<TestBucket>() {
@Override
public int compare(TestBucket o1, TestBucket o2) {
int order = o1.sectionSort - o2.sectionSort;
if( order == 0){
order = o1.testSort - o2.testSort;
}
return order;
}
});
}
private void addEmptySectionsToBucketList(Map<String, TestSection> testSectionMap, List<TestBucket> bucketList) {
for( String sectionName : testSectionMap.keySet()){
TestSection section = testSectionMap.get(sectionName);
TestBucket testBucket = new TestBucket();
testBucket.sectionSort = section.getSortOrderInt();
testBucket.testSection = sectionName;
testBucket.testSort = 0;
testBucket.testName = null;
bucketList.add(testBucket);
}
}
private Map<String, TestSection> getTestSectionNameMap() {
List<TestSection> allTestSections = new TestSectionDAOImpl().getAllActiveTestSections();
Map<String, TestSection> testSectionMap = new HashMap<String, TestSection>();
for( TestSection section : allTestSections){
testSectionMap.put( section.getLocalizedName(), section);
}
return testSectionMap;
}
@Override
protected String getNameForReportRequest() {
return StringUtil.getMessageForKey("openreports.all.tests.aggregate");
}
private void setTestAggregates() {
reportItems = new ArrayList<HaitiAggregateReportData>();
for( TestBucket bucket : testBucketList ){
HaitiAggregateReportData data = new HaitiAggregateReportData();
data.setFinished( bucket.finishedCount );
data.setNotStarted( bucket.notStartedCount );
data.setInProgress( bucket.inProgressCount );
data.setTestName( bucket.testName );
data.setSectionName( bucket.testSection );
reportItems.add( data );
}
}
private class TestBucket {
public String testName = "";
public int testSort = 0;
public String testSection = "";
public int sectionSort = 0;
public int notStartedCount = 0;
public int inProgressCount = 0;
public int finishedCount = 0;
}
@Override
protected String getNameForReport() {
return StringUtil.getContextualMessageForKey("openreports.all.tests.aggregate");
}
}