Programming is an art….
Application development is an art, too…. 🙂
Sometimes we all happen to have a situation where there seems to be no appropriate solution. But the truth is that there is always a simple solution, even in the most difficult case.
First of all, let me introduce some prerequisites for this article.
We have developed a new process which includes a number of independent steps.
At the first stage, we need to find someone who will be replacing the person responsible for approving decisions when he is out of the office (on vacation, sick leave, etc). In other words, we need to find a substitute. For this reason, our web development specialist creates a smart Fiori application which fully meets our criteria. This app allows us to select a substitute for the responsible person and set the range of days of absence.
At the second stage, we develop OData service which provides our Fiori app with all necessary information. This includes development of entity sets operating with the data concerning both the employee set and the substitute set. There is no interesting information here, so we omit the details of these artifacts, since they fulfill usual routines, such as reading, creating, deleting, and updating appropriate data.
What we need to do here is to describe more precisely the process of substitution, because understanding the full process is a key to understanding the most interesting detail of this solution. When we try to replace one person with another, we have to change authorization objects. In other words, we have to grant the authorization to a new person. In our case these authorization objects were HR’s objects, which made our task still more complicated.
So here are some steps:
- Read authorization objects assigned to our responsible person. For this purpose, we create a method which gets all roles that belong to the responsible person.
- Then we read all authorization objects assigned to our new substitute and try to calculate the difference between the sets of roles. In this step, we always know which authorization objects we must grant to the substitute.
- Then we should check all new roles because in some cases we may grant some inappropriate roles which are outdated for this period or not suitable. In this step, we have a clear list of roles which we grant to the substitute.
- In this step, we assign new roles. For this purpose, we create a function module
ZFM_HCM_SUBSTITUTE_ADD_ROLES which is declared as RFC function module.
This module allows us to run a background job call via the method assign_roles_via_job :
FUNCTION zfm_hcm_substitute_add_roles. *"---------------------------------------------------------------------- *"*"Local Interface: *" IMPORTING *" VALUE(IV_SUBSTITUTE) TYPE SYUNAME *"---------------------------------------------------------------------- DATA : lt_return TYPE bapiret2_t, lv_subrc TYPE sysubrc. * Try to run background job CALL METHOD zcl_hcm_substitute_service=>assign_roles_via_job EXPORTING iv_substitute = iv_substitute iv_jobname = zcl_hcm_substitute_service=>c_job_name_assign IMPORTING et_return = lt_return ev_subrc = lv_subrc.
Realization of this method includes filling in the parameters to start the background job.
We need to schedule a simple report ZHCM_SUBST_ROLE_ASSIGN as background. But each and every new time this report must be scheduled with new parameters.
This is quite an interesting task. Each time, we have to create a new variant for the report and start it. For this purpose, we create a new method.
* Create variant CALL METHOD zcl_hcm_substitute_service=>create_variant_for_assign
In this method, we fill in all appropriate parameters and create a new variant.
CALL FUNCTION 'RS_CREATE_VARIANT'.
Then we schedule and start a new job.
But here we face a difficult situation when we cannot assign new roles for the substitute, because our background user does not have appropriate authorization to fulfill this action. At this stage of development, we cannot solve this problem. But our main architect finds a perfect solution.
We try to start our rfc function via a special destination.
* Run rfc function CALL FUNCTION 'ZFM_HCM_SUBSTITUTE_ADD_ROLES' STARTING NEW TASK co_task_add DESTINATION lv_dest EXPORTING iv_substitute = lv_uname_subs.
This destination is described as:
In this case, we manage to perform our task:
- We change authority objects via user BTC_FITVCROS.
- This user works only in the background mode and cannot work in the foreground mode, therefore this user cannot be used by any person without an authorization check.
After the period expires we should reassign the role of a substitute. Here we use the same method, but before this action we should determine actual (up-to-date) authorization roles. For this purpose, we get existing roles for the substitute, delete the roles which were granted to him before and then reassign the new set of roles.
Hope this article will be useful for you. Good luck in SAP application development!