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. For more information, see my blog post Generic Object Services (GOS) toolbar in CRM Billing.)
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.
Now create same exit (class) in T-code SE24 and with interface IF_INBOUND_EXIT_BCS.
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.
As a result, we can see PDF documents stored in SAP and can be seen in GOS toolbar.