CRM and CX Blogs by SAP
Stay up-to-date on the latest developments and product news about intelligent customer experience and CRM technologies through blog posts from SAP experts.
cancel
Showing results for 
Search instead for 
Did you mean: 
JerryWang
Product and Topic Expert
Product and Topic Expert
457
Recently I am working on CRM Interactive Report and I was quite confusing about the difference between these two key figures below:



This report is created based on Reporting Area: ServiceOrder

The technical name for "Gross Value of Service Orders": /CRMBW/SVO_GV

"Gross Value Header": /CRMBW/GV_SVOH



From this customizing I know the cache table to display report key figure values for Service Order is: CRMD_DHR_HSRVORD




However in this table there is only one field GROSS_VALUE_H, and how can this single field serve two key figures mentioned in the title of this blog?



Via debugging I have figured out how the key figure values are retrieved from database table and rendered in WebUI.

It consists of two steps:

1. the guid of orders which fulfills the specified search criteria in WebUI is fetched from CRMD_ORDER_INDEX via reporting framework API CRM_BSP_OIC_1O_SEARCH_FROM_RF.

I write a simple report to simulate the call sent from Reporting UI:


REPORT crm_bw_gross_value_header.

PARAMETERS: date TYPE sy-datum OBLIGATORY DEFAULT '20150127'.
DATA: lt_table TYPE TABLE OF crmd_dhr_hsrvord.
TYPES: BEGIN OF t_oltp_srv_order,
n_of_unplan_conf TYPE crmt_number_of_h,
predecessor_srv TYPE crmt_boolean,
n_of_srv_conf TYPE crmt_number_of_h,
n_of_srv_order TYPE crmt_number_of_h,
grval_unplan TYPE crmt_gross_value_cum,
object_type TYPE swo_objtyp,
gross_value_h TYPE crmt_gross_value_cum,
grval_srv_order TYPE crmt_gross_value_cum,
stat_open TYPE crmt_status_open,
changed_at TYPE crmt_changed_at_usr,
created_at TYPE crmt_created_at_usr,
lc_srv_duration TYPE crmt_bw_lifecycle,
lc_srv_dur_unit TYPE crmt_bw_lifecycle_unit,
srq_work_dura TYPE timedura,
srq_work_unit TYPE timeunitdu,
srq_tot_dura TYPE timedura,
srq_tot_unit TYPE timeunitdu,
srq_work_dura_qu TYPE crmt_srv_duration,
srq_work_unit_qu TYPE crmt_srv_duration_uom,
srq_tot_dura_qu TYPE crmt_srv_duration,
srq_tot_unit_qu TYPE crmt_srv_duration_uom,
END OF t_oltp_srv_order.
DATA: ls_oltp_srv_order TYPE t_oltp_srv_order,
lt_oltp_srv_order TYPE TABLE OF t_oltp_srv_order,
lt_single_filter_tab TYPE crmt_name_value_pair_tab,
lt_guid_list TYPE crmt_bsp_objectkey_tab,
lt_multi_filter_tab TYPE crmt_bsp_search_multi_val_tab,
ls_multi_filter LIKE LINE OF lt_multi_filter_tab,
ls_filter_item TYPE LINE OF crmt_bsp_range_tab,
lt_person TYPE crmt_report_gp_guid_intnum_ta,
lt_return TYPE bapiret2_t,
lv_gross_h TYPE crmt_gross_value_cum,
lv_sum_so TYPE crmt_gross_value_cum,
lt_guid TYPE crmt_object_guid_tab.

DATA(ls_template) = VALUE crmt_name_value_pair( name = 'TEMPLATE_TYPE' ).
APPEND ls_template TO lt_single_filter_tab.

ls_multi_filter-fieldname = 'OBJECT_TYPE'.
ls_filter_item = VALUE #( sign = 'I' option = 'EQ' low = 'BUS2000116' ).
APPEND ls_filter_item TO ls_multi_filter-searchvalues.
ls_filter_item-low = 'BUS2000117'.
APPEND ls_filter_item TO ls_multi_filter-searchvalues.
APPEND ls_multi_filter TO lt_multi_filter_tab.

CALL FUNCTION 'CRM_RESOLVE_RESPONSE_AREA'
EXPORTING
iv_my = ''
iv_team = ''
iv_group = 'X'
IMPORTING
ev_gp_guids_intnum = lt_person.
CLEAR: ls_multi_filter.
ls_multi_filter-fieldname = 'BU_PARTNER'.
LOOP AT lt_person ASSIGNING FIELD-SYMBOL(<person>).
ls_filter_item = VALUE #( sign = 'I' option = 'EQ' low = <person>-gp_extnum ).
APPEND ls_filter_item TO ls_multi_filter-searchvalues.
ENDLOOP.
APPEND ls_multi_filter TO lt_multi_filter_tab.

CLEAR: ls_multi_filter.
ls_multi_filter-fieldname = 'PARTNER_FCT'.
ls_filter_item = VALUE #( sign = 'I' option = 'EQ' low = '00000012' )."Sales Representative
APPEND ls_filter_item TO ls_multi_filter-searchvalues.
ls_filter_item = VALUE #( sign = 'I' option = 'EQ' low = '00000014' )."Employee Responsible
APPEND ls_filter_item TO ls_multi_filter-searchvalues.
APPEND ls_multi_filter TO lt_multi_filter_tab.

CLEAR: ls_multi_filter.
ls_multi_filter-fieldname = 'OBJECT_ID'.
APPEND ls_multi_filter TO lt_multi_filter_tab.

CLEAR: ls_multi_filter.

ls_multi_filter-fieldname = 'POSTING_DATE'.
ls_filter_item = VALUE #( sign = 'I' option = 'EQ' low = date ).
APPEND ls_filter_item TO ls_multi_filter-searchvalues.
APPEND ls_multi_filter TO lt_multi_filter_tab.

CALL FUNCTION 'CRM_BSP_OIC_1O_SEARCH_FROM_RF'
EXPORTING
it_search_tab = lt_single_filter_tab
it_multivalues = lt_multi_filter_tab
iv_extern_call = 'X'
iv_select_for_headerlevel = 'X'
iv_obj_il = '/CRMBW/OLTP_SRV_ORDER'
iv_report_area = 'SERVICEORDER'
IMPORTING
et_guidlist = lt_guid_list
et_return = lt_return.

Execute the report, in my system for posting date 2015.01.27, there are five Service Orders & Service Confirmation:



2. Buffer table CRMD_DHR_HSRVORD is then read with the guid fetched from step1, and key figure calculation is done in BAdI implementation class CL_CRM_RFQ1OCALC_STATUS_COMMON.

In line 638 the logic is clear: the gross value of Service Order key figure is only accumulated when the given order is a Service Order ( object_type = 'BUS2000116' ).



This BAdI is called within OLTP extractor belonging to Service Order Reporting Area: /CRMBW/OLTP_EXTRACT_SRV_ORDER



As a result I can now continue with my simulation report to calculate these two key figures with the same logic:


lt_guid = CORRESPONDING #( lt_guid_list ).
SELECT * INTO TABLE lt_table FROM crmd_dhr_hsrvord FOR ALL ENTRIES IN lt_guid
WHERE guid = lt_guid-table_line.

LOOP AT lt_table ASSIGNING FIELD-SYMBOL(<field>).
lv_gross_h = lv_gross_h + <field>-gross_value_h.
IF <field>-object_type = 'BUS2000116'.
lv_sum_so = lv_sum_so + <field>-gross_value_h.
ENDIF.
ENDLOOP.

WRITE:/ |Gross Value Header:{ lv_gross_h }| COLOR COL_NEGATIVE.
WRITE:/ |Gross Value of Service Order: { lv_sum_so }| COLOR COL_NEGATIVE.

Now execute the report, and you can get the same calculated value as you see in WebUI for posting date 2015.01.27:



Alternatively I have written another report which calls the Reporing framework API from a higher level. The two steps mentioned above are embedded within API RSOA_DSOURCE_READ_REMOTE_DATA.


REPORT crm_bw_read_gross_value.
TYPES:
BEGIN OF rsurfcdata,
clustr TYPE indx_clstr,
clustd TYPE indx_clust,
END OF rsurfcdata,
lty_t_container TYPE STANDARD TABLE OF rsurfcdata WITH DEFAULT KEY.
DATA: lv_max TYPE int4,
l_t_selections TYPE sbiwa_t_select,
l_t_fields TYPE sbiwa_t_fields,
ls_field LIKE LINE OF l_t_fields,
l_t_container TYPE lty_t_container,
l_t_msg TYPE rs_t_msg.
PARAMETERS: logsys TYPE logsys OBLIGATORY DEFAULT 'QHDCLNT504',
date TYPE sy-datum OBLIGATORY DEFAULT '20150127'.

DATA: ls_selection LIKE LINE OF l_t_selections.

ls_selection = value #( fieldnm = 'APP_SERVER' sign = 'I' option = 'EQ' low = 'ldciqhd' ).
APPENd ls_selection TO l_t_selections.

ls_selection = value #( fieldnm = 'LOG_SYSTEM' sign = 'I' option = 'EQ' low = logsys ).
APPENd ls_selection TO l_t_selections.

ls_selection = value #( fieldnm = 'REPORT_AREA' sign = 'I' option = 'EQ' low = 'SERVICEORDER' ).
APPENd ls_selection TO l_t_selections.

ls_selection = value #( fieldnm = 'SELECTION_ID' sign = 'I' option = 'EQ' low = '0000' ).
APPENd ls_selection TO l_t_selections.

ls_selection = value #( fieldnm = 'USERNAME' sign = 'I' option = 'EQ' low = sy-uname ).
APPENd ls_selection TO l_t_selections.

ls_selection = value #( fieldnm = 'POSTING_DATE' sign = 'I' option = 'EQ' low = date ).
APPENd ls_selection TO l_t_selections.

ls_field-fieldnm = 'APP_SERVER'.
APPEND ls_field TO l_t_fields.

ls_field-fieldnm = 'LOG_SYSTEM'.
APPEND ls_field TO l_t_fields.

ls_field-fieldnm = 'REPORT_AREA'.
APPEND ls_field TO l_t_fields.

ls_field-fieldnm = 'SELECTION_ID'.
APPEND ls_field TO l_t_fields.

ls_field-fieldnm = 'USERNAME'.
APPEND ls_field TO l_t_fields.

ls_field-fieldnm = 'POSTING_DATE'.
APPEND ls_field TO l_t_fields.

ls_field-fieldnm = 'CURRENCY'.
APPEND ls_field TO l_t_fields.

ls_field-fieldnm = 'GROSS_VALUE_H'.
APPEND ls_field TO l_t_fields.

ls_field-fieldnm = 'GRVAL_SRV_ORDER'.
APPEND ls_field TO l_t_fields.

CALL FUNCTION 'RSOA_DSOURCE_READ_REMOTE_DATA'
EXPORTING
i_datasource = '/CRMBW/OLTP_SRV_ORDER'
i_slogsys = logsys
i_maxrows = lv_max
TABLES
i_t_selections = l_t_selections
i_t_fields = l_t_fields
e_t_container = l_t_container
e_t_msg = l_t_msg
EXCEPTIONS
remote_read_failed = 1
x_message = 2.

WRITE:/ lines( l_t_container ).

Of source the response stored in l_t_container has compressed format, which could be parsed by the corresponding program specified in variable l_program.




The name of this program could be read from function module RSAR_ISOURCE_MD_T_GET. See the following report as an example:


REPORT crm_bw_read_metadata.

PARAMETERS: oltp TYPE rsa_isource OBLIGATORY DEFAULT '/CRMBW/OLTP_SRV_ORDER',
logsys TYPE rsa_logsys OBLIGATORY DEFAULT 'QHDCLNT504'.

DATA: l_s_osoltp TYPE rsarc_s_rsosoltp,
l_t_fields TYPE rsarc_t_rsfield,
l_s_ts TYPE rsarc_s_rsts,
l_t_tsfields TYPE rsarc_t_rstsfield,
l_t_selfields TYPE rsarc_t_rsfield.
CALL FUNCTION 'RSAR_ISOURCE_MD_T_GET'
EXPORTING
i_isource = oltp
i_objvers = 'A'
i_logsys = logsys
i_tobjvers = 'A'
i_without_authority = rs_c_true
i_selfields_for_rc = rs_c_true
IMPORTING
e_s_osoltp = l_s_osoltp
e_t_field = l_t_fields
e_t_selfd = l_t_selfields
e_s_ts = l_s_ts
e_t_tsfield = l_t_tsfields
EXCEPTIONS
isource_not_found = 1
unauthorized = 2
OTHERS = 3.

WRITE:/ lines( l_t_fields ).

The program name to parse the reporting response into ABAP format is stored in variable l_s_ts: