@KcEventMethod
 public KcEventResult validateProjectPersonnel(BudgetSaveProjectPersonnelEvent event) {
   KcEventResult result = new KcEventResult();
   result.getMessageMap().addToErrorPath(event.getErrorPath());
   verifyJobCode(event, result);
   result.getMessageMap().removeFromErrorPath(event.getErrorPath());
   return result;
 }
  @KcEventMethod
  public boolean processBudgetPersonnelBusinessRules(BudgetSaveEvent event) {
    boolean valid = true;

    List<BudgetPerson> budgetPersons = event.getBudget().getBudgetPersons();

    // not an error - ProposalHierarchy parents are allowed to have duplicate BudgetPersons
    BudgetParent budgetParent = event.getBudget().getBudgetParent().getDocument().getBudgetParent();
    if (budgetParent instanceof DevelopmentProposal
        && ((DevelopmentProposal) budgetParent).isParent()) {
      KcEventResult result = isNotDuplicateBudgetPersons(budgetPersons);
      GlobalVariables.getMessageMap().merge(result.getMessageMap());
    }
    return valid;
  }
  @KcEventMethod
  public KcEventResult processBudgetLineItemExpenseRules(BudgetExpensesRuleEvent event) {
    KcEventResult result = new KcEventResult();
    Budget budget = event.getBudget();

    if (budget.getTotalCostLimit().isGreaterThan(new ScaleTwoDecimal(0))
        && budget.getTotalCost().isGreaterThan(budget.getTotalCostLimit())) {
      result
          .getMessageMap()
          .putWarning(event.getErrorPath(), KeyConstants.WARNING_TOTAL_COST_LIMIT_EXCEEDED);
    }

    if (budget.getTotalDirectCostLimit().isGreaterThan(new ScaleTwoDecimal(0))
        && budget.getTotalDirectCost().isGreaterThan(budget.getTotalDirectCostLimit())) {
      result
          .getMessageMap()
          .putWarning(event.getErrorPath(), KeyConstants.WARNING_TOTAL_DIRECT_COST_LIMIT_EXCEEDED);
    }

    String errorPath = BUDGET_PERSONNEL_COST_DETAILS_ID;
    if (event
        .getErrorPath()
        .equalsIgnoreCase(BudgetConstants.BudgetAuditRules.NON_PERSONNEL_COSTS.getPageId())) {
      errorPath = BUDGET_NON_PERSONNEL_COST_DETAILS_ID;
    }

    for (BudgetPeriod budgetPeriod : budget.getBudgetPeriods()) {
      if (budgetPeriod.getTotalCostLimit().isGreaterThan(new ScaleTwoDecimal(0))
          && budgetPeriod.getTotalCost().isGreaterThan(budgetPeriod.getTotalCostLimit())) {
        result
            .getMessageMap()
            .putWarning(
                errorPath + "_" + budgetPeriod.getBudgetPeriod(),
                KeyConstants.WARNING_PERIOD_COST_LIMIT_EXCEEDED,
                new String[] {budgetPeriod.getBudgetPeriod().toString()});
      }
      if (budgetPeriod.getDirectCostLimit().isGreaterThan(new ScaleTwoDecimal(0))
          && budgetPeriod.getTotalDirectCost().isGreaterThan(budgetPeriod.getDirectCostLimit())) {
        result
            .getMessageMap()
            .putWarning(
                errorPath + "_" + budgetPeriod.getBudgetPeriod(),
                KeyConstants.WARNING_PERIOD_DIRECT_COST_LIMIT_EXCEEDED,
                new String[] {budgetPeriod.getBudgetPeriod().toString()});
      }
    }
    return result;
  }
 protected boolean isNewJobCodeValid(BudgetPerson budgetPerson, KcEventResult result) {
   JobCode jobCode = getJobCodeService().findJobCodeRef(budgetPerson.getJobCode());
   String jobCodeValidationEnabledInd =
       this.paramService.getParameterValueAsString(
           Budget.class, Constants.BUDGET_JOBCODE_VALIDATION_ENABLED);
   if (jobCodeValidationEnabledInd.equals("Y")) {
     if (jobCode == null) {
       result.getMessageMap().putError("jobCode", KeyConstants.ERROR_PERSON_INVALID_JOBCODE_VALUE);
       result.setSuccess(false);
       return false;
     } else {
       return true;
     }
   } else {
     return true;
   }
 }
 protected void verifyJobCode(BudgetSaveProjectPersonnelEvent event, KcEventResult result) {
   List<BudgetLineItem> budgetLineItems = getBudgetLineItems(event);
   BudgetPerson budgetPerson = event.getBudgetPerson();
   if (isJobCodeChanged(budgetPerson) && isNewJobCodeValid(budgetPerson, result)) {
     if (isBudgetPersonExistsInPersonnelDetails(budgetLineItems, budgetPerson)) {
       if (isJobCodeValid(budgetPerson)) {
         updateJobCodeOnDetailsFromPerson(budgetLineItems, budgetPerson);
       } else {
         result.setSuccess(false);
       }
     }
   }
 }
  protected KcEventResult isNotDuplicateBudgetPersons(List<BudgetPerson> budgetPersons) {
    KcEventResult result = new KcEventResult();
    MessageMap messages = new MessageMap();
    result.setSuccess(true);

    for (int i = 0; i < budgetPersons.size(); i++) {
      BudgetPerson budgetPerson = budgetPersons.get(i);
      for (int j = i + 1; j < budgetPersons.size(); j++) {
        BudgetPerson budgetPersonCompare = budgetPersons.get(j);
        if (budgetPerson.isDuplicatePerson(budgetPersonCompare)) {
          messages.putError(
              "budgetPersons[" + j + "].personName",
              KeyConstants.ERROR_DUPLICATE_BUDGET_PERSON,
              budgetPerson.getPersonName());
          result.setSuccess(false);
        }
      }
    }

    result.setMessageMap(messages);
    return result;
  }