Scheduled_actions_title.JPG

Summary

We have the assignment block for scheduled actions in SAP CRM where the end users could ahead and execute certain actions like generating the adobe forms/smart forms, Sending an email, Starting workflow and other mundane activities. This document is actually simulating the similar service in the form of RFC enabled function module(engulfed as/in ODATA service) which would be consumed in SAPUI5/FIORI app thus allowing to replicate the provision of action profile execution in SAP CRM.

Author(s):

Rajwin Singh Sood

Company: Mindtree

Created on: 5th July 2016


my latest photo.jpg


Rajwin Singh Sood is currently working as SAP CRM Technical Manager at Mindtree. He has got experience of about 10 years in SAP ABAP and SAP CRM web UI. He is

also a SAP CRM EHP2 Certified associated consultant. Prior to working with Mindtree he had worked with  Atos,SAP India(SAP

Global Delivery), Capgemini , Accenture and Infosys. He worked in SAP CRM Web Ui in areas like BSP

enhancements, transaction launchers, BOL Programming, BRFPlus.

Scenario


So as specified in the summary we have the requirement wherein the end user wants to execute actions in UI5/FIORI application as its working in SAP CRM.  In order to achieve this we need to :-

  • Develop RFC enabled function module to first enlist the number of active actions for the particular transaction
  • Develop RFC enabled function module to execute on the basis of transaction GUID and Action type(which will input coming from the above function module)
  • Develop ODATA service in Netweaver gateway server using transaction SEGW transaction and call the above RFC enabled function modules.


Note:- ODATA development is not in scope of this document as RFC function modules were critical. you can refer to SCN in case you need some guide on ODATA.

Step1 RFC Enlisting the number of active actions for the particular transaction:-


Before going through the code its important to understand that as far triggering of actions are concerned there are two important SAP tables namely  ppfttrigg(PPF: Actions) and  crmd_action_asyn(Asynchronous Actions Monitoring). Table ppfttrigg contains the list of actions which are suppose to be triggered/ needs to be triggered whereas crmd_action_asyn will highlight what was the end result of the execution. If you would refer to the GENIL class CL_CRM_ADMIN_ACIIL(for BOL object ACI for actions) method IF_GENIL_APPL_INTLAY~GET_DYNAMIC_QUERY_RESULT there you could a SELECT join on both these tables. This is just for your reference, Now we’ll develop a Z FM which will have importing parameter as:-

Pic1.JPG




where object id is nothing but the transaction id

and the exporting parameter as

pic2.JPG




its a custom table type containing the following parameters:-


pic3.JPG




now the FM logic/code with self explanatory comments is enumerated below:-


CONSTANTS : lc_dom_nm_status TYPE domname VALUE ‘PPFDTSTAT’,

               lc_dom_nm_medium TYPE domname VALUE ‘PPFDMETYPE’,

               lc_application   TYPE ppfdappl VALUE ‘CRM_ORDER’.

****Type declaration

   TYPES : BEGIN OF lty_action_definition,

             ttype      TYPE ppfdtt,

             ttypedescr TYPE ppfdttt,

           END OF lty_action_definition.

***Data declaration

   DATA : lt_ppfttrigg         TYPE STANDARD TABLE OF ppfttrigg,

          lt_action_definition TYPE TABLE OF lty_action_definition,

          lv_date_create       TYPE ppfdcdate,

          lv_time_create       TYPE ppfdctime,

          lv_time              TYPE uzeit,

          lt_statusdd_value    TYPE TABLE OF dd07v,

          ls_status_value      LIKE LINE OF lt_statusdd_value,

          lt_statusdd_value1   TYPE TABLE OF dd07v,

          lt_procmed_value     TYPE TABLE OF dd07v,

          ls_procmed_value     LIKE LINE OF lt_procmed_value,

          lt_procmed_value1    TYPE TABLE OF dd07v,

          ls_action_definition TYPE lty_action_definition,

          ls_action_item       TYPE crmt_action_attr_aciil,

          ls_ppfttrigg         TYPE ppfttrigg.

***fetch all the texts maintained for status and medium types

   CALL FUNCTION ‘DD_DOMA_GET’

     EXPORTING

       domain_name   = lc_dom_nm_status

*     get_state     = ‘M  ‘

       langu         = sy-langu

       prid          = 0

       withtext      = ‘X’

     TABLES

       dd07v_tab_a   = lt_statusdd_value

       dd07v_tab_n   = lt_statusdd_value1

     EXCEPTIONS

       illegal_value = 1

       op_failure    = 2

       OTHERS        = 3.

   CALL FUNCTION ‘DD_DOMA_GET’

     EXPORTING

       domain_name   = lc_dom_nm_medium

*     get_state     = ‘M  ‘

       langu         = sy-langu

       prid          = 0

       withtext      = ‘X’

     TABLES

       dd07v_tab_a   = lt_procmed_value

       dd07v_tab_n   = lt_procmed_value1

     EXCEPTIONS

       illegal_value = 1

       op_failure    = 2

       OTHERS        = 3.

****first fetch all the scheduled actions

   SELECT * FROM ppfttrigg INTO TABLE lt_ppfttrigg WHERE applkey = iv_object_id AND

                                                         applctn = lc_application. “#EC CI_NOFIRST

   IF sy-subrc IS INITIAL.

***fetch the action texts

     SELECT name text FROM ppftttcut INTO TABLE lt_action_definition FOR ALL ENTRIES IN lt_ppfttrigg WHERE name = lt_ppfttrigg-ttype

                                                                                                     AND langu = sy-langu.

     IF sy-subrc IS INITIAL.

     ENDIF.

     LOOP AT lt_ppfttrigg INTO ls_ppfttrigg.

       ls_action_item-guid = ls_ppfttrigg-appl_oid.

***populate the action profile and description

       READ TABLE lt_action_definition INTO  ls_action_definition WITH KEY ttype = ls_ppfttrigg-ttype.

       IF sy-subrc IS INITIAL.

         ls_action_item-ttype      = ls_action_definition-ttype.

         ls_action_item-ttypedescr = ls_action_definition-ttypedescr.

       ENDIF.

       ls_action_item-context = ls_ppfttrigg-context.

***populate status and description

       READ TABLE lt_statusdd_value INTO ls_status_value WITH KEY domvalue_l = ls_ppfttrigg-status.

       IF sy-subrc IS INITIAL.

         ls_action_item-status     = ls_status_value-domvalue_l.

         ls_action_item-statusdesc = ls_status_value-ddtext.

       ENDIF.

***populate the medium and their description

       READ TABLE lt_procmed_value INTO ls_procmed_value WITH KEY domvalue_l = ls_ppfttrigg-metype.

       IF sy-subrc IS INITIAL.

         ls_action_item-mediumtype   = ls_procmed_value-domvalue_l.

         ls_action_item-mediumdesc    = ls_procmed_value-ddtext.

       ENDIF.

       ls_action_item-is_inactiv = ls_ppfttrigg-is_inactiv.

       ls_action_item-execdialog = ls_ppfttrigg-execdialog.

       ls_action_item-usercreate = ls_ppfttrigg-usercreate.

*****creation date

       CONVERT TIME STAMP ls_ppfttrigg-timecreate TIME ZONE sy-zonlo

       INTO DATE ls_action_item-datecreate TIME sy-uzeit.

*****creation time

       CONVERT TIME STAMP ls_ppfttrigg-timecreate TIME ZONE sy-zonlo

       INTO TIME ls_action_item-timecreate.

       APPEND ls_action_item TO et_action_item.

     ENDLOOP.

   ENDIF.

the above function module will get the complete list of active triggers.

  • Step 2 :- Develop RFC enabled function module to execute on the basis of transaction GUID and Action type(which will input coming from the above function module)

      Now we come to the RFC function module which will execute the actions on the basis of the list which will be outcome of above function module.

importing paramters are:-

pic4.JPG

If you note carefully both these parameters are actually the outcome of the first function module which in turn will act as input to this FM.

the exporting/outcome will the result of the execution:-

Pic5.JPG

Finally the self explanatory code is given below:-

***constant declaration

   CONSTANTS: lc_message1 TYPE string VALUE ‘Not processed’,

              lc_message2 TYPE string VALUE ‘Successfully processed’,

              lc_message3 TYPE string VALUE ‘Incorrectly processed’.

****Include

   INCLUDE crm_direct.

***Data declaration

   DATA lv_guid_ref    TYPE crmt_object_guid.

   DATA lr_context     TYPE REF TO cl_doc_context_crm_order.

   DATA lv_toolbar     TYPE boolean.

   DATA lr_manager     TYPE REF TO cl_manager_ppf.

   DATA lt_context     TYPE ppftctxtir.

   DATA lt_trigger     TYPE ppfttrgor.

   DATA ls_trigger     TYPE ppfdtrgor.

   DATA lt_action      TYPE crmt_action_get_tab.

   DATA ls_action      TYPE crmt_action_get.

   DATA lr_object      TYPE REF TO object.

   DATA lr_action      TYPE REF TO cl_trigger_ppf.

   DATA lv_status      TYPE i.

   DATA lt_objects_to_save  TYPE crmt_object_guid_tab.

   DATA ls_objects_to_save  TYPE crmt_object_guid.

   DATA lv_protocol    TYPE balloghndl.

   DATA lt_guids       TYPE crmt_object_guid_tab.

   DATA: ls_statistics      TYPE bal_s_scnt,

         lv_contains_errors TYPE crmt_boolean.

* 1. context create

   CALL FUNCTION ‘CRM_ACTION_CONTEXT_CREATE’

     EXPORTING

       iv_header_guid                 = iv_header_guid

       iv_object_guid                 = iv_header_guid

     IMPORTING

       ev_context                     = lr_context

     EXCEPTIONS

       no_actionprofile_for_proc_type = 1

       no_actionprofile_for_item_type = 2

       order_read_failed              = 3

       OTHERS                         = 4.

   IF sy-subrc IS NOT INITIAL.

     “do nothing

   ENDIF.

* 2. action deterimne

   IF lr_context IS BOUND.

     CALL FUNCTION ‘CRM_ACTION_DETERMINE’

       EXPORTING

         iv_header_guid      = iv_header_guid

         iv_object_guid      = iv_header_guid

         iv_context          = lr_context

         iv_for_toolbar_only = lv_toolbar

         iv_no_detlog        = true.

     INSERT lr_context INTO TABLE lt_context.

   ENDIF.

* 3. get actions from ppf manager

   lr_manager = cl_manager_ppf=>get_instance( ).

   IF lr_manager IS BOUND.

     CALL METHOD lr_manager->get_active_triggers

       EXPORTING

         it_contexts = lt_context

       IMPORTING

         et_triggers = lt_trigger.

   ENDIF.

* 4. fill exporting parameters

   LOOP AT lt_trigger INTO ls_trigger.

     ls_action-guid = ls_trigger->read_guid( ).

     ls_action-def  = ls_trigger->get_ttype( ).

     ls_action-text = cl_view_service_ppf=>get_descrp_for_dropdown(

                                           io_trigger = ls_trigger ).

     INSERT ls_action INTO TABLE lt_action.

   ENDLOOP.

* 5 get actions from object services

   CLEAR ls_action.

   READ TABLE lt_action INTO ls_action WITH KEY def = iv_action_name.

   IF sy-subrc IS INITIAL.

     CALL METHOD ca_trigger_ppf=>agent->if_os_ca_persistency~get_persistent_by_oid

       EXPORTING

         i_oid  = ls_action-guid

       RECEIVING

         result = lr_object.

     lr_action ?= lr_object.

   ENDIF.

* 6 execute action

   IF lr_action IS BOUND.

     “CALL METHOD lr_action->set_is_inactiv( space ).

     CALL METHOD lr_action->set_processed_manually

       EXPORTING

         i_processed_manually = true.

     CALL METHOD lr_action->execute

       RECEIVING

         rp_rc                   = lv_status

       EXCEPTIONS

         empty_medium_reference  = 1

         empty_appl_reference    = 2

         locked                  = 3

         document_is_locked      = 4

         inactive                = 5

         startcondition_not_true = 6

         OTHERS                  = 7.

   ENDIF.

****now check for response type

* 0  Not processed

* 1  Successfully processed

* 2  Incorrectly processed

   CASE lv_status.

     WHEN 0.

       MOVE lc_message1 TO iv_exec_result.

     WHEN 1.

       MOVE lc_message2 TO iv_exec_result.

     WHEN 2.

       MOVE lc_message3 TO iv_exec_result.

     WHEN OTHERS.

   ENDCASE.

*****saving the action excution result in the table otherwise the executed action won’t be saved

   LOOP AT lt_trigger INTO ls_trigger.

     ls_action-guid = ls_trigger->read_guid( ).

     ls_action-def  = ls_trigger->get_ttype( ).

     ls_action-text = cl_view_service_ppf=>get_descrp_for_dropdown(

                                           io_trigger = ls_trigger ).

     IF ls_action-def EQ iv_action_name.

       IF ls_trigger->get_status( ) NE 1 OR ls_trigger->get_metype( ) NE ‘MET’.

* Mark action as finished

         UPDATE crmd_action_asyn SET finished = abap_true WHERE os_guid = ls_action-guid.

         COMMIT WORK.

         EXIT.

       ENDIF.

********************************************************************

*     get protocol

       lv_protocol = ls_trigger->getm_processing_log( ).

       INSERT iv_header_guid INTO TABLE lt_guids.

*   save guids and trigger new determination if needed

       CALL FUNCTION ‘CRM_ORDER_SAVE’

         EXPORTING

           it_objects_to_save = lt_guids

         EXCEPTIONS

           document_not_saved = 1

           OTHERS             = 2.

********************************************************************

*   write message into ppf-log

       IF sy-subrc NE 0.

         CALL METHOD cl_log_ppf=>add_message

           EXPORTING

             ip_problemclass = ‘2’

             ip_handle       = lv_protocol.

*     set return status

         CALL METHOD ls_trigger->set_status

           EXPORTING

             i_status = ‘2’.

       ENDIF.

       IF ls_statistics-msg_cnt_e > 0.

         lv_contains_errors = abap_true.

       ENDIF.

* Mark action as finished

       UPDATE crmd_action_asyn SET finished = abap_true contains_errors = lv_contains_errors WHERE os_guid = ls_action-guid.

       COMMIT WORK.

       EXIT.

     ENDIF.

   ENDLOOP.

This FM would not only execute the action but will also update the outcome with respect to the one order transaction.

Hope so this document will prove helpful for anyone who has the requirement of incorporating the action execution remotely.

To report this post you need to login first.

Be the first to leave a comment

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

Leave a Reply