Enterprise Resource Planning Blogs by SAP
Get insights and updates about cloud ERP and RISE with SAP, SAP S/4HANA and SAP S/4HANA Cloud, and more enterprise management capabilities with SAP blog posts.
cancel
Showing results for 
Search instead for 
Did you mean: 
harivenkatesh_s
Product and Topic Expert
Product and Topic Expert

Introduction


The transactional data extraction views for standard extractor are available with SAP S/4HANA On-premise 2022 edition. The standard extractors are based on the table ACDOCU and does not contain the group reporting based reporting logic. Please note that the general recommendation is to use the standard extractor and you need to build the reporting logic on the target system. However, in this blog, we will discuss about the options of extracting the data that includes reporting logic from SAP S/4HANA On-premise for group reporting (source system) to SAP BW/4HANA (target system). The existing analytical stack of group reporting brings various logics such as Periodic Modes (PER/YTD), Group Derivation (or Group Structure), Restatement & Multi Group Currency, Hierarchy Elimination (Cons Unit/Segment/Profit Center) whereas the standard extractor does not include these reporting logics.

How can we extract data with reporting logic?


You can use the API: API_CNSLDTNGRPJRNLITEM. The API has the reporting logic and this acts as the full stack (without reporting item). As a pre-requisite, you need to add this service in the transaction /n/iwfnd/maint_service in your target system as shown below:


API Service


You can write an ABAP report by consuming the above API so that it takes the data from source system with reporting logic and put it into target system (say for e.g., in ADSO). Please follow the below steps:

a. You need to set the API URL. The filters can be provided appropriately, and the projection can be part of it. The new API link is provided at the end of this blog.

b. Create the HTTP client for the above URL.

c. Set the header fields and receive the HTTP response.

d. You need to convert the response to an internal table.

e. Pass the table to the function 'RSDRI_DATA_WRAP' and also specify the ADSO in the function 'RSDSO_WRITE_API_RFC'. This will help you to insert the records into the ADSO. Make sure the projection fields exist as an info-object in ADSO.

You can refer to the (rough coding) sample report that illustrates the above steps:
*&---------------------------------------------------------------------*
*& Report Z_SAMPLE
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT Z_SAMPLE.
DATA: lo_http_client TYPE REF TO if_http_client.
DATA: lt_header_fields TYPE tihttpnvp.
DATA: ls_header_fields TYPE ihttpnvp.
DATA: response TYPE string.

DATA(l_url) = |http://<your server:your port>/sap/opu/odata/sap/API_CNSLDTNGRPJRNLITEM/CnsldtnGrpJrnlItem(P_ConsolidationUnitHierarchy='RGCUH'| &&
|,P_ConsolidationPrftCtrHier='$',P_ConsolidationSegmentHier='$',P_KeyDate=datetime'2018-12-31T00:00:00')| &&
|/Results?$select=ConsolidationGroup,ConsolidationUnitForElim,FiscalYearPeriod,FinancialStatementItem,ProfitCenter,SubItem,| &&
|SubItemCategory,ConsolidationUnit,AmountInLocalCurrency,AmountInGroupCurrency| &&
|,CnsldtnQuantityInBaseUnit&$filter=ConsolidationVersion eq '<your value>'|.
"you can provide additional filters as per your convenience
CALL METHOD cl_http_client=>create_by_url
EXPORTING
url = l_url
IMPORTING
client = lo_http_client
EXCEPTIONS
argument_not_found = 1
plugin_not_active = 2
internal_error = 3
OTHERS = 4.

IF sy-subrc <> 0.
" error
ENDIF.


lo_http_client->request->set_method('GET').

ls_header_fields-name = 'Content-Type'.
ls_header_fields-value = 'application/json'.
APPEND ls_header_fields TO lt_header_fields.
CLEAR ls_header_fields.

ls_header_fields-name = 'Accept'.
ls_header_fields-value = 'application/json'.
APPEND ls_header_fields TO lt_header_fields.
CLEAR ls_header_fields.

ls_header_fields-name = 'APIKey'.
ls_header_fields-value = '<API_KEY>'.
APPEND ls_header_fields TO lt_header_fields.
CLEAR ls_header_fields.

CALL METHOD lo_http_client->request->set_header_fields
EXPORTING
fields = lt_header_fields.

CALL METHOD lo_http_client->send
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
http_invalid_timeout = 4
OTHERS = 5.

IF sy-subrc = 0.
CALL METHOD lo_http_client->receive
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
OTHERS = 5.
ENDIF.

IF sy-subrc <> 0.
"error
ENDIF.

response = lo_http_client->response->get_cdata( ).

DATA(lref_result) = /ui2/cl_json=>generate( json = response ).
ASSIGN lref_result->* TO FIELD-SYMBOL(<lref_result>).

ASSIGN COMPONENT 'D' OF STRUCTURE <lref_result> TO FIELD-SYMBOL(<lv_result>).
ASSIGN <lv_result>->* TO FIELD-SYMBOL(<l_result>).

ASSIGN COMPONENT 'RESULTS' OF STRUCTURE <l_result> TO FIELD-SYMBOL(<l_adso_res>).
ASSIGN <l_adso_res>->* TO FIELD-SYMBOL(<ls_adso_res>).


TYPES:
ty_s_dso_data TYPE /bic/azfullst1, "changes as per your adso
ty_t_dso_data TYPE STANDARD TABLE OF /bic/azfullst1. "changes as per your adso

DATA:
gs_dso_data TYPE /bic/azfullst1, "changes as per your adso
l_char type string,
gt_dso_data TYPE STANDARD TABLE OF /bic/azfullst1, "changes as per your adso,
gv_numrec TYPE i,
gt_log_msgs TYPE rs_t_msg,
gs_log_msg TYPE rs_s_msg,
gt_log_msgs2 TYPE STANDARD TABLE OF abapsource,
gv_log_msg2 TYPE abapsource,
gv_idx TYPE i,
lt_data_250 TYPE bapi6116tda.
*

FIELD-SYMBOLS : <l_adso>,
<l_adsoval>,
<l_CunitElim>,
<l_CunitElimVal>,
<l_FSItem>,
<l_FSItemVal>,
<l_Subit>,
<l_SubitVal>,
<l_Subty>,
<l_SubtyVal>,
<l_cunit>,
<l_cunitVal>,
<l_congr>,
<l_congrVal>,
<l_PRcntr>,
<l_PRcntrVal>,
<l_Lcur>,
<l_LcurVal>,
<l_fiscper>,
<l_fiscperVal>,
<l_Qty>,
<l_QtyVal>,
<l_AmntLC>,
<l_AmntLCVal>,
<l_AmntGC>,
<l_AmntGCVal>.


LOOP AT <ls_adso_res> ASSIGNING <l_adso>.

ASSIGN <l_adso>->* TO <l_adsoval>.

* ASSIGN COMPONENT 'D' OF STRUCTURE <l_adso> TO FIELD-SYMBOL(<l_result>).

ASSIGN COMPONENT 'AMOUNTINGROUPCURRENCY' OF STRUCTURE <l_adsoval> TO <l_AmntGCVal>.
ASSIGN COMPONENT 'AMOUNTINLOCALCURRENCY' OF STRUCTURE <l_adsoval> TO <l_AmntLCVal>.
ASSIGN COMPONENT 'CNSLDTNQUANTITYINBASEUNIT' OF STRUCTURE <l_adsoval> TO <l_QtyVal>.
ASSIGN COMPONENT 'CONSOLIDATIONUNITFORELIM' OF STRUCTURE <l_adsoval> TO <l_CunitElimVal>.
ASSIGN COMPONENT 'FINANCIALSTATEMENTITEM' OF STRUCTURE <l_adsoval> TO <l_FSItemVal>.
ASSIGN COMPONENT 'FISCALYEARPERIOD' OF STRUCTURE <l_adsoval> TO <l_fiscperVal>.
ASSIGN COMPONENT 'CONSOLIDATIONUNIT' OF STRUCTURE <l_adsoval> TO <l_cunitVal>.
ASSIGN COMPONENT 'CONSOLIDATIONGROUP' OF STRUCTURE <l_adsoval> TO <l_congrVal>.
ASSIGN COMPONENT 'PROFITCENTER' OF STRUCTURE <l_adsoval> TO <l_PRcntrVal>.
ASSIGN COMPONENT 'SUBITEM' OF STRUCTURE <l_adsoval> TO <l_SubitVal>.
ASSIGN COMPONENT 'SUBITEMCATEGORY' OF STRUCTURE <l_adsoval> TO <l_SubtyVal>.

gs_dso_data-/bic/zksl = conv f( <l_AmntGCVal>->* ) .


IF <l_CunitElimVal>->* is initial.
gs_dso_data-/bic/zrbunitel = ''.
ELSE.
gs_dso_data-/bic/zrbunitel = <l_CunitElimVal>->*.
ENDIF.

gs_dso_data-/bic/zfsitem = <l_FSItemVal>->*.

gs_dso_data-/bic/zsubit = <l_SubitVal>->*.

gs_dso_data-/bic/zsubty = <l_SubtyVal>->*.

gs_dso_data-/bic/zrbunit = <l_cunitVal>->*.

gs_dso_data-/bic/zrcongr = <l_congrVal>->*.

gs_dso_data-/bic/zprctr = <l_PRcntrVal>->*.

gs_dso_data-/bic/zhsl = <l_AmntLCVal>->*.

APPEND gs_dso_data TO gt_dso_data.

ENDLOOP.

CALL FUNCTION 'RSDRI_DATA_WRAP'
EXPORTING
i_t_data = gt_dso_data
i_unicode_result = rs_c_false
i_compress = rs_c_false
i_result250 = rs_c_true
IMPORTING
e_t_outdata250 = lt_data_250.


CALL FUNCTION 'RSDSO_WRITE_API_RFC'
EXPORTING
i_adsonm = '<your adso>'
i_allow_new_sids = rs_c_true
* I_RFCDATA_UC =
it_rfcdata_250 = lt_data_250
* I_DEBUG = RS_C_FALSE
IMPORTING
e_lines_inserted = gv_numrec
et_msg = gt_log_msgs
* E_UPD_REQ_TSN = DATA(l_req_tsn)
EXCEPTIONS
write_failed = 1
activation_failed = 2
datastore_not_found = 3
OTHERS = 4.

CASE sy-subrc.
WHEN 0.
WRITE: 'Number of records inserted: ', gv_numrec.
WHEN 1.
WRITE: 'ERR! Insert failed...'.
WHEN 2.
WRITE: 'ERR! ADSO not found'.
WHEN OTHERS.
WRITE: 'ERR! Something (what?) went wrong'.
ENDCASE.

NEW-LINE.
NEW-LINE.

LOOP AT gt_log_msgs INTO gs_log_msg.
CALL FUNCTION 'RS_MSG_TEXT'
EXPORTING
* text_type = 'L'
msgid = gs_log_msg-msgid " Message ID
msgno = gs_log_msg-msgno " Message Number
msgv1 = gs_log_msg-msgv1
msgv2 = gs_log_msg-msgv2
msgv3 = gs_log_msg-msgv3
msgv4 = gs_log_msg-msgv4
* dialog = abap_true
TABLES
msgtext = gt_log_msgs2
EXCEPTIONS
message_not_exists = 1
OTHERS = 2.
IF sy-subrc <> 0.
"ERROR
ENDIF.
ENDLOOP.

LOOP AT gt_log_msgs2 INTO gv_log_msg2.
WRITE: / gv_log_msg2.
ENDLOOP.

Please feel free to improvise the report at your end. The video below compares the results between the source and the target system:


Is Delta Possible?


No. But there is a workaround. You can use the time stamp which is provided as a field (CreationDateTime) in the API. You can use this field as the filter in the URL of the API and can manage the data that you would like to extract from source system as per the filter value of this field.

What are the other options?


You can also use the BADI provider: RSO_BADI_PROVIDER. However, you need to have the reporting logic built at your end through the class that implements the interface IF_RSO_BADI_PROV. You can use the standard extractor and use the BADI class for building your reporting logic.

Concluding with Additional links:


Please feel free to share your thoughts by commenting on this blog. Also, we can use this blog as a communication tool for any clarification that you require on this topic. You can also follow my profile for more content on analytical application for group reporting. I would recommend posting your questions by specifying the tag: “SAP S/4HANA Finance for group reporting”

Creating BAdI Providers | SAP Help Portal

Transaction Data for Group Reporting - Read (Version 2) | SAP Help Portal

CDS View Consolidation Group Journal Entry Item for Data Extraction | SAP Help Portal
5 Comments