---
parser: v2
auto_validation: true
primary_tag: programming-tool>abap-extensibility
tags: [ tutorial>intermediate, tutorial>license, programming-tool>abap-extensibility, topic>cloud, software-product>sap-s-4hana-cloud ]
time: 15
author_name: Peter Persiel
author_profile: https://github.com/peterpersiel
slug: abap-extensibility-cbo-execute-outbound-service
canonical_url: https://developers.sap.com/tutorials/abap-extensibility-cbo-execute-outbound-service
---
<!-- DONE with BGO/100 -->
<!-- SAP S/4HANA Extensibility Tutorial: https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-sap/sap-s-4hana-extensibility-tutorial/ba-p/13293080 -->
# Execute an Outbound Service from Custom Business Object Logic

<!-- description -->Call an external service of SAP Business Accelerator Hub from inside the logic implementation of a custom business object.

## You will learn

- How to get needed service data from SAP Business Accelerator Hub Sandbox
- How to configure outbound service connection in SAP S/4HANA Cloud system
- How to call and process an outbound service in custom business object logic

## Prerequisites  

- **Authorizations:** Your user needs business role(s) with business catalogs **Extensibility - Custom Business Objects** (ID: `SAP_CORE_BC_EXT_CBO`), **Communication Management** (ID: `SAP_CORE_BC_COM`) and **Extensibility - Custom Communication Scenarios** (ID: `SAP_CORE_BC_EXT_CCS`) in your **SAP S/4HANA Cloud** system
- Your user needs access to **[SAP Business Accelerator Hub](https://api.sap.com)**.
- **Example Objects:** Existence of custom business object `Bonus Entitlement`, refer to instructions below for [Bonus Entitlement CBO](#step-1).

## Additional Info

- The example application of `Bonus Entitlement` will be enhanced by a feedback functionality. The manager's feedback will be translated automatically into English by calling the externally available service **SAP Translation Hub** of SAP.
- Be aware that the example is done with the SAP Business Accelerator Hub Sandbox system only. This shall only give an idea on how it works and cannot be used productively.
- Tutorial feasibility last checked with SAP S/4HANA Cloud Release 2608
  
---

### Prerequsite: Bonus Entitlement CBO
As a prerequisite, create another Custom Business Object `Bonus Entitlement`. Also refer to [Part IV: Associated Business Objects (Bonus Entitlement with - Plan & Sales Order)](https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-sap/part-iv-associated-business-objects-bonus-entitlement-with-plan-amp-sales/ba-p/13345817).

  - Business Object ID: `YY1_BONUSENTITLEMENT`
  - Enabled Features: Determination and Validation, User Interface, System Administrative Data
  - Nodes: `BONUSENTITLEMENT`
  - Fields:
    - Description, Type = Text with Length = 255
    - Calculation Start Date, Type = Date
    - Calculation End Date, Type = Date
    - Actual Revenue Amount, Type = Amount with Currency
    - Low Bonus Amount, Type = Amount with Currency
    - High Bonus Amount, Type = Amount with Currency
    - Total Bonus Amount, Type = Amount with Currency
    - Bonus Plan ID, Type = Numeric Identifier with Length = 10
  - Determination Logic (After Modification):
```abap
DATA: bonusplan TYPE yy1_bonusplan.
DATA: bonusplan_id TYPE yy1_bonusplan-id.

IF bonusentitlement-bonusplanid IS INITIAL.
    RETURN.
ELSE.
    " get Bonus Plan
    SELECT *
    FROM yy1_bonusplan
    INTO @bonusplan
    WHERE id EQ @bonusentitlement-bonusplanid.
    ENDSELECT.

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

    " 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 minimum bonus
    IF ( bonusentitlement-actualrevenueamount_v / bonusplan-targetamount_v ) GT bonusplan-lowbonusassignmentfactor.
        bonusentitlement-lowbonusamount_v = bonusentitlement-actualrevenueamount_v * bonusplan-lowbonuspercentage_v / 100.
        bonusentitlement-lowbonusamount_c = bonusplan-targetamount_c.
    ELSE.
        CLEAR bonusentitlement-lowbonusamount_v.
        CLEAR bonusentitlement-lowbonusamount_c.
    ENDIF.

    " 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_v / 100.
        bonusentitlement-highbonusamount_c = bonusplan-targetamount_c.
    ELSE.
        CLEAR bonusentitlement-highbonusamount_v.
        CLEAR bonusentitlement-highbonusamount_c.
    ENDIF.

    " 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_v ).
    DATA(highf_s) = CONV string( bonusplan-highbonusassignmentfactor ).
    DATA(highp_s) = CONV string( bonusplan-highbonuspercentage_v ).

    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.
ENDIF.
```
  - Validation Logic (Before Save):
```abap
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.'.
    RETURN.
    ELSE.

    * 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.
        RETURN.
    ELSE.

        " get Bonus Plan
        SELECT *
        FROM yy1_bonusplan
        INTO @bonusplan
        WHERE id EQ @bonusentitlement-bonusplanid.
        ENDSELECT.

        IF bonusplan IS INITIAL.
        CONCATENATE 'Bonus Plan ' bonusentitlement-bonusplanid 'does not exist. Bonus calculation impossible.' INTO message SEPARATED BY space.
        RETURN.
        ENDIF.

        message = 'Bonus calculated' .
        valid = abap_true.
    ENDIF.
ENDIF.
```

### Excursus - Try out the service in SAP Business Accelerator Hub

To get to know the SAP Translation Hub service first, you can try it out in SAP Business Accelerator Hub.

<!--border-->
1. Go to [Software Translation on SAP Business Accelerator Hub](https://api.sap.com/api/translationhubK8S/tryout), provided as part of SAP Translation Hub.

2. Expand the **Try Out** section .

3. Choose the POST operation **/v3/translate** under **Translate API for V3**.

4. Switch to **Body** section of **REQUEST**.

5. Exchange the default body with this simplified example.

   ```json
   {
       "sourceLanguage": "en",
       "targetLanguage": "es",
       "units": [
           {
               "value": "Your text to be translated"
           }
       ]
   }
   ```

6. Hit the **Run** button.

7. The **RESPONSE** to the service call will appear.

### Get service end point and API Key

To configure the connection to the system and the outbound scenario you will need the service's end point. To retrieve the endpoint, switch to the **Overview** section and open the **Configuration Details**. Use the **SANDBOX URL** as endpoint for this tutorial.

![Service End Point: Request URL in response section](https://raw.githubusercontent.com/sap-tutorials/abap-core-development/main/tutorials/abap-extensibility-cbo-execute-outbound-service/API_Hub_GetServiceEndPoint.png)

To authenticate during a service call later, you will need an API key from the SAP Business Accelerator Hub.

1. Still in Software Translation in SAP Business Accelerator Hub, scroll to top and press **Show API Key**

    ![Button to show API Key of in SAP Business Accelerator Hub](https://raw.githubusercontent.com/sap-tutorials/abap-core-development/main/tutorials/abap-extensibility-cbo-execute-outbound-service/API_Hub_ShowAPI_Key.png)
    A pop up opens.

2. Press **Copy Key and Close** to save the key to your clipboard.

    ![Pop Up to Copy API Key](https://raw.githubusercontent.com/sap-tutorials/abap-core-development/main/tutorials/abap-extensibility-cbo-execute-outbound-service/API_Hub_popUp_CopyAPI_Key.png)

3. Paste the application key into a text editor for later use.

### Create Communication System for Sandbox

In order to allow communication with the SAP Business Accelerator Hub Sandbox you have to create a communication system for it in your SAP S/4HANA Cloud System.

1. Enter your SAP S/4HANA Cloud system's Fiori Launchpad.

2. Start typing **Communication Systems** in the Launchpad search and open the App from the results.

    ![Communication Systems application from search results](https://raw.githubusercontent.com/sap-tutorials/abap-core-development/main/tutorials/abap-extensibility-cbo-execute-outbound-service/FLP_searchResult_CS.png)

3. Execute the action to create a **New** Communication System.

4. Enter following Data into the input fields.

    | Field Label    | Field Value               |
    | :------------- | :-------------------------|
    | System ID      | **`SANDBOX_API_SAP_COM`** |
    | System Name    | **`SANDBOX_API_SAP_COM`** |

    ![Pop Up to create New Communication System](https://raw.githubusercontent.com/sap-tutorials/abap-core-development/main/tutorials/abap-extensibility-cbo-execute-outbound-service/CS_NewPopUp.png)

5. Press **Create**

    The Details screen of the new Communication System opens.

6. Enter as **Host Name** `sandbox.api.sap.com`, which is the domain part of the service's end point that you got in the previous step.

7. Scroll down to the **Outbound Users** section and  press the **+** button to add an outbound user.

    Select the **Authentication Method** option **`None`** as authentication will be done via the API Key directly in coding.

    ![Pop Up to create New Outbound](https://raw.githubusercontent.com/sap-tutorials/abap-core-development/main/tutorials/abap-extensibility-cbo-execute-outbound-service/CS_OutboundUserPopUp.png)

8. Press **Create** to finish the outbound user creation. The pop up closes.

9. Press **Save** to finish the communication system creation.

### Create custom communication scenario for outbound service

Define the external SAP Business Accelerator Hub service as an available Communication Scenario.

1. Start typing **Custom Communication Scenario** in the Launchpad search and open the App from the results.

    ![Custom Communication Scenario application from search results](https://raw.githubusercontent.com/sap-tutorials/abap-core-development/main/tutorials/abap-extensibility-cbo-execute-outbound-service/FLP_searchResult_CCS.png)

2. Execute the action to create a **New** Custom Communication Scenario.

    A pop up opens.

3. Enter following data into the input fields and press the **New** button

    | Field Label               | Field Value                                                      |
    | :------------------------ | :--------------------------------------------------------------- |
    | Communication Scenario ID | **`SAP_TRANSLATION_HUB`** (prefix `YY1_` is added automatically) |
    | Description               | **`Scenario for SAP Translation Hub`**                           |

    ![Scenario creation pop up](https://raw.githubusercontent.com/sap-tutorials/abap-core-development/main/tutorials/abap-extensibility-cbo-execute-outbound-service/CreateCCS.png)

    The details UI for the scenario opens.

4. Switch to the **Outbound Service** section

    ![Switch to outbound services in scenario maintenance](https://raw.githubusercontent.com/sap-tutorials/abap-core-development/main/tutorials/abap-extensibility-cbo-execute-outbound-service/CCS_addOB_service.png)

5. Press **Add** to start outbound service creation. A pop up opens.

    ![Pop Up to create outbound service](https://raw.githubusercontent.com/sap-tutorials/abap-core-development/main/tutorials/abap-extensibility-cbo-execute-outbound-service/CCS_createOB_service.png)

    Enter following data into the input fields

    | Field Label         | Field Value                                                                                                       |
    | :-------------------| :---------------------------------------------------------------------------------------------------------------  |
    | Description         | **`Outbound Service for SAP Translation Hub`**                                                                    |
    | Outbound Service ID | **`OS_SAP_TRANSLATION_HUB`** (prefix `YY1_` and suffix `_REST` are added automatically)                           |
    | URL Path            | **`/swtranslation/v3/translate`** (service-specific path of the previously obtained SANBOX_URL + request path)    |

6. Press **Create** to finish the outbound service creation.

7. Another pop up opens and tells that only one instance of this communication scenario per client will be supported. Confirm with **OK**.
   Both pop ups close.

8. Press **Save**.

9. Press **Publish** to finish the custom communication scenario creation.

### Create communication arrangement for outbound service

Create a Communication Arrangement for the scenario you created, using the designated Communication System.

1. Start typing **Communication Arrangements** in the Launchpad search and open the App from the results.

    ![Custom Communication Arrangements application from search results](https://raw.githubusercontent.com/sap-tutorials/abap-core-development/main/tutorials/abap-extensibility-cbo-execute-outbound-service/FLP_searchResult_CA.png)

2. Execute the action to create a **New** Custom Communication Arrangement.

    A pop up opens.

3. **Select** or **Enter** following data.

    | Field Label      | Field Value                                       |
    | :--------------- | :------------------------------------------------ |
    | Scenario         | **`YY1_SAP_TRANSLATION_HUB`**                     |
    | Arrangement Name | **`YY1_SAP_TRANSLATION_HUB_SANDBOX_API_SAP_COM`** |

4. Press **Create**.

    ![Communication Creation Pop Up](https://raw.githubusercontent.com/sap-tutorials/abap-core-development/main/tutorials/abap-extensibility-cbo-execute-outbound-service/CA_createPopUp.png)

    The pop up closes and the Arrangement's Detail Page opens.

5. Select Communication System `SANDBOX_API_SAP_COM`

    ![Communication System Selection in Communication Arrangement](https://raw.githubusercontent.com/sap-tutorials/abap-core-development/main/tutorials/abap-extensibility-cbo-execute-outbound-service/CA_SelectSystem.png)

6. Make sure the outbound service for SAP Translation Hub is active and **Save** the Arrangement.

### Extend custom business object data structure

Add fields to persists feedback at the custom business object `Bonus Entitlement`.

1. Start typing **Custom Business Objects** in the Launchpad search and open the App from the results.

    ![Custom Business Objects application from search results](https://raw.githubusercontent.com/sap-tutorials/abap-core-development/main/tutorials/abap-extensibility-cbo-execute-outbound-service/FLP_search_resultCBO.png)

2. Open the business object `Bonus Entitlement`.

3. Start Edit Mode by executing the **Edit Draft** action.

4. Switch to **Fields** section.

5. Add following **New** fields

    | Field Label               | Field Identifier        | Field Type | Field Properties   |
    | :-------------------------| :---------------------- | :----------| :----------------- |
    | **`Feedback`**            | **`Feedback`**          | **`Text`** | Length: **`255`**  |
    | **`Feedback's language`** | **`FeedbacksLanguage`** | **`Text`** | Length: **`2`**    |
    | **`Feedback in english`** | **`FeedbackInEnglish`** | **`Text`** | Length: **`255`**  |

6. **Publish** the business object.

### Enhance custom business object logic

Now as the business object has just been published, the logic can be enhanced by the translation functionality. ABAP for key users was enhanced by the classes `CL_BLE_HTTP_CLIENT`, `CL_BLE_HTTP_REQUEST` and `CX_BLE_HTTP_EXCEPTION` to enable you to work with HTTP requests.

1. Switch to **Logic** section.

2. Enter the **After Modification** Event Logic and **Edit** the code .

    ![Enter After Modification logic](https://raw.githubusercontent.com/sap-tutorials/abap-core-development/main/tutorials/abap-extensibility-cbo-execute-outbound-service/CBO_go2AfterModify.png)

3. Create the HTTP Client

    To call an external service from within your custom business object logic, you need to create an HTTP client.

    - In the existing code, locate the IF block that checks whether `bonusentitlement-bonusplanid IS INITIAL`, and insert your logic just before the final ENDIF
  
    - Implement a check if the outbound service is available

        ```abap
        * Check if the outbound service is available
        CHECK cl_ble_http_client=>is_service_available(
            communication_scenario = 'YY1_SAP_TRANSLATION_HUB'
            outbound_service       = 'YY1_OS_SAP_TRANSLATION_HUB_REST'
        ) = abap_true.
        ```

    - Implement creation of HTTP client

        ```abap
        * Create HTTP client to access the outbound service
        DATA(lo_client) = cl_ble_http_client=>create(
            communication_scenario = 'YY1_SAP_TRANSLATION_HUB'
            outbound_service       = 'YY1_OS_SAP_TRANSLATION_HUB_REST'
        ).
        ```

4. Build the Request Body String

    Implement the creation of the Request Body.

    Since the goal is to translate any language other than English into English, the target language is set to English. The source language and the feedback to be translated are retrieved from the relevant fields of the custom business object.

    The request body in JSON format looks as follows:

   ```json
   {
       "sourceLanguage": "es",
       "targetLanguage": "en",
       "units": [
           {
               "value": "Su texto a traducir"
           }
       ]
   }
   ```

    Within the custom business object logic, the request must be provided as a string. Replace the `sourceLanguage` and `value` fields with appropriate variables. To generate the JSON string in the required format for the request body, you can use the [XCO JSON module](https://help.sap.com/docs/SAP_S4HANA_CLOUD/0f69f8fb28ac4bf48d2b57b9637e81fa/b3b824fb2b244bc0a95667567cdb9103.html?version=LATEST&locale=en-US), which is part of the Key User (KU) edition of the XCO library.

   ```abap
   * Create request body json string
   DATA(lo_json_builder) = xco_ku_json=>data->builder( ).
   lo_json_builder->begin_object(
       )->add_member( 'sourceLanguage'
           )->add_string( bonusentitlement-feedbackslanguage
       )->add_member( 'targetLanguage'
           )->add_string( 'en'
       )->add_member( 'units'
           )->begin_array(
               )->begin_object(
                   )->add_member( 'value'
                       )->add_string( bonusentitlement-feedback
               )->end_object(
           )->end_array(
   )->end_object( ).

   DATA(lv_request_body) = lo_json_builder->get_data( )->to_string( ).
   ```

5. Create the HTTP Request

    Create the HTTP request and set several properties

   ```abap
   * Creation of the HTTP request
   DATA(request) = cl_ble_http_request=>create( ).
   request->set_method( if_ble_http_request=>co_method-post
   )->set_body( lv_request_body
   )->set_header_parameter( name  = 'APIKey'
                            value = '< YOUR API KEY >'
   )->set_content_type( 'application/json; charset=utf-8' ).
   ```

6. Send the Request and Process the Response

    1. Implement sending the request by the use of the before created HTTP client and receive the response.

        ```abap
        * Send a request and receive a response.
        DATA(response) = lo_client->send( request ).
        ```

    2. Implement getting the response body from the response.

        ```abap
        * Get the body of the response.
        DATA(lv_response_body) = response->get_body( ).
        ```

    3. The response body in JSON format will look like this:

        ```json
        {
            "units": [
                {
                "key": "key_193bbaa9-a59a-4827-8e45-39d666edd003",
                "value": "Su texto a traducir",
                "translations": [
                    {
                    "language": "en",
                    "value": "Your text to translate",
                    "translationProvider": 1,
                    "qualityIndex": 25
                    }
                ]
                }
            ]
        }
        ```

    4. Implement logic to extract the translation part from the JSON string using the [XCO JSON module](https://help.sap.com/docs/SAP_S4HANA_CLOUD/0f69f8fb28ac4bf48d2b57b9637e81fa/b3b824fb2b244bc0a95667567cdb9103.html?version=LATEST&locale=en-US).

        ```abap  
        * Get translation from response
        TYPES:
            BEGIN OF ts_translation,
                language             TYPE string,
                value                TYPE string,
                translation_provider TYPE i,
                quality_index        TYPE i,
            END OF ts_translation,
            BEGIN OF ts_unit,
                key          TYPE string,
                value        TYPE string,
                translations TYPE STANDARD TABLE OF ts_translation WITH NON-UNIQUE DEFAULT KEY,
            END OF ts_unit,
            BEGIN OF ts_response,
                units TYPE STANDARD TABLE OF ts_unit WITH NON-UNIQUE DEFAULT KEY,
            END OF ts_response.
        DATA ls_response TYPE ts_response.

        xco_ku_json=>data->from_string( lv_response_body )->apply( VALUE #(
            ( xco_ku_json=>transformation->pascal_case_to_underscore )
        ) )->write_to( REF #( ls_response ) ).

        bonusentitlement-feedbackinenglish = ls_response-units[ 1 ]-translations[ 1 ]-value.
        ```

        The response of the service call is translated into a corresponding ABAP structure. With help of the built-in Camel case/Pascal case to underscore transformation the JSON data is adjusted to ABAP requirements.

    5. Implement error handling

        Consider a proper error handling by putting a TRY and CATCH block around the service call logic.

        ```abap
        TRY.

        " < CODING PARTS OF THIS STEP FROM BEFORE TO BE PLACED HERE >

         CATCH cx_ble_http_exception INTO DATA(lx).
        * The http status code can be checked.
                CASE lx->status_code.
                    WHEN 404.
        * Error handling
                    WHEN OTHERS.
        * Error handling
                ENDCASE.
        ENDTRY.
        ```

7. **Save and Publish** the After Modification logic.

### Test the application

1. Start typing **Bonus Entitlement** in the Launchpad search and open the App from the results.

    ![Bonus Entitlements application from search results](https://raw.githubusercontent.com/sap-tutorials/abap-core-development/main/tutorials/abap-extensibility-cbo-execute-outbound-service/FLP_searchResult_BonusEntitlements.png)

2. Open a `Bonus Entitlement` in **Edit** mode.

3. Enter following data

    | Field Label         | Field Value               |
    | :------------------ | :------------------------ |
    | Feedback            | **`Su texto a traducir`** |
    | Feedback's Language | **`es`**                  |

    > Please note that the language code must be entered in lower case to ensure that the service call is successful.

4. **Save** the Bonus Entitlement. The translation will get filled.

### Test yourself

