Background: We are currently running K2 BlackPearl 4.7 with March 2018 Update.
Problem: The tasks fails to open for traget users when using Out of Office Tasks.
Error Message: Worklist item could not be opened. 24411 K2:DomainDomainUser from 172.xx.x.xxx:xxxx is not allowed to open the worklist item with SN=29531_44
Issue: Currently when a user sets their status as out of office and fowards all assigned tasks to a delgated users, the user is able to use the Out of The Box Worklist to access and action tasks, although when using the customer worklist the user recieves an error listed above. After some reading online was I was able to conclude that this has to do with how our Custom Worklist was written and how it opens the task items is incorrect as follows:
What our current service uses - WorklistItem = this.Connection.OpenWorklistItem
What we need our modified service to use to open shared items - WorklistItem = this.Connection.OpenSharedWorklistItem
I need some possible help and guidence as to how I can incorrporate the open shared worklist item call into our current custome WorkList Service using the correct API calls and still being able to handle regular tasks that are not shared or deligated, below is how it is current written. I am not proficent .NET and would appreicate any help I can get in this matter.
using System;using System.Linq;using SourceCode.Workflow.Client;namespace WL{ public static class ClientTask { public static RequestApprovalTask OpenApprovalTask(string serialNumber, bool readOnly) { if(string.IsNullOrWhiteSpace(serialNumber)) throw new ArgumentException("Parameter 'serialNumber' can not be null, empty or whitespace."); var splitIndex = serialNumber.IndexOf('_'); if(splitIndex <= 0) throw new ArgumentException("Parameter 'serialNumber' does not represent a valid client event serial number. Format should be <Process Instance ID>_<Activity Destination Instance ID>."); using(var connection = ConnectionHelper.CreateWorkflowConnection()) { var processInstanceID = int.Parse(serialNumber.Substring(0, splitIndex)); var criteria = new WorklistCriteria(); criteria.AddFilterField(WCField.ProcessID, WCCompare.Equal, processInstanceID); // Approval client events are configured as plan all at once, 1 slot; so we need to open the worklist first. // Trying to open the worklist item by serial number directly, without first opening the worklist will fail. var worklist = connection.OpenWorklist(criteria); // Try to find the worklist item by serial number. This will only return a result if the item is open or available. var clientTask = worklist .Cast<WorklistItem>() .Where(i => string.Equals(i.SerialNumber, serialNumber, StringComparison.InvariantCultureIgnoreCase)) .FirstOrDefault(); try { if(clientTask != null) { // Found our worklist item by serial number clientTask.Open(readOnly ? false : true); } else { // If we don't have a worklist item here, it's probably allocated to someone else // so try to find the allocated item. clientTask = worklist .Cast<WorklistItem>() .Where(i => i.Status == WorklistStatus.Allocated) .FirstOrDefault(); if(clientTask == null) throw new ApplicationException("The requested task could not be located. Serial Number: " + serialNumber); } return new RequestApprovalTask { RequestID = Guid.Parse((clientTask.ProcessInstance.DataFieldse"RequestID"].Value ?? string.Empty).ToString()), AllocatedUser = clientTask.AllocatedUser }; } finally { connection.Close(); } } } public static void ReleaseApprovalTask(string serialNumber) { using(var connection = ConnectionHelper.CreateWorkflowConnection()) { var criteria = new WorklistCriteria(); criteria.AddFilterField(WCField.SerialNumber, WCCompare.Equal, serialNumber); var worklist = connection.OpenWorklist(criteria); if(worklist == null || worklist.Count == 0) return; var clientTask = worklistk0]; clientTask.Release(); connection.Close(); } } } public class RequestApprovalTask { public Guid RequestID { get; set; } public string AllocatedUser { get; set; } }}