/** * 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.sample.action; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.validator.GenericValidator; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.DynaActionForm; 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.common.action.BaseAction; import us.mn.state.health.lims.common.action.IActionConstants; import us.mn.state.health.lims.common.formfields.FormFields; import us.mn.state.health.lims.common.services.*; import us.mn.state.health.lims.common.services.DisplayListService.ListType; import us.mn.state.health.lims.common.services.StatusService.AnalysisStatus; import us.mn.state.health.lims.common.services.StatusService.SampleStatus; import us.mn.state.health.lims.common.util.DateUtil; import us.mn.state.health.lims.common.util.StringUtil; import us.mn.state.health.lims.login.dao.UserModuleDAO; import us.mn.state.health.lims.login.daoimpl.UserModuleDAOImpl; import us.mn.state.health.lims.patient.action.bean.PatientSearch; import us.mn.state.health.lims.patient.valueholder.Patient; import us.mn.state.health.lims.sample.bean.SampleEditItem; 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.samplehuman.daoimpl.SampleHumanDAOImpl; import us.mn.state.health.lims.sampleitem.dao.SampleItemDAO; import us.mn.state.health.lims.sampleitem.daoimpl.SampleItemDAOImpl; import us.mn.state.health.lims.sampleitem.valueholder.SampleItem; import us.mn.state.health.lims.test.dao.TestDAO; import us.mn.state.health.lims.test.daoimpl.TestDAOImpl; import us.mn.state.health.lims.test.valueholder.Test; import us.mn.state.health.lims.typeofsample.dao.TypeOfSampleDAO; import us.mn.state.health.lims.typeofsample.dao.TypeOfSampleTestDAO; import us.mn.state.health.lims.typeofsample.daoimpl.TypeOfSampleDAOImpl; import us.mn.state.health.lims.typeofsample.daoimpl.TypeOfSampleTestDAOImpl; import us.mn.state.health.lims.typeofsample.valueholder.TypeOfSample; import us.mn.state.health.lims.typeofsample.valueholder.TypeOfSampleTest; import us.mn.state.health.lims.userrole.daoimpl.UserRoleDAOImpl; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.lang.reflect.InvocationTargetException; import java.util.*; public class SampleEditAction extends BaseAction { private static final TypeOfSampleDAO typeOfSampleDAO = new TypeOfSampleDAOImpl(); private static final AnalysisDAO analysisDAO = new AnalysisDAOImpl(); private static final UserModuleDAO userModuleDAO = new UserModuleDAOImpl(); private static final SampleEditItemComparator testComparator = new SampleEditItemComparator(); private static final Set<Integer> excludedAnalysisStatusList; private static final Set<Integer> ENTERED_STATUS_SAMPLE_LIST = new HashSet<Integer>(); private static final Collection<String> ABLE_TO_CANCEL_ROLE_NAMES = new ArrayList<String>( ); private boolean isEditable = false; private String maxAccessionNumber; static { excludedAnalysisStatusList = new HashSet<Integer>(); excludedAnalysisStatusList.add(Integer.parseInt(StatusService.getInstance().getStatusID(AnalysisStatus.Canceled))); ENTERED_STATUS_SAMPLE_LIST.add( Integer.parseInt( StatusService.getInstance().getStatusID( SampleStatus.Entered ) ) ); ABLE_TO_CANCEL_ROLE_NAMES.add( "Validator" ); ABLE_TO_CANCEL_ROLE_NAMES.add( "Validation"); ABLE_TO_CANCEL_ROLE_NAMES.add( "Biologist" ); } protected ActionForward performAction(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { String forward = "success"; request.getSession().setAttribute(SAVE_DISABLED, TRUE); DynaActionForm dynaForm = (DynaActionForm) form; String accessionNumber = request.getParameter("accessionNumber"); boolean allowedToCancelResults = userModuleDAO.isUserAdmin(request) || new UserRoleDAOImpl().userInRole( currentUserId, ABLE_TO_CANCEL_ROLE_NAMES ); if( GenericValidator.isBlankOrNull(accessionNumber)){ accessionNumber = getMostRecentAccessionNumberForPaitient( request.getParameter("patientID")); } dynaForm.initialize(mapping); isEditable = "readwrite".equals(request.getSession().getAttribute(IActionConstants.SAMPLE_EDIT_WRITABLE)) || "readwrite".equals(request.getParameter("type")); PropertyUtils.setProperty(dynaForm, "isEditable", isEditable); if (!GenericValidator.isBlankOrNull(accessionNumber)) { PropertyUtils.setProperty(dynaForm, "accessionNumber", accessionNumber); PropertyUtils.setProperty(dynaForm, "searchFinished", Boolean.TRUE); Sample sample = getSample(accessionNumber); if (sample != null && !GenericValidator.isBlankOrNull(sample.getId())) { List<SampleItem> sampleItemList = getSampleItems(sample); setPatientInfo(dynaForm, sample); List<SampleEditItem> currentTestList = getCurrentTestInfo( sampleItemList, accessionNumber, allowedToCancelResults ); PropertyUtils.setProperty(dynaForm, "existingTests", currentTestList); setAddableTestInfo(dynaForm, sampleItemList, accessionNumber); setAddableSampleTypes(dynaForm); setSampleOrderInfo(dynaForm, sample); PropertyUtils.setProperty( dynaForm, "ableToCancelResults", hasResults(currentTestList, allowedToCancelResults) ); PropertyUtils.setProperty(dynaForm, "maxAccessionNumber", maxAccessionNumber); PropertyUtils.setProperty( dynaForm, "isConfirmationSample", new SampleService( sample ).isConfirmationSample() ); } else { PropertyUtils.setProperty(dynaForm, "noSampleFound", Boolean.TRUE); } } else { PropertyUtils.setProperty(dynaForm, "searchFinished", Boolean.FALSE); request.getSession().setAttribute(IActionConstants.SAMPLE_EDIT_WRITABLE, request.getParameter("type")); } if (FormFields.getInstance().useField(FormFields.Field.InitialSampleCondition)) { PropertyUtils.setProperty(dynaForm, "initialSampleConditionList", DisplayListService.getList(ListType.INITIAL_SAMPLE_CONDITION)); } PropertyUtils.setProperty(form, "currentDate", DateUtil.getCurrentDateAsText()); PatientSearch patientSearch = new PatientSearch(); patientSearch.setLoadFromServerWithPatient( true ); patientSearch.setSelectedPatientActionButtonText( StringUtil.getMessageForKey( "label.patient.search.select" ) ); PropertyUtils.setProperty( form, "patientSearch", patientSearch ); return mapping.findForward(forward); } private Boolean hasResults( List<SampleEditItem> currentTestList, boolean allowedToCancelResults ){ if( !allowedToCancelResults){ return false; } for( SampleEditItem editItem : currentTestList){ if( editItem.isHasResults()){ return true; } } return false; } private void setSampleOrderInfo( DynaActionForm dynaForm, Sample sample ) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { SampleOrderService sampleOrderService = new SampleOrderService( sample ); PropertyUtils.setProperty( dynaForm, "sampleOrderItems", sampleOrderService.getSampleOrderItem() ); } private String getMostRecentAccessionNumberForPaitient(String patientID) { String accessionNumber = null; if( !GenericValidator.isBlankOrNull(patientID)){ List<Sample> samples = new SampleHumanDAOImpl().getSamplesForPatient(patientID); int maxId = 0; for( Sample sample : samples){ if( Integer.parseInt(sample.getId()) > maxId){ maxId = Integer.parseInt(sample.getId()); accessionNumber = sample.getAccessionNumber(); } } } return accessionNumber; } private Sample getSample(String accessionNumber) { SampleDAO sampleDAO = new SampleDAOImpl(); return sampleDAO.getSampleByAccessionNumber(accessionNumber); } private List<SampleItem> getSampleItems(Sample sample) { SampleItemDAO sampleItemDAO = new SampleItemDAOImpl(); return sampleItemDAO.getSampleItemsBySampleIdAndStatus(sample.getId(), ENTERED_STATUS_SAMPLE_LIST ); } private void setPatientInfo(DynaActionForm dynaForm, Sample sample) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { Patient patient = new SampleHumanDAOImpl().getPatientForSample(sample); IPatientService patientService = new PatientService(patient); PropertyUtils.setProperty( dynaForm, "patientName", patientService.getLastFirstName() ); PropertyUtils.setProperty(dynaForm, "dob", patientService.getEnteredDOB()); PropertyUtils.setProperty(dynaForm, "gender", patientService.getGender()); PropertyUtils.setProperty(dynaForm, "nationalId", patientService.getNationalId()); } private List<SampleEditItem> getCurrentTestInfo( List<SampleItem> sampleItemList, String accessionNumber, boolean allowedToCancelAll ) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { List<SampleEditItem> currentTestList = new ArrayList<SampleEditItem>(); for (SampleItem sampleItem : sampleItemList) { addCurrentTestsToList(sampleItem, currentTestList, accessionNumber, allowedToCancelAll); } return currentTestList; } private void addCurrentTestsToList(SampleItem sampleItem, List<SampleEditItem> currentTestList, String accessionNumber, boolean allowedToCancelAll) { TypeOfSample typeOfSample = new TypeOfSample(); typeOfSample.setId(sampleItem.getTypeOfSampleId()); typeOfSampleDAO.getData(typeOfSample); List<Analysis> analysisList = analysisDAO.getAnalysesBySampleItemsExcludingByStatusIds(sampleItem, excludedAnalysisStatusList); List<SampleEditItem> analysisSampleItemList = new ArrayList<SampleEditItem>(); String collectionDate = DateUtil.convertTimestampToStringDate( sampleItem.getCollectionDate() ); String collectionTime = DateUtil.convertTimestampToStringTime( sampleItem.getCollectionDate() ); boolean canRemove = true; for (Analysis analysis : analysisList) { SampleEditItem sampleEditItem = new SampleEditItem(); sampleEditItem.setTestId(analysis.getTest().getId()); sampleEditItem.setTestName(TestService.getUserLocalizedTestName( analysis.getTest() )); sampleEditItem.setSampleItemId(sampleItem.getId()); boolean canCancel = allowedToCancelAll || (!StatusService.getInstance().matches( analysis.getStatusId(), AnalysisStatus.Canceled ) && StatusService.getInstance().matches( analysis.getStatusId(), AnalysisStatus.NotStarted )); if( !canCancel){ canRemove = false; } sampleEditItem.setCanCancel(canCancel); sampleEditItem.setAnalysisId(analysis.getId()); sampleEditItem.setStatus(StatusService.getInstance().getStatusNameFromId(analysis.getStatusId())); sampleEditItem.setSortOrder(analysis.getTest().getSortOrder()); sampleEditItem.setHasResults( !StatusService.getInstance().matches( analysis.getStatusId(), AnalysisStatus.NotStarted ) ); analysisSampleItemList.add(sampleEditItem); } if (!analysisSampleItemList.isEmpty()) { Collections.sort(analysisSampleItemList, testComparator); SampleEditItem firstItem = analysisSampleItemList.get( 0 ); firstItem.setAccessionNumber(accessionNumber + "-" + sampleItem.getSortOrder()); firstItem.setSampleType(typeOfSample.getLocalizedName()); firstItem.setCanRemoveSample(canRemove); firstItem.setCollectionDate( collectionDate == null ? "" : collectionDate ); firstItem.setCollectionTime( collectionTime ); maxAccessionNumber = analysisSampleItemList.get(0).getAccessionNumber(); currentTestList.addAll(analysisSampleItemList); } } private void setAddableTestInfo(DynaActionForm dynaForm, List<SampleItem> sampleItemList, String accessionNumber) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { List<SampleEditItem> possibleTestList = new ArrayList<SampleEditItem>(); for (SampleItem sampleItem : sampleItemList) { addPossibleTestsToList(sampleItem, possibleTestList, accessionNumber); } PropertyUtils.setProperty(dynaForm, "possibleTests", possibleTestList); PropertyUtils.setProperty(dynaForm, "testSectionList", DisplayListService.getList(ListType.TEST_SECTION)); } private void setAddableSampleTypes(DynaActionForm dynaForm) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { PropertyUtils.setProperty(dynaForm, "sampleTypes", DisplayListService.getList(ListType.SAMPLE_TYPE_ACTIVE)); } private void addPossibleTestsToList(SampleItem sampleItem, List<SampleEditItem> possibleTestList, String accessionNumber) { TypeOfSample typeOfSample = new TypeOfSample(); typeOfSample.setId(sampleItem.getTypeOfSampleId()); typeOfSampleDAO.getData( typeOfSample ); TestDAO testDAO = new TestDAOImpl(); Test test = new Test(); TypeOfSampleTestDAO sampleTypeTestDAO = new TypeOfSampleTestDAOImpl(); List<TypeOfSampleTest> typeOfSampleTestList = sampleTypeTestDAO.getTypeOfSampleTestsForSampleType(typeOfSample.getId()); List<SampleEditItem> typeOfTestSampleItemList = new ArrayList<SampleEditItem>(); for (TypeOfSampleTest typeOfSampleTest : typeOfSampleTestList) { SampleEditItem sampleEditItem = new SampleEditItem(); sampleEditItem.setTestId(typeOfSampleTest.getTestId()); test.setId(typeOfSampleTest.getTestId()); testDAO.getData(test); if ("Y".equals(test.getIsActive()) && test.getOrderable()) { sampleEditItem.setTestName( TestService.getUserLocalizedTestName( test ) ); sampleEditItem.setSampleItemId(sampleItem.getId()); sampleEditItem.setSortOrder(test.getSortOrder()); typeOfTestSampleItemList.add(sampleEditItem); } } if (!typeOfTestSampleItemList.isEmpty()) { Collections.sort(typeOfTestSampleItemList, testComparator); typeOfTestSampleItemList.get(0).setAccessionNumber(accessionNumber + "-" + sampleItem.getSortOrder()); typeOfTestSampleItemList.get(0).setSampleType(typeOfSample.getLocalizedName()); possibleTestList.addAll(typeOfTestSampleItemList); } } protected String getPageTitleKey() { return isEditable ? StringUtil.getContextualKeyForKey("sample.edit.title") : StringUtil.getContextualKeyForKey("sample.view.title"); } protected String getPageSubtitleKey() { return isEditable ? StringUtil.getContextualKeyForKey("sample.edit.subtitle") : StringUtil .getContextualKeyForKey("sample.view.subtitle"); } private static class SampleEditItemComparator implements Comparator<SampleEditItem> { public int compare(SampleEditItem o1, SampleEditItem o2) { if (GenericValidator.isBlankOrNull(o1.getSortOrder()) || GenericValidator.isBlankOrNull(o2.getSortOrder())) { return o1.getTestName().compareTo(o2.getTestName()); } try { return Integer.parseInt(o1.getSortOrder()) - Integer.parseInt(o2.getSortOrder()); } catch (NumberFormatException e) { return o1.getTestName().compareTo(o2.getTestName()); } } } }