I want to Reject all approvals of workitem that has been pending for certain days eg 30 days.. here is my code ..but its not working

import sailpoint.object.WorkflowCase;
import sailpoint.object.TaskResult;
import sailpoint.object.WorkItem;
import sailpoint.api.Workflower;
import sailpoint.object.Filter;
import sailpoint.object.QueryOptions;
import sailpoint.object.Identity;
import sailpoint.tools.Message;
import java.util.List;
import java.util.ArrayList;
import java.util.Date;
import java.util.Calendar;
import java.text.SimpleDateFormat;
import org.apache.log4j.Logger;

Logger logger = Logger.getLogger("AIZWorkflow.TerminateQuicklinkWorkItems");
logger.debug("ENTRY : Inside TerminateQuicklinkWorkItems");

List workItemsList = new ArrayList();
List failedWorkItemsList = new ArrayList();

int workItemsCount = 0;
int numDays = 30;
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DAY_OF_MONTH, -numDays);
date = cal.getTime();

QueryOptions qo = new QueryOptions();
qo.addFilter(Filter.eq("type", "Approval"));
qo.addFilter(Filter.le("created", date));

workItemsCount = context.countObjects(WorkItem.class, qo);
Iterator workItems = context.search(WorkItem.class, qo);

logger.debug("WorkItems size::" + workItems);
int i = 0;

try {
    if (workItems != null) {
        while (workItems.hasNext()) {
            i++;
            logger.debug("======================Record Number::" + i);

            WorkItem pendingWorkItem = (WorkItem) workItems.next();
            String wiName = pendingWorkItem.getName();
            logger.debug("WorkItem Id:::" + wiName);
            logger.debug("WorkItem Type:::" + pendingWorkItem.getType());
            String wiDescription = pendingWorkItem.getDescription();
            logger.debug("WorkItem description:::" + wiDescription);

            try {
                pendingWorkItem.setState(WorkItem.State.Rejected);
                context.saveObject(pendingWorkItem);
                workItemsList.add("WorkItem Rejected:" + wiName + "\r\n");
            } catch (Exception ex) {
                logger.error("Failed to reject WorkItem: " + wiName, ex);
                taskResult.setCompletionStatus(TaskResult.CompletionStatus.Warning);
                taskResult.addMessage(new Message(Message.Type.Warn, "The task completed successfully but there were one or more errors", (Object[]) null));
                failedWorkItemsList.add("WorkItem Failed:" + wiName + "\r\n --------------------------------------------------------- \r\n ");
            }
        }
    }
    
    // Commit the transaction after processing all work items
    context.commitTransaction();

} catch (Exception e) {
    logger.error("Exception occurred during processing", e);
    context.rollbackTransaction();
    throw e; // Re-throw exception for higher-level handling
}

Did you get chance to try out the sample snippet shared in the another thread ?

yes but it is still showing up in workitem UI. after adding

Workflower flower = new Workflower((SailPointContext)context);
	    flower.process(workitemObj, true);

the task result status is changed to warning

try this code for just one id

		WorkItem workitemObj = context.getObjectById(WorkItem.class, "abcdcndnd");
	    workitemObj.setState(WorkItem.State.Finished);
	    workitemObj.setCompleter("completer");

	      ApprovalSet aset = workitemObj.getApprovalSet();
	      if (aset != null) {
	        List<ApprovalItem> items = aset.getItems();
	        if (items != null)
	          for (ApprovalItem appitem : items) {
	            if (appitem.getState() == null) {
	              //appitem.setState(WorkItem.State.Finished);
	              appitem.setState(WorkItem.State.Rejected);
	              appitem.setApprover("spadmin");
	              //appitem.setComments(comments);
	            } 
	          }  
	      } 
	     
	    Workflower flower = new Workflower((SailPointContext)context);
	    flower.process(workitemObj, true);
1 Like

i did exactly what u said… still i can see it in my UI… chek my final code if any mistakes

import sailpoint.object.*;
import org.apache.log4j.Logger;
import java.util.*;
import sailpoint.api.*;
import sailpoint.workflow.WorkItemLibrary;

public class ProcessExpiredWorkItems {

    private static final Logger logger = Logger.getLogger("AIZWorkflow.ProcessExpiredWorkItems");

    public String processExpiredWorkItems(SailPointContext context) throws Exception {
        List<String> workItemsList = new ArrayList<>();
        List<String> failedWorkItemsList = new ArrayList<>();

        int workItemsCount = 0;
        int numDays = 30;

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        Date date = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DAY_OF_MONTH, -numDays);
        date = cal.getTime();

        QueryOptions qo = new QueryOptions();
        qo.setCloneResults(true);
        qo.addFilter(Filter.eq("type", "Approval"));
        qo.addFilter(Filter.le("created", date));

        workItemsCount = context.countObjects(WorkItem.class, qo);

        Iterator<WorkItem> workItems = context.search(WorkItem.class, qo);
        int i = 0;

        if (workItems != null) {
            while (workItems.hasNext()) {
                i++;
                logger.debug("======================Record Number::" + i);

                WorkItem pendingWorkItem = workItems.next();
                logger.debug("WorkItem Id:::" + pendingWorkItem.getName());

                String workItemId = pendingWorkItem.getName();

                workItemsList.add("WorkItem Expired:" + workItemId + "\r\n --------------------------------------------------------- \r\n ");

                logger.debug("Pending WorkItem match Found::" + pendingWorkItem.getName());
                try {
                    // Set the state and completer for the WorkItem
                    pendingWorkItem.setState(WorkItem.State.Finished);
                    pendingWorkItem.setCompleter("spadmin");

                    // Retrieve and update ApprovalItems if present
                    ApprovalSet approvalSet = pendingWorkItem.getApprovalSet();
                    if (approvalSet != null) {
                        List<ApprovalItem> approvalItems = approvalSet.getItems();
                        if (approvalItems != null) {
                            for (ApprovalItem approvalItem : approvalItems) {
                                if (approvalItem.getState() == null) {
                                    approvalItem.setState(WorkItem.State.Rejected);
                                    approvalItem.setApprover("spadmin");
                                    // Optionally set comments if needed
                                    // approvalItem.setComments("Your comment here");
                                }
                            }
                        }
                    }

                    // Process the WorkItem with the updated state
                    Workflower workflower = new Workflower(context);
                    workflower.process(pendingWorkItem, true);

                    workItemsList.add("WorkItem Processed:" + workItemId + "\r\n --------------------------------------------------------- \r\n ");
                } catch (Exception ex) {
                    logger.error("Close Work item failed for: " + workItemId);
                    logger.error("Close Work item failed: " + ex.getMessage(), ex);
                    failedWorkItemsList.add("WorkItem Failed:" + workItemId + "\r\n --------------------------------------------------------- \r\n ");
                }
            }
        }

        TaskResult taskResult = context.getObjectByName(TaskResult.class, "AIZ-TerminateApprovalWorkItems");

        if (taskResult != null) {
            taskResult.setAttribute("workItemsCount", String.valueOf(workItemsCount));
            logger.debug("Close WorkItems task result count: " + workItemsCount);

            if (workItemsList != null && !workItemsList.isEmpty()) {
                taskResult.setAttribute("workItemsFound", "Work Item" + " \r\n" + workItemsList.toString().replace(",", "").replace("[", "").replace("]", "") + " \r\n");
                logger.debug("Close WorkItems workItemsList");
            } else {
                taskResult.setAttribute("workItemsFound", "No Matching WorkItems Found");
            }

            if (failedWorkItemsList != null && !failedWorkItemsList.isEmpty()) {
                taskResult.setAttribute("failedWorkItemsFound", "Work Item" + " \r\n" + failedWorkItemsList.toString().replace(",", "").replace("[", "").replace("]", "") + " \r\n");
            } else {
                taskResult.setAttribute("failedWorkItemsFound", "No Matching WorkItems Found");
            }
        }

        return "Success";
    }
}

@autorun6464
If you want to simply reject the request, you can use the below code.

 WorkItem workitemObj = context.getObjectByName(WorkItem.class, "<Workitem Name>");
  //workitemObj.toXml();
  Workflower flower = new Workflower(context);
  flower.reject(workitemObj);

replace the with the actual name.

Hope this helps.

3 Likes