Header Ads

How to enhance Opportunity search for a custom date type


How to enhance Opportunity search for a custom date type

Most of the time, Customers create its own date-types to assign different dates to business transactions like opportunities. These date-types are assigned to date-profile which in-turn assigned to transaction type.

Lets take an example, Customer has enhanced its opportunity transaction to have 'Contract Signature Date' with date-type ZCONTDATE and maintain this date in milestone assignment block in opportunity. Standard SAP CRM doesn't support business transaction search, based on these custom date-types.

Customer wants to enhance its opportunity search with one of the custom date-type. To achieve the desired functionality, refer the following steps by step procedure:

1. Enhance the Opportunity Search Structure: Create an append structure, for exampleZZCRMST_QUERY_OPP_BTIL to opportunity search structure CRMST_QUERY_OPP_BTIL.
Opp_search_struct_enh.png
2.  Enable field in design layer: Being a custom field it wouldn't be available in search view configuration by default, hence, we need to enable design layer configuration for this field.

     Refer the following location and image to do this change         
     SPRO->Customer Relationship Management->UI Framework->Design Layer->Copy SAP Design Objects

Design_Obj.png
3. Change Opportunity Search View Configuration: As soon as, we enable the design layer configuration for the field, field would start appearing in available field list for search context node in opportunity search view configuration. Move the field from available list to displayed field list in correct view configuration according to your business role etc.


4 Implement the BADI CRM_BADI_RF_Q1O_SEARCH:

After completing step 3, you would be able to see Contract Signature Date in Opportunity search screen and also there would be date popup value help associated with this field as you have used DATUM as type of this field.

If you perform search based on this date field, it wouldn't work as we still need to write the search logic based on this date field. We could achieve this by implementing the CRM_BADI_RF_Q1O_SEARCH BADI. There could be multiple implementations for this BADI, It executes the correct implementation based on filter value. In our case, we need to enhance opportunity search so will give the BTQOPP as filter value to filter attribute OBJ_IL.


Implement the searchmethod of this BADI.

Important Point:
  1. If there is an implementation exists for this BADI for a particular filter value like BTQOPP (For Opportunity) this would always execute the BADI implementation (not the standard Opportunity search ) for Opportunity search irrespective of the search parameters used in search. Hence, we need to take care for standard search along with our custom field search in BADI implementation.
  2. Dates are stored as timestamp in table scapptseg.

     Refer the sample code below:

  1.    METHOD if_crm_rf_q1o_search~search.  
  2.   
  3.   DATA: ls_return                 TYPE bapiret2.  
  4.   DATA: ls_multi_val              TYPE crmt_bsp_search_multi_val.  
  5.   DATA: ls_multi_val_temp         TYPE crmt_bsp_search_multi_val.  
  6.   DATA: lt_multi_val              TYPE crmt_bsp_search_multi_val_tab.  
  7.   DATA: lv_zzcondate_search       TYPE boolean.  
  8.   DATA: lv_std_search_req         TYPE boolean.  
  9.   DATA: lt_bsp_range              TYPE crmt_bsp_range_tab.  
  10.   DATA: lt_guids_temp             TYPE crmt_object_guid_tab.  
  11.   DATA: lv_guid                   TYPE crmt_object_guid.  
  12.   DATA: lt_guids                  TYPE crmt_object_guid_tab.  
  13.   DATA: lt_guidlist               TYPE crmt_bsp_objectkey_tab.  
  14.   DATA: ls_guidlist               TYPE crmt_bsp_objectkey.  
  15.   DATA: lv_dt_string              TYPE string.  
  16.   DATA: lv_time                   TYPE sy-timlo.  
  17.   DATA: lv_recs                   TYPE int4.  
  18.   DATA: lv_recs_temp              TYPE int4.  
  19.   DATA: lv_max_hit                TYPE int4.  
  20.   DATA: lv_number                 TYPE int4.  
  21.   
  22.   
  23.   CONSTANTS:  
  24.         c_abap_true               TYPE boolean VALUE 'X',  
  25.         c_abap_false              TYPE boolean VALUE '',  
  26.         lc_timelow                TYPE sy-timlo VALUE '000000',  
  27.         lc_timehigh               TYPE sy-timlo VALUE '235959'.  
  28.   
  29.   FIELD-SYMBOLS:  
  30.         <fs_bsp_range>            TYPE crmt_bsp_range.  
  31.   
  32.   lv_zzcondate_search = c_abap_false.   " Flag to check whether search is based on Contract Signature Date or not  
  33.   lv_std_search_req = c_abap_true.      " Flag to check whether standard search is required or not  
  34.   lv_max_hit = 0.  
  35.   lt_multi_val[] = it_multivalues[].  
  36.   READ TABLE it_multivalues INTO ls_multi_val  
  37.               WITH KEY fieldname = 'ZZCONTDATE'. " IF Contract Sig. Date is there in search parameter then set lv_zzcondate_search to true  
  38.   IF sy-subrc = 0.  
  39.     lv_zzcondate_search = c_abap_true.  
  40.     DELETE lt_multi_val WHERE fieldname = 'ZZCONTDATE'.   " In Standard search Contact Sig. Parameter shouldn't be passed  
  41.     DESCRIBE TABLE lt_multi_val LINES lv_recs.  
  42.   
  43. * If only OBJECT_ID is there in search parameter list with no values in its value internal table that means no search parameter is passed.  
  44.     IF lv_recs = 1.  
  45.       READ TABLE lt_multi_val INTO ls_multi_val_temp WITH KEY fieldname = 'OBJECT_ID'.  
  46.       IF sy-subrc = 0.  
  47.         DESCRIBE TABLE ls_multi_val_temp-searchvalues LINES lv_recs." ls_multi_val_temp-searchvalues is search parameter value table for that field  
  48.         IF lv_recs = 0.  
  49.           lv_std_search_req = c_abap_false.  
  50.         ENDIF.  
  51.       ENDIF.  
  52.     ENDIF.  
  53.   ENDIF.  
  54.   
  55.   CLEAR lv_recs.  
  56.   IF lv_std_search_req = c_abap_true. " Call standard search only if lv_std_search_req is true  
  57.     IF lv_zzcondate_search = c_abap_true." Search is based on Contract Sig. date as well some other fields so set the max limit to 1000  
  58.       lv_number = 1000.  
  59.     ELSE. "Search is only based on standard fields or other than Contact Sig. date  
  60.       lv_number = iv_number.  
  61.     ENDIF.  
  62.     CALL FUNCTION 'CRM_BSP_OIC_1O_SEARCH_FROM_RF'  
  63.       EXPORTING  
  64.         it_search_tab             = it_search_tab  
  65.         it_multivalues            = lt_multi_val  
  66.         iv_number                 = lv_number  
  67.         iv_extern_call            = 'X'  
  68.         iv_select_for_headerlevel = 'X'  
  69.       IMPORTING  
  70.         et_guidlist               = lt_guidlist  
  71.         et_return                 = et_return  
  72.       EXCEPTIONS  
  73.         date_not_correct          = 1  
  74.         no_card_type              = 2  
  75.         no_card_no                = 3  
  76.         no_program_id             = 4.  
  77.     CASE sy-subrc.  
  78.       WHEN 1.  
  79.         CALL FUNCTION 'BALW_BAPIRETURN_GET2'  
  80.           EXPORTING  
  81.             type   = 'E'  
  82.             cl     = 'CRMN_REPORT'  
  83.             number = 141  
  84.           IMPORTING  
  85.             return = ls_return.  
  86.         APPEND ls_return TO et_return.  
  87.       WHEN 2.  
  88.         CALL FUNCTION 'BALW_BAPIRETURN_GET2'  
  89.           EXPORTING  
  90.             type   = 'E'  
  91.             cl     = 'CRMN_REPORT'  
  92.             number = 128  
  93.           IMPORTING  
  94.             return = ls_return.  
  95.         APPEND ls_return TO et_return.  
  96.       WHEN 3.  
  97.         CALL FUNCTION 'BALW_BAPIRETURN_GET2'  
  98.           EXPORTING  
  99.             type   = 'E'  
  100.             cl     = 'CRMN_REPORT'  
  101.             number = 129  
  102.           IMPORTING  
  103.             return = ls_return.  
  104.         APPEND ls_return TO et_return.  
  105.       WHEN 4.  
  106.         CALL FUNCTION 'BALW_BAPIRETURN_GET2'  
  107.           EXPORTING  
  108.             type   = 'E'  
  109.             cl     = 'CRMN_REPORT'  
  110.             number = 142  
  111.           IMPORTING  
  112.             return = ls_return.  
  113.         APPEND ls_return TO et_return.  
  114.     ENDCASE.  
  115.   ENDIF.  
  116.   
  117.   IF lv_zzcondate_search = c_abap_true. " means search is also based on Contract Sig. date  
  118.   
  119.     REFRESH: lt_guids_temp, lt_guids.  
  120.     lt_bsp_range = ls_multi_val-searchvalues.  
  121.   
  122.     LOOP AT lt_bsp_range ASSIGNING <fs_bsp_range>.  
  123.   
  124. * Contract Sign. date is stored as a timestamp in the table so convert date to time table  
  125. * For exaple Contact Sig. date  EQ 07/06/2009 would be replaced by 20090706000000 to 20090706235959 range, with BT Option, to cover  
  126. * full time of that date.  
  127.   
  128.       IF <fs_bsp_range>-option = 'EQ'.  
  129.         lv_dt_string = <fs_bsp_range>-low.  
  130.         CONCATENATE lv_dt_string '000000' INTO lv_dt_string.  
  131.         <fs_bsp_range>-low = lv_dt_string.  
  132.         <fs_bsp_range>-option = 'BT'.  
  133.   
  134.         CLEAR lv_dt_string.  
  135.         lv_dt_string = <fs_bsp_range>-low.  
  136.         REPLACE '000000' WITH '235959' INTO lv_dt_string.  
  137.         <fs_bsp_range>-high = lv_dt_string.  
  138.       ELSE.  
  139.   
  140.         IF <fs_bsp_range>-option = 'LT'.  
  141.           lv_time = lc_timehigh.  
  142.         ELSEIF <fs_bsp_range>-option = 'GT'.  
  143.           lv_time = lc_timelow.  
  144.         ELSEIF <fs_bsp_range>-option = 'BT'.  
  145.           lv_time = lc_timelow.  
  146.         ENDIF.  
  147.   
  148.         CLEAR lv_dt_string.  
  149.         lv_dt_string = <fs_bsp_range>-low.  
  150.         CONCATENATE lv_dt_string '000000' INTO lv_dt_string.  
  151.         <fs_bsp_range>-low = lv_dt_string.  
  152.   
  153.         IF NOT <fs_bsp_range>-high IS INITIAL.  
  154.           CLEAR lv_dt_string.  
  155.           lv_dt_string = <fs_bsp_range>-high.  
  156.           CONCATENATE lv_dt_string '235959' INTO lv_dt_string.  
  157.           <fs_bsp_range>-high = lv_dt_string.  
  158.         ENDIF.  
  159.   
  160.       ENDIF.  
  161.   
  162.     ENDLOOP.  
  163.   
  164.     IF lv_std_search_req = c_abap_false.  
  165. * Means no standard parameter is passed and search is only based on Contract Sig. date so get the result UP to MAX_HIT and return  
  166.   
  167. * Fetch Opportunity based on Contract Signature Date  
  168.       SELECT a~guid_hi FROM crmd_link AS a INNER JOIN scapptseg AS b ON a~guid_set = b~appl_guid  
  169.                        INTO TABLE lt_guids_temp UP TO iv_number ROWS WHERE b~tst_from IN lt_bsp_range AND  
  170.                                                         b~appt_type = 'ZCONTDATE' AND  
  171.                                                         a~objtype_hi = '05' AND  
  172.                                                         a~objtype_set = '30' .  
  173.       LOOP AT lt_guids_temp INTO lv_guid.  
  174.         APPEND lv_guid TO et_guidlist.  
  175.       ENDLOOP.  
  176.   
  177.       RETURN.  
  178.     ENDIF.  
  179.   
  180. * Search is based on some standard field as well as Contract Sig. date  
  181.   
  182. * Fetch Opportunity based on Contract Signature Date  
  183.     SELECT a~guid_hi FROM crmd_link AS a INNER JOIN scapptseg AS b ON a~guid_set = b~appl_guid  
  184.                      INTO TABLE lt_guids_temp WHERE b~tst_from IN lt_bsp_range AND  
  185.                                                       b~appt_type = 'ZCONTDATE' AND  
  186.                                                       a~objtype_hi = '05' AND  
  187.                                                       a~objtype_set = '30'.  
  188.   
  189.     IF sy-subrc = 0.  
  190.       SORT lt_guidlist.  
  191.       DESCRIBE TABLE lt_guidlist LINES lv_recs.  
  192.       DESCRIBE TABLE lt_guids_temp LINES lv_recs_temp.  
  193.   
  194. * Check which table has less number of records, will loop on that table.  
  195.       IF lv_recs < lv_recs_temp.  
  196.         LOOP AT lt_guidlist INTO ls_guidlist.  
  197.           READ TABLE lt_guids_temp TRANSPORTING NO FIELDS WITH KEY table_line = ls_guidlist BINARY SEARCH.  
  198.           IF sy-subrc = 0.  
  199.             lv_max_hit = lv_max_hit + 1.  
  200.             APPEND ls_guidlist TO et_guidlist.  
  201.             IF lv_max_hit = iv_number.  
  202.               EXIT.  
  203.             ENDIF.  
  204.           ENDIF.  
  205.         ENDLOOP.  
  206.       ELSE.  
  207.         LOOP AT lt_guids_temp INTO lv_guid.  
  208.           READ TABLE lt_guidlist TRANSPORTING NO FIELDS WITH KEY table_line = lv_guid BINARY SEARCH.  
  209.           IF sy-subrc = 0.  
  210.             lv_max_hit = lv_max_hit + 1.  
  211.             APPEND lv_guid TO et_guidlist.  
  212.             IF lv_max_hit = iv_number.  
  213.               EXIT.  
  214.             ENDIF.  
  215.           ENDIF.  
  216.         ENDLOOP.  
  217.       ENDIF.  
  218.     ENDIF.  
  219.   
  220.   ELSE."    Search is only based on standard fields or other than Contact Sig. date  
  221.     LOOP AT lt_guidlist INTO ls_guidlist.  
  222.       APPEND ls_guidlist TO et_guidlist.  
  223.     ENDLOOP.  
  224.   
  225.   ENDIF.  
  226.   
  227. ENDMETHOD.  
Powered by Blogger.