When things are not quite as simple as they look – or: the struggles of getting a workflow-task to cooperate
This saga started when I asked the question How to get contracted developers to read, accept and adhere to development guidelines a couple of months ago. After quite some lively discussions and many helpful contributions I picked a response provided by Mike Pokraka as the best answer as this seemed to be a workable solution, neatly spelled out in the SAP-Press Workflow book’s chapter he wrote. There however was – and still is – one important caveat when it comes to Workflow: I know and understand very little about the topic and so did have some misgivings about tackling this right from the start. But, as I wanted to add one more poke for external developers to actually check out our development guidelines and as there was nobody else readily available to set this up, I decided to give it a try. If nothing else, I figured, I could at least learn a little bit about an SAP-area I rarely engage with.
Act 1 – Why the heck does it work in the sandbox but not the dev-system?
In order to not break anything while dabbling with workflow, I defined the various bits and pieces as outlined in Mike’s chapter in a sandbox system where I got them to work – or so I thought! – fairly quickly. Things than simmered for a couple of weeks until a colleague who knows more about workflows than me, had the time to quickly check things out before I “freed” them from the sandbox system.
This is when the “fun” really started!
I re-created the workflow-defnition and the object-code step-by-step in the dev-system figuring that if I did everything the way I had already done it once in the sandbox and if things then looked the same, they also should behave the same. Foolish me! While the work-item always got created okay in the sandbox, non was created in the dev-system which I couldn’t – and still can’t – fully explain. Testing the workflow from SWDD in dev always ended in an error. After manually comparing definition and code between the systems and not spotting any differences, I asked my first question related to this activity in Q&A as I wasn’t even able to pinpoint what the actual issue might have been.
Rob Dielemans and Mike Pokraka helped me to narrow down the root-cause for the failure which was the deadline determination via the defined class-method. The really weird thing is that a deadline could for example be calculated in both the sandbox- and the dev-system when done as a simple calculation based on the work-item creation date plus 3 days. It just didn’t work via the class-method in the dev-system. And apart from some unspecific hunch that there might potentially be something off in the workflow configuration (SWU3) I still don’t know what’s causing this. A feeling I don’t really like! On the other hand, this wasn’t a really crucial part for my requirement so I decided to just let it slide and do without the deadline determination.
Act 2 – Yes, I’d really like to set the priority of the work-item to “1” and let the developer know about this
The next stumbling block to get this to work the way I had envisioned turned out to be showing an express notification for the work-item to a new external developer upon logging-in or her/his next activity in the system. To begin with, I didn’t see a place in SWDD where the default priority could be easily changed to something else and I was mystified how to then also get an express message triggered. So, it was time for question #2 to try and figure this out. Again, Rob and Mike came to my rescue and explained where the work-item’s priority can be switched (a pretty well hidden feature in the 2nd to last tab for the workflow-step called “Miscellaneous”) and that the “express notification” is actually a function of SAPOffice and not SAP-Workflow. Who would have guessed? Certainly not me!
In parallel to setting things up via SWDD and the ABAP-OO bits and pieces, I wrote a wrapper program to actually trigger the work-item creation. I didn’t have any intention or need to make this event-driven, so wanted to have a simple means to just do it via a report program. Towards the end of Act 2, I had something working along those lines:
Most of the processing logic happens in my wrapper-program which does the following:
- Select user(s) based on selection-screen input with FM BAPI_USER_GETLIST
Next steps are done within a loop for the selected users
- Determine who actually has S_DEVELOP with FM SUSR_USER_AUTH_FOR_OBJ_GET and only proceed for those that do
- Fill the relevant data and trigger the task with FM SAP_WAPI_START_WORKFLOW
- If the task was triggered successfully, change the newly created task’s priority to “1” (express) with FM SAP_WAPI_CHANGE_WORKITEM_PRIO (just setting the status in the workflow/task definition doesn’t seem to be enough)
- If that also worked, trigger a short internal express message to the developer via methods in CL_BCS to alert her/him about the new work item waiting to be processed in the SAP Business Workplace. I found this class via an old discussion thread which mentioned example programs being available for how to utilise it. Program BCS_EXAMPLE_3 had the applicable code which I only needed to slightly modify and drop into a method in my program.
- The result of steps 3 to 5 gets reported in a concatenated message field in an ALV-list
- As an alternative to steps 3 to 6, the program can also just list the status of the latest work item for the selected user(s) via FM SAP_WAPI_WORKITEMS_BY_TASK
Bottom line: this turned out to be more involved than I had first thought but it also gave me the opportunity to dabble a bit with SAP workflow and a bit more with ABAP-OO logic. It may not be the most straightforward solution for the requirement I wanted to tackle but as long as it worked I could live with that!
Perhaps I shouldn’t have written “as long as it worked” in that comment because soon after and during some testing I figured out that I still had an issue, namely that the work-item I intended to “send” to one – and only one! – specific user, ended up in everybody’s workflow-inbox as an executable work-item. Not good – and a real cliff-hanger to end Act 2 with!
Act 3 – One work-item in way too many inboxes – how come and how to stop it?
The main purpose of creating the work-item is to be able to track whether or not an external developer has aknowledged reading our development guidelines. So, finding out that the work-item was made available in everybody’s inbox came as a bit of an unwanted surprise – esp. once I realised that they even showed up in a colleague’s inbox who I hadn’t included in my list of recipients.So, high time for question #3 to find out how to have a general task workitem only show up in one specific user’s inbox. If I couldn’t get this to work, it would unfortunately render this whole exercise rather pointless as there’d then be no clear 1:1 assignment of who gets/sees the work-item and who processes it.
Mike was kind enough to yet again patiently explain what the issue might be and I tried to apply his suggestions. Unfortunately, the results were rather mixed at first. And even with the fairly straightforward option to trigger almost everything directly from my wrapper-program I still ended up with the work-item showing up in everybody’s inbox.
What obviously didn’t help was my ongoing struggle to make heads and tails of the various WF- and OO-related bits and pieces involved in making this work and I’m really grateful to Mike who patiently walked me through all of this providing response after response to my questions. At the time of this writing we were at about 17 nestings deep of replies in our back and forth!
And this is when I finally noticed what I had overlooked thus far with all the WF- and OO-stuff vying for my attention: an optional table tantalicingly called “AGENTS” the function module SAP_WAPI_START_WORKFLOW accepted as input.
So, I added a bit of code to my program to define and fil this internal table:
DATA: ls_agents TYPE swragent, lt_agents TYPE TABLE OF swragent. "Make sure that the workitem only ends up in the relevant user's inbox! ls_agents-otype = 'US'. ls_agents-objid = i_agent. APPEND ls_agents TO lt_agents.
Guess what? When I then ran my program for my own and my colleague’s user-IDs each of us just got to see the intended work-item in the workflow-inbox and others didn’t receive it! Just what I wanted all along so at long last, this saga had its happy ending!
Kudos where kudos are due
As already mentioned a couple of times throughout the post, I’m really grateful for Rob Dielemans‘ and Mike Pokraka‘s guidance, suggestions and patience. I’m fairly certain that I’d have thrown in the proverbial towel quite a while ago had I not had their assistance. So, thanks much for bearing with me throughout this saga!