/**
   * @param awardBalancesReportEntry
   * @param reportDetail
   */
  private void setReportDate(
      ContractsGrantsAwardBalancesReport awardBalancesReportEntry,
      ContractsGrantsAwardBalancesReportDetailDataHolder reportDetail) {
    reportDetail.setProposalNumber(awardBalancesReportEntry.getProposalNumber());

    String agencyName =
        (ObjectUtils.isNull(awardBalancesReportEntry.getAgency()))
            ? null
            : awardBalancesReportEntry.getAgency().getReportingName();
    reportDetail.setAgencyName(agencyName);

    reportDetail.setAwardProjectTitle(awardBalancesReportEntry.getAwardProjectTitle());
    reportDetail.setAwardStatusCode(awardBalancesReportEntry.getAwardStatusCode());

    reportDetail.setAwardBeginningDate(awardBalancesReportEntry.getAwardBeginningDate());
    reportDetail.setAwardEndingDate(awardBalancesReportEntry.getAwardEndingDate());

    reportDetail.setPrimaryProjectDirector(
        awardBalancesReportEntry.getAwardPrimaryProjectDirectorName());
    reportDetail.setPrimaryFundManager(awardBalancesReportEntry.getAwardPrimaryFundManagerName());

    BigDecimal awardTotalAmount =
        (ObjectUtils.isNull(awardBalancesReportEntry.getAwardTotalAmountForReport()))
            ? BigDecimal.ZERO
            : awardBalancesReportEntry.getAwardTotalAmountForReport().bigDecimalValue();
    reportDetail.setAwardTotalAmount(awardTotalAmount);

    BigDecimal totalBilledToDate =
        (ObjectUtils.isNull(awardBalancesReportEntry.getTotalBilledToDate()))
            ? BigDecimal.ZERO
            : awardBalancesReportEntry.getTotalBilledToDate().bigDecimalValue();
    reportDetail.setTotalBilledToDate(totalBilledToDate);

    BigDecimal totalPaymentsToDate =
        (ObjectUtils.isNull(awardBalancesReportEntry.getTotalPaymentsToDate()))
            ? BigDecimal.ZERO
            : awardBalancesReportEntry.getTotalPaymentsToDate().bigDecimalValue();
    reportDetail.setTotalPaymentsToDate(totalPaymentsToDate);

    reportDetail.setAmountCurrentlyDue(totalBilledToDate.subtract(totalPaymentsToDate));
  }
  /**
   * This service is used to print the report.
   *
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @return
   * @throws Exception
   */
  public ActionForward print(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {
    ContractsGrantsAwardBalancesReportLookupForm awardBalancesReportLookupForm =
        (ContractsGrantsAwardBalancesReportLookupForm) form;

    String methodToCall = findMethodToCall(form, request);
    if (methodToCall.equalsIgnoreCase(KRADConstants.SEARCH_METHOD)) {
      GlobalVariables.getUserSession().removeObjectsByPrefix(KRADConstants.SEARCH_METHOD);
    }

    Lookupable kualiLookupable = awardBalancesReportLookupForm.getLookupable();
    if (kualiLookupable == null) {
      throw new RuntimeException("Lookupable is null.");
    }

    List<ResultRow> resultTable = new ArrayList<ResultRow>();

    // validate search parameters
    kualiLookupable.validateSearchParameters(awardBalancesReportLookupForm.getFields());

    // this is for 200 limit. turn it off for report.
    boolean isUnbounded = true;

    List<ContractsGrantsAwardBalancesReport> displayList =
        (List<ContractsGrantsAwardBalancesReport>)
            kualiLookupable.performLookup(awardBalancesReportLookupForm, resultTable, isUnbounded);
    Object sortIndexObject =
        GlobalVariables.getUserSession().retrieveObject(ArConstants.SORT_INDEX_SESSION_KEY);

    if (ObjectUtils.isNull(sortIndexObject) || sortIndexObject.toString() == "0") {
      sortIndexObject = "0";
    }
    // get sort property
    String sortPropertyName =
        getFieldNameForSorting(
            Integer.parseInt(sortIndexObject.toString()), "ContractsGrantsAwardBalancesReport");

    // sort list
    sortReport(displayList, sortPropertyName);

    // check field is valid for subtotal
    boolean isFieldSubtotalRequired =
        CGConstants.ReportsConstants.awardBalancesReportSubtotalFieldsList.contains(
            sortPropertyName);
    Map<String, KualiDecimal> subTotalMap = new HashMap<String, KualiDecimal>();

    if (isFieldSubtotalRequired) {
      subTotalMap = buildSubTotalMap(displayList, sortPropertyName);
    }

    // build report
    ContractsGrantsReportDataHolder awardBalancesReportDataHolder =
        new ContractsGrantsReportDataHolder();
    List<ContractsGrantsAwardBalancesReportDetailDataHolder> details =
        awardBalancesReportDataHolder.getDetails();

    for (ContractsGrantsAwardBalancesReport awardBalancesReportEntry : displayList) {
      ContractsGrantsAwardBalancesReportDetailDataHolder reportDetail =
          new ContractsGrantsAwardBalancesReportDetailDataHolder();
      // set report data
      setReportDate(awardBalancesReportEntry, reportDetail);

      if (isFieldSubtotalRequired) {
        // set sortedFieldValue for grouping in the report
        reportDetail.setSortedFieldValue(
            getPropertyValue(awardBalancesReportEntry, sortPropertyName));
        reportDetail.setDisplaySubtotal(true);
        // set subTotal from subTotalMap
        reportDetail.setSubTotal(
            subTotalMap
                .get(getPropertyValue(awardBalancesReportEntry, sortPropertyName))
                .bigDecimalValue());
      } else {
        // set this to empty string for not displaying subtotal
        reportDetail.setDisplaySubtotal(false);
      }
      details.add(reportDetail);
    }
    awardBalancesReportDataHolder.setDetails(details);

    // build search criteria for report
    buildReportForSearchCriteia(
        awardBalancesReportDataHolder.getSearchCriteria(),
        awardBalancesReportLookupForm.getFieldsForLookup());

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    String reportFileName =
        SpringContext.getBean(ContractsGrantsAwardBalancesReportService.class)
            .generateReport(awardBalancesReportDataHolder, baos);
    WebUtils.saveMimeOutputStreamAsFile(
        response,
        ReportGeneration.PDF_MIME_TYPE,
        baos,
        reportFileName + ReportGeneration.PDF_FILE_EXTENSION);
    return null;
  }