Wednesday, 15 February 2023

Save/Process Incoming e-mail and attachments in SAP

Summary: This blog post will demonstrate how to handle incoming email with PDF attachments and save them against any transaction in SAP.

We will use GOS functionality to save the document but same kind of logiccan be used to save/process the attachments in the SAP system. I am taking an example of CRM billing document here.

(Since there is no designated space in CRM billing to store documents at the transaction level, we chosen to enable the GOS toolbar and save all transaction-related attachments there.

First, we must confirm that the specified email domain is permitted by the T-code SCOT’s settings for Inbound Messages. (Here it is *, which denotes that it accepts all.)

SAP ABAP Certification, SAP ABAP Career, SAP ABAP Skills, SAP ABAP Jobs, SAP ABAP Tutorial and Materials

In next step, under Inbound processing, enter recipient address ( generally it should be unique system address and should connect basis/security team before putting any email address over here, Just to demonstrate the solution, I am putting specific email ID), Exit Name ( Z-class ), calling sequence and save.

SAP ABAP Certification, SAP ABAP Career, SAP ABAP Skills, SAP ABAP Jobs, SAP ABAP Tutorial and Materials

Now create same exit (class) in T-code SE24 and with interface IF_INBOUND_EXIT_BCS.

SAP ABAP Certification, SAP ABAP Career, SAP ABAP Skills, SAP ABAP Jobs, SAP ABAP Tutorial and Materials

Next implement both methods coming from interface as per below code snippet.

Method : IF_INBOUND_EXIT_BCS~CREATE_INSTANCE

*Create instance of the object with the class itself

    DATA(lo_ref_instance) = NEW zcl_billing_email_in( ).
    IF lo_ref_instance IS BOUND.
      ro_ref = lo_ref_instance.
    ENDIF.

Method : IF_INBOUND_EXIT_BCS~PROCESS_INBOUND

In order to read/parse the data and identify the transaction to work on, we requested that the sender provide a reference number in SAP (in this case, the CRM billing document) in the subject line.

  METHOD if_inbound_exit_bcs~process_inbound.
    CONSTANTS: lc_pdf               TYPE char3 VALUE 'PDF',        "Document Type PDF
               lc_hyphen            TYPE char01 VALUE '-'.

    DATA: lv_official_doc TYPE itl_official_docno.        "Billing Official Document

    CLEAR: e_retcode, es_t100msg.

*Extract Attachment from e-mail
    TRY .
        IF io_sreq IS BOUND.
* Get document
          DATA(lo_ref_document) = io_sreq->get_document( ).
          IF lo_ref_document IS BOUND.
* Get subject line of the e-mail
            SPLIT lo_ref_document->get_subject( ) AT lc_hyphen INTO DATA(lv_doc1) lv_official_doc.

* Find all the PDF attachments and process it.
            lv_official_doc = shift_left( lv_official_doc ).
            IF lv_official_doc IS NOT INITIAL.
* Extract all the billing details from official document in respect to billing
              TRY.
                  IF lv_billing_doc IS NOT INITIAL.
                    DO lo_ref_document->get_body_part_count( ) TIMES.
                      TRY.
                          DATA(lv_doc_type) = lo_ref_document->get_body_part_attributes( im_part = sy-index )-doc_type.
                          TRANSLATE lv_doc_type TO UPPER CASE.

* If Document type is PDF then only proceed as program needs to look into PDF attachments only
                          IF lv_doc_type = lc_pdf.
                            DATA(lv_pdffound_flag) = abap_true.
* Get the file name of attached document
                            DATA(lv_filename) = lo_ref_document->get_body_part_attributes( im_part = sy-index  )-filename.

* Get the content of attached file in hex format.
                            DATA(ls_body_part_content) = lo_ref_document->get_body_part_content( sy-index ).

                            IF lv_filename IS NOT INITIAL AND ls_body_part_content IS NOT INITIAL.
* Attach PDF documents against Billing document which would be shown under attachments section in GOS toolbar
                              CALL METHOD me->attach_docs_in_billing
                                EXPORTING
                                  iv_body_part_content = ls_body_part_content
                                  iv_billing_doc       = lv_billing_doc
                                  iv_objtype           = lv_objtype
                                  iv_filename          = lv_filename
                                IMPORTING
                                  ev_data_xstring      = DATA(lv_xstring).
                            ENDIF.
                          ENDIF.
                        CATCH cx_document_bcs.
                          CONTINUE.
                      ENDTRY.
                      CLEAR: lv_xstring,ls_body_part_content,
                             lv_doc_type, lv_filename.
                    ENDDO.
                  ENDIF.
                CATCH cx_abap_error_analyze.
                  e_retcode  = if_inbound_exit_bcs=>gc_continue.
              ENDTRY.
            ENDIF.
          ENDIF.
        ENDIF.
      CATCH cx_os_object_not_found.
        e_retcode  = if_inbound_exit_bcs=>gc_continue.
    ENDTRY.
  ENDMETHOD.
 
Method : ATTACH_DOCS_IN_BILLING

The below method is invoked within the aforementioned code fragment and is required to finish the end-to-end functionality.

 CONSTANTS : lc_region_b    TYPE so_fol_rg VALUE 'B',
                lc_appl_crmb   TYPE bef_appl VALUE 'CRMB',
                lc_objsns_o    TYPE so_obj_sns VALUE 'O',
                lc_fileext_pdf TYPE so_fileext VALUE 'pdf',
                lc_objtype_ext TYPE so_obj_tp VALUE 'EXT'.

    DATA: lt_objhead   TYPE STANDARD TABLE OF soli,
          ls_obj_id    TYPE soodk,
          ls_folder_id TYPE soodk,
          lt_data      TYPE soli_tab.

    CLEAR ev_data_xstring.
    IF iv_billing_doc IS NOT INITIAL
      AND iv_body_part_content-cont_hex IS NOT INITIAL.

      TRY.
*Convert Hex data into Xstring
          CALL METHOD cl_bcs_convert=>xtab_to_xstring
            EXPORTING
              it_xtab    = iv_body_part_content-cont_hex
            RECEIVING
              rv_xstring = DATA(lv_xstring).
          IF lv_xstring IS NOT INITIAL.
* Convert XString data to SOLIX format
            CALL METHOD cl_bcs_convert=>xstring_to_solix
              EXPORTING
                iv_xstring = lv_xstring
              RECEIVING
                et_solix   = DATA(lt_solix).
            IF lt_solix IS NOT INITIAL.
* Convert binary (SOLIXTAB) to SOLITAB
              CALL FUNCTION 'SO_SOLIXTAB_TO_SOLITAB'
                EXPORTING
                  ip_solixtab = lt_solix
                IMPORTING
                  ep_solitab  = lt_data.
            ENDIF.
          ENDIF.
        CATCH cx_bcs .
          RETURN.
      ENDTRY.

      IF lt_data IS NOT INITIAL.
* Get Folder ID for root
        CALL FUNCTION 'SO_FOLDER_ROOT_ID_GET'
          EXPORTING
            region                = lc_region_b
          IMPORTING
            folder_id             = ls_folder_id
          EXCEPTIONS
            communication_failure = 1
            owner_not_exist       = 2
            system_failure        = 3
            x_error               = 4
            OTHERS                = 5.
        IF sy-subrc EQ 0 AND ls_folder_id IS NOT INITIAL.
          DATA(wa_obj_data) = VALUE sood1( objsns = lc_objsns_o           "sensitivity of object (o-standard)
                                           objla = sy-langu               "language
                                           objdes = iv_filename           "filename
                                           file_ext = lc_fileext_pdf      "file extension PDF
                                           objlen = lines( lt_data ) * 255 ).

* Insert PDF Attachment data
          CALL FUNCTION 'SO_OBJECT_INSERT'
            EXPORTING
              folder_id                  = ls_folder_id
              object_hd_change           = wa_obj_data
              object_type                = lc_objtype_ext                   "PC Document
            IMPORTING
              object_id                  = ls_obj_id
            TABLES
              objcont                    = lt_data
              objhead                    = lt_objhead
            EXCEPTIONS
              active_user_not_exist      = 1
              communication_failure      = 2
              component_not_available    = 3
              dl_name_exist              = 4
              folder_not_exist           = 5
              folder_no_authorization    = 6
              object_type_not_exist      = 7
              operation_no_authorization = 8
              owner_not_exist            = 9
              parameter_error            = 10
              substitute_not_active      = 11
              substitute_not_defined     = 12
              system_failure             = 13
              x_error                    = 14
              OTHERS                     = 15.

* To link the document attachment and business object
          IF sy-subrc = 0 AND ls_obj_id IS NOT INITIAL.
            DATA(ls_folmem_k) = VALUE sofmk( foltp = ls_folder_id-objtp
                                             folyr = ls_folder_id-objyr
                                             folno = ls_folder_id-objno
                                             doctp = ls_obj_id-objtp
                                             docyr = ls_obj_id-objyr
                                             docno = ls_obj_id-objno ).

            DATA(ls_attach) = VALUE borident( objtype = cl_gos_api=>c_message
                                              objkey = CONV swo_typeid( ls_folmem_k ) ).

            DATA(ls_object) = VALUE borident( objkey = CONV swo_typeid( iv_billing_doc && lc_appl_crmb )  " Billing Doc and Application
                                              objtype = iv_objtype ).                                      "Billing Business Object
* Create PDF Attachment in Billing GOS toolbar
            CALL FUNCTION 'BINARY_RELATION_CREATE'
              EXPORTING
                obj_rolea      = ls_object
                obj_roleb      = ls_attach
                relationtype   = cl_gos_api=>c_atta(4)
              EXCEPTIONS
                no_model       = 1
                internal_error = 2
                unknown        = 3
                OTHERS         = 4.
            IF sy-subrc EQ 0.
              ev_data_xstring = lv_xstring.
            ENDIF.
          ENDIF.
        ENDIF.
      ENDIF.
    ENDIF.
 
Now trigger the email with PDF attachments along with Billing document( or reference #) in subject line.

SAP ABAP Certification, SAP ABAP Career, SAP ABAP Skills, SAP ABAP Jobs, SAP ABAP Tutorial and Materials

As a result, we can see PDF documents stored in SAP and can be seen in GOS toolbar.

SAP ABAP Certification, SAP ABAP Career, SAP ABAP Skills, SAP ABAP Jobs, SAP ABAP Tutorial and Materials

No comments:

Post a Comment