Working with Get_Dquery_Definition
SAP CRM Account search
When searching for accounts we f.i. can't search for their Sales Area Data. But let's say we only want to display accounts that have a certain Sales Office. This guide explains how to add a field from one component (Sales) into a search of another (Account Search). Of course the data has to be related -> check the GENIL Model Browser.Step by Step
1. Get technical data of the Account Search
Log in to the Web UI and navigate to the Account Management. Under Search, click on Accounts. Now click in any input field and press F2 to get the technical data. So we write down:Component: BP_HEAD_SEARCH
View: MainSearch
Context Node: SEARCH
Role Key (Found): ZSALES
2. Get technical data of the Sales Office
Log in to the Web UI and navigate to the Account Management. Under Search, click on Accounts. Search for any account and look at it. Find the Sales Area Data and click on Edit respectively New. Locate Sales Office under Organization and click into the picklist. While still clicking, press F2 to get the technical data. So we write down:Component: BP_SALES
View: CorpAccountOrgEF
Context Node: BUILRESORG
Attribute: STRUCT.SALES_OFFICE
3. Get the dictionary structure of the Account Search
We can find structures through the Genil Model Browser - Transaction GENIL_MODEL_BROWSER. Choose Component Set ALL and press F8. Open the node Search Objects and locate BuilHeaderSearch. Open Attribute Structure and write down...Account Head Search Structure: CRMT_BUPA_IL_HEADER_SEARCH
4. Get the dictionary data element of the Sales Office
Again open the Genil Model Browser with Component Set ALL. We know that account and sales data are related. So we search through the Relations.Open Root Objects and locate BuilHeader. Open node Relations and search for the sales relation. You'll find one called BuilSalesArrangementRel.
Open it and again open the Relations node. There you'll find an object called BuilResponsibleOrganisationRel. Open this relation and its object. Now open Attribute Structure and the structure below it: there is our Sales Office. Open it to get the dictionary data element and write it down...
Sales Office Data Element: CRMT_SALES_OFFICE
5. Extend the Account Search structure
Open structure CRMT_BUPA_IL_HEADER_SEARCH and click on the "Append Structure" button. Create a new structure in your customer Namespace i.e. ZCRMT_BUPA_IL_HEADER_SEARCH and add the Sales Office as ZZSALES_OFFICE with the data element we found in Step 4.6. Add the Sales Office to the Account Search page
Now that we have the field Sales Office in the account search structure can we add it to the View MainSearch as search parameter.Open the Component Workbench - transaction BSP_WD_CMPWB - and display BP_HEAD_SEARCH. Double click on View MainSearch and go the Configuration tab. Select the configuration of found Role Key in step 1 (or copy configuration if there is none existing yet). Locate in Available Search Criteria the newly added Sales Office, move it to the right side and display it.
Can we search yet? No!
We added the field to the search structure but that's it. The search logic is missing. At the moment the search would try to find the Sales Office directly in the account header data - and that obviously won't work.
7. Enhance the Business Partner Search with BAdI implementation
Because we added a new field which doesn't belong to the account header data, must we program our own search logic. This is done using BAdI Implementation. In transaction se18 we got to find the needed BAdI and its Enhancement Spot:Enhancement Spot: CRM_BUPA_IL_SEARCH
BAdI: BADI_CRM_BUPA_IL_SEARCH_EXT
Open the above mentioned Enhancement Spot and go to tab Enh. Spot Element Definitions. Open the search extension BAdI, right click on Implementation and choose Create Implementation. You will get a window showing all existing implementations. Click on New (empty paper icon). Follow the instructions to create the implementation.
Open the newly created Enhancement Implementation. In tab Enh. Implementation Elements expand your BAdI and double click on Implementing Class. If a class has not yet been created, create one.
Now we reached the programming part. Open your Implementing Class and the method IF_EX_CRM_BUPA_IL_SEARCH_EXT~SEARCH_CRITERIA_INITIAL. This method should check if there are relevant search criteria for this implementation. In our case we check if the Sales Office has been filled:
data: ls_bupa_header_search type crmt_bupa_il_header_search. move-corresponding is_parameters to ls_bupa_header_search. " set search parameters in accout search structure if ls_bupa_header_search-zzsales_office is not initial. " check if the Sales Office has been filled... cv_is_not_initial = abap_true. "...and set the changing parameter to true endif.
Now open the actual search method IF_EX_CRM_BUPA_IL_SEARCH_EXT~SEARCH_PARTNERS. This method either gets the business partner that were found so far or nothing (parameter CT_PARTNER_KEYS). In the second case, this method has to search for all partners and return the ones that have the searched Sales Office. The code I'm going to post is just an example. There are maybe better ways to do it.
Data definitions:
data: ls_bupa_header_search type crmt_bupa_il_header_search, " account search structure ls_partner_key type bupa_partner_guid, " strucutre of the parameter CT_PARTNER_KEYS ls_partner_crm type crmm_but_lnk0141, " table which contains the SET_GUID of the partner (read by PARTNER_GUID) ls_partner_sales type crmm_but_set0140, " table which contains the SALES_OFFICE of partner (read by SET_GUID) lv_guid type crmmspl_bp_l0011-set_guid, " local SET_GUID variable rt_bu_type type range of but000-type, " partner category range table for selectiong table BUT000 rs_bu_type like line of rt_bu_type, " structure for partner category range table lv_index type sytabix, " index variable to hold sy-tabix lv_i type i. " misc. numeric variable
move-corresponding is_parameters to ls_bupa_header_search.
if ct_partner_keys is initial. " set partner category filter cv_category_filtered = abap_true. rs_bu_type-sign = 'I'. rs_bu_type-option = 'EQ'. if is_category-organizations = abap_true. rs_bu_type-low = '2'. append rs_bu_type to rt_bu_type. endif. if is_category-persons = abap_true. rs_bu_type-low = '1'. append rs_bu_type to rt_bu_type. endif. if is_category-groups = abap_true. rs_bu_type-low = '3'. append rs_bu_type to rt_bu_type. endif. " get partners select partner partner_guid from but000 into corresponding fields of table ct_partner_keys where type in rt_bu_type. endif.
loop at ct_partner_keys into ls_partner_key. lv_index = sy-tabix. clear: ls_partner_crm, ls_partner_sales, lv_guid. " try to get set guid... select single * from crmm_but_lnk0141 into ls_partner_crm where partner_guid = ls_partner_key-partner_guid. if sy-subrc = 0. " check if partner has wanted sales office... if ls_bupa_header_search-zzsales_office cs '*'. replace all occurrences of '*' in ls_bupa_header_search-zzsales_office with '%'. select single * from crmm_but_set0140 into ls_partner_sales where set_guid = ls_partner_crm-set_guid and sales_office like ls_bupa_header_search-zzsales_office. else. select single * from crmm_but_set0140 into ls_partner_sales where set_guid = ls_partner_crm-set_guid and sales_office = ls_bupa_header_search-zzsales_office. endif. if sy-subrc <> 0. "...if not, remove partner delete ct_partner_keys index lv_index. endif. else. "...if not existing, remove partner (no sales data exist for partner) delete ct_partner_keys index lv_index. endif.
if ct_partner_keys is initial.
raise no_partners_found.
endif.
8. Create an Enhancement Set (optional)
If we want to add a picklist for our Sales Office we have to enhance the account main search and add the picklist through programming. To do that we need an Enhancement Set. Such a set is created using transaction sm34 with View Cluster BSPWDVC_CMP_EXT.Secondly the Enhancement Set needs to be assigned to a client. This is done in transaction sm30 with View BSPWDV_EHSET_ASG.
9. Enhance Account Search View (optional)
Display BP_HEAD_SEARCH in the Component Workbench with your just created Enhancement Set. Right click on View MainSearch and choose Enhance. Create all objects needed.10. Add a picklist to the Sales Office search parameter (optional)
Go to the implementation class of the enhanced MainSearch View (probably called ZL_BP_HEAD_MAINSEARCH_IMPL). Redefine the method GET_DQUERY_DEFINITIONS. Make sure that you call the original code from class CL_BP_HEAD_MAINSEARCH_IMPL by using the super->get_dquery_definitions call. In addition to the Sales Office we also provide a dropdown list for the Sales Group. This is how I've done it:Data defintions:
DATA: lt_ddlb TYPE bsp_wd_dropdown_table, " drop down table type of method ls_ddlb TYPE bsp_wd_dropdown_line, " cl_crm_uiu_bp_cust_get=>get_val_for_sales_office lt_ddlb_opt TYPE crmt_thtmlb_search_ddlb_nvp, " drop down table type of field ddlb_options ls_ddlb_opt TYPE crms_thtmlb_search_ddlb_nvp, " of parameter rt_result lt_ddlb_group TYPE bsp_wd_dropdown_table, ls_ddlb_group TYPE bsp_wd_dropdown_line, lt_ddlb_opt_group TYPE crmt_thtmlb_search_ddlb_nvp, ls_ddlb_opt_group TYPE crms_thtmlb_search_ddlb_nvp, lt_operators type CRMT_THTMLB_SEARCH_OPERATOR, lv_operator type CRM_THTMLB_SEARCH_OPERATOR, ls_sales_area TYPE crmt_bus_sales_area, " sales area structure lv_sales_office TYPE crmt_sales_office, lt_partner_crm TYPE TABLE OF crmmspl_bp_l0011, ls_partner_crm TYPE crmmspl_bp_l0011. FIELD-SYMBOLS: <rs_result> LIKE LINE OF rt_result.
CALL METHOD super->get_dquery_definitions
RECEIVING
rt_result = rt_result.
" Initial line of Sales Offices
APPEND INITIAL LINE TO lt_ddlb.
MOVE-CORRESPONDING ls_ddlb TO ls_ddlb_opt.
APPEND ls_ddlb_opt TO lt_ddlb_opt.
" Initial line of Sales Groups
APPEND INITIAL LINE TO lt_ddlb_group.
MOVE-CORRESPONDING ls_ddlb_group TO ls_ddlb_opt_group.
APPEND ls_ddlb_opt_group TO lt_ddlb_opt_group.
" Get all Sales Organizaions
SELECT DISTINCT sales_org channel division
FROM crmmspl_bp_l0011
INTO CORRESPONDING FIELDS OF TABLE lt_partner_crm.
LOOP AT lt_partner_crm INTO ls_partner_crm.
MOVE-CORRESPONDING ls_partner_crm TO ls_sales_area.
" Get values for SALES_OFFICE provide sales area
CALL METHOD cl_crm_uiu_bp_cust_get=>get_val_for_sales_office
EXPORTING
is_sales_area = ls_sales_area
RECEIVING
rt_value = lt_ddlb
EXCEPTIONS
error_occurred = 1
OTHERS = 2.
IF sy-subrc = 0.
LOOP AT lt_ddlb INTO ls_ddlb.
lv_sales_office = ls_ddlb-key.
" get sales groups
CALL METHOD cl_crm_uiu_bp_cust_get=>get_val_for_sales_group
EXPORTING
is_sales_area = ls_sales_area
iv_sales_office = lv_sales_office
RECEIVING
rt_value = lt_ddlb_group
EXCEPTIONS
error_occurred = 1
OTHERS = 2.
IF sy-subrc = 0.
LOOP AT lt_ddlb_group INTO ls_ddlb_group.
MOVE-CORRESPONDING ls_ddlb_group TO ls_ddlb_opt_group.
APPEND ls_ddlb_opt_group TO lt_ddlb_opt_group.
ENDLOOP.
ENDIF.
MOVE-CORRESPONDING ls_ddlb TO ls_ddlb_opt.
APPEND ls_ddlb_opt TO lt_ddlb_opt.
ENDLOOP.
ENDIF.
ENDLOOP.
lv_operator = 'EQ'.
append lv_operator to lt_operators.
LOOP AT rt_result ASSIGNING <rs_result>.
CASE <rs_result>-field.
WHEN 'ZZSALES_OFFICE'.
SORT lt_ddlb_opt BY value.
<rs_result>-ddlb_options = lt_ddlb_opt.
<rs_result>-operators = lt_operators.
WHEN 'ZZSALES_GROUP'.
SORT lt_ddlb_opt_group BY value.
<rs_result>-ddlb_options = lt_ddlb_opt_group.
<rs_result>-operators = lt_operators.
WHEN OTHERS.
ENDCASE.
ENDLOOP.
--------------------------------------------------------------------------------------------------------------------------
contact us for all your SAP Consulting , Implementation and Support requirements www.anniesummerconsulting.com
Post a Comment