/**
   * Handles a restriction on accounting lines assigned to trade-in items. If the accounting Line is
   * for a trade-in item type, and the accounting line has contents, the user is not allowed to
   * change the contents of the calculated values.
   *
   * <p>The trade-in may not yet have a sequence number, so the old way of relying solely on
   * sequence number (in method super.approvedForUnqualifiedEditing() is incomplete, and needs this
   * extra check for trade-ins.
   *
   * @param accountingLine the accounting line being examined
   * @return whether the accounting line is editable according to the trade-in/non-empty restriction
   */
  private boolean isEditableBasedOnTradeInRestriction(
      AccountingDocument accountingDocument, AccountingLine accountingLine) {
    boolean retval = true;
    // if the accounting Line is for a trade-In, and the line has contents, the user is not allowed
    // to
    // change the contents of the calculated values
    if ((accountingLine != null) && (accountingLine instanceof PurApAccountingLine)) {
      PurApItem purApItem = (((PurApAccountingLine) accountingLine)).getPurapItem();

      // this small block is to allow for another way to get to the purApItem if the
      // incoming accounting line does not yet have a purApItem attached. Calling it is not
      // completely necessary any more, unless/until the functional team members decide to
      // add more item types to the read-only accounting lines list.
      if (purApItem == null) {
        purApItem = findTheItemForAccountingLine(accountingDocument, accountingLine);
      }

      if (purApItem != null) {
        String itemTypeCode = purApItem.getItemTypeCode();
        if (itemTypeCode
            .toUpperCase()
            .equalsIgnoreCase(PurapParameterConstants.PURAP_ITEM_TYPE_TRDI)) {
          // does the line have any contents? if so, then the user cannot edit them
          if ((accountingLine.getChartOfAccountsCode() != null)
              || (accountingLine.getAccountNumber() != null)
              || (accountingLine.getFinancialObjectCode() != null)) {
            retval = false;
          }
        }
        // there has been a call to "if (purApItem.getItemAssignedToTradeInIndicator()) {" here
        // that required the earlier use of findTheItemForAccountingLine()
      }
    }
    return retval;
  }
  /**
   * Find the item to which an accounting line belongs. Convenience/Utility method.
   *
   * <p>Some methods that require an accounting line with a purApItem attached were getting
   * accounting lines passed in that did not yet have a purApItem. I needed a way to match the
   * accounting line to the proper item.
   *
   * @param accountingDocument the document holding both the accounting line and the item to which
   *     the accounting line is attached
   * @param accountingLine the accounting line of interest, for which a containing item should be
   *     found
   * @return the item to which the incoming accounting line is attached
   */
  protected PurApItem findTheItemForAccountingLine(
      AccountingDocument accountingDocument, AccountingLine accountingLine) {
    PurApItem retval = null;
    List<PurApItem> listItems = null;

    scan:
    {
      if (accountingDocument instanceof PurchasingAccountsPayableDocumentBase) {
        listItems = ((PurchasingAccountsPayableDocumentBase) accountingDocument).getItems();

        // loop through all items in the document to see if the item has an accounting line that
        // matches the one passed in
        for (PurApItem oneItem : listItems) {
          List<PurApAccountingLine> acctLines = oneItem.getSourceAccountingLines();
          for (PurApAccountingLine oneAcctLine : acctLines) {
            // we want to compare the exact same memory location, not the contents
            if (oneAcctLine == accountingLine) {
              retval = oneItem;

              // we found it, so I can stop altogether.
              break scan;
            }
          }
        }
      }
    }

    return retval;
  }