protected BudgetPeriod findBudgetPeriod(BudgetSubAwardPeriodDetail detail, Budget budget) {
   for (BudgetPeriod period : budget.getBudgetPeriods()) {
     if (ObjectUtils.equals(detail.getBudgetPeriod(), period.getBudgetPeriod())) {
       return period;
     }
   }
   return null;
 }
 public void prepareBudgetSubAwards(Budget budget) {
   populateBudgetSubAwardAttachments(budget);
   for (BudgetSubAwards subAward : budget.getBudgetSubAwards()) {
     for (BudgetPeriod period : budget.getBudgetPeriods()) {
       BudgetSubAwardPeriodDetail detail = null;
       for (BudgetSubAwardPeriodDetail curDetail : subAward.getBudgetSubAwardPeriodDetails()) {
         if (ObjectUtils.equals(curDetail.getBudgetPeriod(), period.getBudgetPeriod())) {
           detail = curDetail;
           break;
         }
       }
       if (detail == null) {
         subAward
             .getBudgetSubAwardPeriodDetails()
             .add(new BudgetSubAwardPeriodDetail(subAward, period));
       }
     }
   }
 }
  /**
   * First find a budget period that matches the start and end date. If that is found, find a
   * subaward period detail with the same budget period number.
   *
   * @param budget
   * @param budgetSubAward
   * @param startDate
   * @param endDate
   * @return
   */
  protected BudgetSubAwardPeriodDetail findBudgetSubAwardPeriodDetail(
      Budget budget, BudgetSubAwards budgetSubAward, Date startDate, Date endDate) {
    BudgetPeriod matchingPeriod = null;
    BudgetSubAwardPeriodDetail matchingDetail = null;
    for (BudgetPeriod period : budget.getBudgetPeriods()) {
      if (startDate.getTime() == period.getStartDate().getTime()
          && endDate.getTime() == period.getEndDate().getTime()) {
        matchingPeriod = period;
        break;
      }
    }
    if (matchingPeriod != null) {

      for (BudgetSubAwardPeriodDetail detail : budgetSubAward.getBudgetSubAwardPeriodDetails()) {
        if (ObjectUtils.equals(detail.getBudgetPeriod(), matchingPeriod.getBudgetPeriod())) {
          matchingDetail = detail;
          break;
        }
      }
    }
    return matchingDetail;
  }
  protected BudgetLineItem findOrCreateLineItem(
      List<BudgetLineItem> lineItems,
      BudgetSubAwardPeriodDetail subAwardDetail,
      BudgetSubAwards subAward,
      BudgetPeriod budgetPeriod,
      String costElement) {
    for (BudgetLineItem curLineItem : lineItems) {
      if (StringUtils.equals(curLineItem.getCostElement(), costElement)) {
        return curLineItem;
      }
    }

    // if we didn't find one already
    BudgetLineItem newLineItem = new BudgetLineItem();
    newLineItem.setCostElement(costElement);
    newLineItem.setSubAwardNumber(subAwardDetail.getSubAwardNumber());
    newLineItem.setLineItemDescription(subAward.getOrganizationName());
    getBudgetService().populateNewBudgetLineItem(newLineItem, budgetPeriod);
    lineItems.add(newLineItem);
    return newLineItem;
  }
 /**
  * This method checks to see if the BudgetSubAwardPeriodDetail has changed from the database
  * version. If checkDirect is true then it checks on the value of direct cost. If checkDirect is
  * false, it is checked based on the value of indirect cost.
  *
  * @param detail
  * @param checkDirect
  * @return
  */
 private boolean hasBeenChanged(BudgetSubAwardPeriodDetail detail, boolean checkDirect) {
   boolean changed = false;
   if (detail != null && detail.getBudgetSubAwardDetailId() != null) {
     Map primaryKeys = new HashMap();
     primaryKeys.put("SUBAWARD_PERIOD_DETAIL_ID", detail.getBudgetSubAwardDetailId());
     BudgetSubAwardPeriodDetail dbDetail =
         getBusinessObjectService()
             .findByPrimaryKey(BudgetSubAwardPeriodDetail.class, primaryKeys);
     if (checkDirect) {
       changed =
           !BudgetDecimal.returnZeroIfNull(detail.getDirectCost())
               .equals(BudgetDecimal.returnZeroIfNull(dbDetail.getDirectCost()));
     } else {
       changed =
           !BudgetDecimal.returnZeroIfNull(detail.getIndirectCost())
               .equals(BudgetDecimal.returnZeroIfNull(dbDetail.getIndirectCost()));
     }
   }
   return changed;
 }
 /**
  * @see
  *     org.kuali.kra.proposaldevelopment.budget.service.BudgetSubAwardService#updateSubAwardBudgetDetails(org.kuali.kra.budget.core.Budget,
  *     org.kuali.kra.proposaldevelopment.budget.bo.BudgetSubAwards, java.util.List)
  */
 public boolean updateSubAwardBudgetDetails(
     Budget budget, BudgetSubAwards budgetSubAward, List<String[]> errors) throws Exception {
   boolean result = true;
   // extarct xml from the pdf because the stored xml has been modified
   if (budgetSubAward.getSubAwardXfdFileData() == null
       || budgetSubAward.getSubAwardXfdFileData().length == 0) {
     errors.add(new String[] {Constants.SUBAWARD_FILE_NOT_EXTRACTED});
     return false;
   }
   PdfReader reader = new PdfReader(budgetSubAward.getSubAwardXfdFileData());
   byte[] xmlContents = getXMLFromPDF(reader);
   if (xmlContents == null) {
     return false;
   }
   javax.xml.parsers.DocumentBuilderFactory domParserFactory =
       javax.xml.parsers.DocumentBuilderFactory.newInstance();
   javax.xml.parsers.DocumentBuilder domParser = domParserFactory.newDocumentBuilder();
   ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(xmlContents);
   org.w3c.dom.Document document = domParser.parse(byteArrayInputStream);
   NodeList budgetYearList =
       XPathAPI.selectNodeList(document, "//*[local-name(.) = 'BudgetYear']");
   DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
   boolean fnfForm = StringUtils.contains(budgetSubAward.getFormName(), "RR_FedNonFedBudget");
   for (int i = 0; i < budgetYearList.getLength(); i++) {
     Node budgetYear = budgetYearList.item(i);
     Node startDateNode = XPathAPI.selectSingleNode(budgetYear, "BudgetPeriodStartDate");
     if (startDateNode == null) {
       startDateNode = XPathAPI.selectSingleNode(budgetYear, "PeriodStartDate");
     }
     Node endDateNode = XPathAPI.selectSingleNode(budgetYear, "BudgetPeriodEndDate");
     if (endDateNode == null) {
       endDateNode = XPathAPI.selectSingleNode(budgetYear, "PeriodEndDate");
     }
     Date startDate = dateFormat.parse(startDateNode.getTextContent());
     Date endDate = dateFormat.parse(endDateNode.getTextContent());
     // attempt to find a matching budget period
     BudgetSubAwardPeriodDetail periodDetail =
         findBudgetSubAwardPeriodDetail(budget, budgetSubAward, startDate, endDate);
     if (periodDetail != null) {
       Node directCostNode, indirectCostNode, costShareNode = null;
       if (fnfForm) {
         directCostNode = XPathAPI.selectSingleNode(budgetYear, "DirectCosts/FederalSummary");
         indirectCostNode =
             XPathAPI.selectSingleNode(
                 budgetYear, "IndirectCosts/TotalIndirectCosts/FederalSummary");
         costShareNode = XPathAPI.selectSingleNode(budgetYear, "TotalCosts/NonFederalSummary");
       } else {
         directCostNode = XPathAPI.selectSingleNode(budgetYear, "DirectCosts");
         indirectCostNode =
             XPathAPI.selectSingleNode(budgetYear, "IndirectCosts/TotalIndirectCosts");
       }
       if (directCostNode != null) {
         periodDetail.setDirectCost(
             new BudgetDecimal(Float.parseFloat(directCostNode.getTextContent())));
       }
       if (indirectCostNode != null) {
         periodDetail.setIndirectCost(
             new BudgetDecimal(Float.parseFloat(indirectCostNode.getTextContent())));
       }
       if (costShareNode != null) {
         periodDetail.setCostShare(
             new BudgetDecimal(Float.parseFloat(costShareNode.getTextContent())));
       } else {
         periodDetail.setCostShare(BudgetDecimal.ZERO);
       }
       periodDetail.computeTotal();
     } else {
       Node budgetPeriodNode = XPathAPI.selectSingleNode(budgetYear, "BudgetPeriod");
       String budgetPeriod = null;
       if (budgetPeriodNode != null) {
         budgetPeriod = budgetPeriodNode.getTextContent();
       }
       LOG.debug(
           "Unable to find matching period for uploaded period '"
               + budgetPeriod
               + "' -- "
               + startDateNode.getTextContent()
               + " - "
               + endDateNode.getTextContent());
       errors.add(
           new String[] {
             Constants.SUBAWARD_FILE_PERIOD_NOT_FOUND,
             budgetPeriod,
             startDateNode.getTextContent(),
             endDateNode.getTextContent()
           });
     }
   }
   return result;
 }
 public void generateSubAwardLineItems(BudgetSubAwards subAward, Budget budget) {
   BudgetDecimal amountChargeFA = new BudgetDecimal(25000);
   String directLtCostElement =
       getParameterService()
           .getParameterValueAsString(
               BudgetDocument.class, Constants.SUBCONTRACTOR_DIRECT_LT_25K_PARAM);
   String directGtCostElement =
       getParameterService()
           .getParameterValueAsString(
               BudgetDocument.class, Constants.SUBCONTRACTOR_DIRECT_GT_25K_PARAM);
   String inDirectLtCostElement =
       getParameterService()
           .getParameterValueAsString(
               BudgetDocument.class, Constants.SUBCONTRACTOR_F_AND_A_LT_25K_PARAM);
   String inDirectGtCostElement =
       getParameterService()
           .getParameterValueAsString(
               BudgetDocument.class, Constants.SUBCONTRACTOR_F_AND_A_GT_25K_PARAM);
   for (BudgetSubAwardPeriodDetail detail : subAward.getBudgetSubAwardPeriodDetails()) {
     BudgetPeriod budgetPeriod = findBudgetPeriod(detail, budget);
     List<BudgetLineItem> currentLineItems =
         findSubAwardLineItems(budgetPeriod, subAward.getSubAwardNumber());
     // zero out existing line items before recalculating
     for (BudgetLineItem item : currentLineItems) {
       item.setDirectCost(BudgetDecimal.ZERO);
       item.setCostSharingAmount(BudgetDecimal.ZERO);
       item.setSubAwardNumber(subAward.getSubAwardNumber());
       item.setLineItemDescription(subAward.getOrganizationName());
     }
     if (BudgetDecimal.returnZeroIfNull(detail.getDirectCost()).isNonZero()
         || hasBeenChanged(detail, true)) {
       BudgetDecimal ltValue = lesserValue(detail.getDirectCost(), amountChargeFA);
       BudgetDecimal gtValue = detail.getDirectCost().subtract(ltValue);
       if (ltValue.isNonZero()) {
         BudgetLineItem lt =
             findOrCreateLineItem(
                 currentLineItems, detail, subAward, budgetPeriod, directLtCostElement);
         lt.setLineItemCost(ltValue);
       }
       if (gtValue.isNonZero()) {
         BudgetLineItem gt =
             findOrCreateLineItem(
                 currentLineItems, detail, subAward, budgetPeriod, directGtCostElement);
         gt.setLineItemCost(gtValue);
       }
       amountChargeFA = amountChargeFA.subtract(ltValue);
     }
     if (BudgetDecimal.returnZeroIfNull(detail.getIndirectCost()).isNonZero()
         || hasBeenChanged(detail, false)) {
       BudgetDecimal ltValue = lesserValue(detail.getIndirectCost(), amountChargeFA);
       BudgetDecimal gtValue = detail.getIndirectCost().subtract(ltValue);
       if (ltValue.isNonZero()) {
         BudgetLineItem lt =
             findOrCreateLineItem(
                 currentLineItems, detail, subAward, budgetPeriod, inDirectLtCostElement);
         lt.setLineItemCost(ltValue);
       }
       if (gtValue.isNonZero()) {
         BudgetLineItem gt =
             findOrCreateLineItem(
                 currentLineItems, detail, subAward, budgetPeriod, inDirectGtCostElement);
         gt.setLineItemCost(gtValue);
       }
       amountChargeFA = amountChargeFA.subtract(ltValue);
     }
     Collections.sort(
         currentLineItems,
         new Comparator<BudgetLineItem>() {
           public int compare(BudgetLineItem arg0, BudgetLineItem arg1) {
             return arg0.getLineItemNumber().compareTo(arg1.getLineItemNumber());
           }
         });
     Iterator<BudgetLineItem> iter = currentLineItems.iterator();
     while (iter.hasNext()) {
       BudgetLineItem lineItem = iter.next();
       if (BudgetDecimal.returnZeroIfNull(lineItem.getLineItemCost()).isZero()) {
         budgetPeriod.getBudgetLineItems().remove(lineItem);
         iter.remove();
       } else {
         if (!budgetPeriod.getBudgetLineItems().contains(lineItem)) {
           budgetPeriod.getBudgetLineItems().add(lineItem);
         }
       }
     }
     if (!currentLineItems.isEmpty()
         && BudgetDecimal.returnZeroIfNull(detail.getCostShare()).isNonZero()) {
       currentLineItems.get(0).setCostSharingAmount(detail.getCostShare());
     }
   }
 }