Overview
SAP provides a robust framework for sending emails, and by leveraging the CL_BCS class, developers can create flexible solutions to manage email communication directly within SAP systems. In this blog post, I'll explain about a custom function module that simplifies email sending, including support for multiple recipients (TO, CC, BCC) and different types of attachments.
Key Features
- Multi-Recipient Support: Easily add recipients as TO, CC, or BCC.
- Attachment Handling: Attach multiple files of different types with ease.
Detailed Walkthrough
Function Module: ZFM_SEND_EMAIL
This custom function module ZFM_SEND_EMAIL efficiently manages email sending by utilizing the CL_BCS class. Here's a breakdown of its key components:
Input and Output Parameters
- Importing Parameters:
- I_SUBJECT: The subject of the email.
- IT_CONTENT: Text content for the email body.
- IT_RECEIPIENTS: List of recipients with types (TO, CC, BCC).
- IT_ATTACHMENTS (optional): List of attachments with types and subjects.
- I_SENDER (optional): Custom sender address.
- Exporting Parameters:
- BAPIRETURN: Return messages indicating the success or failure of the operation.
Table Types
- ZTT_UIYT_IUSR: Contains user ID, email address, and send type.
ZTT_UIYT_IUSR - table type of ZSTR_UIYT_IUSR which has below fields
USRID 1 Types UNAME CHAR 12 0 0 User Name
EMAIL 1 Types AD_SMTPADR CHAR 241 0 0 E-Mail Address
SENDTYPE 1 Types ZSENDTYPE CHAR 2 0 0 Send Type (TO/CC/BC) - ZTT_EMAIL_ATTACHMENT: Handles attachment type, subject, and content.
ZTT_EMAIL_ATTACHMENT - table type of ZSTR_EMAIL_ATTACHMENT which has below fields
ATTACH_TYPE 1 Types SO_OBJ_TP CHAR 3 0 0 Code for document class
ATTACH_SUBJECT 1 Types SO_OBJ_DES CHAR 50 0 0 Short description of contents
ATTACH_XSTRING 1 Types ZXSTRING RAWSTRING 0 0 0 Attachment
Core Logic
- Initialization: Prepare the email content and subject.
- Recipient Assignment: Fetch email addresses and assign send types (TO, CC, BCC).
- Email Content Formatting: Convert plain text or HTML content for the email body.
- Document Creation: Utilize CL_DOCUMENT_BCS to create email content and attachments.
- Email Sending: Execute the send operation and handle any errors or confirmations.
Error Handling
This function module also provides error handling using BAPI message functions, ensuring that any issues encountered during the email sending process are logged and communicated.
Code snippet:
FUNCTION zfm_send_email.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" REFERENCE(I_SUBJECT) TYPE SO_OBJ_DES
*" REFERENCE(IT_CONTENT) TYPE SOLI_TAB
*" REFERENCE(IT_RECEIPIENTS) TYPE ZTT_UIYT_IUSR
*" REFERENCE(IT_ATTACHMENTS) TYPE ZTT_EMAIL_ATTACHMENT OPTIONAL
*" REFERENCE(I_SENDER) TYPE RDTX OPTIONAL
*" EXPORTING
*" REFERENCE(BAPIRETURN) TYPE BAPIRET2_T
*"----------------------------------------------------------------------
DATA: lt_email_content TYPE TABLE OF soli,
ls_email_content TYPE soli,
lt_receipients TYPE TABLE OF zstr_uiyt_iusr,
ls_receipients TYPE zstr_uiyt_iusr.
FIELD-SYMBOLS <fs_receipients> TYPE zstr_uiyt_iusr.
DATA: lv_email_subject TYPE so_obj_des,
lt_message TYPE TABLE OF soli,
ls_return TYPE bapiret2,
lv_text TYPE soli-line,
send_email TYPE REF TO cl_bcs,
document TYPE REF TO cl_document_bcs,
recipient TYPE REF TO if_recipient_bcs,
sent_to_all TYPE os_boolean,
lv_attach_content_solix TYPE solix_tab,
lv_attach_size TYPE so_obj_len.
* Initialization
lt_email_content[] = it_content[].
lv_email_subject = i_subject.
* Validate recipients
IF it_receipients[] IS INITIAL.
CLEAR ls_return.
ls_return-type = 'E'.
ls_return-id = 'ZMSG_DM'.
ls_return-number = '001'.
CALL FUNCTION 'BAPI_MESSAGE_GETDETAIL'
EXPORTING
id = ls_return-id
number = ls_return-number
language = sy-langu
textformat = 'ASC'
IMPORTING
message = ls_return-message.
IF sy-subrc = 0.
APPEND ls_return TO bapireturn.
ENDIF.
RETURN.
ELSE.
lt_receipients[] = it_receipients[].
ENDIF.
* Get Email Id for the User Name
LOOP AT lt_receipients ASSIGNING <fs_receipients> WHERE email IS INITIAL.
SELECT SINGLE b~smtp_addr INTO <fs_receipients>-email
FROM usr21 AS a
INNER JOIN adr6 AS b
ON a~persnumber = b~persnumber
AND a~addrnumber = b~addrnumber
WHERE a~bname = <fs_receipients>-usrid
AND b~date_from LE sy-datum.
ENDLOOP.
* Get the Content of the Mail
APPEND '<body>' TO lt_message.
LOOP AT lt_email_content INTO ls_email_content.
IF ls_email_content-line IS INITIAL OR ls_email_content-line CS '....'.
lv_text = ls_email_content-line.
REPLACE ALL OCCURRENCES OF '....' IN lv_text WITH ''.
ELSE.
CONCATENATE '<p>' ls_email_content-line '</p>' INTO lv_text.
ENDIF.
APPEND lv_text TO lt_message.
ENDLOOP.
APPEND '</body>' TO lt_message.
APPEND '<br>' TO lt_message.
TRY.
* Initiate
send_email = cl_bcs=>create_persistent( ).
* Create Document
document = cl_document_bcs=>create_document(
i_type = 'HTM'
i_subject = lv_email_subject
i_text = lt_message ).
* Add Attachments
LOOP AT it_attachments INTO DATA(ls_attachment).
IF ls_attachment-attach_type IS NOT INITIAL AND
ls_attachment-attach_subject IS NOT INITIAL AND
ls_attachment-attach_xstring IS NOT INITIAL.
lv_attach_content_solix = cl_document_bcs=>xstring_to_solix( ls_attachment-attach_xstring ).
lv_attach_size = xstrlen( ls_attachment-attach_xstring ).
document->add_attachment(
i_attachment_type = ls_attachment-attach_type
i_attachment_subject = ls_attachment-attach_subject
i_attachment_size = lv_attach_size
i_att_content_hex = lv_attach_content_solix ).
ENDIF.
CLEAR ls_attachment.
ENDLOOP.
* Set Document to the Mail
send_email->set_document( document ).
** Optionally Add Sender
* IF i_sender IS NOT INITIAL.
* send_email->set_sender(
* cl_cam_address_bcs=>create_internet_address(
* i_address_string = CONV #( i_sender )
* ) ).
* ENDIF.
* Add Recipients to Mail
LOOP AT lt_receipients INTO ls_receipients WHERE email IS NOT INITIAL.
recipient = cl_cam_address_bcs=>create_internet_address( ls_receipients-email ).
CASE ls_receipients-sendtype.
WHEN 'TO'.
send_email->add_recipient( i_recipient = recipient ).
WHEN 'CC'.
send_email->add_recipient( i_recipient = recipient i_copy = 'X' ).
WHEN 'BC'.
send_email->add_recipient( i_recipient = recipient i_blind_copy = 'X' ).
WHEN OTHERS.
send_email->add_recipient( i_recipient = recipient ).
ENDCASE.
ENDLOOP.
* Send Email
send_email->set_send_immediately( 'X' ).
sent_to_all = send_email->send( i_with_error_screen = 'X' ).
IF sent_to_all EQ 'X'.
COMMIT WORK AND WAIT.
CLEAR ls_return.
ls_return-type = 'S'.
ls_return-id = 'ZMSG_DM'.
ls_return-number = '002'.
CALL FUNCTION 'BAPI_MESSAGE_GETDETAIL'
EXPORTING
id = ls_return-id
number = ls_return-number
language = sy-langu
textformat = 'ASC'
IMPORTING
message = ls_return-message.
IF sy-subrc = 0.
APPEND ls_return TO bapireturn.
ENDIF.
ELSE.
ROLLBACK WORK.
CLEAR ls_return.
ls_return-type = 'E'.
ls_return-id = 'ZMSG_DM'.
ls_return-number = '003'.
CALL FUNCTION 'BAPI_MESSAGE_GETDETAIL'
EXPORTING
id = ls_return-id
number = ls_return-number
language = sy-langu
textformat = 'ASC'
IMPORTING
message = ls_return-message.
IF sy-subrc = 0.
APPEND ls_return TO bapireturn.
ENDIF.
RETURN.
ENDIF.
CATCH cx_address_bcs.
CATCH cx_document_bcs.
CATCH cx_send_req_bcs.
ENDTRY.
ENDFUNCTION. Conclusion
By implementing this custom function module, you can significantly enhance your system's email capabilities. This solution ensures that your email communications are efficient and reliable.
Happy coding!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.