Skip to Content

During a recent CRM Mobile Sales implementation project we ran into an issue with activities, leads and opportunities created from the mobile device. They would have most of the organizational structure elements such as Sales Organization, Division, Sales Office, etc. determined and populated but not the Distribution Channel. It turns out that if several options are available (more than 1 distribution channel is defined), then the distribution channel cannot be uniquely identified and is left blank. That results in a warning message sent back to the device, prompting the user to enter the distribution channel. The app itself does not allow for the maintenance of Org Structure fields, so the only way in that case would be to update the data in the CRM backend. Unless….you use some BADI’s.

The purpose of this blog is to explain how to go about the task of implementing those BADI’s and the challenges they pose.

After reading the blog not only should you be able to do exactly what we’ve done, that is default the distribution channel in activities, leads and opportunities, but also have a good idea of how to use the BADI’s to modify the contents of other fields as well.

The Mobile Sales Add-on (the application logic) that sits on the CRM backend comes with enhancement spot /MSA/CRM_MOBILE_SALES. That enhancement spot contains a number of BADI definitions as shown in the screenshot below:

In our case we decided to implement 3 of them:

  • /MSA/BADI_ACTIVITY
  • /MSA/BADI_LEAD
  • /MSA/BADI_OPPORTUNITY

For starters we decided to tackle activities. The code example later in this blog is based on the BADI for activities. Other BADI’s can be implemented in a similar fashion with only a few minor updates to the code.

The first step was to create an enhancement implementation like the one shown below:

From there, for each BADI implementation we defined an implementing class like the activity one shown below:

As you see above, each BADI has 4 methods:

  • GETLIST
  • GETDETAIL
  • CREATE
  • CHANGE

We needed to implement the “CREATE” method in order to populate the default distribution channel for activities created from the mobile device.

And that’s where we faced some challenges. It turned out that the BADI is called at the end of function module /MSA/TA_ACVT_CREATE. This happens after the activity has already been created and committed in the function module. What that means is,  any changes to the table parameters passed to the create method of the BADI are not reflected in the activity. In order to accomplish that, the already created object (activity) has to be modified using some function module or a BAPI from within the BADI. For a long time we tried and tried but to no avail. We also considered using implicit enhancement spots to accomplish the task but it caused more harm than good. For example a change of the distribution channel would force all other org structure fields to go blank. Please see this link: http://scn.sap.com/thread/3176810 pointing to an SCN forum thread describing those challenges.

Finally, we came up with code that does the trick.

The key was to call the following function modules:

CRM_ORDER_MAINTAIN, and

CRM_ORDER_SAVE

from the BADI, and then commit work.

In order for the CRM_ORDER_MAINTAIN to properly update the org structure, its IT_ORGMAN parameter (structure) needs to be populated but that is not enough. Table parameter CT_INPUT_FIELDS must also contain the field names that actually need to be updated. If that table is blank or lists additional field names that do not have a corresponding value in IT_ORGMAN, then you’ll be overwriting those with initial values. The easiest way to get the fields into IT_ORGMAN is to use function module CRM_INPUT_FIELDS_DETER_MOBILE.

As for modifying/populating the contents of fields other than the distribution channel or other org structure fields, please take a closer look at function module CRM_ORDER_MAINTAIN and its interface. Just always remember to build the correct field list with CRM_INPUT_FIELDS_DETER_MOBILE before calling it.

Below is the code in its entirety for the activity create method. Leads and opportunities can be handled exactly the same way but you’ll need to change the method parameter name in the code. For example activities use CT_ACTIVITY_H for header data, and leads use CT_HEADER instead. Please read through the below code and pay attention to the comments to understand what happens at different steps.

Hope this will be helpful for all of you implementing or planning on implementing CRM Mobile Sales. Any feedback will be greatly appreciated.

METHOD /MSA/IF_CE_ACTIVITY~CREATE.

  DATA: LS_ORG       TYPE CRMT_ORGMAN_COM,

        LT_ORG       TYPE CRMT_ORGMAN_COMT,

        LT_EXCEPTION TYPE CRMT_EXCEPTION_T,

        LS_OBJ2SAVE  TYPE CRMT_OBJECT_GUID,

        LT_OBJ2SAVE  TYPE CRMT_OBJECT_GUID_TAB,

        LC_DDIC_ORGDATA    TYPE DDOBJNAME

                              VALUE ‘CRMT_ORGMAN_COM’.

  DATA: LT_INPUT_FIELDS TYPE CRMT_INPUT_FIELD_TAB.

  FIELD-SYMBOLS: <FS_RETURN> TYPE BAPIRET2.

  CLEAR LS_ORG.

  REFRESH LT_ORG.

  CT_ACTIVITY_H-DIS_CHANNEL = ’10’.                    “Here  default distribution channel is set.

  LS_ORG-REF_KIND     = ‘A’.                           “Value A means this pertains to

                                                       “the object header.

                                                       “Use ‘A’ for leads and oppty’s too.

  LS_ORG-REF_GUID     = CT_ACTIVITY_H-OBJECT_GUID.     “GUID of the activity to be updated.

  LS_ORG-DIS_CHANNEL  = CT_ACTIVITY_H-DIS_CHANNEL.     “Distribution channel

  APPEND LS_ORG TO LT_ORG.

  CALL FUNCTION ‘CRM_INPUT_FIELDS_DETER_MOBILE’        ” This fm builds table LT_INPUT_FIELDS for

                                                       ” CMR_ORDER_MAINTAIN

    EXPORTING

      IS_NEW            = LS_ORG

      IV_DATA_DDIC_NAME = LC_DDIC_ORGDATA

      IV_REF_GUID       = LS_ORG-REF_GUID

      IV_REF_HANDLE     = LS_ORG-REF_HANDLE

      IV_REF_KIND       = LS_ORG-REF_KIND

      IV_OBJECTNAME     = ‘ORGMAN’                     “GC_OBJECT_NAME-ORGMAN

    IMPORTING

      CT_INPUT_FIELD    = LT_INPUT_FIELDS              ” This internal table is critical for

                                                       ” CRM_ORDER_MAINTAIN!!!

    EXCEPTIONS                                            

      ERROR_OCCURRED    = 1

      OTHERS            = 2.

  CALL FUNCTION ‘CRM_ORDER_MAINTAIN’

    EXPORTING

      IT_ORGMAN             = LT_ORG                   ” Org Structure Field Values

    IMPORTING

      ET_EXCEPTION          = LT_EXCEPTION            

    CHANGING

*     CT_ORDERADM_H         =

*     CT_ORDERADM_I         =

      CT_INPUT_FIELDS       = LT_INPUT_FIELDS          ” Field names to be updated.

                                                       ” Should match LT_ORG

*     CV_LOG_HANDLE         =

*     CT_PARTNER_ATTRIBUTES =

*     CT_DOC_FLOW           =

    EXCEPTIONS

      ERROR_OCCURRED        = 1

      DOCUMENT_LOCKED       = 2

      NO_CHANGE_ALLOWED     = 3

      NO_AUTHORITY          = 4

      OTHERS                = 5.

  IF SY-SUBRC <> 0.

* Implement suitable error handling here

  ELSE.

* Since an error message was already generated prior to calling the BADI,

* we need to delete it from the RETURN table so that the device does not receive an error/warning.

    READ TABLE RETURN ASSIGNING <FS_RETURN> WITH KEY TYPE = ‘W’ ID = ‘CRM_ORGMAN’ NUMBER = ‘034’.

    IF SY-SUBRC = 0.

      DELETE RETURN INDEX SY-TABIX.

    ENDIF.

  ENDIF.

* Finally, let’s save the changes:

  LS_OBJ2SAVE = LS_ORG-REF_GUID .

  APPEND LS_OBJ2SAVE TO LT_OBJ2SAVE.

  CALL FUNCTION ‘CRM_ORDER_SAVE’

    EXPORTING

      IT_OBJECTS_TO_SAVE         = LT_OBJ2SAVE

*     IV_UPDATE_TASK_LOCAL       = FALSE

*     IV_SAVE_FRAME_LOG          = FALSE

*     IV_NO_BDOC_SEND            = FALSE

*     IT_ACTIVE_SWITCH           =

*   IMPORTING

*     ET_SAVED_OBJECTS           =

*     ET_EXCEPTION               =

*     ET_OBJECTS_NOT_SAVED       =

*   CHANGING

*     CV_LOG_HANDLE              =

    EXCEPTIONS

      DOCUMENT_NOT_SAVED         = 1

      OTHERS                     = 2

            .

  IF SY-SUBRC <> 0.

* Implement suitable error handling here

  ENDIF.

* And the final commit:

  CALL FUNCTION ‘BAPI_TRANSACTION_COMMIT’

    EXPORTING

      WAIT = ‘X’.

ENDMETHOD.

To report this post you need to login first.

1 Comment

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

Leave a Reply