Enterprise Resource Planning Blogs by SAP
Get insights and updates about cloud ERP and RISE with SAP, SAP S/4HANA and SAP S/4HANA Cloud, and more enterprise management capabilities with SAP blog posts.
Showing results for 
Search instead for 
Did you mean: 
0 Kudos
So far, we created a simple application with custom business object “Bonus Plan” to save employee specific rules for bonus entitlement.

Task: Create a second Custom Business Object to work with the existing one.

Example: A Manager wants to create a "Bonus Entitlement" (= bonus calculation) based on sales volume that uses data of a bonus plan.


I) Having completed all preceding parts of SAP S/4HANA Extensibility Tutorial.

II) Having Sales Orders in the system for the employee of the bonus plan as creator. The sales Orders where created within the validity period of the bonus plan. Their sum of Net Amount should be higher than multiplication product of bonus plan's Target Amount and High Bonus Assignment Factor.

To be able to create Sales Order a user needs Business Catalog SAP_SD_BC_SO_PROC_MC.

To be able to complete Sales Orders a user needs Business Catalog SAP_LE_BC_ODLV_PROC_MC

Step 1: Creating the Business Object "Bonus Entitlement"

Create the second Business Object, named Bonus Entitlement.

1. Open the Custom Business Objects Application

2. Execute New action

3. Enter the name "Bonus Entitlement" in the opening pop up

4. Close the pop up by clicking create

5. In the following view for editing the custom business object “Go to Fields and Logic” of the root node “Bonus Entitlement” in the structure view

6. Create following fields

field name field properties
Description text of length 255
Calculation Start Date Date
Calculation End Date Date
Actual Revenue Amount Amount
Low Bonus Amount Amount
High Bonus Amount Amount
Total Bonus Amount Amount
Bonus Plan ID Text of length 20

7. Go back via app action

8. Check the System Administrative data

9. Publish the business object

Step 2: Implementing the Bonus Entitlement's Business logic

After Modification

1. Open the business object and “Go to Fields and Logic”.

2. Enter the After Modification Event Logic

3. Implement following functionality

  • Check preconditions for the bonus calculation
    Hint: Bonus plan must be set.

  • Get the bonus plan data and check that it is in status "Released"
    Hint: For the SELECT the bonus plan ID must me right aligned in the text field. You can achieve that with the help of length function strln() and the SHIFT statement. When calculating the number of places that the id shall be shifted right, bear in mind that the minuend, the id length has to be subtracted from is 19 not 20 (which would be the length of the id's text field).

  • Set the bonus entitlement's calculation period equal to the bonus plan's validity period

DATA: bonusplan TYPE yy1_bonusplan.
DATA: bonusplan_id TYPE yy1_bonusplan-id.

IF bonusentitlement-bonusplanid IS INITIAL.
" get Bonus Plan
" convert bonusplan ID for SELECT
bonusplan_id = bonusentitlement-bonusplanid.
DATA: length TYPE i.
length = strlen( bonusentitlement-bonusplanid ).
SHIFT bonusplan_id BY ( 19 - length ) PLACES RIGHT.

FROM yy1_bonusplan
INTO @bonusplan
WHERE id EQ @bonusplan_id.

IF bonusplan-releasestatus EQ '2'.
" fill calculation period (should actually be done by plan when creating entitlement)
bonusentitlement-calculationstartdate = bonusplan-validitystartdate.
bonusentitlement-calculationenddate = bonusplan-validityenddate.

Bonus Calculation

  • Get the employee's actual revenue from the completed Sales Orders that he created in the validity period of the bonus plan
    Hint: There is the CDS view I_SalesOrderItemCube with the parameters Exchange Rate (take 'M') and Display Currency (should be the one from bonus plan's target amount). This view offers the netamountindisplaycurrency which does already currency conversion
    Hint: You need following view field to restrict the results correctly:

    • "createdbyuser"

    • "overallsdprocessstatus" (value "C" stands for completed)

    • "creationdate"

    " get completed Sales Orders for bonus plan's employee
    SELECT FROM i_salesorderitemcube( p_exchangeratetype = 'M', p_displaycurrency = @bonusplan-targetamount_c )
    FIELDS SUM( netamountindisplaycurrency )
    WHERE createdbyuser = @bonusplan-employeeid
    AND overallsdprocessstatus = 'C'
    AND creationdate BETWEEN @bonusplan-validitystartdate AND @bonusplan-validityenddate
    INTO @bonusentitlement-actualrevenueamount_v.

    bonusentitlement-actualrevenueamount_c = bonusplan-targetamount_c.​

  • Calculate the revenue based bonus by implementing the following rules:

    • If the employee reached more than the multiplication product of Target Amount and Low Bonus Assignment Factor, he gets the Low Bonus Percentage of his revenue as Low Bonus Amount
      Hint: If (ActualRevenueAmount / TargetAmount) > LowBonusAssignmentFactor, then LowBonusAmount = ActualRevenueAmount * LowBonusPercentage

    • If the employee reached more than the multiplication product of Target Amount and High Bonus Assignment Factor, he gets the High Bonus Percentage of his revenue above that multiplication product as High Bonus Amount additionally to the Low Bonus Amount.
      Hint: If (ActualRevenueAmount / TargetAmount) > HighBonusAssignmentFactor, then HighBonusAmount = (ActualRevenueAmount – (TargetAmount * HighBonusAssignmentFactor)) * HighBonusPercentage.

    " calculate minimum bonus
    IF ( bonusentitlement-actualrevenueamount_v / bonusplan-targetamount_v ) GT bonusplan-lowbonusassignmentfactor.
    bonusentitlement-lowbonusamount_v = bonusentitlement-actualrevenueamount_v * bonusplan-lowbonuspercentage / 100.
    bonusentitlement-lowbonusamount_c = bonusplan-targetamount_c.
    CLEAR bonusentitlement-lowbonusamount_v.
    CLEAR bonusentitlement-lowbonusamount_c.

    " calculate maximum bonus
    IF ( bonusentitlement-actualrevenueamount_v / bonusplan-targetamount_v ) GT bonusplan-highbonusassignmentfactor.
    bonusentitlement-highbonusamount_v = ( bonusentitlement-actualrevenueamount_v - ( bonusplan-targetamount_v * bonusplan-highbonusassignmentfactor ) ) * bonusplan-highbonuspercentage / 100.
    bonusentitlement-highbonusamount_c = bonusplan-targetamount_c.
    CLEAR bonusentitlement-highbonusamount_v.
    CLEAR bonusentitlement-highbonusamount_c.

  • Sum the different bonuses to the Total one.

  • For information write bonus plan data into the description
    " calculate total bonus
    bonusentitlement-totalbonusamount_v = bonusentitlement-lowbonusamount_v + bonusentitlement-highbonusamount_v.
    bonusentitlement-totalbonusamount_c = bonusplan-targetamount_c.

    DATA(actrevenue_s) = CONV string( bonusentitlement-actualrevenueamount_v ).
    DATA(target_s) = CONV string( bonusplan-targetamount_v ).
    DATA(lowf_s) = CONV string( bonusplan-lowbonusassignmentfactor ).
    DATA(lowp_s) = CONV string( bonusplan-lowbonuspercentage ).
    DATA(highf_s) = CONV string( bonusplan-highbonusassignmentfactor ).
    DATA(highp_s) = CONV string( bonusplan-highbonuspercentage ).
    CONCATENATE 'Bonus Run for Plan: ' bonusentitlement-bonusplanid
    ' with Target Amount: ' target_s
    ', Low Factor: ' lowf_s
    ', Low Percentage: ' lowp_s
    ', High Factor: ' highf_s
    ', High Percentage: ' highp_s INTO bonusentitlement-description SEPARATED BY space.

4. Publish the After Modification Logic

Before Save

5. Go back via application's action and enter the Before Save Event Logic

6. Implement a check that the Bonus entitlement is unique, which means the only one for the associated bonus plan.
Hint: as there's no direct connection between plan and entitlement on plan's side, make use of the fact, that there can be only one entitlement with the current one's and that must have the same creation point in time
valid = abap_false.

* check for consistency
DATA: bonusplan TYPE yy1_bonusplan.
DATA: bonusplan_id TYPE yy1_bonusplan-id.

IF bonusentitlement-bonusplanid IS INITIAL.
message = 'No Bonus Plan set. Bonus calculation impossible.'.
* check for uniqueness
SELECT SINGLE @abap_true FROM yy1_bonusentitlement INTO @DATA(rv_exists) WHERE bonusplanid EQ @bonusentitlement-bonusplanid
AND sap_createddatetime NE @bonusentitlement-sap_createddatetime.

IF rv_exists EQ abap_true.
CONCATENATE 'Bonus Entitlement for Bonus Plan ' bonusentitlement-bonusplanid 'already exists' INTO message SEPARATED BY SPACE.
" get Bonus Plan
" convert bonusplan ID for SELECT
bonusplan_id = bonusentitlement-bonusplanid.
DATA: length TYPE i.
length = strlen( bonusentitlement-bonusplanid ).
SHIFT bonusplan_id BY ( 19 - length ) PLACES RIGHT.

FROM yy1_bonusplan
INTO @bonusplan
WHERE id EQ @bonusplan_id.

IF bonusplan IS INITIAL.
CONCATENATE 'Bonus Plan ' bonusentitlement-bonusplanid 'does not exist. Bonus calculation impossible.' INTO message SEPARATED BY SPACE.
ELSEIF bonusplan-releasestatus NE '2'.
CONCATENATE 'Bonus Plan ' bonusentitlement-bonusplanid 'is not released. Bonus calculation not allowed yet.' INTO message SEPARATED BY SPACE.
message = 'Bonus calculated' .
valid = abap_true.

7. Publish the Before Save Logic

Step 3: Creating UI and application access

1. Open the Bonus Entitlement in Custom Business Objects application.

2. Start edit mode by executing the “Edit Draft” action.

2. Check the two boxes for UI Generation and Service Generation.

3. Publish the business object to trigger the generation of UIs (Master and Detail) and OData Service.

4. Go to Custom Catalog Extension application by clicking the “Maintain Catalogs” action.
A new window will open.
5. Start adding a catalog with the “Add” action.

6. In the opening value help narrow down the result list by searching for “Extensibility”, select the Catalog with role ID “SAP_CORE_BC_EXT” and press “OK”.

7. Select the just added Catalog and publish it.

This step takes some minutes, the screen refreshes automatically and once the status switches from unpublished to published, you can close this application’s window and proceed.

8. Back in the Custom Business Object application’s window, go to the SAP Fiori Launchpad via Home action.

9. Refresh the Browser window with key F5 for that the catalog extension becomes visible.
Now there is the Bonus Plan application’s tile in the Extensibility group.

10. Open the application by clicking its tile.

Step 4: Testing

1. Open the Bonus Entitlement application.

2. Create an object.

3. Enter following data

field value
Bonus Plan 1

4. Save the Bonus Entitlement. All Data of the Entitlement will get filled.