/**
   * gets the item from preq and restores the values from the original PO
   *
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @return actionForward
   * @throws Exception
   */
  public ActionForward restoreItemAccountsAmounts(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {
    AccountsPayableFormBase payableForm = (AccountsPayableFormBase) form;
    AccountsPayableDocument apDoc = (AccountsPayableDocument) payableForm.getDocument();

    String[] indexes = getSelectedItemNumber(request);
    int itemIndex = Integer.parseInt(indexes[0]);

    PurApItem item = apDoc.getItem((itemIndex));

    // first reset the the corresponding po items accounts amounts to this item
    restoreItemAccountsAmounts(apDoc, item);

    item.setItemQuantity(null);
    item.setItemTaxAmount(null);

    item.refreshReferenceObject(PurapPropertyConstants.ITEM_TYPE);

    final KualiDecimal itemExtendedPrice =
        (item.getExtendedPrice() == null) ? KualiDecimal.ZERO : item.getExtendedPrice();
    ;
    if (item.getItemType().isQuantityBasedGeneralLedgerIndicator()) {
      KualiDecimal newExtendedPrice = item.calculateExtendedPrice();
      item.setExtendedPrice(newExtendedPrice);
    }

    return mapping.findForward(KFSConstants.MAPPING_BASIC);
  }
  /**
   * Perform calculation on item line.
   *
   * @param mapping An ActionMapping
   * @param form An ActionForm
   * @param request The HttpServletRequest
   * @param response The HttpServletResponse
   * @return An ActionForward
   */
  @Override
  public ActionForward calculate(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {
    AccountsPayableFormBase apForm = (AccountsPayableFormBase) form;
    AccountsPayableDocument apDoc = (AccountsPayableDocument) apForm.getDocument();

    //   //recalculate the amounts and percents on the accounting line.
    SpringContext.getBean(PurapAccountingService.class).updateAccountAmounts(apDoc);

    // call precalculate
    if (SpringContext.getBean(KualiRuleService.class)
        .applyRules(new AttributedPreCalculateAccountsPayableEvent(apDoc))) {
      customCalculate(apDoc);

      // set calculated flag according to document type and status
      if (apForm instanceof PaymentRequestForm
          && apDoc
              .getApplicationDocumentStatus()
              .equals(PaymentRequestStatuses.APPDOC_AWAITING_TAX_REVIEW)) {
        // set calculated tax flag for tax area calculation
        PaymentRequestForm preqForm = (PaymentRequestForm) apForm;
        preqForm.setCalculatedTax(true);
      } else {
        // set calculated flag for document calculation, whether or not the process calculation rule
        // passes, since it only gives warning
        apForm.setCalculated(true);
      }
    }

    return super.calculate(mapping, form, request, response);
  }
  /**
   * @see
   *     org.kuali.kfs.sys.web.struts.KualiAccountingDocumentFormBase#populate(javax.servlet.http.HttpServletRequest)
   */
  @Override
  public void populate(HttpServletRequest request) {
    super.populate(request);
    AccountsPayableDocument apDoc = (AccountsPayableDocument) this.getDocument();

    // update po doc
    if (apDoc.getPurchaseOrderIdentifier() != null) {
      apDoc.setPurchaseOrderDocument(
          SpringContext.getBean(PurchaseOrderService.class)
              .getCurrentPurchaseOrder(apDoc.getPurchaseOrderIdentifier()));
    }

    // update counts after populate
    updateItemCounts();
  }
  /**
   * restores the preq preqItem' accounts amounts with po's item's account lines amounts.
   *
   * @param apDoc
   * @param preqItem
   */
  protected void restoreItemAccountsAmounts(AccountsPayableDocument apDoc, PurApItem preqItem) {
    List<PurApItem> pOItems = apDoc.getPurchaseOrderDocument().getItems();

    PurApItem pOItem = getPOItem(pOItems, preqItem.getItemLineNumber());
    if (ObjectUtils.isNotNull(pOItem)) {
      //   preqItem.setItemUnitPrice(pOItem.getItemUnitPrice());
      List<PurApAccountingLine> preqAccountingLines = preqItem.getSourceAccountingLines();
      for (PurApAccountingLine lineAcct : preqAccountingLines) {
        updateItemAccountLine(pOItem, lineAcct);
      }
    }
  }
  /**
   * gets the item from preq and restores the values from the original PO and then redistributes the
   * amounts based on extended cost and quantity
   *
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @return actionForward
   * @throws Exception
   */
  public ActionForward recalculateItemAccountsAmounts(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {
    AccountsPayableFormBase payableForm = (AccountsPayableFormBase) form;
    AccountsPayableDocument apDoc = (AccountsPayableDocument) payableForm.getDocument();

    PurapAccountingService purapAccountingService =
        SpringContext.getBean(PurapAccountingService.class);

    String[] indexes = getSelectedItemNumber(request);
    int itemIndex = Integer.parseInt(indexes[0]);

    PurApItem item = apDoc.getItem((itemIndex));

    // first reset the the corresponding po items accounts amounts to this item
    restoreItemAccountsAmounts(apDoc, item);

    item.refreshReferenceObject(PurapPropertyConstants.ITEM_TYPE);

    final KualiDecimal itemExtendedPrice =
        (item.getExtendedPrice() == null) ? KualiDecimal.ZERO : item.getExtendedPrice();
    ;
    if (item.getItemType().isQuantityBasedGeneralLedgerIndicator()) {
      KualiDecimal newExtendedPrice = item.calculateExtendedPrice();
      item.setExtendedPrice(newExtendedPrice);
    }

    PaymentRequestDocument preqDoc = (PaymentRequestDocument) apDoc;

    // set amounts on any empty
    preqDoc.updateExtendedPriceOnItems();

    // calculation just for the tax area, only at tax review stage
    // by now, the general calculation shall have been done.
    if (preqDoc
        .getApplicationDocumentStatus()
        .equals(PaymentRequestStatuses.APPDOC_AWAITING_TAX_REVIEW)) {
      SpringContext.getBean(PaymentRequestService.class).calculateTaxArea(preqDoc);
    }

    // notice we're ignoring whether the boolean, because these are just warnings they shouldn't
    // halt anything
    // Calculate Payment request before rules since the rule check totalAmount.
    SpringContext.getBean(PaymentRequestService.class).calculatePaymentRequest(preqDoc, true);
    SpringContext.getBean(KualiRuleService.class)
        .applyRules(new AttributedCalculateAccountsPayableEvent(preqDoc));

    PurchasingAccountsPayableDocumentBase document = (PurchasingAccountsPayableDocumentBase) apDoc;
    String accountDistributionMethod = document.getAccountDistributionMethod();

    if (PurapConstants.AccountDistributionMethodCodes.SEQUENTIAL_CODE.equalsIgnoreCase(
        accountDistributionMethod)) {
      // update the accounts amounts for PREQ and distribution method = sequential
      purapAccountingService.updatePreqItemAccountAmounts(item);
    } else {
      List<PurApAccountingLine> sourceAccountingLines = item.getSourceAccountingLines();
      for (PurApAccountingLine acctLine : sourceAccountingLines) {
        acctLine.setAmount(KualiDecimal.ZERO);
      }

      purapAccountingService.updatePreqProportionalItemAccountAmounts(item);
    }

    return mapping.findForward(KFSConstants.MAPPING_BASIC);
  }