Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
karthikarjun
Active Contributor
1,340

Disclaimer: There are various methods to develop the SAP RAP program, but I've opted for a basic approach to comprehend table custom concepts and explore the fundamentals from a beginner's perspective. If you're already proficient in advanced techniques, feel free to move on and explore other content.

I) Introduction:

If you're new to this blog series, I recommend starting with PART-1 by clicking the link provided. This post is PART-2, so starting with PART-1 will help you grasp the topic better, especially since it uses story-based learning.

II) Agenda:

  1. Background Insights: Delving into the Story Behind
  2. Getting to Know SAP RAP: Understanding the SAP RAP
  3. Practical Implementation: Learning the Practical Details Step-by-Step
  4. Integration: Connecting with SAP RAP - Integration with SAP RAP using the Integration Suite - S4HC
  5. Wrapping Up: Summarizing Key Points and Looking Ahead

III) Background Insights: Delving into the Story Behind

Continue....

Sundhara Pandian, a key person at Kotravai Coffee Group in Queenstown, New Zealand wants to make sure they always have great coffee. He uses SAP S4HC to organize how they get their coffee supplies. Sundhara sets up a special table in SAP S/4HANA Cloud to keep track of orders and deliveries. This helps them manage their stock better.

He also makes things easier by using a smart SAP Fiori interface and a special kind of computer program called ABAP class. These help him handle data automatically, making it simpler to manage their coffee stock.

To make everything run even smoother, Sundhara connects with SAP's Integration Suite. This lets them talk quickly with their coffee supplier in Bremen, Germany. With this setup, they can manage orders better and always have the best coffee beans for the people of Queenstown to enjoy.

IV) Getting to Know SAP RAP: Understanding the SAP RAP

This blog outlines the process of creating a transactional SAP Fiori elements application using SAP RAP (RESTful ABAP Programming Model). SAP RAP is essential for building transactional apps, OData-based services, and extensions in ABAP Cloud.

karthikarjun_0-1716732395746.png

This guide covers creating a database table, ABAP class, and user interface, including the necessary configurations and steps to ensure seamless integration with SAP's Integration Suite. We start by defining a database table ZDTPOGRCOCKPIT to store purchase order (PO) and goods receipt (GR) data.

IV) Practical Implementation: Learning the Practical Details Step-by-Step

The following code assists in creating fields within a custom table. We can incorporate annotation methods as shown below.

 

 

 

 

 

@EndUserText.label : 'Cockpit table for PO and GR'
@AbapCatalog.enhancement.category : #EXTENSIBLE_ANY
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zdtpogrcockpit {
  key client            : abap.clnt not null;
  key purchaseorder     : ebeln not null;
  key purchaseorderitem : ebelp not null;
  poqtyunit             : meins;
  poqty2                : abap.dec(16,3);
  grqtyunit             : meins;
  grqty                 : abap.dec(16,3);
  gryear                : mjahr;
  grnumber              : mblnr;
  status                : abap.char(50);
  comments              : abap.char(50);
  created_by            : abp_creation_user;
  created_at            : abp_creation_tstmpl;
  local_last_changed_by : abp_locinst_lastchange_user;
  local_last_changed_at : abp_locinst_lastchange_tstmpl;
  last_changed_at       : abp_lastchange_tstmpl;
}

 

 

 

 

Creating the ABAP Class

Next, we create an ABAP class ZCLPOGRCOCKPIT to load data from standard SAP tables into our custom table.

Create Class to load the data from SAP table to custom table for reference.

 

 

 

 

CLASS zclpogrcockpit DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS zclpogrcockpit IMPLEMENTATION.

  METHOD if_oo_adt_classrun~main.

    DATA: lt_purchase_orders TYPE TABLE OF zdtpogrcockpit,
          ls_purchase_order  TYPE zdtpogrcockpit,
          lt_gr_data         TYPE TABLE OF i_materialdocumentitem_2,
          ls_gr_data         LIKE LINE OF lt_gr_data,
          lt_po_data         TYPE TABLE OF i_purchaseorderitemapi01,
          ls_po_data         LIKE LINE OF lt_po_data,
          group_id           TYPE string VALUE '001'.

    TRY.
        " Select GR data
        SELECT * FROM i_materialdocumentitem_2 INTO TABLE @LT_gr_data.
        IF sy-subrc <> 0 OR lines( lt_gr_data ) = 0.
          out->write( |Failed to select GR data. Table is empty or data not found.| ).
          RETURN.
        ELSE.
          out->write( |GR data successfully selected. Number of records: { lines( lt_gr_data ) }.| ).
        ENDIF.

        " Select PO data
        SELECT * FROM i_purchaseorderitemapi01 INTO TABLE @LT_po_data.
        IF sy-subrc <> 0 OR lines( lt_po_data ) = 0.
          out->write( |Failed to select PO data. Table is empty or data not found.| ).
          RETURN.
        ELSE.
          out->write( |PO data successfully selected. Number of records: { lines( lt_po_data ) }.| ).
        ENDIF.

        " Loop over purchase orders
        LOOP AT lt_po_data INTO ls_po_data.

          " Loop over GR data to find matching records
          LOOP AT lt_gr_data INTO ls_gr_data
            WHERE purchaseorder     = ls_po_data-purchaseorder
              AND purchaseorderitem = ls_po_data-purchaseorderitem.

            " Insert data into zdtpogrcockpit
            ls_purchase_order-client            = sy-mandt.
            ls_purchase_order-purchaseorder     = ls_po_data-purchaseorder.
            ls_purchase_order-purchaseorderitem = ls_po_data-purchaseorderitem.
            ls_purchase_order-poqtyunit         = ls_po_data-purchaseorderquantityunit.
            ls_purchase_order-poqty2            = ls_po_data-orderquantity.
            ls_purchase_order-grqtyunit         = ls_gr_data-entryunit.
            ls_purchase_order-grqty             = ls_gr_data-quantityinbaseunit.
            ls_purchase_order-gryear            = ls_gr_data-materialdocumentyear.
            ls_purchase_order-grnumber          = ls_gr_data-materialdocument.

            APPEND ls_purchase_order TO lt_purchase_orders.

          ENDLOOP.

        ENDLOOP.

        " Delete existing data
        DELETE FROM zdtpogrcockpit.
        IF sy-subrc <> 0.
          out->write( |Failed to delete existing data.| ).
          RETURN.
        ENDIF.

        " Remove duplicates from lt_purchase_orders
        SORT lt_purchase_orders BY client purchaseorder purchaseorderitem.
        DELETE ADJACENT DUPLICATES FROM lt_purchase_orders COMPARING client purchaseorder purchaseorderitem.

        " Insert data into database table
        INSERT zdtpogrcockpit FROM TABLE _purchase_orders.
        IF sy-subrc <> 0.
          out->write( |Failed to insert new data.| ).
          RETURN.
        ENDIF.

        COMMIT WORK.

        out->write( |[RAP001] Demo data generated for table zdtpogrcockpit { group_id }. | ).

      CATCH cx_root INTO DATA(lx_root).
        out->write( |An error occurred: | && lx_root->get_text( ) ).
        ROLLBACK WORK.
    ENDTRY.

  ENDMETHOD.

ENDCLASS.

 

 

 

 

Follow the steps below to construct the user interface for our custom table

Service Binding:

Publish the service binding to expose the data and generate the UI in the SAP Fiori Launchpad.

karthikarjun_1-1716732395756.png

The following is a set of tools in ABAP (Advanced Business Application Programming) that can improve how we define behaviors, extend metadata, and define and implement services with business logic.

karthikarjun_2-1716732395759.png

You can click the preview button below to see the user interface screen displaying the custom database fields and tables that have been created.

karthikarjun_3-1716732395761.png

Metadata Extension

Use metadata extensions to add UI labels and buttons. This enhances the user interface and user experience by providing meaningful labels and actionable buttons.

 

 

 

 

@Metadata.layer: #CORE
@UI: {
  headerInfo: {
    typeName: 'Purchase Order Cockpit',
    typeNamePlural: 'Purchase Order Cockpits'
  }
}
annotate view ZC_DTPOGRCOCKPIT with
{
  .facet: [{
    id: 'idIdentification',
    type: #IDENTIFICATION_REFERENCE,
    label: 'Purchase Order Cockpit',
    position: 10
  }]
  .lineItem: [{
    position: 10,
    importance: #MEDIUM,
    label: 'Purchase Order',
    invocationGrouping: #CHANGE_SET
  }]
  .identification: [{
    position: 10,
    label: 'Purchase Order'
  }]
  Purchaseorder;
  .lineItem: [{
    position: 20,
    importance: #MEDIUM,
    label: 'PO Item'
  }]
  .identification: [{
    position: 20,
    label: 'PO Item'
  }]
  Purchaseorderitem;
  .lineItem: [{
    position: 30,
    importance: #MEDIUM,
    label: 'PO Qty'
  }]
  .identification: [{
    position: 30,
    label: 'PO Qty'
  }]
  Poqty2;
  .lineItem: [{
    position: 40,
    importance: #MEDIUM,
    label: 'PO Qty Unit'
  }]
  .identification: [{
    position: 40,
    label: 'PO Qty Unit'
  }]
  Poqtyunit;
  .lineItem: [{
    position: 50,
    importance: #MEDIUM,
    label: 'GR Qty'
  }]
  .identification: [{
    position: 50,
    label: 'GR Qty'
  }]
  Grqty;
  .lineItem: [{
    position: 60,
    importance: #MEDIUM,
    label: 'GR Qty Unit'
  }]
  .identification: [{
    position: 60,
    label: 'GR Qty Unit'
  }]
  Grqtyunit;
  .lineItem: [{
    position: 70,
    importance: #MEDIUM,
    label: 'GR Year'
  }]
  .identification: [{
    position: 70,
    label: 'GR Year'
  }]
  Gryear;
  .lineItem: [{
    position: 80,
    importance: #MEDIUM,
    label: 'GR Number'
  }]
  .identification: [{
    position: 80,
    label: 'GR Number'
  }]
  Grnumber;
  .lineItem: [{
    position: 90,
    importance: #MEDIUM,
    label: 'Status'
  }]
  .identification: [{
    position: 90,
    label: 'Status'
  }]
  Status;
  .lineItem: [{
    position: 100,
    importance: #MEDIUM,
    label: 'Comments'
  }]
  .identification: [{
    position: 100,
    label: 'Comments'
  }]
  Comments;
  // Annotation for the custom Submit action
  .lineItem: [{
    position: 110,
    type: #FOR_ACTION,
    dataAction: 'Submit',
    label: 'Send to GR-Automation System'
  }]
  .hidden: true
  LocalLastChangedAt;
}

 

 

 

 

Here is the user interface view following the metadata extension. Utilize metadata extension to incorporate UI labels and buttons, considered best practice for enhancing user interface and button functionalities.

Generated UI:

karthikarjun_0-1716776799502.png

Implementing Actions in the RAP

Creating Actions for Submit Button

Define the necessary actions in the CDS view and annotate them in the metadata. Implement the actions in the ABAP behavior definition, ensuring that the button appearance and behavior are customized in the Fiori Elements UI.

Here are the auto generated objects. You can modify the code with the highlighted portions as follows:

Program: ZR_DTPOGRCOCKPIT

karthikarjun_5-1716732395772.png

Program: ZC_DTPOGRCOCKPIT

karthikarjun_6-1716732395775.png

To include the feature and instance in the ZR_DTPOGRCOCKPIT with the specified item to retrieve the instance keys in the ABAP class, you can use the following code:

karthikarjun_7-1716732395780.png

  • Specify the action in your CDS view: Describe what action you want to perform within your CDS view.
  • Provide annotations for the action in your metadata: Add additional information about the action in the metadata.
  • Add the action logic in your ABAP behavior definition: Implement the action's functionality within your ABAP behavior definition.
  • Customize the appearance and behavior of the button in the Fiori Elements UI if needed: Optionally, modify how the button looks and behaves in the Fiori Elements user interface.

Create actions implementation to the submit button:

You can utilize the provided class below to implement the submit actions triggered from the UI button: The class has enhanced in the behavior implementation.

Global class:

 

 

 

 

CLASS ZBP_R_DTPOGRCOCKPIT DEFINITION PUBLIC ABSTRACT FINAL FOR BEHAVIOR OF ZR_DTPOGRCOCKPIT.

ENDCLASS.

CLASS ZBP_R_DTPOGRCOCKPIT IMPLEMENTATION.
ENDCLASS.

 

 

 

 

Local Types:

 

 

 

 

CLASS lhc_zr_dtpogrcockpit DEFINITION INHERITING FROM cl_abap_behavior_handler.
  PRIVATE SECTION.
    METHODS global_authorization FOR GLOBAL AUTHORIZATION
      IMPORTING REQUEST requested_authorizations FOR zr_dtpogrcockpit RESULT result.
    METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION
      IMPORTING keys REQUEST requested_authorizations FOR zr_dtpogrcockpit RESULT result.
    METHODS get_instance_features FOR INSTANCE FEATURES
      IMPORTING keys REQUEST requested_features FOR zr_dtpogrcockpit RESULT result.
    METHODS submit FOR MODIFY IMPORTING keys FOR ACTION zr_dtpogrcockpit~Submit RESULT result.
ENDCLASS.

CLASS lhc_zr_dtpogrcockpit IMPLEMENTATION.

  METHOD global_authorization.
  ENDMETHOD.

  METHOD get_instance_authorizations.
  ENDMETHOD.

  METHOD get_instance_features.
  ENDMETHOD.

  METHOD submit.
  " Get the keys from the request
  data(lv_keys) = keys.

  TRY.
      " Create HTTP client using destination
      DATA(lo_destination) = cl_http_destination_provider=>create_by_comm_arrangement(
                                 comm_scenario  = 'YY1_DEMO_POGR_COM'
                                 service_id     = 'YY1_DEMO_POGR_SUBMIT_REST'
                               ).

        DATA(lo_http_client) = cl_web_http_client_manager=>create_by_http_destination( i_destination = lo_destination ).
        DATA(lo_request) = lo_http_client->get_http_request( ).
        DATA(lv_json) = /ui2/cl_json=>serialize( lv_keys ).
        lo_request->set_text( lv_json ).
        lo_request->set_header_field( i_name = 'Content-Type' i_value = 'application/json; charset=UTF-8' ).
***** POST message
        DATA(post_response) = lo_http_client->execute( if_web_http_client=>post )->get_text(  ).
        lo_http_client->close(  ).
    CATCH cx_root INTO DATA(lx_exception).
      " Handle exceptions
      RETURN.
  ENDTRY.
ENDMETHOD.
ENDCLASS.

 

 

 

 

Here we have implemented the class and define the basic class for the action items to be get performed in the SAP RAP

VI) Integration: Connecting with SAP RAP - Integration with SAP RAP using the Integration Suite - S4HC

To establish a connection with the Integration Suite, set up the required communication arrangements and scenarios within the S4HC system. This facilitates connecting to the Integration Suite server securely through a tunnel.

Communication Scenario

  • Go to Custom Communication Scenarios application.
  • Enter the Scenario ID: DEMO_POGR_COM.
  • Create the Communication Scenario by adding an outbound service ID and providing the suffix path for the Integration Suite API.
  • Publish the custom arrangements.

To utilize the Integration Suite API, you'll need to create a communication arrangement and a custom scenario with the following names, for instance:

  • Communication Scenario: 'YY1_DEMO_POGR_COM'
  • Service ID: 'YY1_DEMO_POGR_SUBMIT_REST'

karthikarjun_8-1716732395788.png

Please enter the Scenario ID as 'DEMO_POGR_COM' and click on 'New' to create the Communication Scenario.

karthikarjun_9-1716732395794.png

  • Click the "Add" button.
  • Enter the outbound service ID.
  • Provide the suffix path for the Integration Suite API.

After setting up the communication scenario and completing the necessary configurations, click the "Publish" button to publish the custom arrangements. Now, navigate to the Communication Arrangement application.

karthikarjun_10-1716732395798.png

Communication Arrangement

  • Go to the Communication Arrangement application.
  • Create a communication system for the Integration Suite.
  • Enter the Integration Suite runtime URL and credentials.
  • Configure the service bindings to enable communication between the S4HC system and the Integration Suite.

karthikarjun_11-1716732395805.png

To create the communication system for Integration Suite and establish the tunnel connection, follow these steps:

  • Go to the Communication System application.
  • Add the required details for the Integration Suite communication system.

karthikarjun_12-1716732395820.png

Please provide the Integration Suite runtime URL and password as instructed.

karthikarjun_13-1716732395827.png

karthikarjun_14-1716732395836.png

Enter the credentials and settings for the communication arrangement to establish a connection between the Integration Suite server and the S4HC system. Next, configure the service bindings to enable communication between the systems.

karthikarjun_15-1716732395861.png

Currently, please refer to the screenshot provided for testing the connection to the Integration Suite server. We'll delve into further details about Integration Suite in Part 4.

karthikarjun_16-1716732395865.png

Testing the Connection

  • Select a record from the S4HC – POGR cockpit.
  • Click the send button to initiate the process.
  • Monitor the Integration Suite to verify the results.

Choose the record from the S4HC POGR cockpit and then click the "Send" button to initiate the action.

karthikarjun_2-1716734230973.png

After clicking this button, navigate to Integration Suite and click on the "Monitor" tile to view the results as indicated below.

karthikarjun_18-1716732395873.png

The finalized appearance of the SAP RAP program in Eclipse entails is as below:

karthikarjun_19-1716732395879.png

VII) Wrapping Up: Summarizing Key Points and Looking Ahead

  1. Understanding Systems and Landscapes: Delve into foundational knowledge through a narrative-driven approach.
  2. Mastering Full-Stack Development: Learn fundamental concepts using illustrative diagrams.
  3. Configuring Eclipse for SAP ADT: Set up Eclipse and establish connectivity with the S/4 HANA Public Cloud system.
  4. Navigating Integration: Explore the intricacies of connecting different systems and optimizing data exchange for seamless integration.

Part 3: Coming soon - Embark on an exploration of AI and ML with our forthcoming model, complete with a custom dashboard.

Part 4: Coming soon - Learn how to connect the circuit using Integration Suite in our upcoming installment.

Author: If you find this information helpful, please consider clicking the "Like" button on this blog and sharing your thoughts in the comments section below. You can also connect with the author on their LinkedIn profile: [Author's LinkedIn Profile]

3 Comments
BTKelly
Product and Topic Expert
Product and Topic Expert
0 Kudos

your class load method has some cut n paste issue.  have a look at your SELECT statement.  the into table need to have @LT_xxxx in general.

BTKelly_0-1716928687612.png

 

karthikarjun
Active Contributor
0 Kudos

Hi  BTKelly - Good catch. Thanks for pointing it out. I've updated it. However, I noticed two things in the community code section.

I copied the code from MS-Word to the community code section (insert/edit code sample) as shown below. When I type "@ lt," it automatically changes "lt" to uppercase "LT." But when I copy the entire code from MS-Word to the code sample box, it ignores "@ lt" completely. You can try it yourself. This suggests that "@" might be treated as a special character in the community code blog. It could be a minor bug. That's why when I copy the entire code, the code section ignores "@ lt" in the SAP community.

karthikarjun_0-1716968790633.png

Steps to replicate: BTKelly

Step-1: Manually update instead of copying and pasting from MS Word.

karthikarjun_0-1716970327720.png

 

Step-2: Click ok

karthikarjun_1-1716970327727.png

 

Step-3: Click save and post the blog. It will automatically convert text from lower case to upper case

karthikarjun_2-1716970327733.png

Step-4: Go to the blog after posting and edit the content. Click the "Insert/Edit Code Sample" button. The content will be automatically deleted. If you post now without noticing, this issue will persist

karthikarjun_3-1716970327740.png

Cheers,

Karthik A

 

AbhishekSharma
Active Contributor
0 Kudos

Hi @karthikarjun very nice and Informative blog post... Many thanks for sharing...

Thanks-

Labels in this area