@Override
 public List<ProtocolOnlineReviewDocumentBase> getProtocolReviewDocumentsForCurrentSubmission(
     ProtocolBase protocol) {
   List<ProtocolOnlineReviewDocumentBase> onlineReviewDocuments =
       new ArrayList<ProtocolOnlineReviewDocumentBase>();
   ProtocolSubmissionBase submission = protocol.getProtocolSubmission();
   List<ProtocolOnlineReviewBase> reviews =
       findProtocolOnlineReviews(protocol.getProtocolId(), submission.getSubmissionId());
   for (ProtocolOnlineReviewBase review : reviews) {
     if (review.isActive()) {
       review.refresh();
       try {
         onlineReviewDocuments.add(
             (ProtocolOnlineReviewDocumentBase)
                 (documentService.getByDocumentHeaderId(
                     review.getProtocolOnlineReviewDocument().getDocumentNumber())));
       } catch (WorkflowException e) {
         throw new RuntimeException(
             String.format(
                 "Could not load ProtocolOnlineReviewBase docuemnt %s due to WorkflowException: %s",
                 review.getProtocolOnlineReviewDocument().getDocumentNumber(), e.getMessage()),
             e);
       }
     }
   }
   return onlineReviewDocuments;
 }
  public PurchaseOrderDocument initiateReopenPurchaseOrder(
      PurchaseOrderDocument po, String annotation) {
    try {
      LogicContainer logicToRun =
          new LogicContainer() {
            public Object runLogic(Object[] objects) throws Exception {
              PurchaseOrderDocument po = (PurchaseOrderDocument) objects[0];

              Note cancelNote = new Note();
              cancelNote.setNoteTypeCode(po.getNoteType().getCode());
              cancelNote.setAuthorUniversalIdentifier(
                  GlobalVariables.getUserSession().getPerson().getPrincipalId());
              cancelNote.setNoteText(
                  SpringContext.getBean(ConfigurationService.class)
                      .getPropertyValueAsString(PurapKeyConstants.AP_REOPENS_PURCHASE_ORDER_NOTE));
              cancelNote.setNotePostedTimestampToCurrent();
              po.addNote(cancelNote);
              SpringContext.getBean(PurapService.class).saveDocumentNoValidation(po);

              return SpringContext.getBean(PurchaseOrderService.class)
                  .createAndRoutePotentialChangeDocument(
                      po.getDocumentNumber(),
                      PurchaseOrderDocTypes.PURCHASE_ORDER_REOPEN_DOCUMENT,
                      (String) objects[1],
                      null,
                      PurchaseOrderStatuses.APPDOC_PENDING_REOPEN);
            }
          };
      return (PurchaseOrderDocument)
          SpringContext.getBean(PurapService.class)
              .performLogicWithFakedUserSession(
                  KFSConstants.SYSTEM_USER, logicToRun, new Object[] {po, annotation});
    } catch (WorkflowException e) {
      String errorMsg = "Workflow Exception caught: " + e.getLocalizedMessage();
      LOG.error(errorMsg, e);
      throw new RuntimeException(errorMsg, e);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  /**
   * This method processes the workflow document actions like save, route and blanket approve
   * depending on the ACCOUNT_AUTO_CREATE_ROUTE system parameter value. If the system parameter
   * value is not of save or submit or blanketapprove, put an error message and quit. Throws an
   * document WorkflowException if the specific document action fails to perform.
   *
   * @param maintenanceAccountDocument, errorMessages
   * @return
   */
  protected void createRouteAutomaticCGAccountDocument(
      MaintenanceDocument maintenanceAccountDocument,
      AccountCreationStatusDTO accountCreationStatus) {

    try {
      String accountAutoCreateRouteValue =
          getParameterService()
              .getParameterValueAsString(
                  Account.class,
                  KcConstants.AccountCreationService
                      .PARAMETER_KC_ACCOUNT_ADMIN_AUTO_CREATE_ACCOUNT_WORKFLOW_ACTION);

      // if the accountAutoCreateRouteValue is not save or submit or blanketApprove then put an
      // error message and quit.
      if (!accountAutoCreateRouteValue.equalsIgnoreCase(KFSConstants.WORKFLOW_DOCUMENT_SAVE)
          && !accountAutoCreateRouteValue.equalsIgnoreCase("submit")
          && !accountAutoCreateRouteValue.equalsIgnoreCase(
              KFSConstants.WORKFLOW_DOCUMENT_BLANKET_APPROVE)) {
        this.setFailStatus(
            accountCreationStatus,
            KcConstants.AccountCreationService
                .ERROR_KC_DOCUMENT_SYSTEM_PARAMETER_INCORRECT_DOCUMENT_ACTION_VALUE);
        LOG.error(
            "Incorrect document status::::: "
                + accountCreationStatus.getErrorMessages().toString());
        return;
      }

      if (accountAutoCreateRouteValue.equalsIgnoreCase(KFSConstants.WORKFLOW_DOCUMENT_SAVE)) {

        // attempt to save if apply rules were successful and there are no errors
        boolean rulesPassed =
            SpringContext.getBean(KualiRuleService.class)
                .applyRules(new SaveDocumentEvent(maintenanceAccountDocument));
        LOG.debug(
            "global variable messages :::  "
                + GlobalVariables.getMessageMap().getErrorMessages().toString());
        if (rulesPassed && GlobalVariables.getMessageMap().hasNoErrors()) {
          getDocumentService().saveDocument(maintenanceAccountDocument);
        } else {
          // get errors from apply rules invocation, also clears global variables
          LOG.info("rule fail formatting errors messages ");
          accountCreationStatus.setErrorMessages(
              GlobalVariablesExtractHelper.extractGlobalVariableErrors());
          try {
            // save document, and catch VE's as we want to do this silently
            getDocumentService().saveDocument(maintenanceAccountDocument);
          } catch (ValidationException ve) {
          }

          accountCreationStatus.setStatus(KcConstants.KcWebService.STATUS_KC_SUCCESS);
          LOG.error(
              KcUtils.getErrorMessage(
                  KcConstants.AccountCreationService.ERROR_KC_DOCUMENT_ACCOUNT_RULES_EXCEPTION,
                  new String[] {maintenanceAccountDocument.getDocumentNumber()}));
        }

      } else if (accountAutoCreateRouteValue.equalsIgnoreCase(
          KFSConstants.WORKFLOW_DOCUMENT_BLANKET_APPROVE)) {

        // attempt to blanket approve if apply rules were successful and there are no errors
        boolean rulesPassed =
            SpringContext.getBean(KualiRuleService.class)
                .applyRules(new BlanketApproveDocumentEvent(maintenanceAccountDocument));

        if (rulesPassed && GlobalVariables.getMessageMap().hasNoErrors()) {
          getDocumentService().blanketApproveDocument(maintenanceAccountDocument, "", null);
        } else {
          // get errors from apply rules invocation, also clears global variables
          accountCreationStatus.setErrorMessages(
              GlobalVariablesExtractHelper.extractGlobalVariableErrors());
          try {
            // save document, and catch VE's as we want to do this silently
            getDocumentService().saveDocument(maintenanceAccountDocument);
          } catch (ValidationException ve) {
          }

          accountCreationStatus.setStatus(KcConstants.KcWebService.STATUS_KC_SUCCESS);
          LOG.error(
              KcUtils.getErrorMessage(
                  KcConstants.AccountCreationService.ERROR_KC_DOCUMENT_ACCOUNT_RULES_EXCEPTION,
                  new String[] {maintenanceAccountDocument.getDocumentNumber()}));
        }

      } else if (accountAutoCreateRouteValue.equalsIgnoreCase("submit")) {

        // attempt to route if apply rules were successful and there are no errors
        boolean rulesPassed =
            SpringContext.getBean(KualiRuleService.class)
                .applyRules(new RouteDocumentEvent(maintenanceAccountDocument));

        if (rulesPassed && GlobalVariables.getMessageMap().hasNoErrors()) {
          getDocumentService().routeDocument(maintenanceAccountDocument, "", null);
        } else {
          // get errors from apply rules invocation, also clears global variables
          accountCreationStatus.setErrorMessages(
              GlobalVariablesExtractHelper.extractGlobalVariableErrors());
          try {
            // save document, and catch VE's as we want to do this silently
            getDocumentService().saveDocument(maintenanceAccountDocument);
          } catch (ValidationException ve) {
          }

          accountCreationStatus.setStatus(KcConstants.KcWebService.STATUS_KC_SUCCESS);
          LOG.error(
              KcUtils.getErrorMessage(
                  KcConstants.AccountCreationService.ERROR_KC_DOCUMENT_ACCOUNT_RULES_EXCEPTION,
                  new String[] {maintenanceAccountDocument.getDocumentNumber()}));
        }
      }

      // set the document number
      accountCreationStatus.setDocumentNumber(maintenanceAccountDocument.getDocumentNumber());

    } catch (WorkflowException wfe) {

      LOG.error(
          KcUtils.getErrorMessage(
                  KcConstants.AccountCreationService
                      .ERROR_KC_DOCUMENT_WORKFLOW_EXCEPTION_DOCUMENT_ACTIONS,
                  null)
              + ": "
              + wfe.getMessage());
      accountCreationStatus.setStatus(KcConstants.KcWebService.STATUS_KC_FAILURE);
      accountCreationStatus
          .getErrorMessages()
          .add(
              KcUtils.getErrorMessage(
                      KcConstants.AccountCreationService
                          .WARNING_KC_DOCUMENT_WORKFLOW_EXCEPTION_DOCUMENT_ACTIONS,
                      null)
                  + ": "
                  + wfe.getMessage());

      try {
        // save it even though it fails to route or blanket approve the document
        try {
          getDocumentService().saveDocument(maintenanceAccountDocument);
        } catch (ValidationException ve) {
          // ok to catch validation exceptions at this point
        }
        accountCreationStatus.setDocumentNumber(maintenanceAccountDocument.getDocumentNumber());
        accountCreationStatus.setStatus(KcConstants.KcWebService.STATUS_KC_SUCCESS);
      } catch (WorkflowException e) {
        LOG.error(
            KcUtils.getErrorMessage(
                    KcConstants.AccountCreationService
                        .WARNING_KC_DOCUMENT_WORKFLOW_EXCEPTION_DOCUMENT_ACTIONS,
                    null)
                + ": "
                + e.getMessage());
        accountCreationStatus.setErrorMessages(
            GlobalVariablesExtractHelper.extractGlobalVariableErrors());
        accountCreationStatus.setStatus(KcConstants.KcWebService.STATUS_KC_FAILURE);
      }

    } catch (Exception ex) {

      LOG.error("Unknown exception occurred: " + ex.getMessage());
      accountCreationStatus.setStatus(KcConstants.KcWebService.STATUS_KC_FAILURE);
      accountCreationStatus.setErrorMessages(
          GlobalVariablesExtractHelper.extractGlobalVariableErrors());
      accountCreationStatus
          .getErrorMessages()
          .add(
              KcUtils.getErrorMessage(
                      KcConstants.AccountCreationService
                          .WARNING_KC_DOCUMENT_WORKFLOW_EXCEPTION_DOCUMENT_ACTIONS,
                      null)
                  + ": "
                  + ex.getMessage());

      try {
        // save it even though it fails to route or blanket approve the document
        try {
          getDocumentService().saveDocument(maintenanceAccountDocument);
        } catch (ValidationException ve) {
          // ok to catch validation exceptions at this point
        }
        accountCreationStatus.setDocumentNumber(maintenanceAccountDocument.getDocumentNumber());
        accountCreationStatus.setStatus(KcConstants.KcWebService.STATUS_KC_SUCCESS);
      } catch (WorkflowException e) {
        LOG.error(
            KcUtils.getErrorMessage(
                    KcConstants.AccountCreationService
                        .WARNING_KC_DOCUMENT_WORKFLOW_EXCEPTION_DOCUMENT_ACTIONS,
                    null)
                + ": "
                + e.getMessage());
        accountCreationStatus.setErrorMessages(
            GlobalVariablesExtractHelper.extractGlobalVariableErrors());
        accountCreationStatus.setStatus(KcConstants.KcWebService.STATUS_KC_FAILURE);
      }
    }
  }
  protected void spawnPoAmendmentForUnorderedItems(
      ReceivingDocument receivingDocument, PurchaseOrderDocument po) {

    // if receiving line document
    if (receivingDocument instanceof LineItemReceivingDocument) {
      LineItemReceivingDocument rlDoc = (LineItemReceivingDocument) receivingDocument;

      // if a new item has been added spawn a purchase order amendment
      if (hasNewUnorderedItem((LineItemReceivingDocument) receivingDocument)) {
        String newSessionUserId = KFSConstants.SYSTEM_USER;
        try {

          LogicContainer logicToRun =
              new LogicContainer() {
                @Override
                public Object runLogic(Object[] objects) throws Exception {
                  LineItemReceivingDocument rlDoc = (LineItemReceivingDocument) objects[0];
                  String poDocNumber = (String) objects[1];

                  // create a PO amendment
                  PurchaseOrderAmendmentDocument amendmentPo =
                      (PurchaseOrderAmendmentDocument)
                          purchaseOrderService.createAndSavePotentialChangeDocument(
                              poDocNumber,
                              PurchaseOrderDocTypes.PURCHASE_ORDER_AMENDMENT_DOCUMENT,
                              PurchaseOrderStatuses.APPDOC_AMENDMENT);

                  // KFSPTS-1769, KFSUPGRADE-339
                  ((CuPurchaseOrderAmendmentDocument) amendmentPo).setSpawnPoa(true);
                  // add new lines to amendement
                  addUnorderedItemsToAmendment(amendmentPo, rlDoc);

                  // route amendment
                  documentService.routeDocument(amendmentPo, null, null);

                  // add note to amendment po document
                  String note =
                      "Purchase Order Amendment "
                          + amendmentPo.getPurapDocumentIdentifier()
                          + " (document id "
                          + amendmentPo.getDocumentNumber()
                          + ") created for new unordered line items due to Receiving (document id "
                          + rlDoc.getDocumentNumber()
                          + ")";

                  Note noteObj = documentService.createNoteFromDocument(amendmentPo, note);
                  amendmentPo.addNote(noteObj);
                  noteService.save(noteObj);

                  return null;
                }
              };

          purapService.performLogicWithFakedUserSession(
              newSessionUserId, logicToRun, new Object[] {rlDoc, po.getDocumentNumber()});
        } catch (WorkflowException e) {
          String errorMsg = "Workflow Exception caught: " + e.getLocalizedMessage();
          throw new RuntimeException(errorMsg, e);
        } catch (Exception e) {
          throw new RuntimeException(e);
        }
      }
    }
  }