Customer Relationship Management Blogs by Members
Find insights on SAP CRM and other customer relationship management products and topics in blog posts from community members and share your own perspective.
cancel
Showing results for 
Search instead for 
Did you mean: 
yashoratna
Participant
Summary : This blog will cover to make hyperlink on specific field and display PDF document on CRM webUI screen in a popup window.

To achieve this functionality, we need to redefine P-method of the attribute with below code logic. I'll take an example of below technical objects to demonstrate the solution.

BSP component : BEABDH_BILLDOC, custom view : ZGOSATTACH, attribute TITLE


(In case, if not all the field value is required to be hyperlinked, then assign hyperlink property to specific field value with on-click event (here DISPLAY_DOC).
CONSTANTS : lc_description TYPE name_komp VALUE 'DESCRIPTION',
lc_atta TYPE string VALUE 'ATTA',
lc_display_doc TYPE string VALUE 'DISPLAY_DOC'.

CASE iv_property.
WHEN if_bsp_wd_model_setter_getter=>fp_fieldtype.
* If Description column is having value as 'ATTA' , then only create a hyperlink and route to DO_HANDLE_EVENT with event handler DISPLAY_DOC
* Only if there is any attachment, then only show the attachment contect in popup.
* In case of Notes and URL, it will be shown a value in Value column
IF collection_wrapper->find( iv_index = iv_index )->get_property_as_string( iv_attr_name = lc_description ) = lc_atta.
rv_value = cl_bsp_dlc_view_descriptor=>field_type_event_link.
ENDIF.
WHEN if_bsp_wd_model_setter_getter=>fp_onclick.
rv_value = lc_display_doc.
ENDCASE.

 

Next step, we need to create and activate one service in T-code SICF on following path: /default_host/sap/crm/

Don't forget to activate the service. It is an essential part of the functionality and could need to be manually activated in every SAP system (Dev/Quality/Production).


 

All the tabs will remain same except handler list, Create a new handler class by copying the class CL_CRM_PREVIEW_PDF framework and put the class name as a handler.


 

In newly created Z handler class, we need to modify both the methods IF_HTTP_EXTENSION~HANDLE_REQUEST and GET_PDF as per below to fulfill the requirements.

Method: IF_HTTP_EXTENSION~HANDLE_REQUEST
CONSTANTS : lc_scenario_p    TYPE string VALUE 'p',
lc_scenario TYPE string VALUE 'scenario',
lc_cache_control TYPE string VALUE 'Cache-Control',
lc_expires TYPE string VALUE 'Expires',
lc_inline TYPE string VALUE 'inline; filename=',
lc_text_plain TYPE string VALUE 'text/plain',
lc_appl_pdf TYPE string VALUE 'application/pdf',
lc_doc_instid_b TYPE string VALUE 'doc_instid_b',
lc_pdf TYPE string VALUE '.pdf'.

DATA: lt_contents TYPE sdokcntbins,
lv_contenttype TYPE string,
lv_scenario TYPE string,
lv_output_len TYPE i.

IF server IS BOUND.
* Read the scenario comes into HTTP Request
lv_scenario = server->request->get_form_field( lc_scenario ).
IF lv_scenario IS INITIAL.
CALL METHOD server->request->get_form_data
EXPORTING
name = lc_scenario
CHANGING
data = lv_scenario.
ENDIF.

* If scenario is p which is set in BSP Component BEABDH_BILLDOC, Enhancement Set ZJD, View ZGOSAttachments, Event Handler EH_ONDISPLAY_DOC
* then only execute the below functionality
IF lv_scenario = lc_scenario_p.
DATA(lv_doc_id) = CONV so_entryid( server->request->get_form_field( lc_doc_instid_b ) ).

* Extract PDF data into XSTRING format to pass into HTTP response
CALL METHOD me->get_pdf
EXPORTING
iv_docid = lv_doc_id
IMPORTING
ev_size = DATA(lv_size)
ev_contents = DATA(lv_contents).

* If LV_SIZE is not having positive value which means error in reading PDF data
* Populate the error displaying the message 'Issue in reading PDF data'.
IF lv_size <= 0.

DATA(lt_objcont) = VALUE soli_tab( ( line = TEXT-001 ) ).
DATA(lv_input_len) = lines( lt_objcont ) * 255.

* Convert Text message into Binary format
CLEAR : lv_output_len,
lt_contents.
CALL FUNCTION 'SCMS_FTEXT_TO_BINARY'
EXPORTING
input_length = lv_input_len
append_to_table = abap_true
IMPORTING
output_length = lv_output_len
TABLES
ftext_tab = lt_objcont
binary_tab = lt_contents
EXCEPTIONS
failed = 1
OTHERS = 2.
IF sy-subrc EQ 0.
DATA(lv_file_size) = CONV sdok_fsize( lv_output_len ).
* Set the content type as plain text in popup
lv_contenttype = lc_text_plain.

LOOP AT lt_contents ASSIGNING FIELD-SYMBOL(<fs_contents>).
lv_size = lv_file_size - ( 1022 * ( sy-tabix - 1 ) ).

IF lv_size >= 1022.
lv_size = 1022.
ENDIF.

* output encoding to prevent XSS
DATA(lv_xwa_str) = CONV string( <fs_contents>-line ).
cl_abap_dyn_prg=>escape_xss_url(
EXPORTING
val = lv_xwa_str
RECEIVING
out = lv_contents ).

* Set the response data in Server
server->response->append_data( data = lv_contents
length = lv_size ).

ENDLOOP.
ENDIF.

ELSE.
* If there is no error and data is converted successfully in XSTRING format, set the content type as application/pdf
lv_file_size = lv_size.
lv_contenttype = lc_appl_pdf.

DATA(lv_filename) = lv_doc_id && lc_pdf .

* output encoding to prevent XSS
lv_xwa_str = CONV string( lv_contents ).
cl_abap_dyn_prg=>escape_xss_url(
EXPORTING
val = lv_xwa_str
RECEIVING
out = lv_contents ).

* Pass the XSTRING data in Server response
server->response->append_data( data = lv_contents
length = lv_size ).
ENDIF.

CLEAR : lv_contents,
lv_size.

* Pass below mandatory server response data and set the heaer fields
DATA(lv_contentdisposition) = lc_inline && lv_filename .
CALL METHOD server->response->set_header_field
EXPORTING
name = 'content-disposition' ##NO_TEXT
value = lv_contentdisposition.

CALL METHOD server->response->set_header_field
EXPORTING
name = 'content-type' ##NO_TEXT
value = lv_contenttype.

CALL METHOD server->response->set_header_field
EXPORTING
name = 'content-filename' ##NO_TEXT
value = lv_filename.

* Delete Cache control and Expires header fields to avoid any cache issue during popup launch

server->response->delete_header_field(
name = lc_cache_control ).

server->response->delete_header_field(
name = lc_expires ).
ENDIF.
ENDIF.

 

Method: GET_PDF
DATA: li_con_hex TYPE STANDARD TABLE OF solix.
CLEAR : ev_size,
ev_contents,
li_con_hex.

* Read the attachment content after passing INSTID_B value for the document, stored in GOS toolbar.
* Content is in the SOLIX format.
CALL FUNCTION 'SO_DOCUMENT_READ_API1'
EXPORTING
document_id = iv_docid
TABLES
contents_hex = li_con_hex
EXCEPTIONS
document_id_not_exist = 1
operation_no_authorization = 2
x_error = 3
OTHERS = 4.
IF sy-subrc = 0.
TRY.
* Convert the SOLIX data into XSTRING format to pass into HTTP response
CALL METHOD cl_bcs_convert=>xtab_to_xstring
EXPORTING
it_xtab = li_con_hex
RECEIVING
rv_xstring = ev_contents.

ev_size = xstrlen( ev_contents ).
CATCH cx_bcs .
CLEAR ev_size.
ENDTRY.
ENDIF.

 

Now create event handler named DISPLAY_DOC in custom view of BSP component as a final step.


Code-Snippet 
CONSTANTS : lc_params          TYPE seocmpname VALUE 'PARAMS',
lc_size_800 TYPE string_data VALUE '800',
lc_size_820 TYPE int4 VALUE 820,
lc_path TYPE string VALUE '/sap/crm/ZCRM_GOS_PRINT',
lc_query TYPE string VALUE 'scenario=p&doc_instid_b=',
lc_alias TYPE string VALUE 'CRM_UIU_BT_GEN/PRINT_PREVIEW_POPUP_TITLE',
lc_viewnm_popup TYPE string VALUE 'GSURLPOPUP/MainWindow',
lc_usage_popup TYPE string VALUE 'CUGSURLPopup',
lc_attrib_instid_b TYPE name_komp VALUE 'INSTID_B'.

DATA :
lo_ref_cn TYPE REF TO cl_bsp_wd_context_node,
lo_ref_obj TYPE REF TO if_bol_bo_property_access,
lo_ref_gos_attach TYPE REF TO if_bol_bo_property_access,
lo_ref_popup TYPE REF TO if_bsp_wd_popup.

TRY .
* get index of the table
IF htmlb_event_ex IS BOUND.
cl_thtmlb_util=>get_event_info( EXPORTING iv_event = htmlb_event_ex
IMPORTING ev_index = DATA(lv_index) ).
IF lv_index IS NOT INITIAL.

lo_ref_gos_attach ?= typed_context->zgosattach->collection_wrapper->find( iv_index = lv_index ).
IF lo_ref_gos_attach IS BOUND.

*Create a popup with the help of window controller and make use of standard URL POPUP Interface View.
lo_ref_popup = me->comp_controller->window_manager->create_popup(
iv_interface_view_name = lc_viewnm_popup
iv_usage_name = lc_usage_popup
iv_title = cl_wd_utilities=>get_otr_text_by_alias( lc_alias ) ).
IF lo_ref_popup IS BOUND.
lo_ref_cn = lo_ref_popup->get_context_node( lc_params ).
IF lo_ref_cn IS BOUND.
lo_ref_obj = lo_ref_cn->collection_wrapper->get_current( ).
IF lo_ref_obj IS BOUND.
* Set up Popup configuration Settings including URL which is setup in SICF service
*Set the URL paramaters INSTID_B which will be retrived in the service handler class later.

DATA(ls_params) = VALUE crmt_gsurlpopup_params( url = cl_crm_web_utility=>create_url( iv_path = lc_path
iv_query = lc_query && lo_ref_gos_attach->get_property_as_string( lc_attrib_instid_b )
iv_in_same_session = abap_false )
height = lc_size_800
width = lc_size_800 ).

* Set PopUp properties to display PDF document
lo_ref_obj->set_properties( ls_params ).
lo_ref_popup->set_display_mode( if_bsp_wd_popup=>c_display_mode_plain ).
lo_ref_popup->set_window_width( lc_size_820 ).
lo_ref_popup->set_window_height( lc_size_820 ).
lo_ref_popup->open( ).
ENDIF.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
CATCH cx_sy_move_cast_error.
RETURN.
ENDTRY.

 

This concludes the functionality. Here in the column Title, the cell data ( First Copy.pdf, Second Copy.pdf and Third Copy.pdf ) which have attachments, will appear hyperlink and clicking on any of them will show PDF document in a popup window as below.


 


 

Thanks again for reading the document. I really appreciate your valuable time. Please continue to follow along and leave us a comment with any advice or insightful ideas.