/**
   * Get the search results that meet the input search criteria.
   *
   * @param fieldValues - Map containing prop name keys and search values
   * @return a List of found business objects
   */
  @Override
  public List getSearchResultsUnbounded(Map fieldValues) {
    List<ContractsGrantsInvoiceDocument> results = new ArrayList<ContractsGrantsInvoiceDocument>();
    setBackLocation((String) fieldValues.get(KFSConstants.BACK_LOCATION));
    setDocFormKey((String) fieldValues.get(KFSConstants.DOC_FORM_KEY));

    total0to30 = KualiDecimal.ZERO;
    total31to60 = KualiDecimal.ZERO;
    total61to90 = KualiDecimal.ZERO;
    total91toSYSPR = KualiDecimal.ZERO;
    totalSYSPRplus1orMore = KualiDecimal.ZERO;
    totalOpenInvoices = KualiDecimal.ZERO;
    totalWriteOffs = KualiDecimal.ZERO;
    totalCredits = KualiDecimal.ZERO;

    reportOption = ArConstants.CustomerAgingReportFields.BILLING_ORG;

    Collection<CustomerInvoiceDocument> invoices = new ArrayList<CustomerInvoiceDocument>();
    Map<String, ContractsAndGrantsAgingReport> knownCustomers =
        new HashMap<String, ContractsAndGrantsAgingReport>();
    ContractsAndGrantsAgingReport custDetail;
    DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
    dateFormat.setLenient(false);

    try {
      Date today = getDateTimeService().getCurrentDate();
      String reportRunDateStr =
          (String) fieldValues.get(ArPropertyConstants.CustomerAgingReportFields.REPORT_RUN_DATE);

      if (ObjectUtils.isNull(reportRunDateStr) || reportRunDateStr.isEmpty()) {
        reportRunDate = today;
      } else {
        reportRunDate = dateFormat.parse(reportRunDateStr);
      }

      // set dates for buckets
      Date cutoffdate30 = DateUtils.addDays(reportRunDate, -30);
      Date cutoffdate31 = DateUtils.addDays(reportRunDate, -31);
      Date cutoffdate60 = DateUtils.addDays(reportRunDate, -60);
      Date cutoffdate61 = DateUtils.addDays(reportRunDate, -61);
      Date cutoffdate90 = DateUtils.addDays(reportRunDate, -90);
      Date cutoffdate91 = DateUtils.addDays(reportRunDate, -91);
      Date cutoffdate120 =
          DateUtils.addDays(reportRunDate, -1 * Integer.parseInt(nbrDaysForLastBucket));
      Date cutoffdate121 = DateUtils.addDays(cutoffdate120, -1);

      // retrieve filtered data according to the lookup
      Map<String, List<ContractsGrantsInvoiceDocument>> cgMapByCustomer =
          contractsGrantsAgingReportService.filterContractsGrantsAgingReport(
              fieldValues, null, new java.sql.Date(reportRunDate.getTime()));

      // prepare list for pdf
      if (ObjectUtils.isNotNull(cgMapByCustomer) && !cgMapByCustomer.isEmpty()) {
        for (String customer : cgMapByCustomer.keySet()) {
          results.addAll(cgMapByCustomer.get(customer));
        }
      }
    } catch (Exception ex) {
      LOG.error(
          "problem during ContractsGrantsAgingReportLookupableHelperServiceImpl.getSearchResultsUnbounded()",
          ex);
    }
    return new CollectionIncomplete<ContractsGrantsInvoiceDocument>(results, (long) results.size());
  }
  /**
   * This method populates ContractsGrantsAgingOpenInvoicesReportDetails (Contracts & Grants Open
   * Invoices Report)
   *
   * @param urlParameters
   */
  @Override
  public List getPopulatedReportDetails(Map urlParameters) {
    List results = new ArrayList();
    String customerNumber = ((String[]) urlParameters.get(KFSPropertyConstants.CUSTOMER_NUMBER))[0];
    String customerName = ((String[]) urlParameters.get(KFSPropertyConstants.CUSTOMER_NAME))[0];

    String orgCode =
        ObjectUtils.isNotNull(urlParameters.get(KFSPropertyConstants.ORGANIZATION_CODE))
            ? ((String[]) urlParameters.get(KFSPropertyConstants.ORGANIZATION_CODE))[0]
            : null;
    String chartCode =
        ObjectUtils.isNotNull(urlParameters.get(ArPropertyConstants.BILLING_CHART_CODE))
            ? ((String[]) urlParameters.get(ArPropertyConstants.BILLING_CHART_CODE))[0]
            : null;
    String strBeginDate =
        ObjectUtils.isNotNull(
                urlParameters.get(KFSConstants.CustomerOpenItemReport.REPORT_BEGIN_DATE))
            ? ((String[]) urlParameters.get(KFSConstants.CustomerOpenItemReport.REPORT_BEGIN_DATE))
                [0]
            : null;
    String strEndDate =
        ObjectUtils.isNotNull(
                urlParameters.get(KFSConstants.CustomerOpenItemReport.REPORT_END_DATE))
            ? ((String[]) urlParameters.get(KFSConstants.CustomerOpenItemReport.REPORT_END_DATE))[0]
            : null;
    java.sql.Date startDate = null;
    java.sql.Date endDate = null;
    List<ContractsGrantsInvoiceDocument> selectedInvoices =
        new ArrayList<ContractsGrantsInvoiceDocument>();
    try {

      if (ObjectUtils.isNotNull(strBeginDate) && StringUtils.isNotEmpty(strBeginDate)) {
        startDate = getDateTimeService().convertToSqlDate(strBeginDate);
      }

      if (ObjectUtils.isNotNull(strEndDate) && StringUtils.isNotEmpty(strEndDate)) {
        endDate = getDateTimeService().convertToSqlDate(strEndDate);
      }

      Map<String, String> fieldValueMap = new HashMap<String, String>();
      for (Object key : urlParameters.keySet()) {
        String val = ((String[]) urlParameters.get(key))[0];
        fieldValueMap.put(key.toString(), val);
      }

      Map<String, List<ContractsGrantsInvoiceDocument>> map =
          contractsGrantsAgingReportService.filterContractsGrantsAgingReport(
              fieldValueMap, startDate, endDate);
      if (ObjectUtils.isNotNull(map) && !map.isEmpty()) {
        selectedInvoices = map.get(customerNumber + "-" + customerName);
      }

      if (selectedInvoices.size() == 0) {
        return results;
      }

    } catch (ParseException ex) {
      LOG.error(
          "problem during ContractsGrantsAgingOpenInvoicesReportServiceImpl.getPopulatedReportDetails",
          ex);
      throw new RuntimeException("Couldn't parse a date", ex);
    }

    populateReportDetails(selectedInvoices, results);
    return results;
  }
  /**
   * Get the search results that meet the input search criteria.
   *
   * @param fieldValues - Map containing prop name keys and search values
   * @return a List of found business objects
   */
  @Override
  public List getSearchResults(Map fieldValues) {
    List<ContractsAndGrantsAgingReport> results = new ArrayList<ContractsAndGrantsAgingReport>();
    setBackLocation((String) fieldValues.get(KFSConstants.BACK_LOCATION));
    setDocFormKey((String) fieldValues.get(KFSConstants.DOC_FORM_KEY));

    total0to30 = KualiDecimal.ZERO;
    total31to60 = KualiDecimal.ZERO;
    total61to90 = KualiDecimal.ZERO;
    total91toSYSPR = KualiDecimal.ZERO;
    totalSYSPRplus1orMore = KualiDecimal.ZERO;
    totalOpenInvoices = KualiDecimal.ZERO;
    totalWriteOffs = KualiDecimal.ZERO;
    totalCredits = KualiDecimal.ZERO;

    Collection<CustomerInvoiceDocument> invoices = new ArrayList<CustomerInvoiceDocument>();
    Map<String, ContractsAndGrantsAgingReport> knownCustomers =
        new HashMap<String, ContractsAndGrantsAgingReport>();
    ContractsAndGrantsAgingReport custDetail;

    DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
    dateFormat.setLenient(false);

    Date today = getDateTimeService().getCurrentDate();
    String reportRunDateStr =
        (String) fieldValues.get(ArPropertyConstants.CustomerAgingReportFields.REPORT_RUN_DATE);
    try {

      if (ObjectUtils.isNull(reportRunDateStr) || reportRunDateStr.isEmpty()) {
        reportRunDate = today;
      } else {
        reportRunDate = dateFormat.parse(reportRunDateStr);
      }
      // set dates for buckets
      Date cutoffdate30 = DateUtils.addDays(reportRunDate, -30);
      Date cutoffdate31 = DateUtils.addDays(reportRunDate, -31);
      Date cutoffdate60 = DateUtils.addDays(reportRunDate, -60);
      Date cutoffdate61 = DateUtils.addDays(reportRunDate, -61);
      Date cutoffdate90 = DateUtils.addDays(reportRunDate, -90);
      Date cutoffdate91 = DateUtils.addDays(reportRunDate, -91);
      Date cutoffdate120 =
          DateUtils.addDays(reportRunDate, -1 * Integer.parseInt(nbrDaysForLastBucket));
      Date cutoffdate121 = DateUtils.addDays(cutoffdate120, -1);

      // retrieve filtered data according to the lookup
      Map<String, List<ContractsGrantsInvoiceDocument>> cgMapByCustomer =
          contractsGrantsAgingReportService.filterContractsGrantsAgingReport(
              fieldValues, null, new java.sql.Date(reportRunDate.getTime()));
      if (ObjectUtils.isNotNull(cgMapByCustomer) && !cgMapByCustomer.isEmpty()) {
        // 30 days
        computeFor0To30DaysByBillingChartAndOrg(
            cgMapByCustomer,
            new java.sql.Date(cutoffdate30.getTime()),
            new java.sql.Date(reportRunDate.getTime()),
            knownCustomers);
        // 60 days
        computeFor31To60DaysByBillingChartAndOrg(
            cgMapByCustomer,
            new java.sql.Date(cutoffdate60.getTime()),
            new java.sql.Date(cutoffdate31.getTime()),
            knownCustomers);
        // 90 days
        computeFor61To90DaysByBillingChartAndOrg(
            cgMapByCustomer,
            new java.sql.Date(cutoffdate90.getTime()),
            new java.sql.Date(cutoffdate61.getTime()),
            knownCustomers);
        // 120 days
        computeFor91ToSYSPRDaysByBillingChartAndOrg(
            cgMapByCustomer,
            new java.sql.Date(cutoffdate120.getTime()),
            new java.sql.Date(cutoffdate91.getTime()),
            knownCustomers);
        // 120 + older
        computeForSYSPRplus1orMoreDaysByBillingChartAndOrg(
            cgMapByCustomer, null, new java.sql.Date(cutoffdate121.getTime()), knownCustomers);
        // credits
        calculateTotalCreditsForCustomers(cgMapByCustomer, knownCustomers);
      }

      CustomerAgingReportDao agingReportDao = SpringContext.getBean(CustomerAgingReportDao.class);
      // prepare customer map.

      for (ContractsAndGrantsAgingReport detail : knownCustomers.values()) {

        // get agency name for customer
        ContractsAndGrantsBillingAgency agencyObj = getAgencyByCustomer(detail.getCustomerNumber());
        if (ObjectUtils.isNotNull(agencyObj)) {
          detail.setReportingName(agencyObj.getReportingName());
          detail.setAgencyNumber(agencyObj.getAgencyNumber());
        }

        // set total open invoices
        KualiDecimal amount =
            detail
                .getUnpaidBalance0to30()
                .add(detail.getUnpaidBalance31to60())
                .add(detail.getUnpaidBalance61to90())
                .add(
                    detail
                        .getUnpaidBalance91toSYSPR()
                        .add(detail.getUnpaidBalanceSYSPRplus1orMore()));
        detail.setTotalOpenInvoices(amount);
        totalOpenInvoices = totalOpenInvoices.add(amount);

        // find total writeoff
        KualiDecimal writeOffAmt =
            agingReportDao.findWriteOffAmountByCustomerNumber(detail.getCustomerNumber());
        if (ObjectUtils.isNotNull(writeOffAmt)) {
          totalWriteOffs = totalWriteOffs.add(writeOffAmt);
        } else {
          writeOffAmt = KualiDecimal.ZERO;
        }
        detail.setTotalWriteOff(writeOffAmt);

        // calculate total credits
        results.add(detail);
      }
    } catch (Exception ex) {
      LOG.error(
          "problem during ContractsGrantsAgingReportLookupableHelperServiceImpl.getSearchResults()",
          ex);
    }
    return new CollectionIncomplete<ContractsAndGrantsAgingReport>(results, (long) results.size());
  }