Wednesday, December 14, 2011

Territory Management – Enhancements

When using Territory Management (TM) some enhancements can make life a lot easier. 
In this blog we will describe some of these enhancements. 

New Customers
Standard all new business partners are added to table CRMD_TERRMAN_LOG so that the delta run of report CRM_TERRMAN_PROC can process new customers. This means that business partners in all roles (except employees). If you want to filter this on for example role (suspects) or type (contact person) you will have to change the standard implementation of the BADI BUPA_GENERAL_UPDATE.
The method CHANGE_BEFORE_UPDATE checks if it is a new customer, here you can filter on any BP you like. In below example we filter on Business Partner Group and Authorization Group.

IF lt_but000_new IS NOT INITIAL. 
  READ TABLE lt_but000_new INDEX 1 INTO ls_but000_new.
  IF lt_but000_old IS INITIAL. 
       ls_partner_keys-partner = ls_but000_new-partner. 
       ls_partner_keys-partner_guid = ls_but000_new-partner_guid. 
" consider only Z003 and Z009 
       IF ( ls_but000_new-bu_group EQ 'Z003' OR ls_but000_new-bu_group EQ 'Z009' ) 
      AND ls_but000_new-augrp IS NOT INITIAL .
           APPEND ls_partner_keys TO lt_partner_keys. 
      ENDIF. 
   ENDIF. 
ENDIF.

Changes in Customer Master Data. 
The territory assignment of customer can change when you change a customer, for instance if you change the address, the customers might move to a different territory. 

The standard code unfortunately only creates an entry in table CRMD_TERRMAN_LOG if you change a field of BUT000 or the address of a business partner. If you use other attributes, like marketing attributes or sales area data, you need to implement the BADI CRM_TM_MASTER_DATA_NOTIFY_BP, with method is_attr_active_for_tm. You could use the following code to register all changes as relevant for TM.

METHOD if_ex_crm_tm_master_notify_bp~is_attr_active_for_tm.
   {... your conditions}
   rv_is_active = 'X'. 
   {............}
ENDMETHOD.

Adding custom attributes to TM 
Territory management standard has several attributes you can use like 

Account: Brick Number, Country, Group, Account ID, Speciality, Account Hierarchy, Postal Code, Region and Subgroup. 

Sales Area: Sales Organization, Distribution channel, divison. 

If you require alternative attributes you can add them in customizing in Master Data Territory Management --> Territory Attributes --> Maintain Territory Attributes. 

For the system to able to work with these new attributes we need to implement the BADI CRM_TERRMAN_ATTRIB. The following methods need to maintained.

PROCESS_RELNSHPS
Use the new attributes during process of report CRM_TERRMAN_PROC 
The report CRM_TERRMAN_PROC determines the customers per territory based on the standard attributes. With this selection it calls this BADI method to filter on custom attributes. In below code we filter Sales group, for a specific Sales Area. Because of high volume in the selection we are not looping over the selection, but we create a new selection and compare that with the standard.

METHOD if_ex_crm_terrman_attrib~process_relnshps.

DATA : lv_zzsales_group TYPE crmt_sales_group. 

DATA : ls_rule_attr TYPE crms_fdt_create_ctxt,
            ls_rule_data TYPE crms_fdt_rule_cell, 
            ls_condition TYPE crms_fdt_rule_condition. 

DATA : lt_accrel TYPE crmt_terr_accrel_t, 
            ls_accrel TYPE crmd_terr_accrel, 
            lt_accrel_sel TYPE crmt_terr_accrel_t, 
            ls_accrel_sel TYPE crmd_terr_accrel, 
            lt_accrel_final TYPE crmt_terr_accrel_t. 

DATA : lv_sales_org TYPE crmt_sales_org, 
            lv_channel TYPE crmt_distribution_channel,
            lv_division TYPE crmt_division. 

DATA : lt_sales_group TYPE RANGE OF crmm_but_set0140-sales_group, 
            ls_sales_group LIKE LINE OF lt_sales_group. 

DATA : lt_set_guid TYPE TABLE OF crmm_but_set0140. 


CHECK ct_accrel IS NOT INITIAL. 
lt_accrel = ct_accrel. 
SORT lt_accrel BY partner_guid. 

READ TABLE it_rule_attr INTO ls_rule_attr WITH KEY attribute = 'ZZSALES_GROUP'. 
IF sy-subrc EQ 0. 
    READ TABLE it_rule_data INTO ls_rule_data WITH KEY col_no = ls_rule_attr-col_no. 
    IF sy-subrc EQ 0. 
        LOOP AT ls_rule_data-conditions INTO ls_condition. 
               ls_sales_group-sign = ls_condition-sign. 
               ls_sales_group-option = ls_condition-option. 
               ls_sales_group-low = ls_condition-lvalue-value. 
               ls_sales_group-high = ls_condition-hvalue-value. 
              APPEND ls_sales_group TO lt_sales_group. 
         ENDLOOP. 
     ENDIF. 
ENDIF. 

READ TABLE it_rule_attr INTO ls_rule_attr WITH KEY attribute = 'SA_SALES_AREA'. 
IF sy-subrc EQ 0. 
   READ TABLE it_rule_data INTO ls_rule_data WITH KEY col_no = ls_rule_attr-col_no. 
   IF sy-subrc EQ 0. 
      READ TABLE ls_rule_data-conditions INTO ls_condition INDEX 1. 
      IF sy-subrc EQ 0. 
          lv_sales_org = ls_condition-lvalue-value(10). 
          lv_channel = ls_condition-lvalue-value+15(2). 
          lv_division = ls_condition-lvalue-value+18(2). 
       ENDIF. 
    ENDIF. 
ENDIF. 
IF ( lv_sales_org IS NOT INITIAL OR lv_channel IS NOT INITIAL OR lv_division IS NOT INITIAL ) AND lt_accrel IS NOT INITIAL. 


SELECT DISTINCT partner_guid 

     INTO CORRESPONDING FIELDS OF TABLE lt_accrel_sel 
     FROM crmm_but_lnk0141 FOR ALL ENTRIES IN lt_accrel 
     WHERE partner_guid EQ lt_accrel-partner_guid 
         AND sales_org EQ lv_sales_org 
         AND channel EQ lv_channel 
         AND division EQ lv_division. 
      IF sy-subrc EQ 0. 
         LOOP AT lt_accrel_sel INTO ls_accrel_sel.
             " take the commom partners along with other fields in table lt_accrel...... 
              READ TABLE lt_accrel WITH KEY partner_guid = ls_accrel_sel-partner_guid 
                   INTO ls_accrel BINARY SEARCH. 
              IF sy-subrc EQ 0. 
                  APPEND ls_accrel TO lt_accrel_final. 
              ENDIF. 
          ENDLOOP. 
          CLEAR : lt_accrel , lt_accrel_sel. 
          lt_accrel = lt_accrel_final. 
          SORT lt_accrel BY partner_guid. 
          CLEAR lt_accrel_final. 
          IF lt_accrel IS INITIAL. 
              CLEAR ct_accrel. 
          ENDIF.
        ELSE. 
           CLEAR ct_accrel. " no selection from sales area ..so clear ct_accrel 
           CLEAR lt_accrel. " no further selection required......... 
        ENDIF. 
      ENDIF. 
    IF lt_sales_group IS NOT INITIAL AND lt_accrel IS NOT INITIAL. 
        SELECT DISTINCT set_guid 
            INTO CORRESPONDING FIELDS OF TABLE lt_set_guid FROM crmm_but_set0140
            WHERE sales_group IN lt_sales_group. 
        IF sy-subrc EQ 0. 
            SELECT DISTINCT partner_guid 
                 INTO CORRESPONDING FIELDS OF TABLE lt_accrel_sel 
                 FROM crmm_but_lnk0141 
                 FOR ALL ENTRIES IN lt_set_guid 
                 WHERE set_guid EQ lt_set_guid-set_guid. 
             IF sy-subrc EQ 0. 
                 LOOP AT lt_accrel_sel 
                      INTO ls_accrel_sel. 
                   "take the commom partners along with other fields in table lt_accrel...... 
                    READ TABLE lt_accrel 
                    WITH KEY partner_guid = ls_accrel_sel-partner_guid 
                    INTO ls_accrel BINARY SEARCH. 
                    IF sy-subrc EQ 0. 
                        APPEND ls_accrel TO lt_accrel_final. 
                    ENDIF. 
                 ENDLOOP. 
             CLEAR : lt_accrel , lt_accrel_sel. lt_accrel = lt_accrel_final. 
             SORT lt_accrel BY partner_guid. 
             CLEAR lt_accrel_final. 
             IF lt_accrel IS INITIAL. 
                 CLEAR ct_accrel. 
             ENDIF. 
         ELSE. 
            CLEAR ct_accrel. " no selection from sales group ..so clear ct_accrel 
            CLEAR lt_accrel. " no further selection required......... 
         ENDIF. 
      ENDIF. 
    ENDIF. 
  IF lt_accrel IS NOT INITIAL. 
     SORT lt_accrel BY partner_guid. 
     CLEAR ct_accrel. 
     ct_accrel = lt_accrel. 
 ENDIF. 
ENDMETHOD.

GET_CUSTOMER_ATTRVAL
Get customer attribute values
METHOD if_ex_crm_terrman_attrib~get_customer_attrval. 

DATA : ls_value_range TYPE crms_terrman_range,
           ls_attr_values TYPE crms_terr_rule_attr. 

  LOOP AT it_value_range INTO ls_value_range. 
     IF ls_value_range-sign EQ 'I' 
     AND ls_value_range-option EQ 'EQ'. 
         ls_attr_values-attribute_id = iv_attr_name. 
         ls_attr_values-value = ls_value_range-low. 
         APPEND ls_attr_values TO et_attr_values. 
     ENDIF. 
  ENDLOOP. 
ENDMETHOD.

GET_POSTAL_CODE
One of the nice things about using the rule engine is that it is now possible to use the between operator for postal codes. You could create one rule for the postal codes between 1000 and 2000. 
In CRM this rule is supported in the standard. However for BW extraction it is not. It will only pas the from postal codes. 

You will need to implement the same BADI as before but then the method Get_Postal_Code


GET_BUSOBJ_ATTRIB_VALUE
METHOD if_ex_crm_terrman_attrib~GET_BUSOBJ_ATTRIB_VALUE
DATA: 
ls_value TYPE text50,
lt_sales_group TYPE TABLE OF crmm_but_set0140, 
ls_sales_group TYPE crmm_but_set0140, 
lv_timestamp TYPE timestamp, 
lv_guid TYPE bu_partner_guid. 

lv_guid = iv_objguid. 

CASE iv_attribute. 

WHEN 'ZZSALES_GROUP'.
    CONVERT DATE sy-datum TIME sy-uzeit 
    INTO TIME STAMP lv_timestamp 
    TIME ZONE sy-zonlo.

    SELECT * INTO CORRESPONDING FIELDS OF TABLE lt_sales_group 
         FROM crmm_but_set0140 AS set 
         INNER JOIN crmm_but_lnk0141 AS link 
         ON link~set_guid = set~set_guid 
         WHERE partner_guid EQ lv_guid 
         AND set~valid_to GE lv_timestamp 
         AND set~valid_from LE lv_timestamp 
         AND link~valid_to GE lv_timestamp 
         AND link~valid_from LE lv_timestamp. 

    IF sy-subrc EQ 0. 
      LOOP AT lt_sales_group INTO ls_sales_group. 
         ls_value = ls_sales_group-sales_group. 
         APPEND ls_value TO et_values. 
      ENDLOOP. 
    ELSE. 
      FREE et_values. 
    ENDIF. 
  ENDCASE. 
ENDMETHOD.

GET_ATTRIB_VAL_DESCRIPTION
METHOD if_ex_crm_terrman_attrib~get_attrib_val_description. 
DATA: lt_text TYPE hrtb_objec, 
lv_objid TYPE pd_objid_r, 
ls_text TYPE objec. 

CASE iv_attribute. 
  WHEN 'ZZSALES_GROUP'. 
    CALL METHOD cl_crm_orgman_services=>list_sales_grps EXPORTING findings_only = space
         IMPORTING sales_grps_text = lt_text. 
                         lv_objid = iv_value+2(8). 
     READ TABLE lt_text INTO ls_text WITH KEY objid = lv_objid. 
     IF sy-subrc EQ 0. 
            ev_value_descr = ls_text-stext. 
     ENDIF. 
  ENDCASE. 
ENDMETHOD.

1 comment:

  1. I am big fan of your blogs. If there is a loyalty program for your readers let me know :)

    ReplyDelete