Dear Friends

Most of us have a requirement where clients try to use shortcuts in SAP for Approvals. I’ve seen many people asking the same question/requirement in SCN for Offline approvals. Even this was a requirement once in my case also. Then I’ve found one similar document with same requirement with ABAP stuff & later I tried the same. So, I wanted to make this as a document & share with all the SCN users. Hope you all support me.

Goto T-code SMICM or run Report RSMONICM_STANDARD

A.png

Now display the services via GotoàServices or press Shift+F1

Now select the logs & Activate

/wp-content/uploads/2013/12/b_348832.png

Now we can see the Active services

Now we need to configure & set the Email Exit Configuration

Goto T-code SO50

/wp-content/uploads/2013/12/c_348953.png

We can also access  via T-code SCOT &  by  following the menu path  click on SettingsàIn Bound processing as ,It also calls SO50 or we can also run a report  BCS_IBND_MAINT

/wp-content/uploads/2013/12/d_348954.png

We have to write an Inbound Exit Class that will process the Inbound E-Mails. That class should be mentioned here.

/wp-content/uploads/2013/12/e_348955.png

Note that we mention our offline e-mail ID here (riploffline@eccdev.yourdomain.com). The class ZZZCL_PROCESS_INBOUND_WORKFLOW is the Exit Class designed to process inbound e-mails as per our need. By default generally the first entry with the CL_APPOINTMENT_REPLY is always present. We include our entry here and set the call sequence. The Document Class / Type is set as “*” to allow all types of documents available in ECC.


Creation of Inbound Exit class

This class implements the interface IF_INBOUND_EXIT_BCS (BCS: Exit for Inbound Processing). The properties tab of the class is shown as

F.png

Now click on Interface tab

/wp-content/uploads/2013/12/g_348957.png

Now click on Methods

/wp-content/uploads/2013/12/h_348958.png

The CREATE_INSTANCE method is called by standard SAP (via SO50 Configuration) to create a unique instance for each inbound e-mail. The code is written below


METHOD if_inbound_exit_bcs~create_instance.

  DATA: ref TYPE REF TO zzzcl_process_inbound_workflow.

* Check if the Instance is initial

  IF ref IS INITIAL.

    CREATE OBJECT ref.

  ENDIF.

* Return the Instance

  ro_ref = ref.

  1. ENDMETHOD.

The interface of the method CREATE_INSTANCE is shown below

/wp-content/uploads/2013/12/i_348959.png

The PROCESS_INBOUND method is the place where we write the exit logic. This is where we will process the desired work item of the workflow and process it based on the e-mail action / reply created by the automated e-mail. The interface of method PROCESS_INBOUND is shown below.

/wp-content/uploads/2013/12/j_348960.png

The code in PROCESS_INBOUND method is below

METHOD if_inbound_exit_bcs~process_inbound.

* Declare for Inbound E-Mail processing (ENJOY )

  DATA: lo_document     TYPE REF TO if_document_bcs,

        l_mail_attr     TYPE bcss_dbpa,

        l_mail_content  TYPE bcss_dbpc,

        lo_reply        TYPE REF TO cl_send_request_bcs,

        sender          TYPE REF TO if_sender_bcs,

        sender_addr     TYPE string,

        lv_email        TYPE comm_id_long,

        send_request    TYPE REF TO cl_bcs,

        ltext           TYPE bcsy_text,

        body_text       TYPE so_text255,

        document        TYPE REF TO cl_document_bcs,

        ex_sender       TYPE REF TO cl_sapuser_bcs,

        recipient       TYPE REF TO if_recipient_bcs,

        bcs_exception   TYPE REF TO cx_bcs,

        sent_to_all     TYPE os_boolean,

        lv_action       TYPE char01,

        lv_wid          TYPE char12,

        lv_wid_num      TYPE sww_wiid,

        lv_wid_func     TYPE swr_struct-workitemid,

        ls_swwwihead    TYPE swwwihead,

        lv_new_status   TYPE sww_wistat,

        lv_action_text  TYPE char12.

*——————————————————————–*

*- Get a pointer to the reply email object -*

*——————————————————————–*

  TRY.

      lo_reply = io_sreq->reply( ).

    CATCH cx_send_req_bcs.

  ENDTRY.

**** Check to make sure this is from an approved Sender

  sender = io_sreq->get_sender( ).

  sender_addr =  sender->address_string( ).

  lv_email = sender_addr.

  TRANSLATE sender_addr TO UPPER CASE.

**** Only reply if this message came from within our mail system or domain

**** SPAMMERS Beware, your e-mails will not be processed!!!

  IF sender_addr CS ‘@YOURDOMAIN.COM‘.

**** send reply and inbound processing

*——————————————————————–*

*- Get email subject -*

*——————————————————————–*

    TRY.

        lo_document = io_sreq->get_document( ).

        l_mail_attr = lo_document->get_body_part_attributes( ‘1’ ).

      CATCH cx_document_bcs.

    ENDTRY.

*——————————————————————–*

*- Get mail body, here you can read the REJECTION Reason -*

*——————————————————————–*

    TRY.

        l_mail_content = lo_document->get_body_part_content( ‘1’ ).

      CATCH cx_document_bcs.

    ENDTRY.

*——————————————————————–*

* YAAAAAHHHHHHOOOO at this point I have the Subject and the Body

*——————————————————————–*

* Now read the subject and process the work item

* Condense the subject to remove blank spaces

    CONDENSE l_mail_attr-subject.

* Read the action

    lv_action = l_mail_attr-subject+0(1).

* Read the work item ID

    lv_wid    = l_mail_attr-subject+1(12).

* Pass to variables

    lv_wid_num = lv_wid.

    lv_wid_func = lv_wid_num.

* First check the status of the work item, process only if READY or IN-PROCESS

    SELECT SINGLE *

      FROM swwwihead

      INTO ls_swwwihead

      WHERE wi_id = lv_wid_num.

* If data not found, indicates an invalid e-mail sent to offline ID

    IF sy-subrc NE 0.

      lv_wid = ‘INVALID WID’.

    ENDIF.

* Check the status, if COMPLETED, send the notification

    IF ls_swwwihead-wi_stat = ‘COMPLETED’.

      TRY.

*     ——– create persistent send request ————————

          send_request = cl_bcs=>create_persistent( ).

*     ——– create and set document ——————————-

*     Build the e-mail Body

          CLEAR: body_text.

          CONCATENATE ‘WORK ITEM ID : ‘

                      lv_wid

                      ‘is in status “COMPLETED”‘ INTO body_text SEPARATED BY space.

          APPEND body_text TO ltext.

          CLEAR: body_text.

          CONCATENATE ‘This has already been processed ‘

                      ‘and cannot be processed again.’ INTO body_text SEPARATED BY space.

          APPEND body_text TO ltext.

          document = cl_document_bcs=>create_document(

                                i_type    = ‘RAW’

                                i_text    = ltext

                                i_length  = ‘510’

                                i_subject = ‘Work Item has already been processed’ ).

*     Add document to send request

          CALL METHOD send_request->set_document( document ).

*     ——— set sender ——————————————-

*     note: this is necessary only if you want to set the sender

*           different from actual user (SY-UNAME). Otherwise sender is

*           set automatically with actual user.

          sender = cl_sapuser_bcs=>create( ‘ECCOFFLINE’ ).

          CALL METHOD send_request->set_sender

            EXPORTING

              i_sender = sender.

*     ——— Add recipient (e-mail address) ———————–

*     Create recipient – passing the receipient e-mail ID

          recipient = cl_cam_address_bcs=>create_internet_address( lv_email ).

*     Add recipient with its respective attributes to send request

          CALL METHOD send_request->add_recipient

            EXPORTING

              i_recipient = recipient

              i_express   = ‘X’.

*     ———- Send document —————————————

          CALL METHOD send_request->send(

            EXPORTING

              i_with_error_screen = ‘X’

            RECEIVING

              result              = sent_to_all ).

          COMMIT WORK.

        CATCH cx_bcs INTO bcs_exception.

      ENDTRY.

    ELSEIF ls_swwwihead-wi_stat = ‘READY’ OR

           ls_swwwihead-wi_stat = ‘STARTED’.

* First process the Work Item Based on the action

      IF lv_action = ‘A’.

* Set the ACTION Text

        lv_action_text = ‘APPROVED’.

* If APPROVED

        CALL FUNCTION ‘SAP_WAPI_DECISION_COMPLETE’

          EXPORTING

            workitem_id          = lv_wid_func

            language             = sy-langu

            user                 = sy-uname

            decision_key         = ‘0001’ “Approval Node

            do_commit            = ‘X’

          IMPORTING

            new_status           = lv_new_status

*  TABLES

*    MESSAGE_LINES        =

*    MESSAGE_STRUCT       =

                  .

      ELSEIF lv_action = ‘R’.

* Set the ACTION Text

        lv_action_text = ‘REJECTED’.

* If REJECTED

        CALL FUNCTION ‘SAP_WAPI_DECISION_COMPLETE’

          EXPORTING

            workitem_id          = lv_wid_func

            language             = sy-langu

            user                 = sy-uname

            decision_key         = ‘0002’ “Rejection Node

            do_commit            = ‘X’

          IMPORTING

            new_status           = lv_new_status

*  TABLES

*    MESSAGE_LINES        =

*    MESSAGE_STRUCT       =

                  .

      ENDIF.

* After the action now send the e-mail

      TRY.

*     ——– create persistent send request ————————

          send_request = cl_bcs=>create_persistent( ).

*     ——– create and set document ——————————-

*     Build the e-mail Body

          CLEAR: body_text.

          CONCATENATE ‘WORK ITEM ID : ‘

                      lv_wid

                      ‘has been’

                      lv_action_text INTO body_text SEPARATED BY space.

          APPEND body_text TO ltext.

          CLEAR: body_text.

          CONCATENATE ‘New status of work item is ‘

                      lv_new_status INTO body_text SEPARATED BY space.

          APPEND body_text TO ltext.

          document = cl_document_bcs=>create_document(

                                i_type    = ‘RAW’

                                i_text    = ltext

                                i_length  = ‘510’

                                i_subject = ‘Work Item processing confirmation’ ).

*     Add document to send request

          CALL METHOD send_request->set_document( document ).

*     ——— set sender ——————————————-

*     note: this is necessary only if you want to set the sender

*           different from actual user (SY-UNAME). Otherwise sender is

*           set automatically with actual user.

          sender = cl_sapuser_bcs=>create( ‘ECCOFFLINE’ ).

          CALL METHOD send_request->set_sender

            EXPORTING

              i_sender = sender.

*     ——— Add recipient (e-mail address) ———————–

*     Create recipient – passing the receipient e-mail ID

          recipient = cl_cam_address_bcs=>create_internet_address( lv_email ).

*     Add recipient with its respective attributes to send request

          CALL METHOD send_request->add_recipient

            EXPORTING

              i_recipient = recipient

              i_express   = ‘X’.

*     ———- Send document —————————————

          CALL METHOD send_request->send(

            EXPORTING

              i_with_error_screen = ‘X’

            RECEIVING

              result              = sent_to_all ).

          COMMIT WORK.

        CATCH cx_bcs INTO bcs_exception.

      ENDTRY.

    ELSE.

* This means the work item is in ERROR or some exception status, NOTIFY!!!!!

* Here you can reply back to the user if they send invalid e-mails to ECCOFFLINE other then clicking on the Processing Links

      TRY.

*     ——– create persistent send request ————————

          send_request = cl_bcs=>create_persistent( ).

*     ——– create and set document ——————————-

*     Build the e-mail Body based on the Work Item ID

          IF lv_wid = ‘INVALID WID’.

* Build E-Mail for Invalid WID

            CLEAR: body_text.

            CONCATENATE ‘This system e-mail is meant only for OFFLINE WORKFLOW Processing.’

                        ‘Please do not send any e-mails to this ID other then via Workflow Processing Offline Links.’ INTO body_text SEPARATED BY space.

            APPEND body_text TO ltext.

            CLEAR: body_text.

            CONCATENATE ‘This is a system generated auto e-mail ‘

                        ‘Please do not reply to this ID.’ INTO body_text SEPARATED BY space.

            APPEND body_text TO ltext.

            document = cl_document_bcs=>create_document(

                                  i_type    = ‘RAW’

                                  i_text    = ltext

                                  i_length  = ‘510’

                                  i_subject = ‘System ID – Please do not reply or send E-Mail’ ).

          ELSE.

* Build E-Mail body for Valid WID gone in exception status

            CLEAR: body_text.

            CONCATENATE ‘WORK ITEM ID ‘

                        lv_wid

                        ‘might not have processed as desired.’ INTO body_text SEPARATED BY space.

            APPEND body_text TO ltext.

            CLEAR: body_text.

            CONCATENATE ‘Please forward this e-mail to the ‘

                        ‘System / Workflow Administrator to help you and analyze / solve it.’ INTO body_text SEPARATED BY space.

            APPEND body_text TO ltext.

            document = cl_document_bcs=>create_document(

                                  i_type    = ‘RAW’

                                  i_text    = ltext

                                  i_length  = ‘510’

                                  i_subject = ‘Work Item exception might have occured’ ).

          ENDIF.

*     Add document to send request

          CALL METHOD send_request->set_document( document ).

*     ——— set sender ——————————————-

*     note: this is necessary only if you want to set the sender

*           different from actual user (SY-UNAME). Otherwise sender is

*           set automatically with actual user.

          sender = cl_sapuser_bcs=>create( ‘ECCOFFLINE’ ).

          CALL METHOD send_request->set_sender

            EXPORTING

              i_sender = sender.

*     ——— Add recipient (e-mail address) ———————–

*     Create recipient – passing the receipient e-mail ID

          recipient = cl_cam_address_bcs=>create_internet_address( lv_email ).

*     Add recipient with its respective attributes to send request

          CALL METHOD send_request->add_recipient

            EXPORTING

              i_recipient = recipient

              i_express   = ‘X’.

*     ———- Send document —————————————

          CALL METHOD send_request->send(

            EXPORTING

              i_with_error_screen = ‘X’

            RECEIVING

              result              = sent_to_all ).

          COMMIT WORK.

        CATCH cx_bcs INTO bcs_exception.

      ENDTRY.

    ENDIF.

* End the IF for checking valid E-Mail

  ENDIF.

ENDMETHOD.

Creation of Workflow will be continued in Part-2. Kindly let me know if anything need to be added here or I missed.

Cheers

Pradyp

To report this post you need to login first.

6 Comments

You must be Logged on to comment or reply to a post.

  1. Cesar Palacios

    Hello thanks for sharing your knowledge about the Offline Mail Approval Process. Im trying to implement it but im having some troubles and some questions too:

     

    1. The riploffline@eccdev.yourdomain.com must exist in the mail server or its not necessary to create this id email?

     

    2. How do you create the eccdev sub domain?

     

    3. Right now im using a fake email wfbatch@yourdomain.com, but my method PROCESS_INBOUND is not being called, is there any error with the email or do i need to create the email id and subdomain so my method is called?

     

    4. I created a ZTEST table that is populated in both methods CREATE_INSTANCE (with a ‘This is a Test Create Instance” text) and PROCESS_INBOUND (with a ‘This is a Test Process Inbound” text). With the email used in point 3, somehow the ZTEST table has the ‘This is a Test Create Instance” text and it looks that the class is being called but only the CREATE_INSTANCE method, and the PROCESS_INBOUND method is not being called.

     

    Thanks for your help and sorry for my english

    (0) 
    1. Mykola Chekalov

      Hello.

       

      Did you this Mail Approval?

      I read this clause and don’t understand, why need to create the new user and not use wf-batch user?

      Could you share your opinion or experience about this theme please?

       

      Thx.

      (0) 

Leave a Reply