Skip to main content

Hello,


I am having a problem with serial numbers and worklist items.


I am saving the K2.SerialNumber in a process instance data field before a client activity which produces a worklist item (using a Default Client Event which has one action of 'processed'), I then clear the data field after the action has been performed.


I am trying to automate actioning these tasks in code outside of the workflow and when I try to open the worklist items for the saved serial number I get an error saying that the worklist item could not be found.


I am assigning the client event to a role and am (in code) impersonating the first user found in the role before opening the worklist item.


Does anyone know why the serial number isn't being stored correctly when it is being stored directly before the client event?  There are a number of tasks, and each have their own data field - the action for any of them is 'processed'.


The code I'm using is below - and the 'pid' field is the saved serial number.


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 




Private



 



 


Sub processTask(ByVal pid As String

)

 



 


Using servCon As Connection = New

Connection()

servCon.Open(SMServerConnString +



 


":5252"

)

 



 


If Not String.IsNullOrEmpty(pid)

Then



 



 


Dim master As SourceCode.Workflow.Client.WorklistItem = servCon.OpenWorklistItem(pid, "ASP", False

)

 



 


'RElease the item if it isn't available



 



 


If master.Status.ToString.ToLower() <> "available" Or master.Status.ToString.ToLower() = String.Empty

Then



master.Release()



 



 


End

If



 



 


'get the name of the user who this is assigned to



 



 


Dim targettedUser As String

= master.DelegatedUsers(0).Name

 



 


'check if the item is assigned to a role rather than a user



 



 


Dim umCB As SCConnectionStringBuilder = New

SCConnectionStringBuilder()

umCB.Host = SMServerConnString


umCB.Port = 5555



umCB.Integrated =



 


True



umCB.IsPrimaryLogin =



 


True



 



 


Dim um As UserRoleManager = New

UserRoleManager()

um.CreateConnection()


um.Connection.Open(umCB.ToString)



 



 


Dim targetIsRole As Boolean =

False



 



 


Try



 



 


If Not um.GetRole(targettedUser) Is Nothing

Then



targetIsRole =



 


True



 



 


End

If



 



 


Catch



targetIsRole =



 


False



 



 


End

Try



 



 


If targetIsRole

Then



 



 


'impersonate the first user in the role!



 



 


Dim role As

SourceCode.Security.UserRoleManager.Management.Role = um.GetRole(targettedUser)

 



 


If role.Include.Count > 0

Then



 



 


Dim roleUser As

RoleItem = um.GetRole(targettedUser).Include(0)

servCon.ImpersonateUser(roleUser.Name.ToString)



 



 


End

If



 



 


Else



 



 


'impersonate the assigned user



servCon.ImpersonateUser(targettedUser)



 



 


End

If



master =



 


Nothing



 



 


Dim oWLi As

SourceCode.Workflow.Client.WorklistItem = servCon.OpenWorklistItem(pid)

 



 


'set the task to processed to close it



oWLi.Actions(



 


"Processed"

).Execute()

 



 


'change the user back to the real one



servCon.RevertUser()



 



 


End

If



 



 


End

Using



 



 


End

Sub


Thanks,


Helen



Hi Helen,


A serial number is built up of the the following: ProcessInstanceID_ActivityDestinationInstanceID. This is unique for each event and each destination user. If you save the serial number in an event which is not your client event, the serial number will be different. This is probably why you are getting the error. Save the serial number in the code-behind of the client event.


With these types of scenarios we recommend the use of Asynchronous Server events instead of Client Events.


Any server event (Data Event, SmartObject Event, Email Event, etc) can be edited to stop the execution of the process and wait for an external system to finish it. This is done in the code-behind of the event by setting the K2.Synchronous flag to false.


In this event you can save the serial number to your system by either building it up from the ProcessInstanceID and ActivityDestinationInstanceID (from the workflow context browser) or by passing the K2.SerialNumber property to your external system in the code-behind.


The external system then connects back to K2 using the SourceCode.Workflow.Client API and calls the Connection.OpenServerItem() method, passing in the serial number. When the item is open you can update the data fields of the process or activity. Then the ServerItem can be finished by calling the ServerItem.Finish() method to let the process continue. Since only certain systems will connect to K2 for this function, the user you are connecting with from the external system should have the "Server Event" process right on the process for it to work.


What works really well is if you are using SmartObjects to store the Serial number and call a SmartObject method from a SmartObject Event, saving the Serial Number by building it up from the workflow context, and then changing the code-behind of this method to be Synchronous = false. Then the process stops at this point and allows another system to complete it by setting some values and this other system can read the serial number from your SmartObject using the SmartObject API.


I hope this helped!


Regards,


Hi Johan,


Thank you so much for your reply but I'm afraid I'm a bit confused!


There doesn't appear to be a code behind object in the Client event, but my code to save the serial number is in the same activity as the client event - the only options I get when I look at the View Code on the Client Event is 'Destination Rule' and 'Succeeding Rule'.  The server code event which saves the serial number to a data process field is directly before the client event, and this is then cleared directly after when the action is performed - all inside the same activity. 


We use the asynchronous stuff in other parts of the Workflow (pretty much the same as you've suggested), but this wouldn't really be appropriate for what we're doing with these worklist items as they could be closed by the user or the code and it doesn't really matter which!  We are using the asynchronous thing when we are waiting for something to be done which we don't want to generate a worklist item for it, and it is very useful!!   We need to worklist items to be produced as a reminder that they need to do something (the something is in a separate system not connected to K2 so they could action the worklist item manually, or our code runs every 30 mins, goes and checks what's been done, then closes the worklist items if they are still active).


I've managed to find a really cumbersome way of doing what I need to.... 



  1. using the Workflow.Management Worklist to find the tasks (using a WorklistCriteriaFilter) I need to close,
  2. then impersonating the first user in the role the task is assigned to (it could be one of a number of roles we have set up),
  3. then looping though their workflow list using Workflow.Client to find their version of the task by matching the same processInstance ID as the management worklist task
  4. then opening that work list item and executing the action using the serial number of that user's task!

The events are set up so that only 1 person in the role needs to action this, rather than everyone in the role, so this works!  The serial number appears to be different for each user in the role which must be why the saved one hasn't worked!


Thank you again for all your help.


Helen


 


Hi Helen,


I believe if you right click on the name of your client event there will be a "View Code" > "Event Item" popup window which you can use to view the code of your Client Event.


In here you will be able to access the Serial Number and then save it to another system.


Let me know if this helped!


Regards,


Reply