Skip to Content
Product Information
Author's profile photo Akshay Kumar

Power of Business Add-Ins in SAP S/4HANA Cloud

In this series of blogs, I am going to share about the use-case based implementations of Cloud BAdis in SAP S/4HANA Cloud.

For this purpose, I have taken those SAP S/4HANA Cloud BAdis which are popular among many of our Customers.

There would be 3 major key learnings for you in this blog:

How to implement a BAdi?

How to consume CDS views in a BAdi?

How to write the business logic for Approver determination?

Timesheet Approver Determination BAdi:

Default functionality of Timesheet Approval:

We are aware that, the Timesheet Approver for CPM Projects is the Project Manager by default.

But there are 2 cases in which a Project Manager gets his/her own time sheet for approval (self-approval) in the standard case:

1- When a Project Manager is also one of the Consultants contributing to the same project and submits his Timesheet for consulting efforts.

2- When Project Manager submits his own time sheet for billing of Project Management efforts.

Although this is an intended functionality, but it is given with the flexibility of customization i.e. we may define who would be the Approver.

Customization using BAdi:

Most of our Professional Services Customers want to customize this behavior by making one of the other project stakeholders as Approver when Project manager submits his Timesheet.

There can be many such scenarios where the Approver needs to be defined by Customers based on different criteria.

Let us look into the details of how we make Project Partner as the Approver of Project Manager’s Timesheet via Timesheet Approver Determination BAdi:

First, let’s implement the Timesheet Approver Determination BAdi and then we will test it.

Note: This BAdi gets called only when the approval scenario is enabled in the configuration app ‘Maintain Data Entry Profiles’ for Timesheet.

Step1: Go to Custom Fields and Logic App, navigate to custom logic tab and Create New Enhanced Implementation.

Step2: Select Business Context – ‘HCM- Timesheet Approver Determination’, BAdi Description and give a name to your implementation.

Step 3:

Insert the below code snippet under logic:

IF timeentry-wbselement IS NOT INITIAL.

SELECT SINGLE _engagementprojfinancialplan_engagementproject-engagementproject

FROM i_workpackage

WHERE workpackage = @timeentry-wbselement

INTO @DATA(lv_eng_project).

SELECT ProjectManager FROM I_EngagementProject

UP TO 1 ROWS

INTO @DATA(lv_project_manager)

WHERE EngagementProject = @lv_eng_project.

ENDSELECT.

IF timeentry-personworkagreement = lv_project_manager.

SELECT EMPLOYMENTINTERNALID FROM i_engagementprojectroles

INTO @DATA(lv_project_partner)

UP TO 1 ROWS

WHERE EngagementProject = @lv_eng_project AND EngagementProjectRole = ‘P004’.

approverperson = lv_project_partner.

ENDSELECT.

ENDIF.

ENDIF.

Let’s understand what happens in above code:

First, we identify the Engagement Project using the CDS view I_workpackage

Then we identify the Project Manager of this Project using CDS view I_engagementproject

When the project manager is the person assigned to work agreement, we determine the Project Partner of this Project using CDS view i_engagementprojectroles

The Project Partner is then assigned as the Approver person

Step 4: Save the logic and Publish it.

Step 5: You should see a success message stating successful publishing of your BAdi.

In the second part, let us test this BAdi:

The below video showcases the behavior after implementation of BAdi and here are the key things to notice it:

Anjani Kumar Mishra is the Project Manager and Consultant who submits his Timesheet and it goes for approval to Project Partner as coded in our BAdi.

Akshay Kumar is Project Partner who gets the Timesheet for approval in his inbox and approves it.

Assigned Tags

      10 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Saumitra Deshmukh
      Saumitra Deshmukh

      Great video! Thanks for sharing this custom logic scenario

      Author's profile photo Sreekanth Krishnan
      Sreekanth Krishnan

      informative. thanks

      Author's profile photo Esmee Peet
      Esmee Peet

      Great article! Could we use the same logic for an ePPM (enterprise) project? I am not sure whether we could retrieve the project manager from there.

      Author's profile photo Christopher Linke
      Christopher Linke

      That's what we're trying right now! Do you have more information in the meanwhile?

      Author's profile photo Lotte Bijsterbosch
      Lotte Bijsterbosch

      Christopher Linke We have recently managed to retrieve it in a BAdI, but it does require several CDS views. By using the following views you can retrieve the project manager: I_EnterpriseProject, I_EnterpriseProjectRole, I_EntProjectEntitlement, I_EnterpriseProjectTeamMember.

      Author's profile photo Christopher Linke
      Christopher Linke

      Thanks! How do you identify if it is an ePPM project though?

      Author's profile photo Christopher Linke
      Christopher Linke

      Hi Esmee Peet ,

      I found the path to determine the project manager. But the BADI wants the "Personnel number" of the project manager and I haven't found a way to get it!? It's not part of the project specific tables and all employee tables I found are not released. Your help would be very much appreciated.

      Cheers,

      Chris

      Author's profile photo Esmee Peet
      Esmee Peet

      Hi Christopher,

      We use the following code:

      ** Check whether timewriting is on a project

      IF timeentry-wbselement IS NOT INITIAL.

      * Get project UUID from project element

      Select Single ProjectUUID FROM I_EnterpriseProjectElement

      Where ProjectElement = ‎@timeentry-wbselement

      INTO ‎@DATA(project_uuid).

      * If the wbs is not an element, get project UUID from project header

      if project_uuid is initial.

      Select Single ProjectUUID FROM I_EnterpriseProject

      Where Project = ‎@timeentry-wbselement

      INTO ‎‎@project_uuid.

      endif.

      * Get the UUID for the project manager role of the project

      Select Single ProjectRoleUUID FROM I_EnterpriseProjectRole

      Where ProjectUUID = @project_uuid AND ProjectRoleType = 'YP_RL_0001'

      INTO ‎@DATA(project_role).

      * Get the UUID for the team member who is the project manager

      Select Single TeamMemberUUID FROM I_EntProjectEntitlement

      Where ProjectRoleUUID = ‎@project_role

      INTO ‎@DATA(teammember_uuid).

      * Get the UUID for the business partner of the project manager

      Select Single BusinessPartnerUUID FROM I_EnterpriseProjectTeamMember

      Where TeamMemberUUID = ‎@teammember_uuid

      INTO ‎@DATA(BP_uuid).

      * Get the personnel number of the project manager

      Select SINGLE PersonWorkAgreement FROM YY1_employee_ID

      WHERE BusinessPartnerUUID = ‎@BP_uuid

      INTO ‎@DATA(approver_projectmanager).

      I hope this helps.

      Regards,

      Esmee

      Author's profile photo Christopher Linke
      Christopher Linke

      Awesome, thank you so much! I was looking for the column/datatype "personnelnumber" and coudn't find anything

      Author's profile photo Roderick Sheng
      Roderick Sheng

      @Akshay Kumar

      Thank you Akshay Kumar for your sharing.
      I have a question and looking forward for your help.
      We company now implementing S/4 HANA Cloud and need to using Sales Order Workflow. So we want to add below codes in BADI - SD_APM_SET_APPROVAL_REASON, which is possible in S/4 OnPrem but not possible in Cloud. Do you have some idea how to writing those codes in Cloud?
      Thanks.

      FIELD-SYMBOLS: <tkomv> TYPE ANY TABLE.
      data xkomv_tab type TAB_KOMV.

      DATA(komv_va) = '(SAPMV45A)XKOMV[]'.

      ASSIGN (komv_va) TO <tkomv>.
      IF sy-subrc IS INITIAL AND <tkomv> IS ASSIGNED.
      xkomv_tab = <tkomv>.
      UNASSIGN <tkomv>.
      SORT xkomv_tab BY kschl.
      ENDIF.

       

       

      ASSIGN (komv_va) TO <tkomv>. will getting error message from Cloud as "The addition 'dynamic-object' in the restricted language scope".