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:
- Background Insights: Delving into the Story Behind
- Getting to Know SAP RAP: Understanding the SAP RAP
- Practical Implementation: Learning the Practical Details Step-by-Step
- Integration: Connecting with SAP RAP - Integration with SAP RAP using the Integration Suite - S4HC
- Wrapping Up: Summarizing Key Points and Looking Ahead
III) Background Insights: Delving into the Story Behind
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.
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.
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.
You can click the preview button below to see the user interface screen displaying the custom database fields and tables that have been created.
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:
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
Program: ZC_DTPOGRCOCKPIT
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:
- 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'
Please enter the Scenario ID as 'DEMO_POGR_COM' and click on 'New' to create the Communication Scenario.
- 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.
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.
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.
Please provide the Integration Suite runtime URL and password as instructed.
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.
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.
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.
After clicking this button, navigate to Integration Suite and click on the "Monitor" tile to view the results as indicated below.
The finalized appearance of the SAP RAP program in Eclipse entails is as below:
VII) Wrapping Up: Summarizing Key Points and Looking Ahead
- Understanding Systems and Landscapes: Delve into foundational knowledge through a narrative-driven approach.
- Mastering Full-Stack Development: Learn fundamental concepts using illustrative diagrams.
- Configuring Eclipse for SAP ADT: Set up Eclipse and establish connectivity with the S/4 HANA Public Cloud system.
- Navigating Integration: Explore the intricacies of connecting different systems and optimizing data exchange for seamless integration.
No comments:
Post a Comment