Skip navigation links

Package com.veeva.vault.sdk.api.workflow

This package provides interfaces to create custom actions for workflows and update entities within workflow processing.

See: Description

Package com.veeva.vault.sdk.api.workflow Description

This package provides interfaces to create custom actions for workflows and update entities within workflow processing.

Record Workflow Actions

Workflows can have custom actions that perform specific instructions. You can use a custom record workflow action to automate certain business processes on an object or document workflow. Document workflows are a type of object workflow configured on the envelope__sys object. If you are unfamiliar with object or document workflows, you should learn more in Vault Help before coding a record workflow action:

You can configure a custom action for workflows on any of the following steps:

A record workflow action is a Java class that implements the RecordWorkflowAction interface and has the @RecordWorkflowActionInfo annotation. The RecordWorkflowActionInfo annotation has the following elements:

Example: Record Workflow Action on a Start Step

The following example illustrates a custom action available for configuration on the Start step of an object workflow configured for the Product object. Once configured on an object workflow's start step participant control, the action will be invoked on all start step events during workflow execution.

This example executes custom logic on the following events:

  @RecordWorkflowActionInfo(label="Custom Approver", object="product__v", stepTypes={WorkflowStepType.START})
  public class CustomApprover implements RecordWorkflowAction {
          public void execute(RecordWorkflowActionContext context) {
             WorkflowEvent event = context.getEvent();
             WorkflowInstance workflowInstance = context.getWorkflowInstance();

             WorkflowInstanceService workflowInstanceService = ServiceLocator.locate(WorkflowInstanceService.class);
             WorkflowParticipantGroup participantGroup = context.getParticipantGroup();

             //DISPLAY_PARTICIPANTS only shows the users/groups provided by the RecordWorkflowAction. It's not officially saved until GET_PARTICIPANTS.
             //Generally, you would display and save the same users/groups.
             if (event == WorkflowEvent.DISPLAY_PARTICIPANTS || event == WorkflowEvent.GET_PARTICIPANTS) {
                 getParticipants(workflowInstanceService, participantGroup);
             } else if (event == WorkflowEvent.AFTER_CREATE) {
                 afterCreate(workflowInstance, participantGroup);
             }
         }
         private void getParticipants(WorkflowInstanceService workflowInstanceService,
                                      WorkflowParticipantGroup participantGroup) {
             Set<String> users = VaultCollections.newSet();
             users.add("1000000");
             users.add("1000001");
             WorkflowParticipantGroupUpdate participantGroupUpdate =
                     workflowInstanceService.newParticipantGroupUpdate(participantGroup)
                             .setUsers(users);
             workflowInstanceService.updateParticipantGroup(participantGroupUpdate);
         }
         private void afterCreate(WorkflowInstance workflowInstance,
                                  WorkflowParticipantGroup participantGroup) {
             NotificationService notificationService = ServiceLocator.locate(NotificationService.class);

             String processInstanceId = workflowInstance.getId();
             Set<String> participantUserIds = participantGroup.getUsers();
             String participantGroupLabel = participantGroup.getLabel();

             NotificationParameters parameters =
                     notificationService.newNotificationParameters()
                             .setRecipientsByUserIds(participantUserIds);
             String notificationText = "You were added to the participant group \"" + participantGroupLabel
                     + "\" of workflow " + processInstanceId;
             NotificationMessage message =
                     notificationService.newNotificationMessage()
                             .setSubject("A new workflow started")
                             .setMessage(notificationText)
                             .setNotificationText(notificationText);
             notificationService.send(parameters, message);
         }
    }
 
 

Example: Record Workflow Action on a Task Step

The following example illustrates an action that is available for configuration on the Task step of an object workflow configured for the Product object. Once configured on an object workflow's task step, the action will be invoked on all task events for that workflow task step during workflow execution. The code in this example handles task creation, completion dialog, completion, cancellation, and reassignment/acceptance.
  @RecordWorkflowActionInfo(label="Approver Task Action", object="product__v", stepTypes={WorkflowStepType.TASK})
  public class ApproverTaskAction implements RecordWorkflowAction {
         public void execute(RecordWorkflowActionContext context) {
             WorkflowEvent taskEvent = context.getEvent();
             if (taskEvent == WorkflowEvent.TASK_AFTER_CREATE) {
                 handleCreate(context);
             } else if (taskEvent == WorkflowEvent.TASK_BEFORE_COMPLETE_DIALOG) {
                 handleCompleteDialog(context);
             } else if (taskEvent == WorkflowEvent.TASK_AFTER_COMPLETE) {
                 handleComplete(context);
             } else if (taskEvent == WorkflowEvent.TASK_AFTER_CANCEL) {
                 handleCancel(context);
             } else if (taskEvent == WorkflowEvent.TASK_AFTER_ASSIGN) {
                 handleAssign(context);
             }
         }
         private void handleCreate(RecordWorkflowActionContext context) {
             LogService logger = ServiceLocator.locate(LogService.class);
             RecordWorkflowActionTaskContext taskContext = context.getTaskContext();
             WorkflowTaskConfiguration taskConfiguration = taskContext.getTaskConfiguration();
             String participantGroupLabel = taskConfiguration.getParticipantGroupLabel();

             List<WorkflowTaskChange> createdTaskChanges = taskContext.getTaskChanges();
             logger.info(createdTaskChanges.size() + " tasks have been created for " +
                     "participant group " + participantGroupLabel);

             for (WorkflowTaskChange taskChange : createdTaskChanges) {
                 WorkflowTaskInstance createdTaskInstance = taskChange.getNew();
                 String taskId = createdTaskInstance.getId();
                 String assigneeId = createdTaskInstance.getAssigneeId();
                 logger.info("Task " + taskId + " has been created for user " + assigneeId);
             }
         }
         private void handleCompleteDialog(RecordWorkflowActionContext context) {
             LogService logger = ServiceLocator.locate(LogService.class);
             logger.info("[Task before complete dialog] The current workflow has the following items: ");
             List<WorkflowItem> workflowItems = context.getWorkflowItems();
             for(WorkflowItem item : workflowItems) {
                 if(item.getWorkflowItemType() == WorkflowItemType.RECORD) {
                     WorkflowItemRecord record = item.getTypedWorkflowItem(WorkflowItemRecord.class);
                     logger.info("Record: {}.{}", record.getObjectName(), record.getRecordId());
                 } else if(item.getWorkflowItemType() == WorkflowItemType.DOCUMENT) {
                     WorkflowItemDocument document = item.getTypedWorkflowItem(WorkflowItemDocument.class);
                     logger.info("Document Version: {}_{}_{}", document.getId(), document.getMajorVersion(), document.getMinorVersion());
                 }
             }
         }
         private void handleComplete(RecordWorkflowActionContext context) {
             WorkflowTaskService workflowTaskService = ServiceLocator.locate(WorkflowTaskService.class);
             WorkflowInstance workflowInstance = context.getWorkflowInstance();
             RecordWorkflowActionTaskContext taskContext = context.getTaskContext();
             WorkflowTaskConfiguration taskConfiguration = taskContext.getTaskConfiguration();
             WorkflowTaskInstance completedTaskInstance = taskContext.getTaskChanges().get(0).getNew();

             // Find all outstanding task instances (assigned or available) for the current task step
             WorkflowTaskQueryParameters queryParameters = workflowTaskService.newWorkflowTaskQueryParameters()
                     .setStatuses(WorkflowTaskStatus.ASSIGNED, WorkflowTaskStatus.AVAILABLE)
                     .setTaskConfigurations(taskConfiguration);
             List<WorkflowTaskInstance> openTaskInstancesForTask =
                     workflowTaskService.getTaskInstances(workflowInstance, queryParameters);

             // Cancel all other outstanding task instances for the current task step
             List<WorkflowTaskInstance> tasksToCancel = VaultCollections.newList();
             for (WorkflowTaskInstance taskInstance : openTaskInstancesForTask) {
                 if (!taskInstance.getId().equals(completedTaskInstance.getId())) {
                     tasksToCancel.add(taskInstance);
                 }
             }
             if (!tasksToCancel.isEmpty()) { workflowTaskService.cancel(workflowInstance, tasksToCancel); }
         }
         private void handleCancel(RecordWorkflowActionContext context) {
             RecordWorkflowActionTaskContext taskContext = context.getTaskContext();
             String taskLabel = taskContext.getTaskConfiguration().getLabel();
             List<WorkflowTaskChange> cancelledTaskChanges = taskContext.getTaskChanges();
             String workflowLabel = context.getWorkflowConfiguration().getLabel();

             NotificationService notificationService = ServiceLocator.locate(NotificationService.class);

             Set<String> recipients = VaultCollections.newSet();
             for (WorkflowTaskChange taskChange : cancelledTaskChanges) {
                 WorkflowTaskInstance cancelledTaskInstance = taskChange.getNew();
                 String assigneeId = cancelledTaskInstance.getAssigneeId();
                 recipients.add(assigneeId);
             }

             NotificationParameters parameters =
                     notificationService.newNotificationParameters()
                             .setRecipientsByUserIds(recipients);
             String notificationText = "Task \"" + taskLabel + "\" was cancelled for workflow \"" + workflowLabel + "\".";
             NotificationMessage message =
                     notificationService.newNotificationMessage()
                             .setSubject(notificationText)
                             .setMessage(notificationText)
                             .setNotificationText(notificationText);
             notificationService.send(parameters, message);
         }
         private void handleAssign(RecordWorkflowActionContext context) {
             RecordWorkflowActionTaskContext taskContext = context.getTaskContext();
             WorkflowTaskChange taskChange = taskContext.getTaskChanges().get(0);
             WorkflowTaskInstance newTaskInstance = taskChange.getNew();
             WorkflowTaskInstance oldTaskInstance = taskChange.getOld();
             WorkflowTaskStatus newTaskStatus = newTaskInstance.getStatus();
             WorkflowTaskStatus oldTaskStatus = oldTaskInstance.getStatus();

             String taskId = newTaskInstance.getId();
             String newAssigneeId = newTaskInstance.getAssigneeId();
             String oldAssigneeId = oldTaskInstance.getAssigneeId();

             LogService logger = ServiceLocator.locate(LogService.class);
             if ((oldTaskStatus == WorkflowTaskStatus.ASSIGNED) && (newTaskStatus == WorkflowTaskStatus.ASSIGNED)) {
                 logger.info("Task " + taskId + " has been reassigned from user " + oldAssigneeId + " to " +
                         "user " + newAssigneeId);
             } else if ((oldTaskStatus == WorkflowTaskStatus.AVAILABLE) && (newTaskStatus == WorkflowTaskStatus.ASSIGNED)) {
                 logger.info("Task " + taskId + " has been accepted by user " + newAssigneeId);
             }
         }
    }
 
 
Skip navigation links

Copyright © Veeva Systems 2017–2023. All rights reserved.