
Resumen: este blog cubrirá la creación de un hipervínculo en un campo específico y mostrará un documento PDF en la pantalla webUI de CRM en una ventana emergente.
Para lograr esta funcionalidad, necesitamos redefinir el método P del atributo con la lógica del código siguiente. Tomaré un ejemplo de los siguientes objetos técnicos para demostrar la solución.
Componente BSP: BEABDH_BILLDOC, vista personalizada: ZGOSATTACH, atributo TITLE
(En caso de que no se requiera que todo el valor del campo tenga un hipervínculo, entonces asigne una propiedad de hipervínculo a un valor de campo específico con un evento al hacer clic (aquí 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.
Siguiente paso, necesitamos crear y activar un servicio en T-code SICF en la siguiente ruta: /default_host/sap/crm/
No olvides activar el servicio. Es una parte esencial de la funcionalidad y es posible que deba activarse manualmente en todos los sistemas SAP (Desarrollo/Calidad/Producción).
Todas las pestañas permanecerán igual excepto la lista de controladores. Cree una nueva clase de controlador copiando el marco de la clase CL_CRM_PREVIEW_PDF y coloque el nombre de la clase como controlador.
En la clase de controlador Z recién creada, debemos modificar los métodos IF_HTTP_EXTENSION~HANDLE_REQUEST y GET_PDF como se indica a continuación para cumplir con los requisitos.
Método: 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.
Método: 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.
Ahora cree un controlador de eventos denominado DISPLAY_DOC en la vista personalizada del componente BSP como paso final.
Fragmento de código
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.
Esto concluye la funcionalidad. Aquí, en la columna Título, los datos de la celda (Primera copia.pdf, Segunda copia.pdf y Tercera copia.pdf) que tienen archivos adjuntos, aparecerá un hipervínculo y al hacer clic en cualquiera de ellos se mostrará el documento PDF en una ventana emergente como se muestra a continuación.
Gracias de nuevo por leer el documento. Realmente aprecio su valioso tiempo. Continúe siguiéndonos y déjenos un comentario con cualquier consejo o idea perspicaz.
Calle Eloy Gonzalo, 27
Madrid, Madrid.
Código Postal 28010
Paseo de la Reforma 26
Colonia Juárez, Cuauhtémoc
Ciudad de México 06600
Real Cariari
Autopista General Cañas,
San José, SJ 40104
Av. Jorge Basadre 349
San Isidro
Lima, LIM 15073