Today's mobility is one of the hot topics in SAP world. Companies are developing new reports and dashboards for mobile environment. Until now lots of custom ALV reports were created and most of their functionality is needed in mobile environment. Rather than new developments for mobile, How can we make this reports mobile enable without modifications?
In this blog series, We will create a Restful service to submit ALV reports and a jquerymobile client to show & visualize report data in mobile.
Before begin, i strongly recommend you to read john.moy3 's blog .
Part 2 - Create JQueryMobile Web Application with Datatables plugin
Part 3 - Visualize ALV Data with Highcharts for iPad
Creating JSON Restful Service to Submit ALV Reports:
Pre-requisites:
Steps:
METHOD if_http_extension~handle_request.
TYPE-POOLS: abap,
kkblo.
DATA: lo_json_data TYPE REF TO zcl_trex_json_serializer,
lo_json_metadata TYPE REF TO zcl_trex_json_serializer.
* Data definition
DATA: _path_info TYPE string,
_verb TYPE string,
_callback TYPE string,
_json_string TYPE string,
_json_string_data TYPE string,
_json_string_metadata TYPE string.
DATA: _it_inputparams TYPE tihttpnvp,
_inputparams TYPE LINE OF tihttpnvp.
DATA: _pgmna TYPE tstc-pgmna,
_tcode TYPE tstc-tcode,
_variant TYPE rsvar-variant.
DATA: _data TYPE REF TO data,
_data_line TYPE REF TO data,
_data_descr TYPE REF TO cl_abap_datadescr,
_data_line_descr TYPE REF TO cl_abap_datadescr.
DATA: _datafield(40).
FIELD-SYMBOLS: <_datafield> TYPE ANY.
DATA: BEGIN OF _metadata,
is_hierseq TYPE abap_bool,
tabname TYPE string,
tabname_line TYPE string,
s_keyinfo TYPE kkblo_keyinfo,
s_layout TYPE lvc_s_layo,
t_fcat TYPE lvc_t_fcat,
t_filter TYPE lvc_t_filt,
t_sort TYPE lvc_t_sort,
END OF _metadata.
FIELD-SYMBOLS: <_data> TYPE ANY TABLE,
<_wa_data> TYPE ANY,
<_wa_metadata> TYPE ANY.
DATA: _fcat TYPE lvc_s_fcat.
DATA: _amount(40),
_waersfield(40),
_currfield(40).
DATA: _ttext TYPE tstct-ttext,
_description TYPE char120.
FIELD-SYMBOLS: <_waers> TYPE ANY,
<_currency> TYPE ANY.
* Process request
_path_info = server->request->get_header_field( name = '~path_info' ).
_verb = server->request->get_header_field( name = '~request_method' ).
* Determine if method is get.
IF _verb NE 'GET'.
CALL METHOD server->response->set_header_field( name = 'Allow' value = 'GET' ).
CALL METHOD server->response->set_status( code = '405' reason = 'Method not allowed' ).
EXIT.
ENDIF.
* Get passed parameters
CALL METHOD server->request->get_form_fields
CHANGING
fields = _it_inputparams.
LOOP AT _it_inputparams INTO _inputparams.
TRANSLATE: _inputparams-name TO UPPER CASE,
_inputparams-value TO UPPER CASE.
MODIFY _it_inputparams FROM _inputparams.
ENDLOOP.
CLEAR _inputparams.
READ TABLE _it_inputparams INTO _inputparams WITH KEY name = 'TCODE'.
_tcode = _inputparams-value.
CLEAR _inputparams.
READ TABLE _it_inputparams INTO _inputparams WITH KEY name = 'CALLBACK'.
_callback = _inputparams-value.
CLEAR _inputparams.
READ TABLE _it_inputparams INTO _inputparams WITH KEY name = 'VARIANT'.
_variant = _inputparams-value.
IF _tcode IS INITIAL.
CALL METHOD server->response->set_status( code = '404' reason = 'Parameter missing' ).
CALL METHOD server->response->set_cdata( data = 'Input Paramater "tcode" is missing' ).
EXIT.
ENDIF.
* progname of tcode
SELECT SINGLE pgmna
INTO _pgmna
FROM tstc
WHERE tcode = _tcode.
IF sy-subrc IS NOT INITIAL.
CALL METHOD server->response->set_status( code = '404' reason = 'Tcode not exist' ).
CALL METHOD server->response->set_cdata( data = 'Input Paramater "tcode" is not exist' ).
EXIT.
ENDIF.
cl_salv_bs_runtime_info=>set( EXPORTING display = abap_false
metadata = abap_true
data = abap_true ).
IF _variant IS INITIAL.
SUBMIT (_pgmna) AND RETURN.
ELSE.
DATA: _it_valutab TYPE STANDARD TABLE OF rsparams.
CALL FUNCTION 'RS_VARIANT_CONTENTS'
EXPORTING
report = _pgmna
variant = _variant
TABLES
valutab = _it_valutab
EXCEPTIONS
variant_non_existent = 1
variant_obsolete = 2
OTHERS = 3.
IF _it_valutab[] IS INITIAL.
SUBMIT (_pgmna) AND RETURN.
ELSE.
* SUBMIT (_pgmna) WITH SELECTION-TABLE _it_valutab AND RETURN.
SUBMIT (_pgmna) USING SELECTION-SET _variant AND RETURN.
ENDIF.
ENDIF.
TRY.
cl_salv_bs_runtime_info=>get_data_ref( IMPORTING
r_data = _data
"r_data_line = _data_line
r_data_descr = _data_descr
r_data_line_descr = _data_line_descr ).
cl_salv_bs_runtime_info=>get_metadata( RECEIVING value = _metadata ).
ASSIGN _data->* TO <_data>.
* Modify data for output
LOOP AT <_data> ASSIGNING <_wa_data>.
* Modify data with conversion routines
LOOP AT _metadata-t_fcat INTO _fcat WHERE edit_mask IS NOT INITIAL
AND inttype = 'C'.
CONCATENATE '<_WA_DATA>-'
_fcat-fieldname
INTO _datafield.
ASSIGN (_datafield) TO <_datafield>.
WRITE <_datafield> TO <_datafield> USING EDIT MASK _fcat-edit_mask.
ENDLOOP.
* Modify currency amount
LOOP AT _metadata-t_fcat INTO _fcat WHERE datatype = 'CURR'
AND cfieldname IS NOT INITIAL.
CONCATENATE '<_WA_DATA>-'
_fcat-cfieldname
INTO _waersfield.
CONCATENATE '<_WA_DATA>-'
_fcat-fieldname
INTO _currfield.
ASSIGN: (_waersfield) TO <_waers>,
(_currfield) TO <_currency>.
CALL FUNCTION 'CURRENCY_AMOUNT_SAP_TO_IDOC'
EXPORTING
currency = <_waers>
sap_amount = <_currency>
IMPORTING
idoc_amount = _amount.
CONDENSE _amount.
<_currency> = _amount.
ENDLOOP.
ENDLOOP.
CATCH cx_salv_bs_sc_runtime_info.
* If error detected then abort
CALL METHOD server->response->set_status( code = '404' reason = 'Unable to retrieve ALV data' ).
CALL METHOD server->response->set_cdata( data = _json_string ).
EXIT.
ENDTRY.
cl_salv_bs_runtime_info=>clear_all( ).
* create instance of json serialiser
CREATE OBJECT lo_json_data
EXPORTING
DATA = <_data>.
* serialize data
lo_json_data->serialize( ).
* get serialized json data string
_json_string_data = lo_json_data->get_data( ).
* create instance of json serialiser
CREATE OBJECT lo_json_metadata
EXPORTING
DATA = _metadata-t_fcat.
* serialize metadata
lo_json_metadata->serialize( ).
* get serialized json metadata string
_json_string_metadata = lo_json_metadata->get_data( ).
IF _json_string_metadata IS NOT INITIAL.
CONCATENATE '"alvMetadata":' _json_string_metadata INTO _json_string_metadata SEPARATED BY space.
ENDIF.
IF _json_string_data IS NOT INITIAL.
CONCATENATE '"alvData":' _json_string_data INTO _json_string_data SEPARATED BY space.
ENDIF.
* Tcode description
SELECT SINGLE ttext
INTO _ttext
FROM tstct
WHERE sprsl = sy-langu
AND tcode = _tcode.
CONCATENATE '"description":"'
_ttext
'"'
INTO _description.
* JSON
CONCATENATE '{'
_description
','
_json_string_metadata
','
_json_string_data
'}'
INTO _json_string
SEPARATED BY space.
* to support JSONP
CONCATENATE _callback
'('
_json_string
')'
INTO _json_string.
*
* set the response mimetype to json
* Set the content type
CALL METHOD server->response->set_header_field(
name = 'Content-Type'
value = 'application/json; charset=utf-8' "for JSON
).
* Set CORS access control to avoid browser policy restrictions around
* Cross Domain communication
CALL METHOD server->response->set_header_field( name = 'Access-Control-Allow-Origin' value = '*' ).
** set Allow methods
* CALL METHOD server->response->set_header_field( name = 'Access-Control-Allow-Methods' value = 'GET' ).
* set the cdata response to the json string
CALL METHOD server->response->set_cdata( data = _json_string ).
ENDMETHOD. "if_http_extension~handle_request
Publish Service:
Steps:
Test Service:
Steps:
You can also pass variant as parameter:
Ex: http://yoursapurl:8000/sap/bc/zsubmitalv?tcode=ZALVREPORT&variant=MYVARIANT
Note:
In ALV, maybe there is "CNTL_ERROR" dump because of the background execution.
To avoid this problem;
1- For reports that was created with REUSE_ALV_GRID_DISPLAY, You have to pass IT_SORT paramater to function.(it can be initial)
DATA: _it_field_catalog TYPE slis_t_fieldcat_alv,
_it_sort_catalog TYPE slis_t_sortinfo_alv ,
_layout TYPE slis_layout_alv,
_title TYPE lvc_title,
_repid LIKE sy-repid.
_repid = sy-repid.
_layout-colwidth_optimize = 'X'.
_layout-zebra = 'X'.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_callback_program = _repid
i_grid_title = _title
i_save = 'A'
is_layout = _layout
it_fieldcat = _it_field_catalog
it_sort = _it_sort_catalog
TABLES
t_outtab = p_it_output[]
EXCEPTIONS
program_error = 1
OTHERS = 2.
2- In OO ALV add offline mode control before creation of custom container in pbo of alv screen
IF cl_gui_alv_grid=>offline( ) IS INITIAL. "Offline mode control
CREATE OBJECT g_custom_container
EXPORTING
container_name = g_container.
ENDIF.
CREATE OBJECT g_grid
EXPORTING
i_parent = g_custom_container.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
4 | |
4 | |
4 | |
3 | |
3 | |
3 | |
3 | |
3 | |
2 | |
2 |