I understand, many of them are aware about different handlers that we can use in our UWL Configuration files, but most of the time we fail to use those and end up doing something which is not required wasting our valuable time, in development or testing or debugging workflows because of unnecessary branches or path.

In many of my projects or client places I have seen that Workflow developers use Loops within workflow, which is not used to reduce redundant steps in process but to validate data entered by user in custom applications before taking process ahead. For e.g.: – If approver rejects a request, and fails to give remarks or comments for rejection in Custom Application (Webdynpro or BSP or Transaction iView), workitem is bounced backed to User using Loop, which is actually not required when it comes to approvals from UWL. Instead of using Loops to bounce back the workitem or request to last processing user incase of validation failure, the use of FunctionModuleActionHandler in UWL config files can help in avoiding the use of unnecessary loops in Workflow making workflow more simpler in design as well as easy to test different paths or branches in workflow.

For any foreground activity or User Decision, you can custom define UWL config file so as to ensure any kind of validations, business checks or trigger of correspondence, by defining custom Actions which calls a remote-enabled Function Module (RFC), passing all necessary Container Values as import parameters to Function Module which can assist in writing any kind of business rules in it before the request(or User Decision) is actually processed or taken or completed.

Please find below sample UWL XML Code Snippet which is configured against a User Decision task of Custom Workflow.

<ItemType name="uwl.task.webflow.TS99900XXX.SAP_HR" connector="WebFlowConnector" defaultView="DefaultView" defaultAction="DisplayTravelRequestForm" executionMode="default">
                 <ItemTypeCriteria systemId="SAP_HR" connector="WebFlowConnector" externalType="TS99900XXX"/>
                   <CustomAttributes>
                                <CustomAttributeSource id="WEBFLOW_CONTAINER" objectIdHolder="externalId" objectType="WebflowContainer" cacheValidity="final">
                                  <Attribute name="PERNR" type="string" displayName="PERNR"/>
                                  <Attribute name="REINR" type="string" displayName="REINR"/>
                                </CustomAttributeSource>
                  </CustomAttributes>
                  <Actions>
                   <Action name="accept" groupAction="yes" handler="FunctionModuleActionHandler">
                                <Properties>
                                 <Property name="FunctionModule" value="ZHR_FM_DEMO_WF"/>
                                 <Property name="DeleteItem" value="false"/>
                                 <Property name="ACTION" value="A"/>
                                 <Property name="WI_ID" value="${item.externalId}"/>
                                 <Property name="PERNR" value="${item.PERNR}"/>
                                 <Property name="REINR" value="${item.REINR}"/>
                                </Properties>
                                <Descriptions default="Approve Travel Request"/>
                   </Action>
                   <Action name="reject" groupAction="yes" handler="FunctionModuleActionHandler">
                                <Properties>
                                 <Property name="FunctionModule" value="ZHR_FM_DEMO_WF"/>
                                 <Property name="DeleteItem" value="false"/>
                                 <Property name="ACTION" value="R"/>
                                 <Property name="WI_ID" value="${item.externalId}"/>
                                 <Property name="PERNR" value="${item.PERNR}"/>
                                 <Property name="REINR" value="${item.REINR}"/>
                                </Properties>
                                <Descriptions default="Reject Travel Request"/>
                   </Action>
                   <Action name="DisplayTravelRequestForm" handler="SAPWebDynproABAPLauncher" returnToDetailViewAllowed="yes" launchInNewWindow="yes" launchNewWindowFeatures="toolbar=no,menubar=no,location=no">
                                 <Properties>
                                   <Property name="WebDynproApplication" value="ZHR_A_DEMO_WF"/>
                                   <Property name="WebDynproNamespace" value="sap"/>
                                   <Property name="PERNR" value="${item.PERNR}"/>
                                  <Property name="REINR" value="${item.REINR}"/>
                                </Properties>
                                  <Descriptions default="Open Travel Request"/>
                  </Action>                           
           </Actions>
      </ItemType>

                  

The above code snippet is self-explanatory in many ways, but still will try to put some light on few points.

1. 

<ItemType name="uwl.task.webflow.TS99900XXX.SAP_HR"

     Defines the User Decision workflow task number for which custom handling is done.

2.

 <CustomAttributes>


Defines Custom Attributes which are associated with workflow task defined in workflow builder PFTC, it helps in reading those value from workitem container. In our example attributes PERNR & REINR are read from Workitem container which is required by us for further processing of user decision.

3.

                   <Action name="accept" groupAction="yes" handler="FunctionModuleActionHandler">

                                <Properties>

                                 <Property name="FunctionModule" value="ZHR_FM_DEMO_WF"/>

                                 <Property name="DeleteItem" value="false"/>

                                 <Property name="ACTION" value="A"/>

                                 <Property name="WI_ID" value="${item.externalId}"/>

                                 <Property name="PERNR" value="${item.PERNR}"/>

                                 <Property name="REINR" value="${item.REINR}"/>

                                </Properties>

                                <Descriptions default="Approve Travel Request"/>

                   </Action>

Similarly, we have to define several actions as per the number of user decisions added in Workflow, also Actions are just buttons that appear in UWL Task Preview which can correspondingly trigger a Function Module in ABAP, call a URL link, open an WebDynpro JAVA/ABAP application, and many more. Please check this link for different Action Handlers that can be used in UWL XML Configuration Action Handlers (SAP Library – Universal Worklist Configuration).

In our example we are using “FunctionModuleActionHandler”, which is used mainly to call a Remote-Enabled Function Module (RFC), on trigger of corresponding action. For e.g. when user clicks on “Approve Travel Request” button in UWL, function module is called along with all required importing parameters, the same parameters are used in function module to do any custom validations. Later on successful validation check, either we can fulfill approval request or pass the error message back to portal. The Structure of Function Module that can be used with FunctionModuleActionHandler is explained in detail here http://help.sap.com/saphelp_nwce71/helpdata/en/d6/7bd981916f4c4aabd5231723efa8e8/content.htm

We can have our own Importing Parameters but Exporting Structure need to be same as explained in above link so as to pass error messages back to portal.

4.

 <Property name="FunctionModule" value="ZHR_FM_DEMO_WF"/>
 <Property name="DeleteItem" value="false"/>


The above two are standard properties which are required while using FunctionModuleActionHandler, Value for property – “FunctionModue” should be remote-enabled Function Module Name. Value for property – “DeleteItem” can be true or false, I have set false because for me task should not get disappeared automatically from UWL after action execution, Task will be removed only when all validation checks are passed successfully and internally the custom Function Module can call standard ABAP FM for completion of Normal Task or User Decision task using following FM “SAP_WAPI_WORKITEM_COMPLETE” and “SAP_WAPI_DECISION_COMPLETE” respectively.

5.

                   <Action name="DisplayTravelRequestForm" handler="SAPWebDynproABAPLauncher" returnToDetailViewAllowed="yes" launchInNewWindow="yes" launchNewWindowFeatures="toolbar=no,menubar=no,location=no">
                                 <Properties>
                                   <Property name="WebDynproApplication" value="ZHR_A_DEMO_WF"/>
                                   <Property name="WebDynproNamespace" value="sap"/>
                                   <Property name="PERNR" value="${item.PERNR}"/>
                                  <Property name="REINR" value="${item.REINR}"/>
                                </Properties>
                                  <Descriptions default="Open Travel Request"/>
                  </Action>      

Point 5. is not relevant to our Post, but just as a add-on another use of action handler is expressed over here, wherein, WebDynpro ABAP application is launched using launcher SAPWebDynproABAPLauncher” along with workitem container values are passed as application parameters for managing the details in application.

I understand that many of us are already known to this options but just to refresh us and to help new entrants for use of already available tools more efficiently.


All credit goes to Jocelyn Dart for inspiring me to write this post. Her point was to just re-collect with few basics and use it in our day-to-day developments to avoid any kind of wrong approaches.

Thanks to all…Thanks Jocelyn…sorry for delay in writing this post.. Its was pending in draft mode since 4 Months.

Regards

Tushar Shinde


To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply