/** Unselects all reason codes. */
  public ActionForward unselectAllReasonCodes(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {
    OrganizationReportSelectionForm organizationReportSelectionForm =
        (OrganizationReportSelectionForm) form;
    for (BudgetConstructionReasonCodePick budgetConstructionReasonCodePick :
        organizationReportSelectionForm.getReasonCodePickList()) {
      budgetConstructionReasonCodePick.setSelectFlag(new Integer(0));
    }

    return mapping.findForward(KFSConstants.MAPPING_BASIC);
  }
  /** Builds URL for the report dump url. */
  protected String buildReportExportForwardURL(
      OrganizationReportSelectionForm organizationReportSelectionForm, ActionMapping mapping) {
    Map<String, String> parameters = new HashMap<String, String>();
    parameters.put(BCConstants.Report.REPORT_MODE, organizationReportSelectionForm.getReportMode());
    parameters.put(BCConstants.IS_ORG_REPORT_REQUEST_PARAMETER, "true");

    return BudgetUrlUtil.buildBudgetUrl(
        mapping, organizationReportSelectionForm, BCConstants.REPORT_EXPORT_ACTION, parameters);
  }
  /**
   * Checks and stores sub-fund, object code, or reason code list depenending on the report mode and
   * which screen we are on.
   *
   * @param organizationReportSelectionForm - OrganizationReportSelectionForm containing the select
   *     lists
   * @param reportMode - BudgetConstructionReportMode for the report being ran
   * @return - true if a selection was found and the list was stored or if we need to show reason
   *     code select screen, false otherwise
   */
  protected boolean storeCodeSelections(
      OrganizationReportSelectionForm organizationReportSelectionForm,
      BudgetConstructionReportMode reportMode,
      String principalName) {
    boolean codeSelected = true;

    if (ReportSelectMode.SUBFUND.equals(reportMode.reportSelectMode)) {
      // came from sub fund select screen so need to store sub fund selection settings
      if (!storedSelectedSubFunds(organizationReportSelectionForm.getSubFundPickList())) {
        codeSelected = false;
      }
    } else if (organizationReportSelectionForm
        .getOperatingModeTitle()
        .equals(BCConstants.Report.OBJECT_CODE_SELECTION_TITLE)) {
      // came from object code select screen so need to store object code selection settings
      if (!storedSelectedObjectCodes(organizationReportSelectionForm.getObjectCodePickList())) {
        codeSelected = false;
      }

      // determine if we need to setup reason code select
      if (ReportSelectMode.REASON.equals(reportMode.reportSelectMode)
          && !organizationReportSelectionForm
              .getBudgetConstructionReportThresholdSettings()
              .isUseThreshold()) {
        BudgetReportsControlListService budgetReportsControlListService =
            SpringContext.getBean(BudgetReportsControlListService.class);

        // rebuild reason code control list
        budgetReportsControlListService.updateReportReasonCodeSelectList(principalName);

        // setup form
        organizationReportSelectionForm.setReasonCodePickList(
            (List) budgetReportsControlListService.retrieveReasonCodeList(principalName));
        organizationReportSelectionForm.setOperatingModeTitle(
            BCConstants.Report.REASON_CODE_SELECTION_TITLE);
        codeSelected = false;
      }
    } else if (organizationReportSelectionForm
        .getOperatingModeTitle()
        .equals(BCConstants.Report.REASON_CODE_SELECTION_TITLE)) {
      // came from reason code select screen so need to store reason code selection settings
      if (!storedSelectedReasonCodes(organizationReportSelectionForm.getReasonCodePickList())) {
        codeSelected = false;
      }
    }

    return codeSelected;
  }
  /**
   * Called from org select or account listing. Checks for needed control list build, makes call to
   * build control list if necessary, and forwards to subfund or object code select page.
   */
  public ActionForward start(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {
    OrganizationReportSelectionForm organizationReportSelectionForm =
        (OrganizationReportSelectionForm) form;
    String principalName = GlobalVariables.getUserSession().getPerson().getPrincipalId();

    // retrieve report mode to determine how control list should be built and what select screen
    // should be rendered
    BudgetConstructionReportMode reportMode =
        BudgetConstructionReportMode.getBudgetConstructionReportModeByName(
            organizationReportSelectionForm.getReportMode());
    if (reportMode == null) {
      LOG.error(
          "Invalid report mode passed to report select action: "
              + organizationReportSelectionForm.getReportMode());
      throw new RuntimeException(
          "Invalid report mode passed to report select action: "
              + organizationReportSelectionForm.getReportMode());
    }

    // retrieve build helper to determine if a control list rebuild is needed
    ReportControlListBuildHelper buildHelper =
        (ReportControlListBuildHelper)
            GlobalVariables.getUserSession()
                .retrieveObject(BCConstants.Report.CONTROL_BUILD_HELPER_SESSION_NAME);
    if (buildHelper == null) {
      // session timeout, need to rebuild build request
      buildHelper = new ReportControlListBuildHelper();

      Collection<BudgetConstructionPullup> selectedOrganizations =
          SpringContext.getBean(BudgetReportsControlListService.class)
              .retrieveSelectedOrganziations(principalName);
      buildHelper.addBuildRequest(
          organizationReportSelectionForm.getCurrentPointOfViewKeyCode(),
          selectedOrganizations,
          reportMode.reportBuildMode);
      GlobalVariables.getUserSession()
          .addObject(BCConstants.Report.CONTROL_BUILD_HELPER_SESSION_NAME, buildHelper);
    }

    // do list builds
    buildControlLists(
        principalName,
        organizationReportSelectionForm.getUniversityFiscalYear(),
        buildHelper,
        reportMode.reportSelectMode);

    // a few reports go just against the account control table, therefore we are ready to run the
    // report
    if (ReportSelectMode.ACCOUNT.equals(reportMode.reportSelectMode)) {
      // fixed null point exception of operationgModeTitle.
      organizationReportSelectionForm.setOperatingModeTitle(
          BCConstants.Report.NONE_SELECTION_TITLE);
      return performReport(mapping, form, request, response);
    }

    // setup action form
    if (ReportSelectMode.SUBFUND.equals(reportMode.reportSelectMode)) {
      organizationReportSelectionForm.setSubFundPickList(
          (List)
              SpringContext.getBean(BudgetReportsControlListService.class)
                  .retrieveSubFundList(principalName));
      organizationReportSelectionForm.setOperatingModeTitle(
          BCConstants.Report.SUB_FUND_SELECTION_TITLE);
    } else if (ReportSelectMode.OBJECT_CODE.equals(reportMode.reportSelectMode)
        || ReportSelectMode.REASON.equals(reportMode.reportSelectMode)) {
      organizationReportSelectionForm.setObjectCodePickList(
          (List)
              SpringContext.getBean(BudgetReportsControlListService.class)
                  .retrieveObjectCodeList(principalName));
      organizationReportSelectionForm.setOperatingModeTitle(
          BCConstants.Report.OBJECT_CODE_SELECTION_TITLE);
      organizationReportSelectionForm
          .getBudgetConstructionReportThresholdSettings()
          .setLockThreshold(reportMode.lockThreshold);
    }

    return mapping.findForward(KFSConstants.MAPPING_BASIC);
  }
  /** Generates the Budget Report and returns pdf. */
  public ActionForward performReport(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {
    OrganizationReportSelectionForm organizationReportSelectionForm =
        (OrganizationReportSelectionForm) form;
    String principalId = GlobalVariables.getUserSession().getPerson().getPrincipalId();

    BudgetConstructionReportMode reportMode =
        BudgetConstructionReportMode.getBudgetConstructionReportModeByName(
            organizationReportSelectionForm.getReportMode());
    if (!storeCodeSelections(organizationReportSelectionForm, reportMode, principalId)) {
      return mapping.findForward(KFSConstants.MAPPING_BASIC);
    }

    // validate threshold settings if needed
    if (reportMode == BudgetConstructionReportMode.REASON_STATISTICS_REPORT
        || reportMode == BudgetConstructionReportMode.REASON_SUMMARY_REPORT
        || reportMode == BudgetConstructionReportMode.SALARY_SUMMARY_REPORT) {
      if (!this.validThresholdSettings(
          organizationReportSelectionForm.getBudgetConstructionReportThresholdSettings())) {
        return mapping.findForward(KFSConstants.MAPPING_BASIC);
      }
    }

    // for report exports foward to export action to display formatting screen
    if (reportMode.export) {
      String exportUrl = this.buildReportExportForwardURL(organizationReportSelectionForm, mapping);
      return new ActionForward(exportUrl, true);
    }

    // build report data and populate report objects for rendering
    Collection reportSet =
        buildReportData(
            reportMode,
            organizationReportSelectionForm.getUniversityFiscalYear(),
            principalId,
            organizationReportSelectionForm.isReportConsolidation(),
            organizationReportSelectionForm.getBudgetConstructionReportThresholdSettings());

    // build pdf and stream back
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    // output the report or a message if empty
    if (reportSet.isEmpty()) {
      List<String> messageList = new ArrayList<String>();
      messageList.add(BCConstants.Report.MSG_REPORT_NO_DATA);
      SpringContext.getBean(BudgetConstructionReportsServiceHelper.class)
          .generatePdf(messageList, baos);
      WebUtils.saveMimeOutputStreamAsFile(
          response,
          ReportGeneration.PDF_MIME_TYPE,
          baos,
          reportMode.jasperFileName + ReportGeneration.PDF_FILE_EXTENSION);
    } else {
      ResourceBundle resourceBundle =
          ResourceBundle.getBundle(
              BCConstants.Report.REPORT_MESSAGES_CLASSPATH, Locale.getDefault());
      Map<String, Object> reportData = new HashMap<String, Object>();
      reportData.put(JRParameter.REPORT_RESOURCE_BUNDLE, resourceBundle);

      SpringContext.getBean(ReportGenerationService.class)
          .generateReportToOutputStream(
              reportData,
              reportSet,
              BCConstants.Report.REPORT_TEMPLATE_CLASSPATH + reportMode.jasperFileName,
              baos);
      WebUtils.saveMimeOutputStreamAsFile(
          response,
          ReportGeneration.PDF_MIME_TYPE,
          baos,
          reportMode.jasperFileName + ReportGeneration.PDF_FILE_EXTENSION);
    }
    return null;
  }