Skip to Content
Requirement: We had a very specific requirement from one of our client where we required deadline monitoring with escalation for CATS Time Sheet and SAP only supports the one level approval where can do the deadline monitoring.
Brief Snapshot of the requirement:
 
  1. As soon as employee submits his timesheet, we need to send a UWL approval item to 1st level supervisor.
  2. Need to do the deadline monitoring here and if the timesheet is not approved in 2 days from day 1st UWL approval item was sent to 1st level manager then we have to send a UWL reminder (2nd notification) to 1st level manager
  3. If timesheet 1st level manager is not approved the timesheet in next 2 days from 2nd notification then we have to determine the escalation manager and send UWL timesheet approval item to determined escalation manager to approve and reject the time.
  4. Both the UWL approval should be kept available to both the manager until it is not Approved / Rejected.
  5. Once a manager approved the timesheet approval item should disappear from both managers UWL.
Technical issues / Challenges:
 
  1. As per the standard timesheet approval solution provided by SAP, we can only have single level approval and if required we can change the Agent by implementing USER Exit.
  2. In configuration also we can’t attach a workflow template to CATS profile; we can only attach the Task here and you want to create a custom task then it have form standard task else developer will encounter challenge to configure that task in CATS profile.
  3. If you have been able to create the custom task with required configuration to trigger a workflow, here the another challenge starts that data has been saved in the CATSDB will have the reference of this task and you will not find the reference of the UWL Approval work item which  will be triggered from the custom approval workflow.
Solution: We have put in a significant effort to achieve the functionality. However we decided to document this solution for the ease of the other Technical/Functional consultants who are facing real time challenges in doing that.
Step involved in Solution:

  1. Create a subtype for CATS business object which has event and method for trigger

       Go to transaction SWO1 to create extension of BO CATS and name it as ZCATS_APP
Step1-1.jpg

     Create a custom event (WFTRIGGER) and method (WFEVENTTRIGGER) with parameters given below:
STEP1-2.jpg
     Parameters definition for event and method:
STEP1-3.jpg
     Method WFEVENTTRIGGER code:
BEGIN_METHOD WFEVENTTRIGGER CHANGING CONTAINER.

DATA:
      PERSONNELNUMBER TYPE CATSFIELDS-PERNR,
      CURRENTDATE TYPE SYST-DATUM,
      TIME TYPE SYST-UZEIT,
      USERNAME TYPE SYST-UNAME,
      ROLE TYPE AFRU_WF-ACT_ROLE,
      WORKITEMID TYPE CATSDB-WORKITEMID.
 
  SWC_GET_ELEMENT CONTAINER ‘PersonnelNumber’ PERSONNELNUMBER.
  SWC_GET_ELEMENT CONTAINER ‘C urrentDate’CURRENTDATE.
  SWC_GET_ELEMENT CONTAINER ‘Time’ TIME.
  SWC_GET_ELEMENT CONTAINER ‘UserName’ USERNAME.
  SWC_GET_ELEMENT CONTAINER ‘Role’ ROLE.
  SWC_GET_ELEMENT CONTAINER ‘WORKITEMID’ WORKITEMID.
  SWC_SET_ELEMENT CONTAINER ‘WORKITEMID’ WORKITEMID.

  DATA: ld_objkey  type SWR_STRUCT-OBJECT_KEY.
            ld_objkey = WORKITEMID.
   DATA:
           ls_cont TYPE swr_cont,
           lt_cont TYPE STANDARD TABLE OF swr_cont.

   DATA: WORKITEMID_IMP LIKE OBJECT-KEY-ITEMID.
   DATA: WI_CHCKWI LIKE SWWWIHEAD-WI_ID.
   DATA: WORKITEM TYPE SWC_OBJECT.
          WORKITEMID_IMP = WORKITEMID.
*- get workflow id
     SWC_GET_PROPERTY WORKITEM ‘WorkitemReference’ WI_CHCKWI.

     IF SY-SUBRC EQ 0 AND NOT WI_CHCKWI IS INITIAL.
        WORKITEMID_IMP = WI_CHCKWI.
     ENDIF.
     ls_cont-element = ‘PERSONNELNUMBER’.
     ls_cont-value = PERSONNELNUMBER.
     APPEND ls_cont TO lt_cont.

     ls_cont-element = ‘CURRENTDATE’.
     ls_cont-value = CURRENTDATE.
     APPEND ls_cont TO lt_cont.
     ls_cont-element = ‘TIME’.
     ls_cont-value = TIME.
     APPEND ls_cont TO lt_cont.

    ls_cont-element = ‘USERNAME’.
    ls_cont-value = USERNAME.
    APPEND ls_cont TO lt_cont.

    ls_cont-element = ‘ROLE’.
    ls_cont-value = ROLE.
    APPEND ls_cont TO lt_cont.
    ls_cont-element = ‘WORKITEMID’.
    ls_cont-value = WORKITEMID_IMP.
    APPEND ls_cont TO lt_cont.

CALL FUNCTION ‘SAP_WAPI_CREATE_EVENT’
  EXPORTING
    OBJECT_TYPE                 = ‘ZCATS_APP’
    OBJECT_KEY                   = ld_objkey
    EVENT                              = ‘WFTRIGGER’
TABLES
   INPUT_CONTAINER         = lt_cont
          .
END_METHOD.
     2. Create custom task which will use trigger method to raise custom WF trigger event         
          Go to transaction PFTC and copy task TS31000007 
STEP2-1.jpg
          Change the object and method in newly created task:
STEP2-2.jpg
          Binding between task TS99900029 and trigger method WFEVENTTRIGGER
STEP2-3.jpg
          Go to transaction PP02 and maintain task Classification / Lock Ind. in infotype (1217). This new task should be classified as ‘General Task’.
STEP2-4.jpg
STEP2-5.jpg

     3. Create linkage between trigger event and custom workflow

        Go to transaction SWE2 to create linkage between event WFTRIGGER and Approval Workflow

STEP3-1.jpg       
  Go to transaction SWE3 to create instant linkage for event WFTRIGGER
STEP3-2.jpg
     4. Attach custom task to CATS profile
          Go to transaction SPRO and follow the below path
STEP4-1.jpg
STEP4-2.jpg

     5. Workflow design and definition

          Overall design of the Time Approval Workflow:
          STEP5-1.jpg
          Overview of Workflow WS99900011 Container:
       STEP5-2.jpg
          Attach EVENT WFTRIGGER to workflow WS99900011:    
      STEP5-1_2.jpg
          Binding between EVENT WFTRIGGER container and Workflow WS99900011 Container:
      STEP5-3.jpg            
          Create a new task to get the CATS business object instance which is corresponding to the workitem generated by the task attached in CATS profile in step 4:
      STEP5-4.jpg
          Task TS99900027 container overview:
      STEP5-5.jpg
          Attach TS99900027 to workflow WS99900011:
      STEP5-6.jpg
          Binding between task TS99900027 and workflow WS99900011 container:
      STEP5-7.jpg
Note: WORKITEMID pass here to task container is the WORKITEMID which come from event container to workflow container and correspond to WORKITEM ID got generated by the task attached in CATS profile.

     Go to transaction PFTC and copy task TS31000007 to send UWL Approval item to Timesheet Manager/Supervisor and key attributes will remains same as original and copying this task to add some additional container elements for further processing:
STEP6-1.jpg
     Attach task TS99900025 to workflow:
STEP6-2.jpg
     Binding between task TS99900025 and workflow WS99900011 container:
STEP6-3.jpg
Note: After putting this in the workflow, we executed the process and found that this step successfully sent the Approval workitem to manager/supervisor but when he/she opens it to approve/reject the timesheet, he got a message that “No data for Approval”.
In our further investigation we found that the time data saved in CATSBD had the reference for workitem which got generated by the task attached in the CATS profile to trigger the workflow, which caused this issue.

To resolve this issue, we are required to update CATSDB with the new workitem id which get generated by the task TS99900025 (sending the UWL approval item to manager). Hence we decided to implement the program exit in class ‘ZCL_UPDATE_CATSDB_FOR_APPROVAL’ for this step in workflow.
STEP7-1.jpg
Class overview for ZCL_UPDATE_CATSDB_FOR_APPROVAL:
STEP7-2.jpg
Interfaces attached to the class ZCL_UPDATE_CATSDB_FOR_APPROVAL
STEP7-3.jpg
Note:

  • Interface IF_WORFLOW is required to use any class in WORKFLOW.
  • Interface IF_SWF_IFS_WORKITEM_EXIT is required to call it from program exit of task and is used to pass the context and data of  workitem to class.

Attributes for class ZCL_UPDATE_CATSDB_FOR_APPROVAL
STEP7-4.jpg

Methods for class ZCL_UPDATE_CATSDB_FOR_APPROVAL

STEP7-5.jpg

Aliases overview for class ZCL_UPDATE_CATSDB_FOR_APPROVAL

STEP7-6.jpg

Parameters for Program Exit Method IF_SWF_IFS_WORKITEM_EXIT~EVENT_RAISED:
STEP7-7.jpg
Signature for Program Exit Method IF_SWF_IFS_WORKITEM_EXIT~EVENT_RAISED:
STEP7-8.jpg
Code for Program Exit Method IF_SWF_IFS_WORKITEM_EXIT~EVENT_RAISED:
METHOD if_swf_ifs_workitem_exit~event_raised.
 
DATA: workitemid_old TYPE sww_wiid,
              workitemid_new
TYPE sww_wiid,
              workflowid
TYPE sww_wiid.

  TYPES: t_catsdb TYPE catsdb.
 
DATA: ls_catsdb TYPE t_catsdb.
 
DATA: lt_catsdb TYPETABLEOF t_catsdb.
 
DATA: it_catsdb TYPESTANDARDTABLEOF catsdb.

  DATA: count TYPE i,
              subrc
TYPE sy-subrc.
 
TYPES: t_container TYPE swr_cont.
 
DATA: ls_container TYPE t_container.
 
DATA: lt_container TYPETABLEOF t_container.
  DATA: message_lines  TYPETABLEOF swr_messag,
             message_struct 
TYPETABLEOF swr_mstruc.

DATA: catwfexit(9) TYPEcVALUE‘CATWFEXIT’.
  IF im_event_name EQ swfco_event_after_creation.
    me->workitem_context = im_workitem_context.
* read task container
   
CALL METHOD me->get_object_from_container
     
EXPORTING
        im_workitem_context = im_workitem_context
     
IMPORTING
        workitemid_new      = workitemid_new.

    CALL METHOD me->get_element_from_container
     
EXPORTING
        im_workitem_context = im_workitem_context
        elementname         =
‘WORKITEMID’                  “#EC NOTEXT
     
IMPORTING
        elementvalue        = workitemid_old.

    CALL METHOD me->get_element_from_container
     
EXPORTING
        im_workitem_context = im_workitem_context
        elementname         =
‘WORKFLOWID’                  “#EC NOTEXT
     
IMPORTING
        elementvalue        = workflowid.

    SELECT * INTO CORRESPONDING FIELDS OF TABLE it_catsdb
       
FROM catsdb WHERE status = ’20’
                     
AND workitemid = workitemid_old.
     IF sy-subrc EQ0.
     
LOOPAT it_catsdb INTO ls_catsdb.
        ls_catsdb-workitemid = workitemid_new.
       
APPEND ls_catsdb TO lt_catsdb.
     
ENDLOOP.

      UPDATE catsdb FROMTABLE lt_catsdb.

*   Need to do the exception handling to avoid short dumps
   
ENDIF.

* Pass new workitem ID to task container
   
CALL METHOD me->pet_element_in_container
     
EXPORTING
        im_workitem_context = im_workitem_context
        elementname         =
‘WORKITEMID_NEW’
        elementvalue        = workitemid_new.

* Pass new workitem ID to workflow container
    ls_container-element =
‘WORKITEMID_NEW’.
    ls_container-
value = workitemid_new.
   
APPEND ls_container TO lt_container.


*   Set to enable the use of FM ‘SAP_WAPI_WRITE_CONTAINER’
SET PARAMETER ID ‘CWE’FIELD catwfexit.

CALLFUNCTION‘SAP_WAPI_WRITE_CONTAINER’
     
EXPORTING
        workitem_id                  = workflowid
       
language                     = sy-langu
        actual_agent                 = sy-uname
        overwrite_tables_simple_cont = ‘ ‘
     
IMPORTING
        return_code                  = subrc
     
TABLES
        simple_container             = lt_container
        message_lines                = message_lines
        message_struct               = message_struct.

    IF sy-subrc EQ 0.
*  We can write the success message to log for future reference  

    ENDIF.
 
ENDIF.
ENDMETHOD.

Note: SAP has implemented a restriction to use FM “SAP_WAPI_WRITE_CONTAINER” from the program exit of the task which was stopping us pass new approval step workitem id to workflow container.
It could have been achieved by doing the Export binding between the task and workflow container. But it only happens when the task successfully completed by the Agent. If the Agent is not completed the task and deadline is reached then we will not get the new workitem id in the workflow container, which is required to enable to escalation in Timesheet Approval.

To enable that we have implemented the “Implicit Enhancement” for CLASS_CONSTRUCTOR method of class “CL_SWF_UTL_WAPI_FRAMEWORK”:
STEP8-1.jpg
Signature and Code for Method GET_ELEMENT_FROM_CONTAINER:
STEP8-2.jpg
METHOD get_element_from_container.
 
INCLUDE <swfcntn01>.
 
DATA wi_container_params TYPEREFTO if_swf_ifs_parameter_container.
 
DATA wi_container TYPEREFTO if_swf_cnt_container.
 
DATA object TYPE sibflporb.

  CLEAR elementvalue.
  wi_container_params = im_workitem_context->get_wi_container( ).
  wi_container ?= wi_container_params.
  swf_get_element wi_container elementname elementvalue.
ENDMETHOD.


Signature and Code for Method GET_OBJECT_FROM_CONTAINER:
STEP8-3.jpg
METHOD get_object_from_container.
 
INCLUDE <swfcntn01>.
 
DATA wi_container_params TYPEREFTO if_swf_ifs_parameter_container.
 
DATA wi_container TYPEREFTO if_swf_cnt_container.
 
DATA object TYPE sibflporb.

  wi_container_params = im_workitem_context->get_wi_container( ).
  wi_container ?= wi_container_params.
  swf_get_element wi_container ‘_WORKITEM’ object.
  workitemid_new = object-instid.
ENDMETHOD.


Signature and Code for Method PET_ELEMENT_IN_CONTAINER:
STEP8-4.jpg
METHOD pet_element_in_container.
 
INCLUDE <swfcntn01>.
 
DATA wi_container_params TYPEREFTO if_swf_ifs_parameter_container.
 
DATA wi_container TYPEREFTO if_swf_cnt_container.
 
DATA object TYPE sibflporb.
  wi_container_params = im_workitem_context->get_wi_container( ).
  wi_container ?= wi_container_params.
  swf_set_element wi_container elementname elementvalue.
ENDMETHOD.

After putting this in place, we have successfully sent the UWL Approval workitem to respective manger/supervisor and he/she is been able to see the timesheet submit by employee for his/her approval.

Define deadline at the approval step which is using task TS99900025:
STEP8-5.jpg

Solution for sending the UWL Approval item to Escalation manager
Now we have to move to the next step where we have to send the UWL Approval workitem to escalation manger in case the defined is reached at previous step of task TS99900025.

Challenges:
We can put the above approval task again in the workflow to send the Timesheet Approval item to escalation manager but we will face following issues:

  • If the above task implement with program exit then 1st level approval will not be able to see the timesheet data
  • If we will put this without program exit which we have implement in the last step then escalation manager will get the error “No data for Approval”

Another option, we can forward the Approval workitem to escalation manger but workitem will disappear from 1st level manger’s UWL.

Hence we thought that once the deadline is reached and we can add the escalation manager as agent to originally generated Timesheet Approval workitem will resolve the issue and we will be following the standard approach provided by SAP of Timesheet approval.

Now don’t have any standard functionality to add agent in the sent workitem without removing t the original agent. To achieve this we copied some standard function
modules and adjusted them for our requirement.

List of FM copied and adjusted:

  • SWW_WI_AGENTS_CHANGE
  • SWW_WI_AGENTS_CHANGE_S
  • RH_WI_ORGTASK_INSERT

Create a new function group with name ZHR_WF_WI_INS_MOD_AGENT which will have the copy of the above function modules:
STEP8-6.jpg
Copy FM SWW_WI_AGENTS_CHANGE to ZSWW_WI_AGENTS_ADD_CHANGE and in new FM we have to replace the call of FM CALL FUNCTION ‘SWW_WI_AGENTS_CHANGE_S’ to CALL FUNCTION ‘ZSWW_WI_AGENTS_CHANGE_S’.

Copy FM SWW_WI_AGENTS_CHANGE to ZSWW_WI_AGENTS_CHANGE_S and in new FM we have to replace the call of FM CALL FUNCTION  RH_WI_ORGTASK_INSERTto CALL FUNCTIONZRH_WI_ORGTASK_INSERT ‘.

Below is the code which needs to be commented from the copied Function Module ZRH_WI_ORGTASK_INSERT to achieve the required functionality.

Go in to code of PERFORM CHANGE_ORGTASK and comment the blow lines of code:
*        IF ACT_ORGTASK-NO_SEL IS INITIAL.
** deactivate agent
*          ACT_ORGTASK-NO_SEL = ‘X’.
*          CLEAR act_orgtask-forward.       “SERN833589
** keep act_orgtask actual and fill upd_org_task for later update
*          MODIFY ACT_ORGTASK.
*          APPEND ACT_ORGTASK TO UPD_ORGTASK.
*        ENDIF.

Now we have the custom FM ZSWW_WI_AGENTS_ADD_CHANGE ready to add new agent in the sent workitem which need to be plugged in our custom “Timesheet Approval Workflow”.

Go to transaction PFTC for creating a new task which will add the escalation manger into the sent Timesheet Approval workitem:
STEP9-1.jpg
Container overview for task TS99900028:
STEP9-2.jpg
Binding between task TS99900028 and Method ADD_ESCALATION_MANAGER:
STEP9-3.jpg
Note: Escalation manager can be determined in a separated step and can be passed through the binding.
Add task to Timesheet Approval workflow WS99900011 as step after deadline reached:
 

Binding between the TS99900028 and Workflow WS99900011:

Signature and Code for Method PET_ELEMENT_IN_CONTAINER:

METHOD add_escalation_manager.
 
TYPES: t_agent TYPE swhactor.
 
DATA: ls_agent TYPE t_agent.
 
DATA: lt_agent TYPE TABLE OF t_agent.

  DATA: count TYPE i.

  ls_agent-otype = utype.
  ls_agent-objid = userid.
  APPEND ls_agent TO lt_agent.

CALLFUNCTION‘ZSWW_WI_AGENTS_ADD_CHANGE’
   
EXPORTING
      agents_append         =
‘X’
      wi_id                 = workitemid_new
      do_commit             =
‘X’
      authorization_checked =
‘ ‘
   
TABLES
      agents                = lt_agent
   
EXCEPTIONS
      no_authorization      =
1
      update_failed         =
2
      invalid_type          =
3
    
OTHERS                = 4.
 
IF sy-subrc <> 0.
* Required error handling can be done here
 
ENDIF.

  CLEAR: ls_agent, lt_agent, lt_agent[].
ENDMETHOD.

Once the above steps are completed you have set the visualization parameter for TS99900025 by using the transaction SWFVISU and these will be same as TS31000007.
To report this post you need to login first.

2 Comments

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

Leave a Reply