Recently I got the demand to enhance the leave request approvel workflow with some mail steps. These mails should also include the attachments, which can be uploaded in the “Leave Request” Fiori App.
To achive this, I used the exit functionality in the mail step.
There you have to provide a class name. The class has to implement the following interface:
IF_SWF_IFS_WORKITEM_EXIT
You will get a method you can implement.
This Method has two parameters, the “Event Name” and the “Workitem Context”.
With the event, you are able to control, in which situations your exit should be fired. In my case, I just need my code run when the workitem is created (event “CREATED”). You’ll find all usable events in domain SWW_EVTTYP.
To get and pass back the attachment to the mail step, a few things need to be done.
First, get the curent workitem container and check, if there is already any attachment. If not, read the request id from the leave request. With this request id, you are able to find the attachment you need. I’ve already written a method for that, you’ll find below. Then convert the xstring to a solix table, create the attachment document with function module “SO_DOCUMENT_INSERT_API1” and “SWO_CREATE” and finally pass it to the container.
METHOD if_swf_ifs_workitem_exit~event_raised.
DATA: lv_container TYPE REF TO if_swf_ifs_parameter_container,
lv_attach TYPE TABLE OF obj_record,
lv_folder_id TYPE soodk,
wa_document_info TYPE sofolenti1,
lv_data TYPE sodocchgi1,
lv_objtype TYPE swo_objtyp,
lv_objkey TYPE swo_typeid,
lv_return TYPE swotreturn,
lv_sofm TYPE swo_objhnd,
lv_objject TYPE obj_record,
tb_obj TYPE TABLE OF obj_record,
it_solix_tab1 TYPE solix_tab,
req_id TYPE tim_req_id,
lv_doc_type TYPE so_obj_tp.
CHECK im_event_name = 'CREATED'.
* Fetch Container
lv_container = im_workitem_context->get_wi_container( ).
* Read attachment to confirm that there is no duplication
TRY.
lv_container->get(
EXPORTING
name = '_ATTACH_OBJECTS'
IMPORTING
value = lv_attach ).
CATCH: cx_swf_cnt_elem_not_found,
cx_swf_cnt_elem_type_conflict,
cx_swf_cnt_unit_type_conflict,
cx_swf_cnt_container.
ENDTRY.
CHECK lv_attach IS INITIAL.
CALL FUNCTION 'SO_FOLDER_ROOT_ID_GET'
EXPORTING
owner = sy-uname
region = 'B'
IMPORTING
folder_id = lv_folder_id.
* Get Request ID
lv_container->get(
EXPORTING
name = 'RequestId'
IMPORTING
value = req_id ).
* Get XSTRING of attachment
zcl_xxx=>get_req_attachment(
EXPORTING
iv_req_id = req_id
IMPORTING
ev_xstring = DATA(xstring)
es_attachment = DATA(ls_attachment) ).
CHECK xstring IS NOT INITIAL.
* Get document type
SELECT SINGLE doc_type FROM toadd INTO @lv_doc_type
WHERE mimetype EQ @ls_attachment-file_type.
IF sy-subrc NE 0.
lv_doc_type = 'PDF'. "If doc_type not found, at least try with pdf.
ENDIF.
* Create and set document
it_solix_tab1 = cl_document_bcs=>xstring_to_solix( xstring ).
* Creating First attachment
lv_data-obj_name = ls_attachment-file_name.
lv_data-obj_descr = ls_attachment-file_name.
lv_data-obj_langu = sy-langu.
lv_data-sensitivty = 'P'.
* lv_data-doc_size = ls_attachment-file_size.
CALL FUNCTION 'SO_DOCUMENT_INSERT_API1'
EXPORTING
folder_id = lv_folder_id
document_data = lv_data
document_type = lv_doc_type
IMPORTING
document_info = wa_document_info
TABLES
contents_hex = it_solix_tab1
EXCEPTIONS
folder_not_exist = 1
document_type_not_exist = 2
operation_no_authorization = 3
parameter_error = 4
x_error = 5
enqueue_error = 6
OTHERS = 7.
* Populate object type and object key for create an instance
lv_objtype = 'SOFM'.
lv_objkey = wa_document_info-doc_id.
CALL FUNCTION 'SWO_CREATE'
EXPORTING
objtype = lv_objtype
objkey = lv_objkey
IMPORTING
object = lv_sofm
return = lv_return
EXCEPTIONS
no_remote_objects = 1
OTHERS = 2.
* Prepare for attaching the object to container
lv_objject-header = 'OBJH'.
lv_objject-type = 'SWO'.
lv_objject-handle = lv_sofm.
APPEND lv_objject TO tb_obj.
*—can be used for other workitems
lv_container->set(
EXPORTING
name = '_ATTACH_OBJECTS'
value = tb_obj[] ).
*–this will add the attachment to email
lv_container->set(
EXPORTING
name = 'ATTACHMENTS'
value = tb_obj[] ).
* Commit the changes
im_workitem_context->do_commit_work( ).
ENDMETHOD.
The following function modules are needed to read the leave request attachment:
METHOD get_req_attachment.
DATA: lv_has_errors TYPE ptreq_has_error_flag,
lt_messages TYPE ptarq_uia_messages_tab,
lt_attachments TYPE hress_t_ptarq_att_info,
ex_has_attachment TYPE boole_d.
CALL FUNCTION 'PT_ARQ_ATTACHMENT_GET'
EXPORTING
im_request_id = iv_req_id
* IM_VERSION_NO =
* IM_DOCUMENT_TYPE =
IMPORTING
ex_has_errors = lv_has_errors
ex_messages = lt_messages
et_attachments = lt_attachments
ex_has_attachment = ex_has_attachment.
CHECK ex_has_attachment EQ abap_true.
TRY.
es_attachment = lt_attachments[ 1 ].
CATCH cx_sy_itab_line_not_found.
ENDTRY.
CALL FUNCTION 'PT_ARQ_ATTACHMENT_DETAIL_GET'
EXPORTING
iv_arc_doc_id = es_attachment-archiv_doc_id
* iv_doc_type =
IMPORTING
ex_file_content = ev_xstring
ex_has_errors = lv_has_errors
ex_messages = lt_messages.
ENDMETHOD.