Technical Articles
SAP Business Technology Platform ABAP environment Deep insert use case for OData Call (client code)
As business object could be hierarchical in nature, OData could also be hierarchical. SAP provides deep insert feature to represent hierarchical objects.
To call any OData API which has hierarchal object structure, we need to use deep insert feature of service consumption model. This article describes how to use deep insert in OData client from SAP Business Technology ABAP environment. Specifically, the code has been written for SAP S/4HANA OData API for Sales Order creation from SAP Business Technology Platform ABAP environment system.
Pre-requisite at high level (Create Communication Objects for a Remote OData Service):
- Cloud connector Setup (if on-prem system)
- Communication arrangement in SAP S/4HANA system
- Destination creation in SAP Business Technology Platform subaccount
- Communication arrangement in SAP Business Technology ABAP environment system for destination service
- Service Consumption Model creation for sales order OData API.
For SAP S/4HANA sales order OData API consumption in SAP Business Technology Platform ABAP environment please refer to following blog (it also resolves UoM related issue for OData call):
I am extending the use case for deep insert.
The code to use the deep insert is as follow:
- Define deep insert type (ty_s_deep_create) & variable (ls_deep_data ) which refers to generated entities (/itapc1/a_salesorder & /itapc1/a_salesorderitem). For child entities create table/structure depending upon child type. For sales order item, I have created a table type (tt_soi_deep_create).
TYPES: tt_soi_deep_create TYPE STANDARD TABLE OF /itapc1/a_salesorderitem WITH NON-UNIQUE DEFAULT KEY.
TYPES: BEGIN OF ty_s_deep_create.
INCLUDE TYPE /itapc1/a_salesorder AS so.
TYPES: _item TYPE tt_soi_deep_create,
END OF ty_s_deep_create.
DATA: ls_so_business_data TYPE /itapc1/a_salesorder,
lsi_business_data TYPE tt_soi_deep_create,
lo_http_client TYPE REF TO if_web_http_client,
lo_client_proxy TYPE REF TO /iwbep/if_cp_client_proxy,
lo_request TYPE REF TO /iwbep/if_cp_request_create,
lo_response TYPE REF TO /iwbep/if_cp_response_create,
it_property_path TYPE /iwbep/if_cp_runtime_types=>ty_t_property_path,
ls_business_data TYPE ty_s_deep_create,
ls_deep_data TYPE ty_s_deep_create
- Create the http client.
lo_http_client = cl_web_http_client_manager=>create_by_http_destination(
cl_http_destination_provider=>create_by_cloud_destination(
i_name= '<destination name> i_authn_mode = if_a4c_cp_service=>service_specific ) ).
- Create the client proxy.
lo_client_proxy = cl_web_OData_client_factory=>create_v2_remote_proxy(EXPORTING iv_service_definition_name = '<service consumption model name>' io_http_client = lo_http_client
iv_relative_service_root = '/sap/opu/OData/sap/API_SALES_ORDER_SRV' ).
- Prepare the business data to be sent (header & items).
ls_so_business_data = VALUE #(salesordertype = 'OR' salesorganization = '3510' distributionchannel = '10' organizationdivision = '00' soldtoparty = '35100001' salesorderdate = 20201211121500 totalnetamount = '0' transactioncurrency = 'EUR' pricingdate = 20201211121500 ).
lsi_business_data = VALUE tt_soi_deep_create( ( salesorderitem = '10' material = 'TG11' pricingdate = 20201211121500 requestedquantity = '1' requestedquantityunit = 'ST' orderquantityunit = 'ST' orderquantitysapunit = 'ST' orderquantityisounit = 'ST' ConfdDelivQtyInOrderQtyUnit = '1' itemnetweight = '1' itemweightunit = 'KG' itemvolume = '1' itemvolumeunit = 'KG' transactioncurrency = 'EUR' ) ).
- Assign the business data to deep insert variable.
MOVE-CORRESPONDING ls_so_business_data TO ls_deep_data.
ls_deep_data-to_item = lsi_business_data.
- Create separate property list for header & item entities. Required for definition for deep insert structure.
DATA it_property TYPE STANDARD TABLE OF String.
APPEND 'SALESORDERTYPE' TO it_property.
APPEND 'SALESORGANIZATION' TO it_property.
APPEND 'DISTRIBUTIONCHANNEL' TO it_property.
APPEND 'ORGANIZATIONDIVISION' TO it_property.
APPEND 'SOLDTOPARTY' TO it_property.
APPEND 'SALESORDERDATE' TO it_property.
APPEND 'TOTALNETAMOUNT' TO it_property.
APPEND 'TRANSACTIONCURRENCY' TO it_property.
APPEND 'PRICINGDATE' TO it_property.
DATA it_deep_property TYPE STANDARD TABLE OF String.
APPEND 'SALESORDERITEM' TO it_deep_property.
APPEND 'MATERIAL' TO it_deep_property.
APPEND 'PRICINGDATE' TO it_deep_property.
APPEND 'REQUESTEDQUANTITY' TO it_deep_property.
APPEND 'REQUESTEDQUANTITYUNIT' TO it_deep_property.
APPEND 'ORDERQUANTITYUNIT' TO it_deep_property.
APPEND 'ORDERQUANTITYSAPUNIT' TO it_deep_property.
APPEND 'ORDERQUANTITYISOUNIT' TO it_deep_property.
APPEND 'CONFDDELIVQTYINORDERQTYUNIT' TO it_deep_property.
APPEND 'ITEMNETWEIGHT' TO it_deep_property.
APPEND 'ITEMWEIGHTUNIT' TO it_deep_property.
APPEND 'ITEMVOLUME' TO it_deep_property.
APPEND 'ITEMVOLUMEUNIT' TO it_deep_property.
APPEND 'TRANSACTIONCURRENCY' TO it_deep_property.
- Create the request for OData call.
lo_request = lo_client_proxy->create_resource_for_entity_set( 'A_SALESORDER' )->create_request_for_create( ).
- Create data description node & set the property list in data description node.
DATA(lo_data_description_node) = lo_request->create_data_descripton_node( ).
lo_data_description_node->set_properties( it_property ).
lo_data_description_node->add_child( '_ITEM' )->set_properties( it_deep_property ).
- Set the business data using deep insert value and data description node.
lo_request->set_deep_business_data(
is_business_data = ls_deep_data
io_data_description = lo_data_description_node ).
- Execute the request.
lo_request->execute( )->get_business_data( IMPORTING es_business_data = ls_business_data ).
lo_request->check_execution( ).
Deep insert(client call) will help to reduce the number of calls to complete a deep structured OData service to one call.
Hi, Sachin
Thanks for sharing the detailed information.
I have one doubt how can we implement for sub parent child....eg. _ScheduleLine of Item child in A_SalesOrder header itself
Thanks