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.

Sara Sampaio

Sara Sampaio

Author Since: March 10, 2022

0 0 votes
Article Rating
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x