Showing results for 
Search instead for 
Did you mean: 
Showing results for 
Search instead for 
Did you mean: 
Showing results for 
Search instead for 
Did you mean: 

Multi Complete Task


Multi Complete Task

Hi everybody. I need a help, please.

I need an API to complete many tasks at one time.

These tasks are on Home Assignments Interface. I need to complete a lot clicking once.

Has anyone did this before? Or know how to do?



Hi Danilo,

There is nothing OOTB in the UI.

As a hint it is possible to write a function to take one workflow and apply the same routing and result to a set of the same type of activities. This basically allows a group 'apply' based on the result of one activity (work item).


The challenge for you is to call this jsp function from a menu in the UI. I have attached a grok link to a JSP page we call (see the params) with a workitem and it then applies the action for that workitem against a list of others (passed in by their oid). This JSP is very separate to Windchill PDMLink but serves as an interesting example.



Hi Stephen.

Many thanks for your answer.

I tried to open the .jsp page you send but it is not possible to open. Could you please send me the file?


<%@page import="com.ptc.arbortext.windchill.asps.structure.client.ASPSMessages"%>

<%@page import="java.util.Enumeration"%>

<%@page import="java.util.HashSet"%>

<%@page import="java.util.Vector"%>

<%@page import="wt.fc.ObjectIdentifier"%>

<%@page import="wt.fc.ObjectReference"%>

<%@page import="wt.fc.PersistenceHelper"%>

<%@page import=""%>

<%@page import=""%>

<%@page import="wt.pom.Transaction"%>

<%@page import="wt.project.Role"%>

<%@page import="wt.session.SessionHelper"%>

<%@page import=""%>

<%@page import=""%>

<%@page import="wt.util.WTException"%>

<%@page import="wt.workflow.definer.WfAssignedActivityTemplate"%>

<%@page import="wt.workflow.definer.WfDefinerHelper"%>

<%@page import="wt.workflow.engine.ProcessData"%>

<%@page import="wt.workflow.engine.WfEngineHelper"%>

<%@page import="wt.workflow.engine.WfProcess"%>

<%@page import="wt.workflow.engine.WfRouterType"%>

<%@page import="wt.workflow.engine.WfTransition"%>

<%@page import="wt.workflow.engine.WfVariable"%>

<%@page import=""%>

<%@page import=""%>

<%@page import=""%>


String sourceOid = request.getParameter("source");

String oids = request.getParameter("oids");

ObjectIdentifier sourceIdentifier = ObjectIdentifier.newObjectIdentifier(sourceOid);

ObjectReference sourceReference = ObjectReference.newObjectReference(sourceIdentifier);

WorkItem source = (WorkItem) sourceReference.getObject();

HashSet<WorkItem> workItems = new HashSet<WorkItem>();

for(String oid : oids.split(";")) {

ObjectIdentifier objectIdentifier = ObjectIdentifier.newObjectIdentifier(oid);

ObjectReference objectReference = ObjectReference.newObjectReference(objectIdentifier);

WorkItem workItem = (WorkItem) objectReference.getObject();



// For the next 30 seconds, check whether the task is completed every second. If it is

// completed, carry on with the method before the end of the 30 seconds. If it gets to

// 30 seconds without being completed, throw an exception. The reason this is needed is that

// just because a WorkItem is incomplete when the method is run, doesn't mean the user

// hasn't completed it. If it is still in the process of completing, it will show up as

// incomplete. So we need to wait a few seconds to be sure whether it is actually complete

// or not.

long start = System.currentTimeMillis();

while (!source.isComplete() || System.currentTimeMillis() < start + 30) {

try {


} catch (InterruptedException e) {

throw new WTException(e);


source = (WorkItem) PersistenceHelper.manager.refresh(source);


// If the source object is not completed, throw an exception

if(!source.isComplete()) {

Object[] params = {};

throw new WTException(ASPSMessages.class.getName(), ASPSMessages.INITIAL_WORKITEM_INCOMPLETE, params);


// Check that there are items in the list

if (workItems == null || workItems.isEmpty()) {



// Check that the Set of WorkItems are not completed

for(WorkItem workItem : workItems) {

if(workItem.isComplete()) {

Object[] params = {};

throw new WTException(ASPSMessages.class.getName(), ASPSMessages.SELECTED_WORKITEM_COMPLETE, params);



// Complete all the WorkItems, taking the result from the source WorkItem

Transaction transaction = new Transaction();

try {


WfAssignedActivity sourceActivity = (WfAssignedActivity) source.getSource().getObject();

WfProcess sourceProcess = sourceActivity.getParentProcess();

ObjectReference sourceAssignmentReference = source.getParentWA();

WfAssignment sourceAssignment = (WfAssignment) sourceAssignmentReference.getObject();

Vector sourceEvents = sourceAssignment.getAllEvents();

ProcessData sourceContext = source.getContext();

for(WorkItem workItem : workItems) {

WfAssignedActivity activity = (WfAssignedActivity) workItem.getSource().getObject();

WfProcess process = activity.getParentProcess();

Team team = (Team) process.getTeamId().getObject();

ProcessData context = new ProcessData();


// Set variables

WfVariable[] variables = sourceContext.getVariableList();

for(WfVariable variable : variables) {

if(variable.getName().equals("self")) {


} else if(variable.getName().equals("primaryBusinessObject")) {







// Set roles


Vector<Role> roles = sourceProcess.getProcessRoles();

for(Role role : roles) {

Enumeration roleEnum = sourceProcess.getPrincipals(role);

while(roleEnum.hasMoreElements()) {

WTPrincipalReference principalReference = (WTPrincipalReference) roleEnum.nextElement();

team.addPrincipal(role, principalReference.getPrincipal());



WTPrincipal user = SessionHelper.getPrincipal();





activity = (WfAssignedActivity) PersistenceHelper.manager.modify(activity);

// Set the relevant routing options on the activity

WfAssignedActivityTemplate aat = (WfAssignedActivityTemplate) activity.getTemplate().getObject();

WfRouterType rt = aat.getRouterType();

if (WfDefinerHelper.service.getRouterExpression(aat) == null && rt.equals(WfRouterType.MANUAL) || rt.equals(WfRouterType.MANUAL_EXCLUSIVE)) {

WfEngineHelper.service.complete(activity, sourceEvents);

} else {

WfEngineHelper.service.changeState(activity, WfTransition.COMPLETE);



// Check that they are all complete

for(WorkItem workItem : workItems) {

if(!workItem.isComplete()) {

Object[] params = {};

throw new WTException(ASPSMessages.class.getName(), ASPSMessages.SELECTED_WORKITEM_INCOMPLETE, params);




transaction = null;

} finally {

if(transaction != null) {






<body onload="window.close()"/>


Hi Stephen.

It worked fine, thank you.

But when the activity is completed using this jsp, the Process Status Table doesn't record that the activity was completed. Is that possible add some parameter in JSP to indicate in Process Status Table that the Activity was completed?

Best Regards