@SuppressWarnings("unchecked")
  private void setUpForNotes(Sample sample) {
    noteIdToIndicatorMap = new HashMap<String, String>();

    List<Result> results = resultDAO.getResultsForSample(sample);
    History searchHistory = new History();
    searchHistory.setReferenceTable(NOTE_TABLE_ID);
    historyList = new ArrayList<History>();

    Note searchNote = new Note();
    searchNote.setReferenceTableId(RESULT_TABLE_ID);
    for (Result result : results) {
      searchNote.setReferenceId(result.getId());

      List<Note> notes = noteDAO.getAllNotesByRefIdRefTable(searchNote);

      for (Note note : notes) {
        searchHistory.setReferenceId(note.getId());
        noteIdToIndicatorMap.put(
            note.getId(), TestService.getLocalizedTestName(result.getAnalysis().getTest()));
        historyList.addAll(auditTrailDAO.getHistoryByRefIdAndRefTableId(searchHistory));
      }
    }

    newValueMap = new HashMap<String, String>();
  }
 private void addResultSets(Analysis analysis, Result result) {
   Sample sample = analysis.getSampleItem().getSample();
   Patient patient = sampleHumanDAO.getPatientForSample(sample);
   List<DocumentTrack> documents =
       documentTrackDAO.getByTypeRecordAndTable(RESULT_REPORT_ID, RESULT_TABLE_ID, result.getId());
   if (documents.isEmpty()) {
     newResultSet.add(new ResultSet(result, null, null, patient, sample, null, false));
   } else {
     modifiedResultSet.add(new ResultSet(result, null, null, patient, sample, null, false));
   }
 }
  /**
   * Move everything appropriate to the referralItem including one or more of the referralResults
   * from the given list. Note: This method removes an item from the referralResults list.
   *
   * @param referralItem The source item
   * @param referralResults The created list
   */
  private List<ReferralResult> setReferralItemForNextTest(
      IReferralResultTest referralItem, List<ReferralResult> referralResults) {

    ReferralResult nextTestFirstResult = referralResults.remove(0);
    List<ReferralResult> resultsForOtherTests = new ArrayList<ReferralResult>(referralResults);

    referralItem.setReferredTestId(nextTestFirstResult.getTestId());
    referralItem.setReferredTestIdShadow(referralItem.getReferredTestId());
    referralItem.setReferredReportDate(
        DateUtil.convertTimestampToStringDate(nextTestFirstResult.getReferralReportDate()));
    // We can not use ResultService because that assumes the result is for an analysis, not a
    // referral
    Result result = nextTestFirstResult.getResult();

    String resultType = (result != null) ? result.getResultType() : "N";
    referralItem.setReferredResultType(resultType);
    if (!ResultType.isMultiSelectVariant(resultType)) {
      if (result != null) {
        String resultValue =
            GenericValidator.isBlankOrNull(result.getValue()) ? "" : result.getValue();
        referralItem.setReferredResult(resultValue);
        referralItem.setReferredDictionaryResult(resultValue);
      }
    } else {
      ArrayList<Result> resultList = new ArrayList<Result>();
      resultList.add(nextTestFirstResult.getResult());

      for (ReferralResult referralResult : referralResults) {
        if (nextTestFirstResult.getTestId().equals(referralResult.getTestId())
            && !GenericValidator.isBlankOrNull(referralResult.getResult().getValue())) {
          resultList.add(referralResult.getResult());
          resultsForOtherTests.remove(referralResult);
        }
      }

      referralItem.setMultiSelectResultValues(
          ResultService.getJSONStringForMultiSelect(resultList));
    }

    return resultsForOtherTests;
  }
  private String getAppropriateResultValue(List<Result> results) {
    Result result = results.get(0);
    if (ResultType.DICTIONARY.matches(result.getResultType())) {
      Dictionary dictionary = dictionaryDAO.getDictionaryById(result.getValue());
      if (dictionary != null) {
        return dictionary.getLocalizedName();
      }
    } else if (ResultType.isMultiSelectVariant(result.getResultType())) {
      Dictionary dictionary = new Dictionary();
      StringBuilder multiResult = new StringBuilder();

      for (Result subResult : results) {
        dictionary.setId(subResult.getValue());
        dictionaryDAO.getData(dictionary);

        if (dictionary.getId() != null) {
          multiResult.append(dictionary.getLocalizedName());
          multiResult.append(", ");
        }
      }

      if (multiResult.length() > 0) {
        multiResult.setLength(multiResult.length() - 2); // remove last ", "
      }

      return multiResult.toString();
    } else {
      String resultValue =
          GenericValidator.isBlankOrNull(result.getValue()) ? "" : result.getValue();

      if (!GenericValidator.isBlankOrNull(resultValue)
          && result.getAnalysis().getTest().getUnitOfMeasure() != null) {
        resultValue += " " + result.getAnalysis().getTest().getUnitOfMeasure().getName();
      }

      return resultValue;
    }

    return "";
  }
  protected ActivityReportBean createActivityReportBean(Result result, boolean useTestName) {
    ActivityReportBean item = new ActivityReportBean();

    ResultService resultService = new ResultService(result);
    SampleService sampleService =
        new SampleService(result.getAnalysis().getSampleItem().getSample());
    PatientService patientService = new PatientService(sampleService.getSample());
    item.setResultValue(resultService.getResultValue("\n", true, true));
    item.setTechnician(resultService.getSignature());
    item.setAccessionNumber(sampleService.getAccessionNumber().substring(PREFIX_LENGTH));
    item.setReceivedDate(sampleService.getReceivedDateWithTwoYearDisplay());
    item.setResultDate(DateUtil.convertTimestampToTwoYearStringDate(result.getLastupdated()));
    item.setCollectionDate(
        DateUtil.convertTimestampToTwoYearStringDate(
            result.getAnalysis().getSampleItem().getCollectionDate()));

    List<String> values = new ArrayList<String>();
    values.add(
        patientService.getLastName() == null ? "" : patientService.getLastName().toUpperCase());
    values.add(patientService.getNationalId());

    String referringPatientId =
        ObservationHistoryService.getValueForSample(
            ObservationType.REFERRERS_PATIENT_ID, sampleService.getSample().getId());
    values.add(referringPatientId == null ? "" : referringPatientId);

    String name = StringUtil.buildDelimitedStringFromList(values, " / ", true);

    if (useTestName) {
      item.setPatientOrTestName(resultService.getTestName());
      item.setNonPrintingPatient(name);
    } else {
      item.setPatientOrTestName(name);
    }

    return item;
  }
  protected ActionForward performAction(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {

    String forward = FWD_SUCCESS;
    request.setAttribute(ALLOW_EDITS_KEY, "true");

    BaseActionForm dynaForm = (BaseActionForm) form;
    // server-side validation (validation.xml)
    ActionMessages errors = dynaForm.validate(mapping, request);

    // bugzilla 2614 allow for NB domain samples
    String selectedTestId = "";

    String referenceTableId = SystemConfiguration.getInstance().getResultReferenceTableId();
    String refId = (String) dynaForm.get("noteRefId");

    String noteIds = (String) dynaForm.get("noteIds");
    String noteSubjects = (String) dynaForm.get("noteSubjects");
    String noteTexts = (String) dynaForm.get("noteTexts");
    String noteTypes = (String) dynaForm.get("noteTypes");
    String noteLastupdateds = (String) dynaForm.get("noteLastupdateds");

    List noteIdList = new ArrayList();
    List noteSubjectList = new ArrayList();
    List noteTextList = new ArrayList();
    List noteTypeList = new ArrayList();
    List noteLastupdatedList = new ArrayList();

    String textSeparator = SystemConfiguration.getInstance().getDefaultTextSeparator();

    NoteDAO noteDAO = new NoteDAOImpl();
    SystemUserDAO systemUserDAO = new SystemUserDAOImpl();
    // bugzilla 2571 go through ReferenceTablesDAO to get reference tables info
    ReferenceTablesDAO referenceTablesDAO = new ReferenceTablesDAOImpl();

    // get sysUserId from login module
    UserSessionData usd = (UserSessionData) request.getSession().getAttribute(USER_SESSION_DATA);
    String sysUserId = String.valueOf(usd.getSystemUserId());
    org.hibernate.Transaction tx = HibernateUtil.getSession().beginTransaction();

    try {

      textSeparator = StringUtil.convertStringToRegEx(textSeparator);

      SystemUser systemUser = new SystemUser();
      systemUser.setId(sysUserId);
      systemUserDAO.getData(systemUser);

      // get all the data required to forward to correct page

      // get analysis id from result
      ResultDAO resultDAO = new ResultDAOImpl();
      Result result = new Result();
      result.setId(refId);
      resultDAO.getData(result);

      String analysisId = result.getAnalysis().getId();

      AnalysisDAO analysisDAO = new AnalysisDAOImpl();
      Analysis analysis = new Analysis();
      analysis.setId(analysisId);
      analysisDAO.getData(analysis);

      // get test id from analysis
      selectedTestId = analysis.getTest().getId();

      // get domain from sample
      SampleItemDAO sampleItemDAO = new SampleItemDAOImpl();
      SampleItem sampleItem = new SampleItem();
      sampleItem.setId(analysis.getSampleItem().getId());
      sampleItemDAO.getData(sampleItem);

      SampleDAO sampleDAO = new SampleDAOImpl();
      Sample sample = new Sample();
      // bugzilla 1773 need to store sample not sampleId for use in sorting
      sample.setId(sampleItem.getSample().getId());
      sampleDAO.getData(sample);

      // bugzilla 2614 allow for NB domain samples
      // now that we have the domain (for forwarding to correct fail page)
      // validate note popup form data!
      try {
        // bugzilla 2254 moved loadListFromStringOfElements to StringUtil
        noteIdList = StringUtil.loadListFromStringOfElements(noteIds, textSeparator, false);
        noteLastupdatedList =
            StringUtil.loadListFromStringOfElements(noteLastupdateds, textSeparator, false);
        // these three need to be validated for empty strings
        noteSubjectList =
            StringUtil.loadListFromStringOfElements(noteSubjects, textSeparator, true);
        noteTextList = StringUtil.loadListFromStringOfElements(noteTexts, textSeparator, true);
        noteTypeList = StringUtil.loadListFromStringOfElements(noteTypes, textSeparator, true);

      } catch (Exception e) {
        // bugzilla 2154
        LogEvent.logError("ResultsEntryNotesUpdateAction", "performAction()", e.toString());
        String messageKey = "note.note";
        ActionError error = new ActionError("errors.invalid", getMessageForKey(messageKey), null);
        errors.add(ActionMessages.GLOBAL_MESSAGE, error);
        saveErrors(request, errors);
        forward = FWD_FAIL;

        return mapping.findForward(forward);
      }

      for (int i = 0; i < noteIdList.size(); i++) {
        Note note = new Note();

        String noteId = (String) noteIdList.get(i);
        note.setReferenceId(refId);
        // bugzilla 1922
        // bugzilla 2571 go through ReferenceTablesDAO to get reference tables info
        ReferenceTables referenceTables = new ReferenceTables();
        referenceTables.setId(referenceTableId);
        // bugzilla 2571
        referenceTablesDAO.getData(referenceTables);
        note.setReferenceTables(referenceTables);
        note.setSystemUser(systemUser);
        note.setSystemUserId(sysUserId);
        // 1926 for audit trail
        note.setSysUserId(sysUserId);

        if (noteId != null && !noteId.equals("0")) {
          note.setId((String) noteIdList.get(i));
          note.setSubject((String) noteSubjectList.get(i));
          note.setText((String) noteTextList.get(i));
          note.setNoteType((String) noteTypeList.get(i));

          Timestamp noteTimestamp = null;
          if (!StringUtil.isNullorNill((String) noteLastupdatedList.get(i))) {

            noteTimestamp = DateUtil.formatStringToTimestamp((String) noteLastupdatedList.get(i));
          }

          note.setLastupdated(noteTimestamp);

          // UPDATE
          noteDAO.updateData(note);
          // }

        } else {
          // this is a new note
          note.setSubject((String) noteSubjectList.get(i));
          note.setText((String) noteTextList.get(i));
          note.setNoteType((String) noteTypeList.get(i));
          // INSERT
          noteDAO.insertData(note);
        }
      }

      tx.commit();

      return getForward(mapping.findForward(forward), selectedTestId, analysisId);

    } catch (LIMSRuntimeException lre) {
      // bugzilla 2154
      LogEvent.logError("ResultsEntryNotesUpdateAction", "performAction()", lre.toString());
      tx.rollback();
      errors = new ActionMessages();
      ActionError error = null;
      if (lre.getException() instanceof org.hibernate.StaleObjectStateException) {
        error = new ActionError("errors.OptimisticLockException", null, null);
      } else {
        if (lre.getException() instanceof LIMSDuplicateRecordException) {
          java.util.Locale locale =
              (java.util.Locale)
                  request.getSession().getAttribute("org.apache.struts.action.LOCALE");
          String messageKey = "note.note";
          String msg =
              ResourceLocator.getInstance().getMessageResources().getMessage(locale, messageKey);
          error = new ActionError("errors.DuplicateRecord", msg, null);

        } else {
          error = new ActionError("errors.UpdateException", null, null);
        }
      }
      errors.add(ActionMessages.GLOBAL_MESSAGE, error);
      saveErrors(request, errors);
      request.setAttribute(Globals.ERROR_KEY, errors);

      // disable previous and next
      request.setAttribute(PREVIOUS_DISABLED, "true");
      request.setAttribute(NEXT_DISABLED, "true");

      // default forward fail
      forward = FWD_FAIL;

    } finally {
      HibernateUtil.closeSession();
    }
    if (forward.equals(FWD_FAIL)
        || forward.equals(FWD_FAIL_HUMAN)
        || forward.equals(FWD_FAIL_ANIMAL)) return mapping.findForward(forward);

    // initialize the form
    dynaForm.initialize(mapping);

    // we need this for subsequent actions to
    // get data related to note parent for forwarding to next page
    request.setAttribute("refId", refId);
    request.setAttribute(SELECTED_TEST_ID, selectedTestId);

    return mapping.findForward(forward);
  }
  @Override
  protected ActionForward performAction(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {

    String forward = FWD_SUCCESS;

    List<IResultUpdate> updaters = ValidationUpdateRegister.getRegisteredUpdaters();
    boolean areListeners = updaters != null && !updaters.isEmpty();

    request.getSession().setAttribute(SAVE_DISABLED, "true");

    BaseActionForm dynaForm = (BaseActionForm) form;

    ResultValidationPaging paging = new ResultValidationPaging();
    paging.updatePagedResults(request, dynaForm);
    List<AnalysisItem> resultItemList = paging.getResults(request);

    String testSectionName = (String) dynaForm.get("testSection");
    String testName = (String) dynaForm.get("testName");
    setRequestType(testSectionName);

    ActionMessages errors = validateModifiedItems(resultItemList);

    if (errors.size() > 0) {
      saveErrors(request, errors);
      request.setAttribute(Globals.ERROR_KEY, errors);
      return mapping.findForward(FWD_VALIDATION_ERROR);
    }

    createSystemUser();
    setSampleFinishedStatuses();

    noteUpdateList = new ArrayList<Note>();
    resultUpdateList = new ArrayList<Result>();
    analysisUpdateList = new ArrayList<Analysis>();
    modifiedResultSet = new ArrayList<ResultSet>();
    newResultSet = new ArrayList<ResultSet>();
    deletableList = new ArrayList<Result>();

    if (testSectionName.equals("serology")) {
      createUpdateElisaList(resultItemList);
    } else {
      createUpdateList(resultItemList, areListeners);
    }

    Transaction tx = HibernateUtil.getSession().beginTransaction();

    try {
      ResultSaveService.removeDeletedResultsInTransaction(deletableList, currentUserId);

      // update analysis
      for (Analysis analysis : analysisUpdateList) {
        analysisDAO.updateData(analysis);
      }

      for (Result result : resultUpdateList) {
        if (result.getId() != null) {
          resultDAO.updateData(result);
        } else {
          resultDAO.insertData(result);
        }
      }

      checkIfSamplesFinished(resultItemList);

      // update finished samples
      for (Sample sample : sampleUpdateList) {
        sampleDAO.updateData(sample);
      }

      // create or update notes
      for (Note note : noteUpdateList) {
        if (note != null) {
          if (note.getId() == null) {
            noteDAO.insertData(note);
          } else {
            noteDAO.updateData(note);
          }
        }
      }

      for (IResultUpdate updater : updaters) {
        updater.transactionalUpdate(this);
      }

      tx.commit();

    } catch (LIMSRuntimeException lre) {
      tx.rollback();
    }

    for (IResultUpdate updater : updaters) {
      updater.postTransactionalCommitUpdate(this);
    }

    if (isBlankOrNull(testSectionName)) {
      return mapping.findForward(forward);
    } else {
      Map<String, String> params = new HashMap<String, String>();
      params.put("type", testSectionName);
      params.put("test", testName);
      params.put("forward", forward);

      return getForwardWithParameters(mapping.findForward(forward), params);
    }
  }
  private ReferralItem getReferralItem(Referral referral) {
    boolean allReferralResultsHaveResults = true;
    List<ReferralResult> referralResults =
        referralResultDAO.getReferralResultsForReferral(referral.getId());
    for (ReferralResult referralResult : referralResults) {
      if (referralResult.getResult() == null
          || GenericValidator.isBlankOrNull(referralResult.getResult().getValue())) {
        allReferralResultsHaveResults = false;
        break;
      }
    }

    if (allReferralResultsHaveResults) {
      return null;
    }

    ReferralItem referralItem = new ReferralItem();

    AnalysisService analysisService = new AnalysisService(referral.getAnalysis());

    referralItem.setCanceled(false);
    referralItem.setReferredResultType("N");
    referralItem.setAccessionNumber(analysisService.getOrderAccessionNumber());

    TypeOfSample typeOfSample = analysisService.getTypeOfSample();
    referralItem.setSampleType(typeOfSample.getLocalizedName());

    referralItem.setReferringTestName(
        TestService.getUserLocalizedTestName(analysisService.getAnalysis().getTest()));
    List<Result> resultList = analysisService.getResults();
    String resultString = "";

    if (!resultList.isEmpty()) {
      Result result = resultList.get(0);
      resultString = getAppropriateResultValue(resultList);
      referralItem.setInLabResultId(result.getId());
    }

    referralItem.setReferralId(referral.getId());
    if (!referralResults.isEmpty()) {
      referralResults = setReferralItemForNextTest(referralItem, referralResults);
      if (!referralResults.isEmpty()) {
        referralItem.setAdditionalTests(getAdditionalReferralTests(referralResults));
      }
    }
    referralItem.setReferralResults(resultString);
    referralItem.setReferralDate(DateUtil.convertTimestampToStringDate(referral.getRequestDate()));
    referralItem.setReferredSendDate(getSendDateOrDefault(referral));
    referralItem.setReferrer(referral.getRequesterName());
    referralItem.setReferralReasonId(referral.getReferralReasonId());
    referralItem.setTestSelectionList(getTestsForTypeOfSample(typeOfSample));
    referralItem.setReferralId(referral.getId());
    if (referral.getOrganization() != null) {
      referralItem.setReferredInstituteId(referral.getOrganization().getId());
    }
    String notes = analysisService.getNotesAsString(true, true, "<br/>", false);
    if (notes != null) {
      referralItem.setPastNotes(notes);
    }

    return referralItem;
  }