cancel
Showing results for 
Search instead for 
Did you mean: 

How to Develop an OData Service: CURD operations, Paging, Sorting, Filtering, and Create_Deep_Entity

vamsi-3333
Discoverer
2,132

Unlock the potential of SAP OData with our comprehensive guide. From basic principles to advanced CRUD operations, we provide practical insights and code snippets. Follow along as we demystify the complexities, supported by clear, illustrative screenshots. Elevate your SAP development skills and streamline data management with confidence.

In my case i want to perform CURD operation on my custom table using OData API.
table : 

vamsi3333_0-1717564225970.png

Creating Project:
Go to SEGW -> Create Project -> Enter Project name and description -> Select package -> Finish.

Creating Entity: After creating the project, there are four components available:

  1. Data Model: Deals with entities, navigations, and associations.
  2. Service Implementation.
  3. Runtime Artifacts: Contains all related classes generated after creating runtime objects.
  4. Service Maintenance.

We can create entities in multiple ways: using BAPI, DDIC table, or manual creation. For CRUD operations on a custom table, I'll utilize a DDIC table to create the entity.

Right click on Data Model -> import -> data structure -> give entity name - > give table name in ABAP Structure -> select fields which you want to export data -> select key fields -> Finish.

vamsi3333_1-1717564927686.png

After all generate the runtime artifacts.

then we are able to see all the DPC, MPC, DPC_EXT, and MPC_EXT classes.
Here i am using DPC_EXT to implement CURD operations.

For CRUD operations in SAP OData, we utilize specific methods:

  • For creating new entries, we use the method CREATE_ENTITY.
  • To delete existing entries, the method DELETE_ENTITY is employed.
  • Reading data involves two methods: GET_ENTITY for fetching single records and GET_ENTITYSET for retrieving multiple records.
  • Finally, to update existing entries, we use the method UPDATE_ENTITY.

These methods serve as the fundamental building blocks for performing CRUD operations on data within SAP OData services.

 

  1. Get_Entity: Beginning with Fetching a Single Record

The Get_Entity operation serves to retrieve individual records from the database tables. It employs the it_key_tab parameter to capture the input passed through the URL. By utilizing this parameter, we can extract the relevant data from the tables. Subsequently, this data is then sent back as a response by populating the er_entity variable. This process enables us to effectively fetch and present single records from the database, facilitating seamless data retrieval in SAP OData.


Here is the sample URL :  

 

 

 

/sap/opu/odata/sap/ZEMP_HEADER_SRV/ZEMP_HEADERSet('9119')

 

 

 


in my case have only one key field so i am passing parameter directly without specifying the field name.

code Snippet for GET_ENTITY :

we need to redefine the method first.

right click on GET_ENTITY -> Redefine.

 

 

 

METHOD ZEMP_HEADERSET_GET_ENTITY.

"""* Declare variables for message handling
  DATA:
    LV_MSGV1             TYPE SYMSGV,
    LO_MSG               TYPE REF TO /IWBEP/IF_MESSAGE_CONTAINER,
    LO_MESSAGE_CONTAINER TYPE REF TO /IWBEP/IF_MESSAGE_CONTAINER,
    LT_MSG_TYPES         TYPE TABLE OF CHAR1.

"""* Extract the value of 'EmpId' from the input key table
"""we are using it_key_tab to url parameter's
  DATA(LV_EMPID) = VALUE #( IT_KEY_TAB[ NAME = 'EmpId' ]-VALUE OPTIONAL ).
  LV_MSGV1 = LV_EMPID.

"""* Retrieve the entity from the custom table based on the EmpId provided
""" and seting into responce "ER_ENTITY"
  SELECT SINGLE * FROM ZEMP_HEADER INTO @ER_ENTITY WHERE EMP_ID = _EMPID.

* If the entity is found and retrieved successfully
  IF SY-SUBRC = 0 AND ER_ENTITY IS NOT INITIAL.
    LV_MSGV1 = ER_ENTITY-EMP_ID.

* Add a success message to the response message container
    CALL METHOD ME->/IWBEP/IF_MGW_CONV_SRV_RUNTIME~GET_MESSAGE_CONTAINER
      RECEIVING
        RO_MESSAGE_CONTAINER = LO_MESSAGE_CONTAINER.
    LO_MESSAGE_CONTAINER = ME->MO_CONTEXT->GET_MESSAGE_CONTAINER( ).
    LO_MESSAGE_CONTAINER->ADD_MESSAGE(
      EXPORTING
        IV_MSG_TYPE = 'S'
        IV_MSG_ID = 'ZEMP_DETAILS'
        IV_MSG_NUMBER = '007'
        IV_MSG_V1 = LV_MSGV1
        IV_IS_LEADING_MESSAGE = ABAP_TRUE
        IV_ADD_TO_RESPONSE_HEADER = ABAP_TRUE
    ).
* Append success message type to the list of message types
    APPEND /IWBEP/IF_MESSAGE_CONTAINER=>GCS_MESSAGE_TYPE-SUCCESS TO LT_MSG_TYPES.

* If entity retrieval fails
  ELSE.
    CALL METHOD ME->/IWBEP/IF_MGW_CONV_SRV_RUNTIME~GET_MESSAGE_CONTAINER
      RECEIVING
        RO_MESSAGE_CONTAINER = LO_MSG.
    CALL METHOD LO_MSG->ADD_MESSAGE
      EXPORTING
        IV_MSG_TYPE   = /IWBEP/CL_COS_LOGGER=>ERROR " Message Type
        IV_MSG_V1     = LV_MSGV1
        IV_MSG_ID     = 'ZEMP_DETAILS'   " Message Class
        IV_MSG_NUMBER = '008'.  " Message Number – Enter EmpId
    RAISE EXCEPTION TYPE /IWBEP/CX_MGW_BUSI_EXCEPTION
      EXPORTING
        MESSAGE_CONTAINER = LO_MSG.
  ENDIF.

ENDMETHOD.

 

 

 

Output : 

GET_ENTITYGET_ENTITY

Success Message :

Success_MessageSuccess_Message

Error Message :

Error_ContainerError_Container

 

2. GET_ENTITYSET: Utilized for Fetching Multiple Records

The GET_ENTITYSET method is employed to retrieve multiple records from the tables. It serves as a powerful tool allowing for operations such as filtering, sorting, paging, and more through the URL parameters. With GET_ENTITYSET, developers can efficiently manage and manipulate large datasets, ensuring optimal performance and usability within SAP OData services.

Example URL : /sap/opu/odata/sap/YOUR_SRV/YourEntitySet?$format=json

Get_Entity_SetGet_Entity_Set

For the GET_ENTITYSET method, various options are available to manipulate the data retrieved:

1. **Filtering**: This is achieved using the $filter parameter in the URL. It allows developers to specify conditions to filter the data.

2. **Paging**:
- **Server-Side Paging**: Utilizes the $skiptocken query for efficient server-side paging.
- **Client-Side Paging**: Employs $top and $skip parameters to control the number of records returned and to skip over a specified number of records, respectively.

3. **Sorting**: The $orderby parameter enables sorting of the retrieved data based on specified fields.

4. **Select with GET Call**: The $select parameter allows developers to specify which fields they want to retrieve in the response.

5. **Search**: Enables searching for specific values within the dataset.

When filtering data with GET calls, the syntax typically follows this pattern: $filter=<field name> <filter operation> <value>.

There are two main ways to extract the filter parameter, operation, and value from the URI:

1.1 . **Lv_filter_string**: This variable holds the filter condition in the format <field name> <filter operation> <value>. For example, if the entity field name is EmpId and the condition is EmpId eq '9110', lv_filter_string will contain 'EmpId eq 9110'.

1.2.  **Io_tech_request_context**: This is a technical request context object that can be used to extract filter parameters programmatically.

It's important to note that if the entity field name matches the table field name, the filter condition can be directly applied using the entity field name (e.g., EmpId). However, if they differ, the filter condition should use the table field name (e.g., Emp_Id) within lv_filter_string to ensure correct filtering.

Code Snippet for LV_FILTER_STRING :

 

 

 

select * from zemp_header into TABLE _entityset WHERE (IV_FILTER_STRING).

 

 

 

Code Snippet for  Io_tech_request_context:

 

 

 

    DATA(LV_FILTER) = IO_TECH_REQUEST_CONTEXT->GET_FILTER( )->GET_FILTER_STRING( ).
    IF LV_FILTER IS NOT INITIAL.
      SELECT * FROM Zemp_header INTO TABLE _ENTITYSET WHERE (LV_FILTER) ORDER BY EMP_ID.
    ELSE.
      SELECT * FROM ZEMP_HEADER INTO TABLE _ENTITYSET ORDER BY EMP_ID.
    ENDIF.

 

 

 

Recommended is Io_tech_request_context…

1.3 Filter Operators:
Filter operators such as 'eq' (equal), 'ne' (not equal), 'gt' (greater than), 'lt' (less than), 'le' (less than or equal to), and 'ge' (greater than or equal to) allow for precise data filtering in OData queries. The syntax for filtering is as follows:

 

 

 

/sap/opu/odata/sap/ZEMP_HEADER_SRV/ZEMP_HEADERSet?$filter=field1 eq 'value ' and field2 eq 'value '.

 

 

 

When filtering dates, the 'datetime' prefix is used to specify the date format:

 

 

 

/sap/opu/odata/sap/ZEMP_HEADER_SRV/ZEMP_HEADERSet?$filter=field1 eq datetime'value'.

 

 

 

 2.1: Paging: ($top, $skip, $skiptoken, $inlinecount):

- $count:
For obtaining the count of records without displaying the records themselves, the $count parameter is utilized. No additional code implementation is required. Example URI:

 

 

 

/sap/opu/odata/sap/ZEMP_HEADER_SRV/ZEMP_HEADERSet/$count

 

 

 

$count$count

$count is particularly useful when only the count of records is required without fetching the actual data.

- $inlinecount:
To display the count along with the records, the $inlinecount parameter is used. Code implementation is required to retrieve the count. Syntax: $inlinecount=allpages. Example URI:

 

 

 

/sap/opu/odata/sap/ZEMP_HEADER_SRV/ZEMP_HEADERSet?$inlinecount=allpages&$format=json

 

 

 

In the code, if inlinecount is requested, the count of records is calculated and included in the response.

 

 

 

IF IO_TECH_REQUEST_CONTEXT->HAS_INLINECOUNT( ) = ABAP_TRUE.
      ES_RESPONSE_CONTEXT-INLINECOUNT = LINES( ET_ENTITYSET ).
    ENDIF.

 

 

 

$inLineCount$inLineCount

2.2 Paging:
- $skip:
Used to skip a specified number of records.
- $top:
Used to select a specified number of top records.
Code snippet:

 

 

 

CALL METHOD /IWBEP/CL_MGW_DATA_UTIL=>PAGING
  EXPORTING
    IS_PAGING = IS_PAGING             "paging structure
  CHANGING
    CT_DATA   = ET_ENTITYSET.

 

 

 

This code snippet retrieves the top records or skips a specified number of records based on the parameters provided.

Example URL: 

 

 

 

/sap/opu/odata/sap/ZEMP_HEADER_SRV/ZEMP_HEADERSet?$skip=2&$format=json

 

 

 

the above URL used to skip first 2 records.

If we use $skip and $top both together..
First skip works then top works…

- Ordering ($orderby):
Used to sort the ET_ENTITYSET based on a field by ascending or descending order.
Code snippet:

 

 

 

****************Sorting using CL_MGW_DATA_UTIL=>ORDERBY
****************Converting Entity Field name to Table Field Name
DATA: LT_ORDER TYPE /IWBEP/T_MGW_SORTING_ORDER.

IF NOT IT_ORDER IS INITIAL.
  LOOP AT IT_ORDER INTO DATA(LS_ORDER).
    LOOP AT LT_ORDERBY INTO DATA(LS_ORDERBY).

      LS_ORDER-PROPERTY = LS_ORDERBY-PROPERTY_PATH.
      LS_ORDER-ORDER = LS_ORDERBY-ORDER.
      APPEND LS_ORDER TO LT_ORDER.
    ENDLOOP.
  ENDLOOP.
****************Converting Entity Field name to Table Field Name
  CALL METHOD /IWBEP/CL_MGW_DATA_UTIL=>ORDERBY
    EXPORTING
      IT_ORDER = LT_ORDER          "the sorting order
    CHANGING
      CT_DATA  = ET_ENTITYSET.
ENDIF.

 

 

 

URL : 

 

 

 

/sap/opu/odata/sap/ZEMP_HEADER_SRV/ZEMP_HEADERSet?$orderby=allpagesEmpId desc&$format=json

 

 

 

$orderBy$orderBy

This code snippet sorts the entity set based on the specified sorting order provided in IT_ORDER. It's essential to convert the entity field names to table field names before sorting.

4. $Select:
The $select parameter allows developers to specify which fields they want to retrieve in the response. This parameter is used to select only the desired fields from the dataset. For example, if there are 20 fields available but only 4 are needed for display, $select can be utilized. By default, if not specified, all fields will be returned.

By default I'm getting 4 fields.

Without $select getting 4 four fieldsWithout $select getting 4 four fields

But I need only two fields to sent :

URL:

 

 

 

/sap/opu/odata/sap/ZEMP_HEADER_SRV/ZEMP_HEADERSet?$select=EmpId,EmpName&$format=json

 

 

 

$select$select

 

Code Snippet for GET_ENTITYSET:

 

 

 

METHOD ZEMP_HEADERSET_GET_ENTITYSET.

  DATA(LT_ORDERBY) = IO_TECH_REQUEST_CONTEXT->GET_ORDERBY( ).

* Filter using IV_FILTER_STRING
* IF IV_FILTER_STRING is NOT INITIAL.
*    select * from zemp_header into TABLE _entityset WHERE (IV_FILTER_STRING).
* ELSE.

  " Filter using IO_TECH_REQUEST_CONTEXT
  DATA(LV_FILTER) = IO_TECH_REQUEST_CONTEXT->GET_FILTER( )->GET_FILTER_STRING( ).
  IF LV_FILTER IS NOT INITIAL.
    SELECT * FROM Zemp_header INTO TABLE _ENTITYSET WHERE (LV_FILTER) ORDER BY EMP_ID.
  ELSE.
    SELECT * FROM ZEMP_HEADER INTO TABLE _ENTITYSET ORDER BY EMP_ID.
  ENDIF.

* Inline Count using io_tech_request_context
  IF IO_TECH_REQUEST_CONTEXT->HAS_INLINECOUNT( ) = ABAP_TRUE.
    ES_RESPONSE_CONTEXT-INLINECOUNT = LINES( ET_ENTITYSET ).
  ENDIF.

  " Sort and Skip using one way
  DATA: LT_ENTITYSET  TYPE ZCL_ZEMP_HEADER_MPC=>TT_ZEMP_HEADER,
        LS_ENTITY     LIKE LINE OF LT_ENTITYSET,
        LV_TABLE_SIZE TYPE I.
  DATA: LV_TOP  TYPE INT4,
        LV_SKIP TYPE INT4,
        LV_MAX  TYPE INT4.
  LV_TOP = IS_PAGING-TOP.
  LV_SKIP = IS_PAGING-SKIP.
  LV_MAX = LV_TOP + LV_SKIP.

*   IF lv_top IS NOT INITIAL OR
*    lv_skip IS NOT INITIAL.
*   LOOP AT lt_entityset INTO ls_entity.
**     IF sy-tabix > lv_skip.
*       APPEND ls_entity TO et_entityset.
*       DESCRIBE TABLE et_entityset LINES lv_table_size.
*       IF lv_top IS NOT INITIAL AND
*          lv_table_size >= lv_top.
*         EXIT.
*       ENDIF.
**     ENDIF.
*   ENDLOOP.
  " No Paging
* ELSE.
*   et_entityset = lt_entityset.
* ENDIF.

* IF lv_top IS NOT INITIAL OR
*    lv_skip IS NOT INITIAL.
*    Delete lt_entityset from 0 to lv_skip.
*    et_entityset = lt_entityset.
*   " No Paging
* ELSE.
*   et_entityset = lt_entityset.
* ENDIF.

  " Sort and Skip using cl_mgw_data_util
  CALL METHOD /IWBEP/CL_MGW_DATA_UTIL=>PAGING
    EXPORTING
      IS_PAGING = IS_PAGING             " paging structure
    CHANGING
      CT_DATA   = ET_ENTITYSET.

  " Sorting using CL_MGW_DATA_UTIL=>ORDERBY

  " Convert Entity Field name to Table Field Name
  DATA: LT_ORDER TYPE /IWBEP/T_MGW_SORTING_ORDER.

  IF NOT IT_ORDER IS INITIAL.
    LOOP AT IT_ORDER INTO DATA(LS_ORDER).
      LOOP AT LT_ORDERBY INTO DATA(LS_ORDERBY).

        LS_ORDER-PROPERTY = LS_ORDERBY-PROPERTY_PATH.
        LS_ORDER-ORDER = LS_ORDERBY-ORDER.
        APPEND LS_ORDER TO LT_ORDER.
      ENDLOOP.
    ENDLOOP.

  " Convert Entity Field name to Table Field Name and apply sorting
    CALL METHOD /IWBEP/CL_MGW_DATA_UTIL=>ORDERBY
      EXPORTING
        IT_ORDER = LT_ORDER          " the sorting order
      CHANGING
        CT_DATA  = ET_ENTITYSET.
  ENDIF.

ENDMETHOD.

 

 

 

 

2) Create_Entity : (Post)

Create_Entity (Post):

The Create_Entity operation, also known as POST Method, is used to create new records in tables via API. Data is typically passed through the request in either XML or JSON format. Upon receiving the data, it is accessed using the io_data_provider.

If the data insertion is successful, a success message is passed to the response. Otherwise, an error message is returned.

In summary, Create_Entity allows for the creation of new records in tables through API requests, handling both successful and unsuccessful data insertion scenarios.

Code snippet:

 

 

 

METHOD zemp_headerset_create_entity.
  " Declare variables
  DATA: ls_entity TYPE zcl_zodata_kv_demo_mpc=>ts_emp_header,
        lv_msgv1  TYPE symsgv,
        lo_msg TYPE REF TO /iwbep/if_message_container,
        lo_message_container TYPE REF TO /iwbep/if_message_container,
        lt_msg_types TYPE TABLE OF char1.

  " Read entry data from the data provider
  io_data_provider->read_entry_data(
    IMPORTING
      es_data = ls_entity
  ).
  
  " Retrieve the value of 'emp_id' from the created entity for messaging
  lv_msgv1 = ls_entity-emp_id.
  
  " Insert the entity into the zemp_header table
  INSERT zemp_header FROM ls_entity.
  
  " If insertion is successful, populate the response entity and add success message
  IF sy-subrc = 0.
    er_entity = ls_entity.
    CALL METHOD me->/iwbep/if_mgw_conv_srv_runtime~get_message_container
    RECEIVING
      ro_message_container = lo_message_container.
    lo_message_container = me->mo_context->get_message_container( ).
    lo_message_container->add_message(
      EXPORTING
        iv_msg_type = 'S'
        iv_msg_id = 'ZEMP_DETAILS'
        iv_msg_number = '000'
        iv_msg_v1 = lv_msgv1
        iv_is_leading_message = abap_true
        iv_add_to_response_header = abap_true
    ).
    " Append success message type to the list of message types
    APPEND /iwbep/if_message_container=>gcs_message_type-success TO lt_msg_types.
    
  " If insertion fails, add error message to response
  ELSE.
    CALL METHOD me->/iwbep/if_mgw_conv_srv_runtime~get_message_container
      RECEIVING
        ro_message_container = lo_msg.
    CALL METHOD lo_msg->add_message
      EXPORTING
        iv_msg_type   = /iwbep/cl_cos_logger=>error " Message Type
        iv_msg_v1     = lv_msgv1
        iv_msg_id     = 'ZEMP_DETAILS'   " Message Class
        iv_msg_number = '001'.  " Message Number – Enter EmpId
    RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
      EXPORTING
        message_container = lo_msg.
  ENDIF.
ENDMETHOD.

 

 

 

We have to use POST method to post the data.

Create_EntityCreate_Entity

Message container..

Success Message of Create_entitySuccess Message of Create_entity

3) UPDATE_ENTITY:

For updating records we have three options put, patch and merge..
Patch and Merge are same…
Diff B/W Put and Patch/Merge

PUT:

  • Requires passing values for all fields in the record.
  • Directly executes the method based on the provided key field.
  • Key field must be explicitly passed in the request.

PATCH/MERGE:

  • Only requires passing the fields that need to be updated, not all fields.
  • Checks if the key field provided in the request matches an existing record in the table before executing the method.
  • If the record with the provided key field exists in the table, the method is executed; otherwise, it is not executed.

UPDATE_ENTITY Code snippet :

 

 

 

METHOD zemp_headerset_update_entity.
  " Declare variables
  DATA:
        lv_msgv1  TYPE symsgv,
        lo_msg TYPE REF TO /iwbep/if_message_container,
        lo_message_container TYPE REF TO /iwbep/if_message_container,
        lt_msg_types TYPE TABLE OF char1.
  DATA : ls_input TYPE zcl_zodata_kv_demo_mpc=>ts_emp_header.

  " Read entry data from the data provider
  io_data_provider->read_entry_data(
    IMPORTING
      es_data = ls_input
  ).
  
  " Retrieve the value of 'emp_id' from the input data for messaging
  lv_msgv1 = ls_input-emp_id.
  
  " Modify the zemp_header table with the input data
  MODIFY zemp_header FROM ls_input.

  " If modification is successful, populate the response entity and add a success message
  IF sy-subrc = 0.
    er_entity = ls_input.
    CALL METHOD me->/iwbep/if_mgw_conv_srv_runtime~get_message_container
    RECEIVING
      ro_message_container = lo_message_container.
    lo_message_container = me->mo_context->get_message_container( ).
    CALL METHOD lo_message_container->add_message
    EXPORTING
      iv_msg_type               = /iwbep/cl_cos_logger=>SUCCESS
      iv_msg_id                 = 'ZEMP_DETAILS'
      iv_msg_number             = '000'
      iv_add_to_response_header = abap_true. "add the message to the header
    lo_message_container = me->mo_context->get_message_container( ).
    lo_message_container->add_message(
      EXPORTING
        iv_msg_type = 'S'
        iv_msg_id = 'ZEMP_DETAILS'
        iv_msg_number = '003'
        iv_msg_v1 = lv_msgv1
        iv_is_leading_message = abap_true
        iv_add_to_response_header = abap_true
    ).
    " Append success message type to the list of message types
    APPEND /iwbep/if_message_container=>gcs_message_type-success TO lt_msg_types.
    
  " If modification fails, add an error message to the response
  ELSE.
    CALL METHOD me->/iwbep/if_mgw_conv_srv_runtime~get_message_container
      RECEIVING
        ro_message_container = lo_msg.
    CALL METHOD lo_msg->add_message
      EXPORTING
        iv_msg_type   = /iwbep/cl_cos_logger=>error " Message Type
        iv_msg_v1     = lv_msgv1
        iv_msg_id     = 'ZEMP_DETAILS'   " Message Class
        iv_msg_number = '004'.  " Message Number – Enter EmpId
    RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
      EXPORTING
        message_container = lo_msg.
  ENDIF.
ENDMETHOD.

 

 

 

Create Deep Entity

To create a Deep Entity in SAP OData service, follow these steps:

in this scenario i used two entities;

 

vamsi3333_5-1717577264161.png

Created on association between them with 1..N cardinality.

vamsi3333_6-1717577489074.png

vamsi3333_7-1717577575225.png

Right Click on Association -> Create -> Give association name(any Zname) -> Principle Entity Type(Select Header Entity) -> Principle cardinality -> Dependent entity type(Select Item entity) -> give dependent cardinality -> check create related navigation property -> Give navigation property for Principle if you want for dependent too.

Step 1: Define Local Types for Deep Entity Structure

Define local types to structure the data for the deep entity creation. This includes both Header and Items entities.

ZCL_MPC_EXT -> Types -> Create Type

vamsi3333_4-1717577150345.png

 

 

 

class ZCL_ZEMP_HDR_ITEM_MPC_EXT definition
  public
  inheriting from ZCL_ZEMP_HDR_ITEM_MPC
  create public .

public section.

  types:
    BEGIN OF TS_DEEP_ENTITY,
           EMP_ID        TYPE HREMPID,
           EMP_NAME      TYPE P08_NAM50,
           EMP_MAIL      TYPE AD_SMTPADR,
           EMP_PHONE     TYPE ZDE_PNO,
           CREATEDBY     TYPE SY-UNAME,
           CREATEDAT     TYPE TIMESTAMP,
           LASTCHANGEDBY TYPE SY-UNAME,
           LASTCHANGEDAT TYPE TIMESTAMP,
           ZEMP_ITEM     TYPE STANDARD TABLE OF ZEMP_DETAILS WITH DEFAULT KEY,
         END OF TS_DEEP_ENTITY .

  methods DEFINE
    redefinition .

 

 

 

 

Step 2: Redefine the DEFINE Method in MPC_EXT

In the MPC_EXT class, redefine the DEFINE method to set up associations between the Header and Items entities. 

 

 

 

  method DEFINE.

    data: lo_entity_type TYPE REF TO /iwbep/if_mgw_odata_entity_typ.
    super->define( ).
    "" Header Entity Name
    lo_entity_type = model->get_entity_type( iv_entity_name = 'zemp_hdr' ).

    "" MPC_EXT Deep Structure Name
    lo_entity_type->bind_structure( iv_structure_name = 'ZCL_ZEMP_HDR_ITEM_MPC_EXT=>TS_DEEP_ENTITY' ).


  endmethod.

 

 

 

Step 3: Redefine the CREATE_DEEP_ENTITY Method

Implement the CREATE_DEEP_ENTITY method in the DPC_EXT class to handle the creation of multiple entities simultaneously. This method will parse the incoming data, create the Header entity, and then create associated Items entities.

Here's a conceptual example of how you might implement these steps:

 

 

 

METHOD /iwbep/if_mgw_appl_srv_runtime~create_deep_entity.

  DATA:
    ls_deep_entity TYPE zcl_zemp_hdr_item_mpc_ext=>ts_deep_entity,
    lt_item TYPE TABLE OF zcl_zemp_hdr_item_mpc_ext=>ts_zemp_item,
    ls_header TYPE zcl_zemp_hdr_item_mpc_ext=>ts_zemp_hdr.

  " Read the incoming data for the deep entity
  io_data_provider->read_entry_data(
    IMPORTING
      es_data = ls_deep_entity
  ).

  " Check if the deep entity data is not initial
  IF ls_deep_entity IS NOT INITIAL.

    " Copy the data for the header entity
    ls_header = CORRESPONDING #( ls_deep_entity ).
    ls_header-mandt = sy-mandt.

    " Update the header entity in the database table
    MODIFY zemp_header FROM ls_header.

    " Check if the update was successful
    IF sy-subrc = 0.

      " Copy the data for the item entities
      lt_item[] = CORRESPONDING #( ls_deep_entity-zemp_item[] ).

      " Set the client field for each item entity
      DO LINES( lt_item[] ) TIMES.
        lt_item[ sy-index ]-mandt = sy-mandt.
      ENDDO.

      " Insert the item entities into the database table
      INSERT zemp_details FROM TABLE lt_item ACCEPTING DUPLICATE KEYS.

      " Check if the insertion was successful
      IF sy-subrc = 0.

        " Populate the output parameter ER_DEEP_ENTITY with the deep entity data
        CALL METHOD me->copy_data_to_ref(
          EXPORTING
            is_data = ls_deep_entity
          CHANGING
            cr_data = er_deep_entity
        ).

      ENDIF.

    ENDIF.

  ENDIF.

ENDMETHOD.

 

 

 

 

  • This method is responsible for creating a deep entity, which involves creating multiple related entities simultaneously.
  • It reads the incoming data for the deep entity using the READ_ENTRY_DATA method of the data provider interface (IO_DATA_PROVIDER).
  • It then processes the data to update the header entity (ZEMP_HEADER) and insert related item entities (ZEMP_DETAILS) into the database table.
  • Finally, it populates the output parameter (ER_DEEP_ENTITY) with the deep entity data if the operations are successful.

 

URL: 

 

 

 

/sap/opu/odata/sap/ZEMP_HDR_ITEM_SRV/zemp_hdrSet

 

 

 

use method POST for create deep entity

Pass HTTP request :

 

 

 

{
  "EmpId" : "9117",
    "EmpName" : "Krishna Vamsi",
    "EmpMail" : "demo@demo.com",
    "EmpPhone" : "0000000000",
    "Createdby" : "",
    "Createdat" : "\/Date(1650963567000)\/",
    "Lastchangedby" : "",
    "Lastchangedat" : "\/Date(1650963567000)\/",
  "zemp_item" : [                                //Item Entity
      {
        "Empid" : "9117",
        "Projects" : "DEMO1",
        "Billing" : "30001.00",
        "CurrType" : "INR",
        "Address" : "WFH"
      },
      {
        "Empid" : "9117",
        "Projects" : "DEMO2",
        "Billing" : "30002.00",
        "CurrType" : "INR",
        "Address" : "WFH"
      },
      {
       "Empid" : "9117",
        "Projects" : "DEMO3",
        "Billing" : "30003.00",
        "CurrType" : "INR",
        "Address" : "WFH"
      }
    ]
}

 

 

 

Create_Deep_entityCreate_Deep_entity

 

Thanks and Regards,
Krishna Vamsi

Accepted Solutions (0)

Answers (1)

Answers (1)

hendrik174
SAP Mentor
SAP Mentor

hi,

why is this posted under Q&A? It looks much more like a blog post.. 

Addiontal comment: The code could use some "clean"-up. Have a look at https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md to get an idea. 

Furthermore, there are already several blogs on the topic, you might want to research and build up on the existing knowledge of the community by posting what's new on your approach or what the reader can learn he or she didn't learn by reading the other blogs.

Best Regards
Hendrik