One of the limitations of SAP CRM Marketing in the context of the utilities industry are the features available for executing marketing campaigns. The only option available in the standard is the campaign execution using bill supplements (Campaign Management with Campaign Execution by Bill Supplements). Besides that, that only available option is the usage of the open channel.

A recurring requirement at all of our customers is the execution of a campaigns in which quotes are sent to existing. Most of the time these quotes are related to a product change process for existing customers (e.g. in order to promote new utilities products). It is well possible to execute these processes using the open channel. However, using the open channel has in my opinion quite some limitations. For example, no quote object is created in SAP CRM. Therefore existing processes requiring the existence of a quote object are not working. An example of such a process is the scan and automatic processing of product change quotes sent back by customers.

In the previous blog SAP CRM Marketing for Utilities – Object based Segmentation without ADS and BW I showed how SAP CRM Marketing can easily be extended in order to also include technical object information in the segmentation. Furthermore, the blog Using the Utilities Process Framework for background processing showed how the Utilities Process Framework can be used in background processing. In this blog I’ll show how this functionality can be combined in order to execute a marketing campaign including the creation of a utilities quote within CRM Marketing.

Note that the source code example provided below are only valid to demonstrate the overall concept and are missing e.g. essential error handling. Therefore, they should not be used directly in an production environment.

Solution Overview

In order to implement the described scenario an implementation of the open channel is used. However, instead of exporting data a utilities quote is created in the system and optionally printed. The overall solution consist of the following parts:

  1. a CDS view to allow object bases segmentation
  2. an implementation of the open channel that create utilities quotes using the Utilities Process Framework
  3. the customizing in CRM Marketing

In the following sections I’ll provide details on the second and third part of the overall solution. Details on the first part are available in the blog mentioned in the introduction.

Open Channel Implementation

The implementation of the open channel is based on the approach described in Using the Utilities Process Framework for background processing. Basically the following steps are necessary

  1. Loop through the target group items
  2. For each target group items get the related objects
  3. Create a utilities quote for each of the objects

The source code below shows the example implementation of the method export_campaign_data for the open channel (BadI CRM_UTIL_MKT_EXE). The creation of the utilities quote is performed in the method create quote. Note that, depending on the implementation of the process class it would also be possible trigger the actual printing of the quote document here.

 METHOD if_ex_crm_mkt_exp_camp_dat~export_campaign_data.

    DATA(bol_core) = cl_crm_bol_core=>get_instance( ).
    bol_core->start_up( iv_appl_name = |ALL| ).

    DATA(target_group) = bol_core->get_root_entity( iv_object_name = |SEGTg|
                                                    iv_object_guid = is_targetgrp-targetgrp_guid ).
    DATA(tg_items) = target_group->get_related_entities( iv_relation_name = |SEGTgTgItemRel| ).

    DATA(tg_iterator) = tg_items->get_iterator( ).
    DATA(tg_item) = tg_iterator->get_first( ).

    WHILE tg_item IS BOUND.
      DATA(i_objects) = tg_item->get_related_entities( iv_relation_name = |SEGTgItemIObjectRel| ).
      DATA(i_object_iterator) = i_objects->get_iterator( ).
      DATA(i_object) = i_object_iterator->get_first( ).

      WHILE i_object IS BOUND.
          i_tg_item  = tg_item
          i_i_object = i_object ).

        "me->print_quote( ).

        i_object = i_object_iterator->get_next( ).

      tg_item = tg_iterator->get_next( ).


An example implementation of the create_quote method using the Utilties Process Framework is shown below.  Note that this implementation is a quick hack to demonstrate the approach. In a productive implementation several area need to be improved. For example, the product for the quote should be read form the campaign data instead of beeing hard coded. Furthermore, checks if the product fits to the PoD as well as error logging for the PoD and partner should be added.

METHOD create_quote.
   DATA(pod) = cl_crm_bol_core=>get_instance( )->get_root_entity(
          iv_object_name           = |PointOfDelivery|
          iv_object_guid           = CONV #( i_i_object->get_property_as_string( iv_attr_name = |IOBJECT_GUID| ) ) ).

    DATA(division) = pod->get_property_as_string( iv_attr_name = |PD_SPARTE| ).

    IF division = |01|.

      DATA(proc_mgr) = cl_crm_iu_process_mgr=>get_instance( profile_id = zc_crm_if_xx_constants=>profil_pmgr ).
      CHECK proc_mgr IS BOUND.

      DATA(proc_context) = proc_mgr->get_context( definition_id = zcl_im_c_crm_im_mkt_oc_cq=>process_definition
                                                  category_id   = zcl_im_c_crm_im_mkt_oc_cq=>process_category ).
      proc_context->set_container_value( name  = 'PARTNER'
                                         value = i_tg_item->get_property_as_string( iv_attr_name = |PARTNER| ) ).

      proc_mgr->is_executable( definition_id = zcl_im_c_crm_im_mkt_oc_cq=>process_definition ).

          definition_id = zcl_im_c_crm_im_mkt_oc_cq=>process_definition
          category_id   = zcl_im_c_crm_im_mkt_oc_cq=>process_category ).

      DATA(item_guid) = proc_mgr->add_item( ).

          uuid          = CONV #( i_i_object->get_property_as_string( iv_attr_name = |IOBJECT_GUID| ) )
          uuid_c22      = DATA(pod_guid) ).

      cl_crm_isu_order_change=>set_pod( iv_guid     = item_guid
                                        iv_pod_guid = pod_guid  ).

      "Product should be read from campaign and should not be hard coded
      cl_crm_isu_order_change=>set_product( iv_guid = item_guid
                                            iv_ordered_prod = |S_GV| ).

          definition_id = zcl_im_c_crm_im_mkt_oc_cq=>process_definition
          category_id   = zcl_im_c_crm_im_mkt_oc_cq=>process_category
          objects_to_be_saved = DATA(objects_to_be_saved) ).

      DATA(transaction) = cl_crm_bol_core=>get_instance( )->get_transaction( ).
      IF transaction->check_save_needed( )   EQ abap_true.
        IF transaction->check_save_possible( ) EQ abap_true.
          IF transaction->save( ) EQ abap_true.
            transaction->commit( ).




The next step is to create the customizing in SAP CRM Marketing. Basically this is the standard customizing for the open channel. For the described scenario I first created a communication medium ZCQU.

Next I activate the BAdI implementation of the open channel created above.

Campaign Execution

With all the preparations in place its now possible to create a campaign using the defined communication channel.

In the example I created a target group using business parts that have a premise on a certain street.

After the campaign is executed a utilities quote for each premise in the target group is created.


Using the described approach it is possible to execute a complete marketing campaign for a utilities company inside SAP CRM Marketing. While this approach is certainly not suitable for high volume campaigns it is in my opinion a nice solution or smaller, recurring campaigns.


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