Acorel
To Acorel.nl
Acorel background

HOWTO: Add attachments to workflow tasks

Pieter Rijlaarsdam, 25 March 2015

When working with SAP workflow, you might want to add attachments to workflow tasks or emails. In my specific requirement, I wanted to attach a quotation document generated by SAP CRM to the workflow task to approve this quotation.

Imagine you have sales reps offering sharp deals to your customers. As you don’t want the deals to be too sharp, you set a number of parameters in which case you want the quotation to be approved.
When deciding on the approval, the salesmanager should be able to look into the deal at hand.

This article focuses on the step that the salesrep has submitted the quotation for approval. If you want more information on approval rules, output generation etc, feel free to contact me and I might be able to give some hints.

Create the decision step or email

Let’s assume we have a workflow built up, Triggers are correct, task recipient determination has been set-up (using the org model, authorizations or a explicit reference in the quotation document).
Either you have a user decision or an email step in your workflow, and you want them to contain a PDF attachment.

In this example, I will be grabbing a PDF document from the server, and add it to the workitem using the bindings. The PDF document has been created using a custom action just before the workflow was triggered, and thus is present on the server the moment we run through the workflow.

Businessobject enhancement

Enhance your businessobject in SWO1 with an additional method called ‘GET_OUTPUT’.
Make the method a synchronous instance method. You can also choose to create a more ‘general’ function as an enhancement on BUS20001 for instance, or create a custom object with a get_document method.

Add a parameter ‘url’ as importing parameter type string.
Add a parameter ‘PDF’ as exporting parameter type businessobject SOFM.

Add the following code to the method.
——————————————————————
data: lv_url type string.
DATA lv_message TYPE string.
DATA: lv_len TYPE i.
DATA: lv_totallen TYPE i.
DATA: gt_file TYPE solix_tab,
      gs_file TYPE solix,
      folder_id TYPE soodk,
      document_data TYPE sodocchgi2,
      document_type TYPE  soodk-objtp ,
      l_originator TYPE soextreci1-receiver,
      l_originator_type TYPE soextreci1-adr_typ,
      document_info TYPE sofolenti1,
      object_header TYPE swftlisti1,
      object_content TYPE swftlisti1.
SWC_GET_ELEMENT CONTAINER ‘URL’ lv_url.
TRY .
* Open and read the dataset
      OPEN DATASET lv_url FOR INPUT IN BINARY MODE MESSAGE lv_message.

      DO.
        READ DATASET lv_url INTO gs_file ACTUAL LENGTH lv_len.
        IF sy-subrc NE 0.
          EXIT.
        ENDIF.
        APPEND gs_file TO gt_file.
        ADD lv_len TO lv_totallen.
      ENDDO.

      CLOSE DATASET ev_url.
* Get folder ID
      CALL FUNCTION ‘SO_FOLDER_ROOT_ID_GET’
        EXPORTING
          region                = ‘B’
        IMPORTING
          folder_id             = folder_id
        EXCEPTIONS
          communication_failure = 1
          owner_not_exist       = 2
          system_failure        = 3
          x_error               = 4
          OTHERS                = 5.
*Get extension from imported url
CALL FUNCTION ‘CRM_EMAIL_SPLIT_FILENAME’
  EXPORTING
    iv_path            = lv_url
 IMPORTING
   EV_FILENAME        = lv_filename
   EV_EXTENSION       = lv_extension
   EV_MIMETYPE        = lv_mimetype
* Prepare document
      document_data-obj_name = ‘ATTACHMENT’.
      concatenate lv_filename ‘.’ lv_extension
                      into document_data-obj_descr.
      document_data-obj_langu = sy-langu.
      document_data-doc_size = lv_totallen.
      document_data-obj_name = ‘MESSAGE’.
      document_type = lv_extension.
      TRANSLATE lv_extension TO UPPER CASE.
      l_originator = sy-uname.
      APPEND document_data-obj_descr TO object_header.
* Generate SOFM document.
      CALL FUNCTION ‘SO_DOC_INSERT_WITH_ORIG_API1’
        EXPORTING
          folder_id                  = folder_id
          document_data              = document_data
          document_type              = document_type
          originator                 = l_originator
          originator_type            = l_originator_type
        IMPORTING
          document_info              = document_info
        TABLES
          object_header              = object_header
          contents_hex               = gt_file
        EXCEPTIONS
          owner_not_exist            = 1
          folder_not_exist           = 2
          document_type_not_exist    = 3
          operation_no_authorization = 4
          parameter_error            = 5
          x_error                    = 6
          enqueue_error              = 7
          OTHERS                     = 8.
    CATCH cx_root.
      ” Set sy-subrc to the standard error option.
      sy-subrc = 8.
  ENDTRY.
* Create SOFM object
  swc_create_object PDF ‘SOFM’ document_info-doc_id.
  SWC_SET_ELEMENT CONTAINER ‘PDF’ PDF.
——————————————————————-

Workitem action to create the SOFM object

Now that we have created the method to retrieve the attachment and create the SOFM object, we add this to our workflow by creating a standard action.
Bind the URL from the workflow to the method.
We create a SOFM container element called ‘PDF’.
We return the result from the method to the PDF container element.
We can now bind the PDF object from the workflow container to the _ATTACH_OBJECTS table in the decision task.
Make sure you choose ‘APPEND’ as binding instruction, so other attachments will not be overwritten.
The result will be that an attachment will be added to the workitem. Similar functionality should work for the send email task. The element to bind to in this case is ‘Attachments’.
You might also want to implement a self-destruct action to delete the SOFM attachment when the job is done (after the decision or after sending the email) in order clean up. This would especially make sense if you are sending large attachments. Haven’t figured this out yet though, feel free to comment if you have.

Pieter Rijlaarsdam

Read all my blogs

Receive our weekly blog by email?
Subscribe here: