/**
   * This method sends out emails for upcoming milestones.
   *
   * @see org.kuali.kfs.module.ar.service.CGEmailService#sendEmail(java.util.List,
   *     org.kuali.kfs.module.ar.businessobject.Award)
   */
  @Override
  public void sendEmail(List<Milestone> milestones, ContractsAndGrantsBillingAward award) {
    LOG.debug("sendEmail() starting");

    MailMessage message = new MailMessage();

    message.setFromAddress(mailService.getBatchMailingList());
    message.setSubject(getEmailSubject(ArConstants.REMINDER_EMAIL_SUBJECT));
    message
        .getToAddresses()
        .add(award.getAwardPrimaryFundManager().getFundManager().getEmailAddress());
    StringBuffer body = new StringBuffer();

    String messageKey =
        kualiConfigurationService.getPropertyValueAsString(
            ArKeyConstants.MESSAGE_CG_UPCOMING_MILESTONES_EMAIL_LINE_1);
    body.append(MessageFormat.format(messageKey, new Object[] {null}));

    body.append(award.getProposalNumber() + ".\n\n");

    for (Milestone milestone : milestones) {

      String milestoneNumber =
          dataDictionaryService.getAttributeLabel(Milestone.class, "milestoneNumber");
      String milestoneDescription =
          dataDictionaryService.getAttributeLabel(Milestone.class, "milestoneDescription");
      String milestoneAmount =
          dataDictionaryService.getAttributeLabel(Milestone.class, "milestoneAmount");
      String milestoneExpectedCompletionDate =
          dataDictionaryService.getAttributeLabel(
              Milestone.class, "milestoneExpectedCompletionDate");
      String milestoneActualCompletionDate =
          dataDictionaryService.getAttributeLabel(Milestone.class, "milestoneActualCompletionDate");

      body.append(milestoneNumber + ": " + milestone.getMilestoneNumber() + " \n");
      body.append(milestoneDescription + ": " + milestone.getMilestoneDescription() + " \n");
      body.append(milestoneAmount + ": " + milestone.getMilestoneAmount() + " \n");
      body.append(
          milestoneExpectedCompletionDate
              + ": "
              + milestone.getMilestoneExpectedCompletionDate()
              + " \n");

      body.append("\n\n");
    }
    body.append("\n\n");

    messageKey =
        kualiConfigurationService.getPropertyValueAsString(
            ArKeyConstants.MESSAGE_CG_UPCOMING_MILESTONES_EMAIL_LINE_2);
    body.append(MessageFormat.format(messageKey, new Object[] {null}) + "\n\n");

    message.setMessage(body.toString());

    try {
      mailService.sendMessage(message);
    } catch (InvalidAddressException ex) {
      // TODO Auto-generated catch block
      LOG.error("InvalidAddressException ", ex);
    } catch (MessagingException ex) {
      // TODO Auto-generated catch block
      LOG.error("MessagingException ", ex);
    }
  }
  /**
   * This method test the validateBillingFrequency functionality. To make it flexible to test all
   * the billing frequencies with various billing periods, this test method call the internal
   * methods and tests it rather testing it as a whole.
   */
  public void testValidateBillingFrequency() {
    ContractsAndGrantsModuleUpdateService moduleUpdateService =
        SpringContext.getBean(ContractsAndGrantsModuleUpdateService.class);

    VerifyBillingFrequencyService verifyBillingFrequencyService =
        SpringContext.getBean(VerifyBillingFrequencyService.class);
    boolean valid = false;
    Date testEndDay = null;
    Date testStartDay = null;
    // To test all billing frequencies with award last billed date null

    // CASE 1 - award last billed Date is null.

    Date date = Date.valueOf("2011-10-31");
    AccountingPeriod currPeriod =
        SpringContext.getBean(AccountingPeriodService.class).getByDate(date);
    // Now to set currentPeriod based on the billing frequency we would want to test.
    // 1. MONTHLY / Milestone/Predetermined.
    ContractsAndGrantsBillingAward award =
        ARAwardFixture.CG_AWARD_MONTHLY_BILLED_DATE_NULL.createAward();

    testEndDay = Date.valueOf("2011-09-30");
    testStartDay = Date.valueOf("2011-01-01");

    Date[] pair =
        verifyBillingFrequencyService.getStartDateAndEndDateOfPreviousBillingPeriod(
            award, currPeriod);

    valid =
        verifyBillingFrequencyService.calculateIfWithinGracePeriod(
            date, pair[1], pair[0], award.getLastBilledDate(), new Integer(0));

    assertEquals(pair[0], testStartDay);
    assertEquals(pair[1], testEndDay);
    assertTrue(valid);

    award = ARAwardFixture.CG_AWARD_MILESTONE_BILLED_DATE_NULL.createAward();
    testEndDay = Date.valueOf("2011-09-30");
    testStartDay = Date.valueOf("2011-01-01");

    pair =
        verifyBillingFrequencyService.getStartDateAndEndDateOfPreviousBillingPeriod(
            award, currPeriod);

    valid = false;
    valid =
        verifyBillingFrequencyService.calculateIfWithinGracePeriod(
            date, pair[1], pair[0], award.getLastBilledDate(), new Integer(0));

    assertEquals(pair[0], testStartDay);
    assertEquals(pair[1], testEndDay);
    assertTrue(valid);

    award = ARAwardFixture.CG_AWARD_PREDETERMINED_BILLED_DATE_NULL.createAward();

    testEndDay = Date.valueOf("2011-09-30");
    testStartDay = Date.valueOf("2011-01-01");

    pair =
        verifyBillingFrequencyService.getStartDateAndEndDateOfPreviousBillingPeriod(
            award, currPeriod);

    valid = false;
    valid =
        verifyBillingFrequencyService.calculateIfWithinGracePeriod(
            date, pair[1], pair[0], award.getLastBilledDate(), new Integer(0));

    assertEquals(pair[0], testStartDay);
    assertEquals(pair[1], testEndDay);
    assertTrue(valid);

    // 2. QUARTERLY

    award = ARAwardFixture.CG_AWARD_QUAR_BILLED_DATE_NULL.createAward();

    testEndDay = Date.valueOf("2011-09-30");
    testStartDay = Date.valueOf("2011-01-01");

    pair =
        verifyBillingFrequencyService.getStartDateAndEndDateOfPreviousBillingPeriod(
            award, currPeriod);

    valid = false;
    valid =
        verifyBillingFrequencyService.calculateIfWithinGracePeriod(
            date, pair[1], pair[0], award.getLastBilledDate(), new Integer(0));

    assertEquals(pair[0], testStartDay);
    assertEquals(pair[1], testEndDay);
    assertTrue(valid);

    // 3. SEMI-ANNUAL

    award = ARAwardFixture.CG_AWARD_SEMI_ANN_BILLED_DATE_NULL.createAward();
    testEndDay = Date.valueOf("2011-06-30");
    testStartDay = Date.valueOf("2011-01-01");

    pair =
        verifyBillingFrequencyService.getStartDateAndEndDateOfPreviousBillingPeriod(
            award, currPeriod);

    valid = false;
    valid =
        verifyBillingFrequencyService.calculateIfWithinGracePeriod(
            date, pair[1], pair[0], award.getLastBilledDate(), new Integer(0));

    assertEquals(pair[0], testStartDay);
    assertEquals(pair[1], testEndDay);
    assertTrue(valid);

    // 4. ANNUALLY

    award = ARAwardFixture.CG_AWARD_ANNUAL_BILLED_DATE_NULL.createAward();
    testEndDay = Date.valueOf("2011-06-30");
    testStartDay = Date.valueOf("2011-01-01");

    pair =
        verifyBillingFrequencyService.getStartDateAndEndDateOfPreviousBillingPeriod(
            award, currPeriod);

    valid = false;
    valid =
        verifyBillingFrequencyService.calculateIfWithinGracePeriod(
            date, pair[1], pair[0], award.getLastBilledDate(), new Integer(0));

    assertEquals(pair[0], testStartDay);
    assertEquals(pair[1], testEndDay);
    assertTrue(valid);

    // 5. LOC Billing

    award = ARAwardFixture.CG_AWARD_LOCB_BILLED_DATE_NULL.createAward();

    testStartDay = Date.valueOf("2011-01-01");

    pair =
        verifyBillingFrequencyService.getStartDateAndEndDateOfPreviousBillingPeriod(
            award, currPeriod);

    assertEquals(pair[0], testStartDay);

    // CASE 2 - award last billed Date is set to appropriate period, current period will also be set
    // to appropriate values.

    // 1. MONTHLY / Milestone/Predetermined.
    date = Date.valueOf("2011-11-01");
    currPeriod = SpringContext.getBean(AccountingPeriodService.class).getByDate(date);

    award = ARAwardFixture.CG_AWARD_MONTHLY_BILLED_DATE_VALID.createAward();

    testEndDay = Date.valueOf("2011-10-31");
    testStartDay = Date.valueOf("2011-10-01");

    pair =
        verifyBillingFrequencyService.getStartDateAndEndDateOfPreviousBillingPeriod(
            award, currPeriod);

    valid = false;
    valid =
        verifyBillingFrequencyService.calculateIfWithinGracePeriod(
            date, pair[1], pair[0], award.getLastBilledDate(), new Integer(0));

    assertEquals(pair[0], testStartDay);
    assertEquals(pair[1], testEndDay);
    assertTrue(valid);

    award = ARAwardFixture.CG_AWARD_MILESTONE_BILLED_DATE_VALID.createAward();
    testEndDay = Date.valueOf("2011-10-31");
    testStartDay = Date.valueOf("2011-10-01");

    pair =
        verifyBillingFrequencyService.getStartDateAndEndDateOfPreviousBillingPeriod(
            award, currPeriod);

    valid = false;
    valid =
        verifyBillingFrequencyService.calculateIfWithinGracePeriod(
            date, pair[1], pair[0], award.getLastBilledDate(), new Integer(0));

    assertEquals(pair[0], testStartDay);
    assertEquals(pair[1], testEndDay);
    assertTrue(valid);

    award = ARAwardFixture.CG_AWARD_PREDETERMINED_BILLED_DATE_VALID.createAward();

    testEndDay = Date.valueOf("2011-10-31");
    testStartDay = Date.valueOf("2011-10-01");

    pair =
        verifyBillingFrequencyService.getStartDateAndEndDateOfPreviousBillingPeriod(
            award, currPeriod);

    valid = false;
    valid =
        verifyBillingFrequencyService.calculateIfWithinGracePeriod(
            date, pair[1], pair[0], award.getLastBilledDate(), new Integer(0));

    assertEquals(pair[0], testStartDay);
    assertEquals(pair[1], testEndDay);
    assertTrue(valid);

    // 2. QUARTERLY

    award = ARAwardFixture.CG_AWARD_QUAR_BILLED_DATE_VALID.createAward();

    testEndDay = Date.valueOf("2011-09-30");
    testStartDay = Date.valueOf("2011-07-01");

    pair =
        verifyBillingFrequencyService.getStartDateAndEndDateOfPreviousBillingPeriod(
            award, currPeriod);

    valid = false;
    valid =
        verifyBillingFrequencyService.calculateIfWithinGracePeriod(
            date, pair[1], pair[0], award.getLastBilledDate(), new Integer(0));

    assertEquals(pair[0], testStartDay);
    assertEquals(pair[1], testEndDay);
    assertTrue(valid);

    // 3. SEMI-ANNUAL
    date = Date.valueOf("2012-01-01");
    currPeriod = SpringContext.getBean(AccountingPeriodService.class).getByDate(date);

    award = ARAwardFixture.CG_AWARD_SEMI_ANN_BILLED_DATE_VALID.createAward();
    testEndDay = Date.valueOf("2011-12-31");
    testStartDay = Date.valueOf("2011-07-01");

    pair =
        verifyBillingFrequencyService.getStartDateAndEndDateOfPreviousBillingPeriod(
            award, currPeriod);

    valid = false;
    valid =
        verifyBillingFrequencyService.calculateIfWithinGracePeriod(
            date, pair[1], pair[0], award.getLastBilledDate(), new Integer(0));

    assertEquals(pair[0], testStartDay);
    assertEquals(pair[1], testEndDay);
    assertTrue(valid);

    // 4. ANNUALLY

    date = Date.valueOf("2011-07-01");
    currPeriod = SpringContext.getBean(AccountingPeriodService.class).getByDate(date);

    award = ARAwardFixture.CG_AWARD_ANNUAL_BILLED_DATE_VALID.createAward();
    testEndDay = Date.valueOf("2011-06-30");
    testStartDay = Date.valueOf("2010-07-01");

    pair =
        verifyBillingFrequencyService.getStartDateAndEndDateOfPreviousBillingPeriod(
            award, currPeriod);

    valid = false;
    valid =
        verifyBillingFrequencyService.calculateIfWithinGracePeriod(
            date, pair[1], pair[0], award.getLastBilledDate(), new Integer(0));

    assertEquals(pair[0], testStartDay);
    assertEquals(pair[1], testEndDay);
    assertTrue(valid);

    // 5. LOC Billing - No grace period validation involved here.

    date = Date.valueOf("2011-12-15");
    currPeriod = SpringContext.getBean(AccountingPeriodService.class).getByDate(date);
    award = ARAwardFixture.CG_AWARD_LOCB_BILLED_DATE_VALID.createAward();

    testStartDay = Date.valueOf("2010-12-14");

    pair =
        verifyBillingFrequencyService.getStartDateAndEndDateOfPreviousBillingPeriod(
            award, currPeriod);

    valid =
        verifyBillingFrequencyService.calculateIfWithinGracePeriod(
            date, pair[1], pair[0], award.getLastBilledDate(), new Integer(0));
    assertEquals(pair[0], testStartDay);
  }