/*
  * This method gets subReportType for BudgetCumulativeIDCForReport by
  * BudgetPeriod. It get the sum of calculatedCost based on BudgetLineItem
  * OnOffCampusFlag and RateClassType
  */
 private SubReportType getBudgetCumulativeIDCForReport() {
   SubReportType subReportType = SubReportType.Factory.newInstance();
   List<ReportType> reportTypeList = new ArrayList<ReportType>();
   ScaleTwoDecimal calculatedCostForOn = ScaleTwoDecimal.ZERO;
   ScaleTwoDecimal calculatedCostForOff = ScaleTwoDecimal.ZERO;
   for (BudgetPeriod budgetPeriod : budget.getBudgetPeriods()) {
     for (BudgetLineItem budgetLineItem : budgetPeriod.getBudgetLineItems()) {
       if (budgetLineItem.getOnOffCampusFlag().booleanValue()) {
         calculatedCostForOn =
             calculatedCostForOn.add(
                 getTotalCalculatedCostByRateClassTypeFromLineItem(
                     RateClassType.OVERHEAD.getRateClassType(), budgetLineItem));
       } else {
         calculatedCostForOff =
             calculatedCostForOff.add(
                 getTotalCalculatedCostByRateClassTypeFromLineItem(
                     RateClassType.OVERHEAD.getRateClassType(), budgetLineItem));
       }
     }
   }
   if (!calculatedCostForOn.equals(ScaleTwoDecimal.ZERO)) {
     ReportType reportTypeForOn =
         getReportTypeForBudgetIndirectCostsForReport(Boolean.TRUE, calculatedCostForOn, null);
     reportTypeList.add(reportTypeForOn);
   }
   if (!calculatedCostForOff.equals(ScaleTwoDecimal.ZERO)) {
     ReportType reportTypeForOff =
         getReportTypeForBudgetIndirectCostsForReport(Boolean.FALSE, calculatedCostForOff, null);
     reportTypeList.add(reportTypeForOff);
   }
   subReportType.setGroupArray(getGroupsType(reportTypeList));
   return subReportType;
 }
 /**
  * This method will set the values to salaryType VO for budget line calculated amount
  *
  * @param salaryTypeVoList is a list contains set of salary types based on budget line calculated
  *     amount
  */
 protected void setSalaryTypesForLineItemCalcuAmount(
     List<SalaryTypeVO> salaryTypeVoList, boolean includeNonPersonnel) {
   List<String> calculatedAmountDescList = new ArrayList<String>();
   SalaryTypeVO salaryTypeVO = new SalaryTypeVO();
   salaryTypeVO.setCostElement(CALCULATED_AMOUNT_COST_ELEMENT_DESC);
   salaryTypeVoList.add(salaryTypeVO);
   for (BudgetPeriod budgetPeriod : budget.getBudgetPeriods()) {
     for (BudgetLineItem budgetLineItem : new ArrayList<>(budgetPeriod.getBudgetLineItems())) {
       List<BudgetLineItemCalculatedAmount> budgetLineItemCalculatedAmounts =
           budgetLineItem.getBudgetLineItemCalculatedAmounts();
       for (BudgetLineItemCalculatedAmount budgetLineItemCalcAmount :
           budgetLineItemCalculatedAmounts) {
         String rateClassCode = budgetLineItemCalcAmount.getRateClassCode();
         String rateTypeCode = budgetLineItemCalcAmount.getRateTypeCode();
         RateClass rateClass = getRateClassBo(rateClassCode);
         String costElementDesc =
             getCostElementDescriptionForLineItem(budgetLineItemCalcAmount, rateClass);
         if (costElementDesc != null && !calculatedAmountDescList.contains(costElementDesc)) {
           calculatedAmountDescList.add(costElementDesc);
           SalaryTypeVO salaryTypeVOForCalculatedAmount = new SalaryTypeVO();
           salaryTypeVOForCalculatedAmount.setName(costElementDesc);
           List<BudgetDataPeriodVO> budgetPeriodDataList =
               getBudgetDataPeriodsForCalculatedAmounts(
                   rateClassCode, rateTypeCode, includeNonPersonnel);
           salaryTypeVOForCalculatedAmount.setBudgetPeriodVOs(budgetPeriodDataList);
           salaryTypeVoList.add(salaryTypeVOForCalculatedAmount);
         }
       }
     }
   }
 }
 /**
  * This method will return the budget data periods for calculated amounts.It checks rate type code
  * ,rate class code against list of Budget LineItem Calculated Amounts for each budget line item
  * of each budget period of budget ,if it is equals then add calculated cost of budget LineItem
  * Calculated Amount to period cost.
  *
  * @param rateClassCode
  * @param rateTypeCode
  * @return list of BudgetDataPeriod VO's
  */
 protected List<BudgetDataPeriodVO> getBudgetDataPeriodsForCalculatedAmounts(
     String rateClassCode, String rateTypeCode, boolean includeNonPersonnel) {
   List<BudgetDataPeriodVO> budgetPeriodDataList = new ArrayList<BudgetDataPeriodVO>();
   int budgetPeriodDataId = 0;
   for (BudgetPeriod budgetPeriod : budget.getBudgetPeriods()) {
     BudgetDataPeriodVO budgetPeriodVO = new BudgetDataPeriodVO();
     budgetPeriodVO.setBudgetPeriodId(++budgetPeriodDataId);
     ScaleTwoDecimal periodCost = ScaleTwoDecimal.ZERO;
     for (BudgetLineItem budgetLineItem : budgetPeriod.getBudgetLineItems()) {
       String budgetCategoryType = getBudgetCategoryTypeCode(budgetLineItem);
       if (includeNonPersonnel || isPersonnel(budgetCategoryType)) {
         for (BudgetLineItemCalculatedAmount budgetLineItemCalcAmount :
             budgetLineItem.getBudgetLineItemCalculatedAmounts()) {
           if (budgetLineItemCalcAmount.getRateClassCode() != null
               && budgetLineItemCalcAmount.getRateClassCode().equals(rateClassCode)
               && budgetLineItemCalcAmount.getRateTypeCode() != null
               && budgetLineItemCalcAmount.getRateTypeCode().equals(rateTypeCode)) {
             periodCost = periodCost.add(budgetLineItemCalcAmount.getCalculatedCost());
           }
         }
       }
     }
     budgetPeriodVO.setPeriodCost(periodCost);
     budgetPeriodDataList.add(budgetPeriodVO);
   }
   return budgetPeriodDataList;
 }
 @KcEventMethod
 public boolean processBudgetFormulatedCostValidations(BudgetSaveEvent event) {
   boolean result = true;
   int budgetPeriodIdx = 0;
   for (BudgetPeriod budgetPeriod : event.getBudget().getBudgetPeriods()) {
     int lineItemIdx = 0;
     for (BudgetLineItem budgetLineItem : budgetPeriod.getBudgetLineItems()) {
       String errorPath =
           "document.budget.budgetPeriod["
               + budgetPeriodIdx
               + "].budgetLineItem["
               + lineItemIdx
               + "].";
       int formulatedCostIdx = 0;
       for (BudgetFormulatedCostDetail budgetFormulatedCost :
           budgetLineItem.getBudgetFormulatedCosts()) {
         result &=
             processBudgetFormulatedCostValidations(
                 budgetFormulatedCost,
                 errorPath + "budgetFormulatedCosts[" + formulatedCostIdx++ + "]");
       }
       lineItemIdx++;
     }
     budgetPeriodIdx++;
   }
   return result;
 }
  @KcEventMethod
  public boolean budgetPersonnelDetailsCheck(SaveBudgetEvent event) {
    boolean valid = true;
    List<BudgetPeriod> budgetPeriods = event.getBudget().getBudgetPeriods();
    List<BudgetLineItem> budgetLineItems;
    int i = 0;
    int j = 0;

    for (BudgetPeriod budgetPeriod : budgetPeriods) {
      j = 0;
      budgetLineItems = budgetPeriod.getBudgetLineItems();
      for (BudgetLineItem budgetLineItem : budgetLineItems) {
        if (budgetLineItem.getBudgetCategory().getBudgetCategoryTypeCode().equals("P")) {
          valid &=
              budgetPersonnelDetailsCheck(
                  event.getBudget(),
                  budgetLineItem,
                  event.getErrorPath() + "budgetPeriod[" + i + "].budgetLineItems[" + j + "]");
        }
        j++;
      }
      i++;
    }

    return valid;
  }
Exemple #6
0
 public ActionForward delete(
     ActionMapping mapping,
     ActionForm form,
     HttpServletRequest request,
     HttpServletResponse response)
     throws Exception {
   BudgetForm budgetForm = (BudgetForm) form;
   AwardBudgetDocument awardBudgetDocument = budgetForm.getBudgetDocument();
   int selectedLineNumber = getSelectedLine(request);
   BudgetSubAwards subAward =
       awardBudgetDocument.getBudget().getBudgetSubAwards().get(selectedLineNumber);
   for (BudgetPeriod period : awardBudgetDocument.getBudget().getBudgetPeriods()) {
     Iterator<BudgetLineItem> iter = period.getBudgetLineItems().iterator();
     while (iter.hasNext()) {
       BudgetLineItem item = iter.next();
       if (org.apache.commons.lang3.ObjectUtils.equals(
           subAward.getSubAwardNumber(), item.getSubAwardNumber())) {
         iter.remove();
       }
     }
   }
   awardBudgetDocument.getBudget().getBudgetSubAwards().remove(selectedLineNumber);
   Collections.sort(awardBudgetDocument.getBudget().getBudgetSubAwards());
   return mapping.findForward(Constants.MAPPING_BASIC);
 }
 /*
  * This method gets reportTypeVO for BudgetCumulativeNonPersonnel by setting
  * parameters data to reportType
  */
 private ReportTypeVO getReportTypeVOForBudgetCumulativeNonPersonnel(
     BudgetLineItem budgetLineItem) {
   ReportTypeVO reportTypeVO = new ReportTypeVO();
   reportTypeVO.setBudgetCategoryDesc(budgetLineItem.getBudgetCategory().getDescription());
   reportTypeVO.setCostElementDesc(getCostElementDescription(budgetLineItem));
   reportTypeVO.setCalculatedCost(budgetLineItem.getLineItemCost());
   return reportTypeVO;
 }
 protected List<BudgetLineItem> findLineItemsByCostElement(
     List<BudgetLineItem> lineItems, String costElement) {
   List<BudgetLineItem> lineItemsFound = new ArrayList<>();
   for (BudgetLineItem lineItem : lineItems) {
     if (StringUtils.equals(lineItem.getCostElement(), costElement)
         && ObjectUtils.equals(lineItem.getSubAwardNumber(), subAward.getSubAwardNumber())) {
       lineItemsFound.add(lineItem);
     }
   }
   return lineItemsFound;
 }
 protected BudgetPeriod getBudgetPeriod() {
   BudgetPeriod budgetPeriod = new BudgetPeriod();
   budgetPeriod.setEndDate(getDate(2016, 6, 30));
   budgetPeriod.setStartDate(getDate(2015, 7, 1));
   final BudgetLineItem budgetLineItem =
       getTravelLineItem(budgetPeriod, getDate(2015, 7, 1), getDate(2016, 6, 30));
   budgetLineItem.setBudgetPeriodBO(budgetPeriod);
   budgetLineItem.setBudgetPeriod(1);
   budgetLineItem.setLineItemNumber(1);
   budgetPeriod.getBudgetLineItems().add(budgetLineItem);
   return budgetPeriod;
 }
 public BudgetPersonnelDetails(BudgetLineItem personnelBudgetSummaryLineItem) {
   initializeBudgetPersonnelDetails();
   this.budgetLineItem = personnelBudgetSummaryLineItem;
   this.startDate = personnelBudgetSummaryLineItem.getStartDate();
   this.endDate = personnelBudgetSummaryLineItem.getEndDate();
   this.budgetPeriod = personnelBudgetSummaryLineItem.getBudgetPeriod();
   this.budgetId = personnelBudgetSummaryLineItem.getBudgetId();
   this.salaryRequested = personnelBudgetSummaryLineItem.getLineItemCost();
   this.personSequenceNumber =
       BudgetConstants.BudgetPerson.SUMMARYPERSON.getPersonSequenceNumber();
   this.personId = BudgetConstants.BudgetPerson.SUMMARYPERSON.getPersonId();
 }
  /**
   * Gets a Collection of sequence numbers from every lines items personnel details
   *
   * @param budgetLineItems the lines items
   * @return Collection of sequence numbers
   */
  private Collection<Integer> getBudgetPersonSequencesFromPersonnelDetails(
      final Collection<BudgetLineItem> budgetLineItems) {
    assert budgetLineItems != null : "the budgetLineItems is null";

    final Collection<Integer> budgetPersonSequences = new ArrayList<Integer>();

    for (final BudgetLineItem budgetLineItem : budgetLineItems) {
      for (final BudgetPersonnelDetails budgetPersonnelDetails :
          budgetLineItem.getBudgetPersonnelDetailsList()) {
        budgetPersonSequences.add(budgetPersonnelDetails.getPersonSequenceNumber());
      }
    }
    return budgetPersonSequences;
  }
 protected boolean isBudgetPersonExistsInPersonnelDetails(
     List<BudgetLineItem> budgetLineItems, BudgetPerson budgetPerson) {
   for (BudgetLineItem budgetLineItem : budgetLineItems) {
     for (BudgetPersonnelDetails budgetPersonnelDetails :
         budgetLineItem.getBudgetPersonnelDetailsList()) {
       if (budgetPersonnelDetails
           .getPersonSequenceNumber()
           .equals(budgetPerson.getPersonSequenceNumber())) {
         return true;
       }
     }
   }
   return false;
 }
 /*
  * Check if this budget person has any budgetdetail set.  This is called before checking whether
  * this person can be deleted.  If retrieve from DB, then it might not be correct because
  * the deleted detail may have not been persisted before delete person is called.
  */
 private boolean isPersonDetailsFound(Budget budget, BudgetPerson budgetPerson) {
   for (BudgetPeriod budgetPeriod : budget.getBudgetPeriods()) {
     for (BudgetLineItem lineItem : budgetPeriod.getBudgetLineItems()) {
       for (BudgetPersonnelDetails budgetPersonnelDetail :
           lineItem.getBudgetPersonnelDetailsList()) {
         if (budgetPersonnelDetail
             .getPersonSequenceNumber()
             .equals(budgetPerson.getPersonSequenceNumber())) {
           return true;
         }
       }
     }
   }
   return false;
 }
 public void populateNewBudgetLineItem(
     BudgetLineItem newBudgetLineItem, BudgetPeriod budgetPeriod) {
   newBudgetLineItem.setBudgetPeriod(budgetPeriod.getBudgetPeriod());
   newBudgetLineItem.setBudgetPeriodId(budgetPeriod.getBudgetPeriodId());
   newBudgetLineItem.setBudgetPeriodBO(budgetPeriod);
   newBudgetLineItem.setStartDate(budgetPeriod.getStartDate());
   newBudgetLineItem.setEndDate(budgetPeriod.getEndDate());
   newBudgetLineItem.setBudgetId(budget.getBudgetId());
   newBudgetLineItem.setLineItemNumber(newLineItemNumber++);
   newBudgetLineItem.setApplyInRateFlag(true);
   newBudgetLineItem.setSubmitCostSharingFlag(budget.getSubmitCostSharingFlag());
 }
  private boolean budgetPersonnelDetailsCheck(
      Budget budget, BudgetLineItem budgetLineItem, String errorPath) {
    boolean valid = true;
    boolean validJobCodeCECombo = false;

    int k = 0;
    for (BudgetPersonnelDetails budgetPersonnelDetails :
        budgetLineItem.getBudgetPersonnelDetailsList()) {
      String detailsErrorPath = errorPath + ".budgetPersonnelDetailsList[" + k + "]";
      valid &=
          !(personnelDetailsCheck(
              budget, budgetLineItem, budgetPersonnelDetails, detailsErrorPath));

      validJobCodeCECombo =
          processCheckJobCodeObjectCodeCombo(budget, budgetPersonnelDetails, true);
      if (!validJobCodeCECombo) {
        GlobalVariables.getMessageMap()
            .putError(
                detailsErrorPath + ".personSequenceNumber",
                KeyConstants.ERROR_SAVE_JOBCODE_COST_ELEMENT_COMBO_INVALID);
      }
      valid &= validJobCodeCECombo;
      k++;
    }

    return valid;
  }
 /*
  * This method will fetch the budget category from the BudgetLineItem
  */
 private String getBudgetCategoryTypeCode(BudgetLineItem budgetLineItem) {
   String budgetCategoryType = null;
   BudgetCategory budgetCategory = budgetLineItem.getBudgetCategory();
   if (budgetCategory != null) {
     budgetCategoryType = budgetCategory.getBudgetCategoryTypeCode();
   }
   return budgetCategoryType;
 }
  /**
   * This method returns the fringe totals.
   *
   * @param currentPersonnelObjectCodes
   * @param budget
   * @return
   */
  protected Map<RateClassRateType, ScaleTwoDecimal> getFringeTotals(
      List<CostElement> currentPersonnelObjectCodes, Budget budget) {
    /*
     * Things like Animal care and Travel also have a rateClassType of E so need to filter that
     * out to only get Personnel
     */
    Map<RateClassRateType, ScaleTwoDecimal> fringeTotals =
        new HashMap<RateClassRateType, ScaleTwoDecimal>();

    if (CollectionUtils.isNotEmpty(currentPersonnelObjectCodes)) {
      for (CostElement personnelCostElement : currentPersonnelObjectCodes) {
        for (BudgetPeriod budgetPeriod : budget.getBudgetPeriods()) {
          List<BudgetLineItem> filteredLineItems =
              getPersonnelLineItems(budgetPeriod, personnelCostElement);
          for (BudgetLineItem lineItem : filteredLineItems) {
            for (BudgetLineItemCalculatedAmount lineItemCalculatedAmount :
                lineItem.getBudgetLineItemCalculatedAmounts()) {
              lineItemCalculatedAmount.refreshReferenceObject("rateClass");
              // Check for Employee Benefits RateClassType
              if (lineItemCalculatedAmount
                  .getRateClass()
                  .getRateClassTypeCode()
                  .equalsIgnoreCase("E")) {
                RateClassRateType currentKey =
                    new RateClassRateType(
                        lineItemCalculatedAmount.getRateClassCode(),
                        lineItemCalculatedAmount.getRateTypeCode());
                if (fringeTotals.containsKey(currentKey)) {
                  fringeTotals.put(
                      currentKey,
                      fringeTotals
                          .get(currentKey)
                          .add(lineItemCalculatedAmount.getCalculatedCost()));
                } else {
                  fringeTotals.put(currentKey, lineItemCalculatedAmount.getCalculatedCost());
                }
              }
            }
          }
        }
      }
    }
    return fringeTotals;
  }
 /*
  * This method will get the budget data periods . For a given cost element
  * description from budget get list of budget periods , iterate over budget
  * periods and get list of budget line items ,iterate over budget line items
  * compare with the cost element description which ever matches add line
  * item cost to period cost.finally set period cost to BudgetDataPeriodVO
  *
  */
 private List<BudgetDataPeriodVO> getBudgetDataPeriodVOsForCostElement(String costElementDesc) {
   List<BudgetDataPeriodVO> budgetPeriodDataList = new ArrayList<BudgetDataPeriodVO>();
   int budgetPeriodDataId = 0;
   for (BudgetPeriod budgetPeriod : budget.getBudgetPeriods()) {
     BudgetDataPeriodVO budgetDataPeriodVO = new BudgetDataPeriodVO();
     budgetDataPeriodVO.setBudgetPeriodId(++budgetPeriodDataId);
     ScaleTwoDecimal periodCost = ScaleTwoDecimal.ZERO;
     for (BudgetLineItem lineItem : budgetPeriod.getBudgetLineItems()) {
       if (lineItem.getCostElementBO() != null
           && lineItem.getCostElementBO().getDescription() != null
           && lineItem.getCostElementBO().getDescription().equals(costElementDesc)) {
         periodCost = periodCost.add(lineItem.getLineItemCost());
       }
     }
     budgetDataPeriodVO.setPeriodCost(periodCost);
     budgetPeriodDataList.add(budgetDataPeriodVO);
   }
   return budgetPeriodDataList;
 }
  /**
   * This method is checks individual line item start and end dates for validity and proper
   * ordering.
   *
   * @param currentBudgetPeriod the period containing the line item
   * @param budgetLineItem the number of the line item
   * @return true if the dates are valid, false otherwise
   */
  protected boolean processCheckLineItemDates(
      BudgetPeriod currentBudgetPeriod, BudgetLineItem budgetLineItem, String errorPath) {
    boolean valid = true;
    MessageMap errorMap = getGlobalVariableService().getMessageMap();

    if (budgetLineItem.getEndDate() == null) {
      errorMap.putError(errorPath + END_DATE, KeyConstants.ERROR_REQUIRED, UPPER_END_DATE);
      valid = false;
    }

    if (budgetLineItem.getStartDate() == null) {
      errorMap.putError(errorPath + START_DATE, KeyConstants.ERROR_REQUIRED, UPPER_START_DATE);
      valid = false;
    }

    if (!valid) return valid;

    if (budgetLineItem.getEndDate().compareTo(budgetLineItem.getStartDate()) < 0) {
      errorMap.putError(errorPath + END_DATE, KeyConstants.ERROR_LINE_ITEM_DATES);
      valid = false;
    }

    if (currentBudgetPeriod.getEndDate().compareTo(budgetLineItem.getEndDate()) < 0) {
      errorMap.putError(
          errorPath + END_DATE,
          KeyConstants.ERROR_LINE_ITEM_END_DATE,
          new String[] {CAN_NOT_BE_AFTER, LOWER_END_DATE});
      valid = false;
    }
    if (currentBudgetPeriod.getStartDate().compareTo(budgetLineItem.getEndDate()) > 0) {
      errorMap.putError(
          errorPath + END_DATE,
          KeyConstants.ERROR_LINE_ITEM_END_DATE,
          new String[] {CAN_NOT_BE_BEFORE, LOWER_START_DATE});
      valid = false;
    }
    if (currentBudgetPeriod.getStartDate().compareTo(budgetLineItem.getStartDate()) > 0) {
      errorMap.putError(
          errorPath + START_DATE,
          KeyConstants.ERROR_LINE_ITEM_START_DATE,
          new String[] {CAN_NOT_BE_BEFORE, LOWER_START_DATE});
      valid = false;
    }
    if (currentBudgetPeriod.getEndDate().compareTo(budgetLineItem.getStartDate()) < 0) {
      errorMap.putError(
          errorPath + START_DATE,
          KeyConstants.ERROR_LINE_ITEM_START_DATE,
          new String[] {CAN_NOT_BE_AFTER, LOWER_END_DATE});
      valid = false;
    }

    return valid;
  }
  /**
   * In order to decrease or increase, the change amount is used, so this can be sent as is without
   * subtracting from previous budget.
   *
   * @return
   */
  public HashMap<String, ScaleTwoDecimal> getNonPersonnelCost(
      Budget currentBudget, AwardBudgetExt previousBudget) {
    HashMap<String, ScaleTwoDecimal> netCost = new HashMap<String, ScaleTwoDecimal>();
    // only do for one period, assume it is the first
    int period = currentBudget.getBudgetPeriods().size() - 1;
    List<BudgetLineItem> currentLineItems =
        currentBudget.getBudgetPeriods().get(period).getBudgetLineItems();

    HashMap<String, ScaleTwoDecimal> currentLineItemCosts = new HashMap<String, ScaleTwoDecimal>();
    for (BudgetLineItem currentLineItem : currentLineItems) {
      if (!StringUtils.equalsIgnoreCase(
          currentLineItem.getBudgetCategory().getBudgetCategoryTypeCode(), "P")) {
        currentLineItemCosts.put(
            currentLineItem.getCostElement(), currentLineItem.getLineItemCost());
      }
    }

    return currentLineItemCosts;
  }
  /**
   * Updates personnel details job code from a person's job code.
   *
   * @param budgetLineItems the lines items
   * @param person the person
   */
  private void updateJobCodeOnDetailsFromPerson(
      final Collection<BudgetLineItem> budgetLineItems, final BudgetPerson person) {
    assert budgetLineItems != null : "the budgetLineItems is null";
    assert person != null : "the person is null";

    if (person.getJobCode() == null) {
      return;
    }

    for (final BudgetLineItem budgetLineItem : budgetLineItems) {
      for (final BudgetPersonnelDetails budgetPersonnelDetails :
          budgetLineItem.getBudgetPersonnelDetailsList()) {
        if (person
            .getPersonSequenceNumber()
            .equals(budgetPersonnelDetails.getPersonSequenceNumber())) {
          budgetPersonnelDetails.setJobCode(person.getJobCode());
        }
      }
    }
  }
 protected void assertExpectedResults(List<Map<String, ScaleTwoDecimal>> results) {
   int index = 0;
   for (BudgetPeriod period : budget.getBudgetPeriods()) {
     for (BudgetLineItem lineItem : period.getBudgetLineItems()) {
       Assert.assertEquals(subAward.getSubAwardNumber(), lineItem.getSubAwardNumber());
       Assert.assertEquals(
           results.get(index).get(lineItem.getCostElement()), lineItem.getLineItemCost());
     }
     for (Map.Entry<String, ScaleTwoDecimal> entry : results.get(index).entrySet()) {
       final List<BudgetLineItem> lineItemsByCostElement =
           findLineItemsByCostElement(period.getBudgetLineItems(), entry.getKey());
       if (entry.getValue().isZero()) {
         Assert.assertTrue(lineItemsByCostElement.size() == 0);
       } else {
         Assert.assertEquals(entry.getValue(), lineItemsByCostElement.get(0).getLineItemCost());
       }
     }
     index++;
   }
 }
 protected BudgetPersonnelRateAndBase getNewBudgetPersonnelRateAndBase(
     ScaleTwoDecimal applicableRate,
     String rateClassCode,
     String rateTypeCode,
     ScaleTwoDecimal calculatedCost,
     ScaleTwoDecimal baseCost,
     String rateClassTypeCode,
     BudgetLineItem lineItem) {
   BudgetPersonnelRateAndBase rateAndBase = new BudgetPersonnelRateAndBaseMock();
   rateAndBase.setRateClassCode(rateClassCode);
   rateAndBase.setRateTypeCode(rateTypeCode);
   rateAndBase.setAppliedRate(applicableRate);
   rateAndBase.setCalculatedCost(calculatedCost);
   rateAndBase.setCalculatedCostSharing(ScaleTwoDecimal.ZERO);
   rateAndBase.setSalaryRequested(baseCost);
   rateAndBase.setRateClass(new RateClass());
   rateAndBase.getRateClass().setRateClassTypeCode(rateClassTypeCode);
   rateAndBase.setStartDate(lineItem.getStartDate());
   rateAndBase.setEndDate(lineItem.getEndDate());
   return rateAndBase;
 }
  @KcEventMethod
  public boolean addPersonnelCheck(AddPersonnelBudgetEvent event) {
    boolean result = true;
    Budget budget = event.getBudget();
    BudgetPeriod budgetPeriod = event.getBudgetPeriod();
    BudgetLineItem newBudgetLineItem = event.getBudgetLineItem();
    BudgetPersonnelDetails budgetPersonDetails = event.getBudgetPersonnelDetails();
    String errorKey = event.getErrorKey();

    GlobalVariables.getMessageMap().addToErrorPath(errorKey);
    if (dictionaryValidationService.validate(newBudgetLineItem).getNumberOfErrors() > 0) {
      result = false;
    }
    GlobalVariables.getMessageMap().removeFromErrorPath(errorKey);

    if (budgetPeriod == null) {
      GlobalVariables.getMessageMap()
          .putError("viewBudgetPeriod", KeyConstants.ERROR_BUDGET_PERIOD_NOT_SELECTED);
      result = false;
    }
    if (newBudgetLineItem.getCostElement() == null
        || StringUtils.equalsIgnoreCase(newBudgetLineItem.getCostElement(), "")) {
      GlobalVariables.getMessageMap()
          .putError(errorKey, KeyConstants.ERROR_COST_ELEMENT_NOT_SELECTED);
      result = false;
    }
    if (budgetPersonDetails.getPersonSequenceNumber() == null) {
      GlobalVariables.getMessageMap()
          .putError(
              "newBudgetPersonnelDetails.personSequenceNumber",
              KeyConstants.ERROR_BUDGET_PERSONNEL_NOT_SELECTED);
      result = false;
    }
    if (!processCheckJobCodeObjectCodeCombo(budget, budgetPersonDetails, false)) {
      GlobalVariables.getMessageMap()
          .putError(errorKey, KeyConstants.ERROR_JOBCODE_COST_ELEMENT_COMBO_INVALID);
      result = false;
    }
    return result;
  }
  /**
   * This method returns the indirect cost for the accounting line.
   *
   * @return
   */
  public Map<RateClassRateType, ScaleTwoDecimal> getIndirectCost(
      Budget currentBudget, AwardBudgetExt previousBudget) {
    int period = currentBudget.getBudgetPeriods().size() - 1;
    List<BudgetLineItem> currentLineItems =
        currentBudget.getBudgetPeriods().get(period).getBudgetLineItems();
    Map<RateClassRateType, ScaleTwoDecimal> currentIndirectTotals =
        new HashMap<RateClassRateType, ScaleTwoDecimal>();

    for (BudgetLineItem lineItem : currentLineItems) {
      for (BudgetLineItemCalculatedAmount lineItemCalculatedAmount :
          lineItem.getBudgetLineItemCalculatedAmounts()) {
        lineItemCalculatedAmount.refreshReferenceObject("rateClass");
        if (lineItemCalculatedAmount.getRateClass().getRateClassTypeCode().equalsIgnoreCase("O")) {
          RateClassRateType currentKey =
              new RateClassRateType(
                  lineItemCalculatedAmount.getRateClassCode(),
                  lineItemCalculatedAmount.getRateTypeCode());
          if (currentIndirectTotals.containsKey(currentKey)) {
            currentIndirectTotals.put(
                currentKey,
                currentIndirectTotals
                    .get(currentKey)
                    .add(lineItemCalculatedAmount.getCalculatedCost()));
          } else {
            currentIndirectTotals.put(currentKey, lineItemCalculatedAmount.getCalculatedCost());
          }
        }
      }
    }

    Map<RateClassRateType, ScaleTwoDecimal> netIndirectTotals =
        new HashMap<RateClassRateType, ScaleTwoDecimal>();
    for (RateClassRateType rate : currentIndirectTotals.keySet()) {
      netIndirectTotals.put(rate, currentIndirectTotals.get(rate));
    }

    return netIndirectTotals;
  }
  /**
   * This method checks business rules related to Budget Expenses functionality
   *
   * @param budgetDocument
   * @return
   */
  protected boolean processBudgetExpenseBusinessRules(BudgetDocument budgetDocument) {
    boolean valid = true;

    MessageMap errorMap = GlobalVariables.getMessageMap();

    List<BudgetPeriod> budgetPeriods = budgetDocument.getBudget().getBudgetPeriods();
    int i = 0;
    int j = 0;
    for (BudgetPeriod budgetPeriod : budgetPeriods) {
      j = 0;
      List<BudgetLineItem> budgetLineItems = budgetPeriod.getBudgetLineItems();
      for (BudgetLineItem budgetLineItem : budgetLineItems) {
        if (budgetLineItem != null
            && budgetLineItem.getStartDate() != null
            && budgetLineItem.getStartDate().before(budgetPeriod.getStartDate())) {
          errorMap.putError(
              "budgetCategoryTypes["
                  + budgetLineItem.getBudgetCategory().getBudgetCategoryTypeCode()
                  + "].budgetPeriods["
                  + i
                  + "].budgetLineItems["
                  + j
                  + "].startDate",
              KeyConstants.ERROR_LINEITEM_STARTDATE_BEFORE_PERIOD_STARTDATE);
          valid = false;
        }
        if (budgetLineItem != null
            && budgetLineItem.getEndDate() != null
            && budgetLineItem.getEndDate().after(budgetPeriod.getEndDate())) {
          errorMap.putError(
              "budgetCategoryTypes["
                  + budgetLineItem.getBudgetCategory().getBudgetCategoryTypeCode()
                  + "].budgetPeriods["
                  + i
                  + "].budgetLineItems["
                  + j
                  + "].endDate",
              KeyConstants.ERROR_LINEITEM_ENDDATE_AFTER_PERIOD_ENDDATE);
          valid = false;
        }

        if (budgetLineItem != null
            && budgetLineItem.getQuantity() != null
            && budgetLineItem.getQuantity().intValue() < 0) {
          errorMap.putError(
              "budgetPeriod[" + i + "].budgetLineItem[" + j + "].quantity",
              KeyConstants.ERROR_NEGATIVE_AMOUNT,
              "Quantity");
          valid = false;
        }

        j++;
      }
      i++;
    }
    return valid;
  }
 /*
  * This method will get the unique list of cost element description.Iterate
  * over budget periods and budget line items check's with map whether that
  * cost element is available in map , if not found add cost element
  * description to map.
  */
 private Map<String, String> getListOfCostElementDescription(
     List<List<BudgetLineItemCalculatedAmount>> budgetLineItemCalcAmountsList) {
   Map<String, String> lineItems = new HashMap<String, String>();
   for (BudgetPeriod budgetPeriod : budget.getBudgetPeriods()) {
     List<BudgetLineItemCalculatedAmount> budgetLineItemCalcAmounts =
         new ArrayList<BudgetLineItemCalculatedAmount>();
     for (BudgetLineItem budgetLineItem : budgetPeriod.getBudgetLineItems()) {
       budgetLineItemCalcAmounts = budgetLineItem.getBudgetLineItemCalculatedAmounts();
       budgetLineItemCalcAmountsList.add(budgetLineItemCalcAmounts);
       if (budgetLineItem.getCostElementBO() != null) {
         String costElementDesc = budgetLineItem.getCostElementBO().getDescription();
         if (costElementDesc != null
             && !lineItems.containsKey(costElementDesc)
             && budgetLineItem.getCostElementBO().getCostElement() != null) {
           lineItems.put(costElementDesc, budgetLineItem.getCostElementBO().getCostElement());
         }
       }
     }
   }
   return lineItems;
 }
  /**
   * This method checks business rules related to Budget Personnel Budget functionality
   *
   * @param budgetDocument
   * @return
   */
  protected boolean processBudgetPersonnelBudgetBusinessRules(BudgetDocument budgetDocument) {
    boolean valid = true;

    MessageMap errorMap = GlobalVariables.getMessageMap();

    List<BudgetPeriod> budgetPeriods = budgetDocument.getBudget().getBudgetPeriods();
    int i = 0;
    int j = 0;
    int k = 0;
    for (BudgetPeriod budgetPeriod : budgetPeriods) {
      j = 0;
      List<BudgetLineItem> budgetLineItems = budgetPeriod.getBudgetLineItems();
      k = 0;
      for (BudgetLineItem budgetLineItem : budgetLineItems) {
        for (BudgetPersonnelDetails budgetPersonnelDetails :
            budgetLineItem.getBudgetPersonnelDetailsList()) {
          if (budgetPersonnelDetails != null
              && budgetPersonnelDetails.getStartDate() != null
              && budgetPersonnelDetails.getStartDate().before(budgetLineItem.getStartDate())) {
            errorMap.putError(
                "budgetPeriod["
                    + i
                    + "].budgetLineItems["
                    + j
                    + "].budgetPersonnelDetailsList["
                    + k
                    + "].startDate",
                KeyConstants.ERROR_PERSONNELBUDGETLINEITEM_STARTDATE_BEFORE_LINEITEM_STARTDATE);
            valid = false;
          }
          if (budgetPersonnelDetails != null
              && budgetPersonnelDetails.getEndDate() != null
              && budgetPersonnelDetails.getEndDate().after(budgetLineItem.getEndDate())) {
            errorMap.putError(
                "budgetPeriod["
                    + i
                    + "].budgetLineItems["
                    + j
                    + "].budgetPersonnelDetailsList["
                    + k
                    + "].endDate",
                KeyConstants.ERROR_PERSONNELBUDGETLINEITEM_ENDDATE_AFTER_LINEITEM_ENDDATE);
            valid = false;
          }
          if (budgetPersonnelDetails.getPercentEffort().isGreaterThan(new ScaleTwoDecimal(100))) {
            errorMap.putError(
                "budgetPeriod["
                    + i
                    + "].budgetLineItems["
                    + j
                    + "].budgetPersonnelDetailsList["
                    + k
                    + "].percentEffort",
                KeyConstants.ERROR_PERCENTAGE,
                Constants.PERCENT_EFFORT_FIELD);
          }
          if (budgetPersonnelDetails.getPercentCharged().isGreaterThan(new ScaleTwoDecimal(100))) {
            errorMap.putError(
                "budgetPeriod["
                    + i
                    + "].budgetLineItems["
                    + j
                    + "].budgetPersonnelDetailsList["
                    + k
                    + "].percentCharged",
                KeyConstants.ERROR_PERCENTAGE,
                Constants.PERCENT_CHARGED_FIELD);
          }
          if (budgetPersonnelDetails
              .getPercentCharged()
              .isGreaterThan(budgetPersonnelDetails.getPercentEffort())) {
            errorMap.putError(
                "budgetPeriod["
                    + i
                    + "].budgetLineItems["
                    + j
                    + "].budgetPersonnelDetailsList["
                    + k
                    + "].percentCharged",
                KeyConstants.ERROR_PERCENT_EFFORT_LESS_THAN_PERCENT_CHARGED);
          }
          k++;
        }
        j++;
      }
      i++;
    }
    return valid;
  }
  @KcEventMethod
  public boolean processApplyToLaterPeriodsWithPersonnelDetails(ApplyToPeriodsBudgetEvent event) {
    MessageMap errorMap = getGlobalVariableService().getMessageMap();
    Budget budget = event.getBudget();
    BudgetLineItem budgetLineItem = event.getBudgetLineItem();

    List<BudgetPeriod> budgetPeriods = budget.getBudgetPeriods();
    BudgetLineItem prevBudgetLineItem = budgetLineItem;
    for (BudgetPeriod budgetPeriod : budgetPeriods) {
      if (budgetPeriod.getBudgetPeriod() <= event.getBudgetPeriod().getBudgetPeriod()) continue;
      QueryList<BudgetLineItem> currentBudgetPeriodLineItems =
          new QueryList<BudgetLineItem>(budgetPeriod.getBudgetLineItems());
      for (BudgetLineItem budgetLineItemToBeApplied : currentBudgetPeriodLineItems) {
        if (prevBudgetLineItem
            .getLineItemNumber()
            .equals(budgetLineItemToBeApplied.getBasedOnLineItem())) {
          if (budgetLineItemToBeApplied
                  .getBudgetCategory()
                  .getBudgetCategoryTypeCode()
                  .equals(PERSONNEL_CATEGORY)
              && (!budgetLineItemToBeApplied.getBudgetPersonnelDetailsList().isEmpty()
                  || !prevBudgetLineItem.getBudgetPersonnelDetailsList().isEmpty())) {
            errorMap.putError(
                event.getErrorPath() + COST_ELEMENT,
                KeyConstants.ERROR_APPLY_TO_LATER_PERIODS,
                budgetLineItemToBeApplied.getBudgetPeriod().toString());
            return false;
          }
        } else if (StringUtils.equals(
            budgetLineItem.getBudgetCategory().getBudgetCategoryTypeCode(), PERSONNEL_CATEGORY)) {
          // Additional Check for Personnel Source Line Item
          if (StringUtils.equals(
                  budgetLineItem.getCostElement(), budgetLineItemToBeApplied.getCostElement())
              && StringUtils.equals(
                  budgetLineItem.getGroupName(), budgetLineItemToBeApplied.getGroupName())) {
            errorMap.putError(
                event.getErrorPath() + COST_ELEMENT,
                KeyConstants.ERROR_PERSONNELLINEITEM_APPLY_TO_LATER_PERIODS,
                budgetLineItemToBeApplied.getBudgetPeriod().toString());
            return false;
          }
        }
      }
    }

    return true;
  }
  @Test
  public void testExample1WithLineItems() throws Exception {
    context.checking(
        new Expectations() {
          {
            one(sponsorHierarchyService).isSponsorNihMultiplePi(NIH_SPONSOR_CODE);
            will(returnValue(true));
          }
        });

    subAward.getBudgetSubAwardPeriodDetails().get(0).setDirectCost(new ScaleTwoDecimal(150000L));
    subAward.getBudgetSubAwardPeriodDetails().get(0).setIndirectCost(new ScaleTwoDecimal(75000L));
    subAward.getBudgetSubAwardPeriodDetails().get(1).setDirectCost(new ScaleTwoDecimal(150000L));
    subAward.getBudgetSubAwardPeriodDetails().get(1).setIndirectCost(new ScaleTwoDecimal(75000L));

    for (BudgetPeriod period : budget.getBudgetPeriods()) {
      BudgetLineItem newLineItem = new BudgetLineItem();
      newLineItem.setBudgetSubAward(subAward);
      newLineItem.setSubAwardNumber(subAward.getSubAwardNumber());
      newLineItem.setDirectCost(new ScaleTwoDecimal(100L));
      newLineItem.setCostSharingAmount(new ScaleTwoDecimal(100L));
      newLineItem.setCostElement(directLt);
      newLineItem.setLineItemNumber(1);
      period.getBudgetLineItems().add(newLineItem);
      newLineItem = (BudgetLineItem) org.kuali.rice.krad.util.ObjectUtils.deepCopy(newLineItem);
      newLineItem.setCostElement(directGt);
      newLineItem.setLineItemNumber(2);
      period.getBudgetLineItems().add(newLineItem);
      newLineItem = (BudgetLineItem) org.kuali.rice.krad.util.ObjectUtils.deepCopy(newLineItem);
      newLineItem.setCostElement(indirectLt);
      newLineItem.setLineItemNumber(3);
      period.getBudgetLineItems().add(newLineItem);
      newLineItem = (BudgetLineItem) org.kuali.rice.krad.util.ObjectUtils.deepCopy(newLineItem);
      newLineItem.setCostElement(indirectGt);
      newLineItem.setLineItemNumber(4);
      period.getBudgetLineItems().add(newLineItem);
    }

    List<Map<String, ScaleTwoDecimal>> expectedResults = new ArrayList<>();
    expectedResults.add(new HashMap<>());
    expectedResults.add(new HashMap<>());
    expectedResults.add(new HashMap<>());
    expectedResults.get(0).put(indirectGt, new ScaleTwoDecimal(75000L));
    expectedResults.get(0).put(indirectLt, ScaleTwoDecimal.ZERO);
    expectedResults.get(0).put(directGt, new ScaleTwoDecimal(125000L));
    expectedResults.get(0).put(directLt, new ScaleTwoDecimal(25000L));
    expectedResults.get(1).put(indirectGt, new ScaleTwoDecimal(75000L));
    expectedResults.get(1).put(indirectLt, ScaleTwoDecimal.ZERO);
    expectedResults.get(1).put(directGt, new ScaleTwoDecimal(150000L));
    expectedResults.get(1).put(directLt, ScaleTwoDecimal.ZERO);
    service.generateSubAwardLineItems(subAward, budget);
    assertExpectedResults(expectedResults);
    assertCostShare(0);
  }