/** * 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.validator.GenericValidator; import org.apache.struts.Globals; import org.apache.struts.action.*; import org.hibernate.StaleObjectStateException; import org.hibernate.Transaction; 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.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.provider.validation.IAccessionNumberValidator.ValidationResults; import us.mn.state.health.lims.common.services.*; import us.mn.state.health.lims.common.services.SampleAddService.SampleTestCollection; 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.common.util.validator.ActionError; import us.mn.state.health.lims.hibernate.HibernateUtil; 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.organization.dao.OrganizationDAO; import us.mn.state.health.lims.organization.dao.OrganizationOrganizationTypeDAO; import us.mn.state.health.lims.organization.daoimpl.OrganizationDAOImpl; import us.mn.state.health.lims.organization.daoimpl.OrganizationOrganizationTypeDAOImpl; import us.mn.state.health.lims.panel.valueholder.Panel; import us.mn.state.health.lims.patient.valueholder.Patient; import us.mn.state.health.lims.person.dao.PersonDAO; import us.mn.state.health.lims.person.daoimpl.PersonDAOImpl; import us.mn.state.health.lims.person.valueholder.Person; import us.mn.state.health.lims.requester.dao.SampleRequesterDAO; import us.mn.state.health.lims.requester.daoimpl.SampleRequesterDAOImpl; import us.mn.state.health.lims.requester.valueholder.SampleRequester; import us.mn.state.health.lims.sample.bean.SampleEditItem; import us.mn.state.health.lims.sample.bean.SampleOrderItem; 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.util.AccessionNumberUtil; import us.mn.state.health.lims.sample.valueholder.Sample; 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.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 javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class SampleEditUpdateAction extends BaseAction { private static final String DEFAULT_ANALYSIS_TYPE = "MANUAL"; private static final AnalysisDAO analysisDAO = new AnalysisDAOImpl(); private static final SampleItemDAO sampleItemDAO = new SampleItemDAOImpl(); private static final SampleDAO sampleDAO = new SampleDAOImpl(); private static final TestDAO testDAO = new TestDAOImpl(); private static final String CANCELED_TEST_STATUS_ID; private static final String CANCELED_SAMPLE_STATUS_ID; private ObservationHistory paymentObservation = null; private static final ObservationHistoryDAO observationDAO = new ObservationHistoryDAOImpl(); private static final TestSectionDAO testSectionDAO = new TestSectionDAOImpl(); private static final PersonDAO personDAO = new PersonDAOImpl(); private static final SampleRequesterDAO sampleRequesterDAO = new SampleRequesterDAOImpl(); private static final OrganizationDAO organizationDAO = new OrganizationDAOImpl(); private static final OrganizationOrganizationTypeDAO orgOrgTypeDAO = new OrganizationOrganizationTypeDAOImpl(); static { CANCELED_TEST_STATUS_ID = StatusService.getInstance().getStatusID(AnalysisStatus.Canceled); CANCELED_SAMPLE_STATUS_ID = StatusService.getInstance().getStatusID(SampleStatus.Canceled); } @SuppressWarnings("unchecked") protected ActionForward performAction(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { ActionMessages errors; request.getSession().setAttribute(SAVE_DISABLED, TRUE); DynaActionForm dynaForm = (DynaActionForm) form; boolean sampleChanged = accessionNumberChanged(dynaForm); Sample updatedSample = null; if (sampleChanged) { errors = validateNewAccessionNumber(dynaForm.getString("newAccessionNumber")); if (!errors.isEmpty()) { saveErrors(request, errors); request.setAttribute(Globals.ERROR_KEY, errors); return mapping.findForward(FWD_FAIL); } else { updatedSample = updateAccessionNumberInSample(dynaForm); } } List<SampleEditItem> existingTests = (List<SampleEditItem>)dynaForm.get( "existingTests" ); List<Analysis> cancelAnalysisList = createRemoveList(existingTests ); List<SampleItem> updateSampleItemList = createSampleItemUpdateList( existingTests ); List<SampleItem> cancelSampleItemList = createCancelSampleList(existingTests, cancelAnalysisList); List<Analysis> addAnalysisList = createAddAanlysisList((List<SampleEditItem>) dynaForm.get("possibleTests")); if( updatedSample == null){ updatedSample = sampleDAO.getSampleByAccessionNumber(dynaForm.getString("accessionNumber")); } String receivedDateForDisplay = updatedSample.getReceivedDateForDisplay(); String collectionDateFromRecieveDate = null; boolean useReceiveDateForCollectionDate = !FormFields.getInstance().useField(Field.CollectionDate); if (useReceiveDateForCollectionDate) { collectionDateFromRecieveDate = receivedDateForDisplay + " 00:00:00"; } SampleAddService sampleAddService = new SampleAddService(dynaForm.getString("sampleXML"), currentUserId, updatedSample, collectionDateFromRecieveDate); List<SampleTestCollection> addedSamples = createAddSampleList(dynaForm, sampleAddService); SampleOrderService sampleOrderService = new SampleOrderService( (SampleOrderItem )dynaForm.get("sampleOrderItems") ); SampleOrderService.SampleOrderPersistenceArtifacts orderArtifacts = sampleOrderService.getPersistenceArtifacts( updatedSample, currentUserId); if( orderArtifacts.getSample() != null){ sampleChanged = true; updatedSample = orderArtifacts.getSample(); } Person referringPerson = orderArtifacts.getProviderPerson(); Patient patient = new SampleService( updatedSample ).getPatient(); Transaction tx = HibernateUtil.getSession().beginTransaction(); try { for( SampleItem sampleItem : updateSampleItemList){ sampleItemDAO.updateData( sampleItem ); } for (Analysis analysis : cancelAnalysisList) { analysisDAO.updateData(analysis); } for (Analysis analysis : addAnalysisList) { if (analysis.getId() == null) { analysisDAO.insertData(analysis, false); // don't check for duplicates } else { analysisDAO.updateData(analysis); } } for (SampleItem sampleItem : cancelSampleItemList) { sampleItemDAO.updateData(sampleItem); } if (sampleChanged ) { sampleDAO.updateData(updatedSample); } if (paymentObservation != null) { paymentObservation.setPatientId( patient.getId() ); observationDAO.insertOrUpdateData( paymentObservation ); } for( SampleTestCollection sampleTestCollection : addedSamples){ sampleItemDAO.insertData(sampleTestCollection.item); for (Test test : sampleTestCollection.tests) { testDAO.getData(test); Analysis analysis = populateAnalysis(sampleTestCollection, test, sampleTestCollection.testIdToUserSectionMap.get(test.getId()), sampleAddService ); analysisDAO.insertData(analysis, false); // false--do not check for duplicates } if( sampleTestCollection.initialSampleConditionIdList != null){ for( ObservationHistory observation : sampleTestCollection.initialSampleConditionIdList){ observation.setPatientId( patient.getId() ); observation.setSampleItemId(sampleTestCollection.item.getId()); observation.setSampleId(sampleTestCollection.item.getSample().getId()); observation.setSysUserId( currentUserId ); observationDAO.insertData(observation); } } } if( referringPerson != null){ if(referringPerson.getId() == null){ personDAO.insertData( referringPerson ); }else{ personDAO.updateData( referringPerson ); } } for(ObservationHistory observation : orderArtifacts.getObservations()){ observationDAO.insertOrUpdateData( observation ); } if( orderArtifacts.getSamplePersonRequester() != null){ SampleRequester samplePersonRequester = orderArtifacts.getSamplePersonRequester(); samplePersonRequester.setRequesterId( orderArtifacts.getProviderPerson().getId() ); sampleRequesterDAO.insertOrUpdateData( samplePersonRequester ); } if( orderArtifacts.getProviderOrganization() != null ){ boolean link = orderArtifacts.getProviderOrganization().getId() == null; organizationDAO.insertOrUpdateData( orderArtifacts.getProviderOrganization() ); if( link){ orgOrgTypeDAO.linkOrganizationAndType( orderArtifacts.getProviderOrganization(), RequesterService.REFERRAL_ORG_TYPE_ID ); } } if( orderArtifacts.getSampleOrganizationRequester() != null){ if(orderArtifacts.getProviderOrganization() != null ){ orderArtifacts.getSampleOrganizationRequester().setRequesterId( orderArtifacts.getProviderOrganization().getId() ); } sampleRequesterDAO.insertOrUpdateData( orderArtifacts.getSampleOrganizationRequester()); } if( orderArtifacts.getDeletableSampleOrganizationRequester() != null){ sampleRequesterDAO.delete(orderArtifacts.getDeletableSampleOrganizationRequester()); } tx.commit(); } catch (LIMSRuntimeException lre) { tx.rollback(); errors = new ActionMessages(); if (lre.getException() instanceof StaleObjectStateException) { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionError("errors.OptimisticLockException", null, null)); } else { lre.printStackTrace(); errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionError("errors.UpdateException", null, null)); } saveErrors(request, errors); request.setAttribute(Globals.ERROR_KEY, errors); return mapping.findForward(FWD_FAIL); } finally { HibernateUtil.closeSession(); } String sampleEditWritable = (String) request.getSession().getAttribute(IActionConstants.SAMPLE_EDIT_WRITABLE); if (GenericValidator.isBlankOrNull(sampleEditWritable)) { return mapping.findForward(FWD_SUCCESS); } else { Map<String, String> params = new HashMap<String, String>(); params.put("type", sampleEditWritable); return getForwardWithParameters(mapping.findForward(FWD_SUCCESS), params); } } private List<SampleItem> createSampleItemUpdateList( List<SampleEditItem> existingTests ){ List<SampleItem> modifyList = new ArrayList<SampleItem>( ); for( SampleEditItem editItem : existingTests){ if(editItem.isSampleItemChanged()){ SampleItem sampleItem = sampleItemDAO.getData( editItem.getSampleItemId() ); if( sampleItem != null ){ String collectionTime = editItem.getCollectionDate(); if(GenericValidator.isBlankOrNull( collectionTime )){ sampleItem.setCollectionDate( null ); } else { collectionTime += " " + (GenericValidator.isBlankOrNull(editItem.getCollectionTime()) ? "00:00" : editItem.getCollectionTime()); sampleItem.setCollectionDate( DateUtil.convertStringDateToTimestamp( collectionTime )); } sampleItem.setSysUserId( currentUserId ); modifyList.add( sampleItem ); } } } return modifyList; } private Analysis populateAnalysis(SampleTestCollection sampleTestCollection, Test test, String userSelectedTestSection, SampleAddService sampleAddService) { java.sql.Date collectionDateTime = DateUtil.convertStringDateTimeToSqlDate(sampleTestCollection.collectionDate); TestSection testSection = test.getTestSection(); if( !GenericValidator.isBlankOrNull(userSelectedTestSection)){ testSection = testSectionDAO.getTestSectionById( userSelectedTestSection); //change } Panel panel = sampleAddService.getPanelForTest(test); Analysis analysis = new Analysis(); analysis.setTest(test); analysis.setIsReportable(test.getIsReportable()); analysis.setAnalysisType(DEFAULT_ANALYSIS_TYPE); analysis.setSampleItem(sampleTestCollection.item); analysis.setSysUserId(sampleTestCollection.item.getSysUserId()); analysis.setRevision("0"); analysis.setStartedDate(collectionDateTime == null ? DateUtil.getNowAsSqlDate() : collectionDateTime ); analysis.setStatusId(StatusService.getInstance().getStatusID(AnalysisStatus.NotStarted)); analysis.setTestSection(testSection); analysis.setPanel(panel); return analysis; } private List<SampleTestCollection> createAddSampleList(DynaActionForm dynaForm, SampleAddService sampleAddService) { String maxAccessionNumber = dynaForm.getString("maxAccessionNumber"); if( !GenericValidator.isBlankOrNull(maxAccessionNumber)){ sampleAddService.setInitialSampleItemOrderValue(Integer.parseInt(maxAccessionNumber.split("-")[1])); } return sampleAddService.createSampleTestCollection(); } private List<SampleItem> createCancelSampleList(List<SampleEditItem> list, List<Analysis> cancelAnalysisList) { List<SampleItem> cancelList = new ArrayList<SampleItem>(); boolean cancelTest = false; for (SampleEditItem editItem : list) { if (editItem.getAccessionNumber() != null) { cancelTest = false; } if (cancelTest && !cancelAnalysisListContainsId(editItem.getAnalysisId(), cancelAnalysisList)) { Analysis analysis = getCancelableAnalysis(editItem); cancelAnalysisList.add(analysis); } if (editItem.isRemoveSample()) { cancelTest = true; SampleItem sampleItem = getCancelableSampleItem(editItem); if (sampleItem != null) { cancelList.add(sampleItem); } if (!cancelAnalysisListContainsId(editItem.getAnalysisId(), cancelAnalysisList)) { Analysis analysis = getCancelableAnalysis(editItem); cancelAnalysisList.add(analysis); } } } return cancelList; } private SampleItem getCancelableSampleItem(SampleEditItem editItem) { String sampleItemId = editItem.getSampleItemId(); SampleItem item = new SampleItem(); item.setId(sampleItemId); sampleItemDAO.getData(item); if (item.getId() != null) { item.setStatusId(CANCELED_SAMPLE_STATUS_ID); item.setSysUserId(currentUserId); return item; } return null; } private boolean cancelAnalysisListContainsId(String analysisId, List<Analysis> cancelAnalysisList) { for (Analysis analysis : cancelAnalysisList) { if (analysisId.equals(analysis.getId())) { return true; } } return false; } private ActionMessages validateNewAccessionNumber(String accessionNumber) { ActionMessages errors = new ActionMessages(); ValidationResults results = AccessionNumberUtil.correctFormat(accessionNumber, false); if (results != ValidationResults.SUCCESS) { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionError("sample.entry.invalid.accession.number.format", null, null)); } else if (AccessionNumberUtil.isUsed(accessionNumber)) { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionError("sample.entry.invalid.accession.number.used", null, null)); } return errors; } private Sample updateAccessionNumberInSample(DynaActionForm dynaForm) { Sample sample = sampleDAO.getSampleByAccessionNumber(dynaForm.getString("accessionNumber")); if (sample != null) { sample.setAccessionNumber(dynaForm.getString("newAccessionNumber")); sample.setSysUserId(currentUserId); } return sample; } private boolean accessionNumberChanged(DynaActionForm dynaForm) { String newAccessionNumber = dynaForm.getString("newAccessionNumber"); return !GenericValidator.isBlankOrNull( newAccessionNumber ) && !newAccessionNumber.equals( dynaForm.getString( "accessionNumber" ) ); } private List<Analysis> createRemoveList(List<SampleEditItem> tests) { List<Analysis> removeAnalysisList = new ArrayList<Analysis>(); for (SampleEditItem sampleEditItem : tests) { if (sampleEditItem.isCanceled()) { Analysis analysis = getCancelableAnalysis(sampleEditItem); removeAnalysisList.add(analysis); } } return removeAnalysisList; } private Analysis getCancelableAnalysis(SampleEditItem sampleEditItem) { Analysis analysis = new Analysis(); analysis.setId(sampleEditItem.getAnalysisId()); analysisDAO.getData(analysis); analysis.setSysUserId(currentUserId); analysis.setStatusId(StatusService.getInstance().getStatusID(AnalysisStatus.Canceled)); return analysis; } private List<Analysis> createAddAanlysisList(List<SampleEditItem> tests) { List<Analysis> addAnalysisList = new ArrayList<Analysis>(); for (SampleEditItem sampleEditItem : tests) { if (sampleEditItem.isAdd()) { Analysis analysis = newOrExistingCanceledAnalysis(sampleEditItem); if (analysis.getId() == null) { SampleItem sampleItem = new SampleItem(); sampleItem.setId(sampleEditItem.getSampleItemId()); sampleItemDAO.getData(sampleItem); analysis.setSampleItem(sampleItem); Test test = new Test(); test.setId(sampleEditItem.getTestId()); testDAO.getData(test); analysis.setTest(test); analysis.setRevision("0"); analysis.setTestSection(test.getTestSection()); analysis.setEnteredDate(DateUtil.getNowAsTimestamp()); analysis.setIsReportable(test.getIsReportable()); analysis.setAnalysisType("MANUAL"); analysis.setStartedDate(DateUtil.getNowAsSqlDate()); } analysis.setStatusId(StatusService.getInstance().getStatusID(AnalysisStatus.NotStarted)); analysis.setSysUserId(currentUserId); addAnalysisList.add(analysis); } } return addAnalysisList; } private Analysis newOrExistingCanceledAnalysis(SampleEditItem sampleEditItem) { List<Analysis> canceledAnalysis = analysisDAO.getAnalysesBySampleItemIdAndStatusId(sampleEditItem.getSampleItemId(), CANCELED_TEST_STATUS_ID); for (Analysis analysis : canceledAnalysis) { if (sampleEditItem.getTestId().equals(analysis.getTest().getId())) { return analysis; } } return new Analysis(); } protected String getPageTitleKey() { return StringUtil.getContextualKeyForKey("sample.edit.title"); } protected String getPageSubtitleKey() { return StringUtil.getContextualKeyForKey("sample.edit.subtitle"); } }