This article was created in response to a support issue logged with K2. The content may include typographical errors and may be revised at any time without notice This article is not considered official documentation for K2 software and is provided “as is” with no warranties.

Issue

The Plan Just Once destination rule - release is not firing via UI when the destination is a Group or Role.

Symptoms

For a process in which the destination rule for a client event is configured with the Plan Just Once options and Groups and Roles are not resolved to users, there is a known bug within K2 Management when using tasklists or navigating to an individual worklist tasks menu where an open instance can be seen and selected.  

The release option is available and appears to complete succesfully, but the task is not released back to the available state.  Within K2 Workspace (legacy), the release option is not available via the UI to begin with.

Resolution

This item will be addressed in a future release, but for now the following is available as workarounds:

1.  Use a GoTo Activity to send the instance back to the same activity, doing so will reassign the task back to the group/role, making it available to all members again.  

Image

2.  Use the API to release the task.  The following is an example of a console application snippet of utilizing the management and worklist APIs to view all open tasks by serial number and folio. It allows you to impersonate a user to release the task via the serial number:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SourceCode.Workflow.Client;
using SourceCode.Hosting.Client.BaseAPI;
using SourceCode.Workflow.Management;

namespace theWorklists
{
class Program
{
static void Main(string[] args)
{
begin:
Console.WriteLine("1.) View Open Items 2.) Release an Open Item (0 to exit): ");
string answer = Console.ReadLine();
int answerINT = Int32.Parse(answer);
if (answerINT == 1)
{
SourceCode.Hosting.Client.BaseAPI.SCConnectionStringBuilder theConnectionString = new SCConnectionStringBuilder();
theConnectionString.Authenticate = true;
theConnectionString.Host = "localhost";
theConnectionString.Integrated = true;
theConnectionString.IsPrimaryLogin = true;
theConnectionString.Port = 5555;
WorkflowManagementServer theServer = new WorkflowManagementServer();
try
{
theServer.CreateConnection();
theServer.Connection.Open(theConnectionString.ToString());
WorklistItems worklistItems = null;

worklistItems = theServer.GetWorklistItems("", "", "", "", "", "", "");
SourceCode.Workflow.Management.Criteria.WorklistCriteriaFilter theFilter = new SourceCode.Workflow.Management.Criteria.WorklistCriteriaFilter();
theFilter.AddRegularFilter(SourceCode.Workflow.Management.WorklistFields.Status, SourceCode.Workflow.Management.Criteria.Comparison.Equals, 1);
worklistItems = theServer.GetWorklistItems(theFilter);
foreach (SourceCode.Workflow.Management.WorklistItem workListItem in worklistItems)
{
Console.WriteLine("Folio: " + workListItem.Folio + " | Status : " + workListItem.Status + " | Serial No: " + workListItem.ProcInstID + "_" + workListItem.ActInstDestID);
}
}
finally
{
theServer.Connection.Close();
}
Console.WriteLine("");
goto begin;
}
else if (answerINT == 2)
{
SourceCode.Workflow.Client.Connection theConnection = new SourceCode.Workflow.Client.Connection();
theConnection.Open("localhost");
Console.WriteLine("Domain: ");
string domain = Console.ReadLine();
Console.WriteLine("User: ");
string user = Console.ReadLine();
theConnection.ImpersonateUser(domain + "\\" + user);
Worklist theWorklist = theConnection.OpenWorklist();
foreach (SourceCode.Workflow.Client.WorklistItem wLitem in theWorklist)
{
Console.WriteLine(wLitem.SerialNumber + " | " + wLitem.Status);
}
Console.WriteLine("Serial Number of item to open (0 to exit): ");
string serialNo = Console.ReadLine();
if (serialNo == "0")
{
System.Environment.Exit(1);
}
else
{
SourceCode.Workflow.Client.WorklistItem theItem = theConnection.OpenWorklistItem(serialNo);
Console.WriteLine(theItem.Status.ToString());
theItem.Release();
Console.WriteLine("");
goto begin;
}
}
else if (answerINT == 0)
{
System.Environment.Exit(1);
}
else
{
Console.WriteLine("SOMETHING WENT SIDEWAYS :(");
}
}
}
}

To get the specific user that has the task open (this is the user that will need to be impersonated to release) you can run the following script against the K2 Database. 

The query can be run by taking the Process Instance ID from the serial number of the task you need to look up. The process instance ID is the first half of the serial number.  

Example Serial Number: "4058_9." The Process Instance Id is '4058'

/* Folling will return the username of user(s) who have specific Proccess Instance Opened */

SELECT WLS.ProcInstID, WLS.ActInstID, A.ActionerName
FROM Server.WorklistSlot WLS
JOIN Server.Actioner A
ON A.ID = WLS.ActionerID
WHERE WLS.ProcInstID = /*ProcInstID From Serial #*/;