Package com.veeva.vault.sdk.api.action


package com.veeva.vault.sdk.api.action
This package provides interfaces to create custom actions.

Record Actions

Objects can have custom actions that perform specific instructions. You can use a custom action to automate certain business processes. You can configure custom record actions as any of the following:
  • User Action: Custom actions for records, called record actions or record user actions, are invoked by a user on a specific record from the UI or API. Learn more about Object User Actions in Vault Help.
  • User Bulk Action: Bulk actions allow users to make changes to up to 1,000 object records at once from the Vault UI. If a user updates more than 500 records with a custom bulk action, Vault splits the update into two separate SDK transactions: one containing the first 500 records and a second containing the remainder. If one transaction throws a RollbackException, it does not rollback the other transaction. Learn more about bulk object record actions in Vault Help.
  • Lifecycle User Action: Actions invoked by a user on a specific object lifecycle state, from the UI or API. You can configure these actions in the Object Lifecycle configuration. Learn more about Object Lifecycle User Actions in Vault Help.
  • Entry Action: Actions automatically invoked when an object record enters a particular lifecycle state. You can configure these actions in the Object Lifecycle configuration. Learn more about Object Entry Actions in Vault Help.
  • Event Action: Actions automatically invoked when a user creates an object record. You can configure these actions in the Object Lifecycle configuration. Learn more about Object Record Event Actions in Vault Help.
  • System Action Step: Actions automatically invoked when an object record enters a particular workflow step. You can configure these actions in the Object Workflow System Action step configuration.
  • Cancellation Action: Actions automatically invoked when a workflow is cancelled.

A Record Action is a Java class that implements the RecordAction interface and has the RecordActionInfo annotation. For example:

  @RecordActionInfo(name="hello__c", label="Say Hello", object="hello_world__c", usages={Usage.USER_ACTION, Usage.WORKFLOW_STEP})
 
   public class Hello implements RecordAction {
      public boolean isExecutable(RecordActionContext context) {
          return true;
      }

      public void execute(RecordActionContext context) {
          // Get the current record on which the action is invoked
          List<Record> records = context.getRecords();
          Record record= records.get(0);

          String name = record.getValue("name__v", ValueType.STRING);
          String[] originalName = null;

          if (!StringUtils.matches(name, "Hello(.*)")) {
              record.setValue("name__v","Hello, " + name);
          } else {
              originalName = StringUtils.split(name, ", ");
              record.setValue("name__v", originalName[1]);
          }
          // Save changes to the current record
          RecordService recordService = ServiceLocator.locate(RecordService.class);
          recordService.batchSaveRecords(VaultCollections.asList(record)).ignoreErrors().execute();
      }

      public void onPreExecute(PreExecutionRecordActionUIContext context) {
         // Get the UserActionUIService
         UserActionUIService userActionUIService = ServiceLocator.locate(UserActionUIService.class);

         // Build a UserActionExecutionBanner with a message
         String dialogMessage = "Sample dialog message";
         String dialogTitle = "Sample dialog title";
         UserActionExecutionDialog dialog = userActionUIService.newUserActionExecutionDialogBuilder()
             .withMessage(dialogMessage)
             .withTitle(dialogTitle)
             .build();

         // Build a PreExecutionUserActionUIBehavior with the banner
         PreExecutionUserActionUIBehavior preExecBehavior = userActionUIService.newPreExecutionUserActionUIBehaviorBuilder()
             .withDialog(dialog)
             .build();

         // Set the pre-execution user action UI behavior on the context
         context.setUserActionUIBehavior(preExecBehavior);
     }

     public void onPostExecute(PostExecutionRecordActionUIContext context) {
         // Get the UserActionUIService
         UserActionUIService userActionUIService = ServiceLocator.locate(UserActionUIService.class);

         // Build a UserActionExecutionBanner with a message
         String bannerMessage = "This is a sample banner message";
         UserActionExecutionBanner banner = userActionUIService.newUserActionExecutionBannerBuilder()
             .withMessage(bannerMessage)
             .build();

         // Build a PostExecutionUserActionUIBehavior with the banner
         PostExecutionUserActionUIBehavior postExecBehavior = userActionUIService.newPostExecutionUserActionUIBehaviorBuilder()
             .withBanner(banner)
             .build();

         // Set the post-execution user action UI behavior on the context
         context.setUserActionUIBehavior(postExecBehavior);
     }
   }
 
 
A class that implements the RecordAction interface must implement the following methods:
  • isExecutable: Determine if this action is visible in the UI or invokable from the REST API. Return true to make the action invokable.
  • execute: The logic to execute when the action is invoked. You can change field values on the current record, as illustrated in this example, or you can use any of the Vault Java SDK services (such as RecordService or QueryService) to change other records.
Optionally, a class that implements the RecordAction interface may also implement the following methods:
  • onPreExecute: The logic to execute before the action is invoked. This is used for setting pre-execution UI behavior for record actions in the USER_ACTION use case. As illustrated in the example above, a pre-execution dialog can be configured here, with a custom title and message.
  • onPostExecute: The logic to execute after the action is invoked. This is used for setting post-execution UI behavior for record actions in the USER_ACTION use case. As illustrated in the example above, a post-execution banner can be configured here, with a custom message.
The RecordActionInfo annotation has the following elements:
  • label: Label of the action
  • object: If specified, the action is available for the specified object only. If omitted, the action is available across all objects.
  • usage: If specified, the action is available for configuring in the specified usages only. For example, USER_ACTION. If omitted, the action is available across all supported usages.
  • user_input_object_type: If your action takes user input, identify the user input object type.
  • user_input_object: If your action takes user input, identify the user input object.

Document Actions

Documents can have custom actions that perform specific instructions. You can use a custom action to automate certain business processes. You can configure custom document actions as any of the following:
  • User Action: Actions invoked by a user on a specific document lifecycle state, from the UI or API. You can configure these actions in the Document Lifecycle configuration. Learn more about Document User Actions in Vault Help.
  • Entry Action: Actions automatically invoked when a document enters a particular lifecycle state. You can configure these actions in the Document Lifecycle configuration. Learn more about Document Entry Actions in Vault Help.

A Document Action is a Java class that implements the DocumentAction interface and has the DocumentActionInfo annotation.

The following is an example of a document user action. We query for a field on all binders a document is referenced in, and then set those values in a field on the document.

 @DocumentActionInfo(name = "get_partners__c", label="Find Partners", usages= Usage.USER_ACTION,lifecycle="general_lifecycle__c")
 public class FindPartners implements DocumentAction {
      public void execute(DocumentActionContext documentActionContext) {
      DocumentVersion docVersion = documentActionContext.getDocumentVersions().get(0);

      //Get the binders this document version is referenced in
      String QueryBindersDocIsIn = "SELECT parent_binder_id__sys " +
      "FROM binder_node__sys WHERE content_id__sys = " + docVersion.getValue("id", ValueType.STRING);
      QueryService queryService = ServiceLocator.locate(QueryService.class);
      QueryResponse bindersDocIsIn = queryService.query(QueryBindersDocIsIn);

      Iterator<QueryResult> iterator = bindersDocIsIn.streamResults().iterator();
      List<String> binderIds = VaultCollections.newList();
      while (iterator.hasNext()) {
         QueryResult idResults = (QueryResult) iterator.next();
          String parentBinderIds = idResults.getValue("parent_binder_id__sys", ValueType.STRING);
          binderIds.add(parentBinderIds);
      }
      //Get partner field values from the List of parent binders
      //Binder IDs must be in a comma separated String for In statement
      String QueryPartners = "SELECT partners__c " +
      "FROM documents WHERE id CONTAINS (" + String.join(",", binderIds) + ")";

      QueryResponse binderPartnerValues = queryService.query(QueryPartners);
      Iterator<QueryResult> partnerIterator = binderPartnerValues.streamResults().iterator();

      Set<String> partnerValues = VaultCollections.newSet();

      while (partnerIterator.hasNext()) {
          QueryResult partnerResults = (QueryResult) partnerIterator.next();
          partnerValues.addAll(partnerResults.getValue("partners__c", ValueType.REFERENCES));
      }

      List<String> partnerValueList = VaultCollections.newList();
      partnerValues.stream().forEach(partner -> partnerValueList.add(partner));

      DocumentService docService = ServiceLocator.locate((DocumentService.class));

      docVersion.setValue("partners__c", partnerValueList);
      docService.saveDocumentVersions(VaultCollections.asList(docVersion));
      }

  public boolean isExecutable(DocumentActionContext documentActionContext) {
      return true;
  }

  public void onPreExecute(PreExecutionDocumentActionUIContext context) {
      // Get the UserActionUIService
      UserActionUIService userActionUIService = ServiceLocator.locate(UserActionUIService.class);

      // Build a UserActionExecutionBanner with a message
      String dialogMessage = "Sample dialog message";
      String dialogTitle = "Sample dialog title";
      UserActionExecutionDialog dialog = userActionUIService.newUserActionExecutionDialogBuilder()
          .withMessage(dialogMessage)
          .withTitle(dialogTitle)
          .build();

      // Build a PreExecutionUserActionUIBehavior with the banner
      PreExecutionUserActionUIBehavior preExecBehavior = userActionUIService.newPreExecutionUserActionUIBehaviorBuilder()
          .withDialog(dialog)
          .build();

      // Set the pre-execution user action UI behavior on the context
      context.setUserActionUIBehavior(preExecBehavior);
  }

  public void onPostExecute(PostExecutionDocumentActionUIContext context) {
      // Get the UserActionUIService
      UserActionUIService userActionUIService = ServiceLocator.locate(UserActionUIService.class);

      // Build a UserActionExecutionBanner with a message
      String bannerMessage = "This is a sample banner message";
      UserActionExecutionBanner banner = userActionUIService.newUserActionExecutionBannerBuilder()
          .withMessage(bannerMessage)
          .build();

      // Build a PostExecutionUserActionUIBehavior with the banner
      PostExecutionUserActionUIBehavior postExecBehavior = userActionUIService.newPostExecutionUserActionUIBehaviorBuilder()
          .withBanner(banner)
          .build();

      // Set the post-execution user action UI behavior on the context
      context.setUserActionUIBehavior(postExecBehavior);
  }
 }
 
 
A class that implements the DocumentAction interface must implement the following methods:
  • isExecutable: Determine if this action is visible in the UI or invokable from the REST API. Return true to make the action invokable.
  • execute: The logic to execute when the action is invoked. You can change field values on the current document, as illustrated in this example, or you can use any of the Vault Java SDK services (such as DocumentService or QueryService) to change other documents.
Optionally, a class that implements the DocumentAction interface may also implement the following methods:
  • onPreExecute: The logic to execute before the action is invoked. This is used for setting pre-execution UI behavior for document actions in the USER_ACTION use case. As illustrated in the example above, a pre-execution dialog can be configured here, with a custom title and message.
  • onPostExecute: The logic to execute after the action is invoked. This is used for setting post-execution UI behavior for document actions in the USER_ACTION use case. As illustrated in the example above, a post-execution banner can be configured here, with a custom message.
The @DocumentActionInfo annotation has the following elements:
  • label: Label of the action
  • lifecycle: If specified, the action is available for the specified lifecycle only. If omitted, the action is available across all document lifecycles.
  • usage: If specified, the action is available for configuring in the specified usages only. For example, USER_ACTION. If omitted, the action is available across all supported usages.
  • user_input_object_type: If your action takes user input, identify the user input object type.
  • user_input_object: If your action takes user input, identify the user input object.