Friday, 17 May 2024

Calling Fragment Form & Send it as an attachment using ABAP Walk-Through

This Blog is based on the Output Management Form and has all of its configuration completed 

Ex for dunning: use maintenance view: V_T047E using code: sm30 to switch between frameworks through drop-down list

Calling Fragment Form & Send it as an attachment using ABAP Walk-Through

Calling Fragment Form & Send it as an attachment using ABAP Walk-Through

First: you can identify Fields for Key & Master Key internal tables for standard fragment form through putting a breaking point

By using framework: sap cloud and using fragment form template  and of course maintain brf+ configuration

In class: CL_SOMU_FORM_SERVICES , Method : GET_DOCUMENT

1. Put a break point in the first line and go back to the previous program to see internal tables passed to form calling for keys.
2. Take screenshots for them, as you will be using them for the custom calling of the form as these fields are maintained according to configuration & master form template derivation.
3. If you need the application ID Key, it’s a concatenation between multiple variables, You will find it in the call back class specific to a given object in the SPRO configuration

SPRO -> CROSS APPLICATION COMPONENTS -> OUTPUT CONTROL (here you can find all of OM Configuration)  -> DEFINE OUTPUT TYPE THEN SELECT THE ENTRY CORRESPONDING TO YOUR BRF+ ROLE and click details, you will find your call back class, in our class for dunning : CL_FIN_FO_DUNN_OUTPUT , all call back classes Implement same interface, then go into method : IF_APOC_COMMON_API~GET_FDP_PARAMETER

Second step:

Activate the legacy printout system and put a breakpoint inside the printing object whether it’s a program or function module, if you are using PDF, you can put a breakpoint in open job FM and trace back through the stack to the transaction screen printing program

In our case for dunning: It prints using FM : “PRINT_DUNNING_NOTICE_PDF”, put a breakpoint there

1. Start comparing the values of the key & master key internal table with local variables available to locate the objects that contain the data which will  be passed to the fragment forms Key internal tables from the standard

1. You will find all the data u need in the objects because whether it is fragment, PDF or whatever technology, the system always collects the same data passed one way or the other

2. After that start creating your custom code to call the fragment form

Consider the condition to identify which master form template to use.

3. Create an enhancement in the standard program to defuse the standard code and prevent its execution, make sure that the standard code doesn’t update standard somewhere along the code as you need to confirm whether it happens through the OData service of fragment or not! ( because if not you will have to use the standard code that does that to make everything consistent )

1. then test the cycle end to end

in our case , here is the example for the PO Form

1. I created a custom program se38 to test using po form

*&---------------------------------------------------------------------*
*& Report ZDUMMY
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ZDUMMY.


SELECTION-SCREEN BEGIN OF BLOCK b1.
  PARAMETERS: p_po_num TYPE ebeln MATCHCODE OBJECT h_ekko OBLIGATORY.
SELECTION-SCREEN END OF BLOCK b1.

INITIALIZATION.

START-OF-SELECTION.
  DATA: lo_cl_somu_form_services TYPE REF TO cl_somu_form_services.
  DATA: lt_keys TYPE cl_somu_form_services=>ty_gt_key.
  DATA: ls_ekko TYPE ekko.
  DATA: lt_master_keys TYPE cl_somu_form_services=>ty_gt_key.
  DATA: lv_content TYPE  xstring.
  DATA: lv_xml TYPE xstring.
  DATA: lv_pages TYPE  fppagecount.
  DATA: lv_trace_string  TYPE string.
  DATA: lv_stop_processing TYPE  abap_bool.
  DATA: lt_message TYPE cl_somu_form_services=>ty_gt_message.
  DATA: lv_output_length TYPE i.
  DATA: lt_generated_pdf  TYPE STANDARD TABLE OF tbl1024 .

  FIELD-SYMBOLS: <ls_key> TYPE cl_somu_form_services=>ty_gs_key.


  SELECT SINGLE *
    FROM ekko
    INTO ls_ekko
    WHERE ebeln = p_po_num.


  " --------------------------- Values for the purchase order form ---------------------------
  APPEND INITIAL LINE TO lt_keys ASSIGNING <ls_key>.
  <ls_key>-name = 'PurchaseOrder'.
  <ls_key>-value = p_po_num.

  APPEND INITIAL LINE TO lt_keys ASSIGNING <ls_key>.
  <ls_key>-name = 'SenderCountry'.
  <ls_key>-value = 'DE'.

  APPEND INITIAL LINE TO lt_keys ASSIGNING <ls_key>.
  <ls_key>-name = 'PurchaseOrderChangeFlag'.
  <ls_key>-value = space.

  APPEND INITIAL LINE TO lt_keys ASSIGNING <ls_key>.
  <ls_key>-name = 'Language'.
  <ls_key>-value = 'E'.


  APPEND INITIAL LINE TO lt_keys ASSIGNING <ls_key>.
  <ls_key>-name = 'ReceiverPartnerNumber'.
  <ls_key>-value = ls_ekko-lifnr.

  " --------------------------- Values for the master form template ---------------------------
  APPEND INITIAL LINE TO lt_master_keys ASSIGNING <ls_key>.
  <ls_key>-name = 'PrintFormDerivationRule'.
  <ls_key>-value = 'PURCHASE_ORDER_MASTER_FOR_COMPANY'.

  APPEND INITIAL LINE TO lt_master_keys ASSIGNING <ls_key>.
  <ls_key>-name = 'WatermarkText'.
  <ls_key>-value = space.

  APPEND INITIAL LINE TO lt_master_keys ASSIGNING <ls_key>.
  <ls_key>-name = 'LocaleCountry'.
  <ls_key>-value = 'DE'.

  APPEND INITIAL LINE TO lt_master_keys ASSIGNING <ls_key>.
  <ls_key>-name = 'LocaleLanguage'.
  <ls_key>-value = 'E'.

  APPEND INITIAL LINE TO lt_master_keys ASSIGNING <ls_key>.
  <ls_key>-name = 'OutputControlApplicationObjectType'.
  <ls_key>-value = 'PURCHASE_ORDER'.

  APPEND INITIAL LINE TO lt_master_keys ASSIGNING <ls_key>.
  <ls_key>-name = 'OutputControlApplicationObject'.
  <ls_key>-value = p_po_num.

  APPEND INITIAL LINE TO lt_master_keys ASSIGNING <ls_key>.
  <ls_key>-name = 'OutputRequestItem'.
  <ls_key>-value = '000001'.

  APPEND INITIAL LINE TO lt_master_keys ASSIGNING <ls_key>.
  <ls_key>-name = 'OutputDocumentType'.
  <ls_key>-value = 'PURCHASE_ORDER'.

  APPEND INITIAL LINE TO lt_master_keys ASSIGNING <ls_key>.
  <ls_key>-name = 'Recipient'.
  <ls_key>-value = ls_ekko-lifnr.

  APPEND INITIAL LINE TO lt_master_keys ASSIGNING <ls_key>.
  <ls_key>-name = 'RecipientRole'.
  <ls_key>-value = 'LF'.

  APPEND INITIAL LINE TO lt_master_keys ASSIGNING <ls_key>.
  <ls_key>-name = 'SenderCountry'.
  <ls_key>-value = 'DE'.


  lo_cl_somu_form_services = cl_somu_form_services=>get_instance( ).


  lo_cl_somu_form_services->get_document( 
   EXPORTING iv_master_form_name  = 'SOMU_FORM_MASTER_A4'
             iv_form_name         = 'MM_PUR_PURCHASE_ORDER'
             it_key               = lt_keys
             it_master_key        = lt_master_keys
             iv_form_language     = 'E'
             iv_form_country      = 'DE'
  IMPORTING  ev_content          = lv_content
             ev_xml               = lv_xml
             ev_pages             = lv_pages
             ev_trace_string      = lv_trace_string
             ev_stop_processing   = lv_stop_processing
             et_message           = lt_message ).
  IF sy-subrc <> 0.
  ENDIF.


  CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
    EXPORTING
      buffer        = lv_content
    IMPORTING
      output_length = lv_output_length
    TABLES
      binary_tab    = lt_generated_pdf.


  " Shows a preview of the generated PDF file in a popup window.
  CALL FUNCTION 'FDM_COLL_INV_PDF_SHOW'
    EXPORTING
      t_pdf = lt_generated_pdf.


"=================================================================================================================

  "Object References
DATA: lo_bcs         TYPE REF TO cl_bcs,
      lo_doc_bcs     TYPE REF TO cl_document_bcs,
      lo_recep       TYPE REF TO if_recipient_bcs,
      lo_sapuser_bcs TYPE REF TO cl_sapuser_bcs,
      lo_cx_bcx      TYPE REF TO cx_bcs,
      lv_string_text  TYPE string,
      lt_text           TYPE bcsy_text,
      lv_bin_filesize TYPE so_obj_len,
      lv_sent_to_all  TYPE os_boolean,
      lt_binary_content TYPE solix_tab.

  CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
    EXPORTING
      buffer        = lv_content
    IMPORTING
      output_length = lv_output_length
    TABLES
      binary_tab    = lt_binary_content[].

lv_bin_filesize = lv_output_length.

  TRY.
*     -------- create persistent send request ------------------------
    lo_bcs = cl_bcs=>create_persistent( ).
      "First line
      CONCATENATE 
                 'Dear Colleague' cl_abap_char_utilities=>newline 
      INTO lv_string_text.
    APPEND lv_string_text TO lt_text.
    CLEAR lv_string_text.
    "Second line
    CONCATENATE 'Please find attached a test smartform.'
     cl_abap_char_utilities=>newline INTO lv_string_text.
    APPEND lv_string_text TO lt_text.
    CLEAR lv_string_text.
    "Third line
    APPEND 'Best Regards,' TO lt_text.
    "Fourth line
    APPEND 'Systems Administrator.' TO lt_text.

*---------------------------------------------------------------------
*-----------------&      Create Document     *------------------------
*---------------------------------------------------------------------
    lo_doc_bcs = cl_document_bcs=>create_document(
                    i_type    = 'RAW'
                    i_text    = lt_text[]
                    i_length  = '12'
                    i_subject = 'Test Email' ).   "Subject of the Email

*---------------------------------------------------------------------
*-----------------&   Add attachment to document     *----------------
*---------------------------------------------------------------------
*     BCS expects document content here e.g. from document upload
*     binary_content = ...
    CALL METHOD lo_doc_bcs->add_attachment
      EXPORTING
        i_attachment_type    = 'PDF'
        i_attachment_size    = lv_bin_filesize
        i_attachment_subject = 'Test Email'
        i_att_content_hex    = lt_binary_content.

*     add document to send request
    CALL METHOD lo_bcs->set_document( lo_doc_bcs ).

*---------------------------------------------------------------------
*------------------------&   Set Sender     *-------------------------
*---------------------------------------------------------------------
*    lo_sapuser_bcs = cl_sapuser_bcs=>create( sy-uname ).
*    CALL METHOD lo_bcs->set_sender
*      EXPORTING
*        i_sender = lo_sapuser_bcs.

lo_recep = 
cl_cam_address_bcs=>create_internet_address('Receiving Email Address').

"Add recipient with its respective attributes to send request
    CALL METHOD lo_bcs->add_recipient
      EXPORTING
        i_recipient = lo_recep
        i_express   = 'X'.

    CALL METHOD lo_bcs->set_send_immediately
      EXPORTING
        i_send_immediately = 'X'.

*---------------------------------------------------------------------
*-----------------&   Send the email    *-----------------------------
*---------------------------------------------------------------------
    CALL METHOD lo_bcs->send(
      EXPORTING
        i_with_error_screen = 'X'
      RECEIVING
        result              = lv_sent_to_all ).

    IF lv_sent_to_all IS NOT INITIAL.
      COMMIT WORK.
    ENDIF.


*---------------------------------------------------------------------
*-----------------&   Exception Handling     *------------------------
*---------------------------------------------------------------------
  CATCH cx_bcs INTO lo_cx_bcx.
    "Appropriate Exception Handling
    WRITE: 'Exception:', lo_cx_bcx->error_type.
ENDTRY.

PS. you can use same concept if you are creating a total custom fragment on your own but you need to 

◉ Create OData Model 
◉ Create Master Template using Maintain Form Template Fiori APP / SFP

Calling Fragment Form & Send it as an attachment using ABAP Walk-Through

◉ Create Content Template using Maintain Form Template Fiori APP / SFP

Calling Fragment Form & Send it as an attachment using ABAP Walk-Through

Start building Up your Solution, i haven't tried build a full custom solution from A to Z but this is the main idea for it.

No comments:

Post a Comment