/**
   * This method will use the DocumentService to create a new document. The documentTypeName is
   * gathered by using MaintenanceDocumentDictionaryService which uses Account class to get the
   * document type name.
   *
   * @param AccountCreationStatusDTO
   * @return document returns a new document for the account document type or null if there is an
   *     exception thrown.
   */
  public Document createCGAccountMaintenanceDocument(
      AccountCreationStatusDTO accountCreationStatus) {

    boolean internalUserSession = false;
    try {
      if (GlobalVariables.getUserSession() == null) {
        internalUserSession = true;
        GlobalVariables.setUserSession(new UserSession(KFSConstants.SYSTEM_USER));
        GlobalVariables.clear();
      }
      Document document =
          getDocumentService()
              .getNewDocument(
                  SpringContext.getBean(MaintenanceDocumentDictionaryService.class)
                      .getDocumentTypeName(Account.class));
      return document;

    } catch (Exception e) {
      accountCreationStatus.setErrorMessages(
          GlobalVariablesExtractHelper.extractGlobalVariableErrors());
      accountCreationStatus.setStatus(KcConstants.KcWebService.STATUS_KC_FAILURE);
      return null;
    } finally {
      // if a user session was established for this call, clear it our
      if (internalUserSession) {
        GlobalVariables.clear();
        GlobalVariables.setUserSession(null);
      }
    }
  }
  /**
   * 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);
      }
    }
  }