The standard product search in CRM will show the user all materials in the system. For this blog we want to help users to quickly find the right products depending on the role they use in the UI. Not all of these requirements can be solved with authorization so in this blog we describe the steps needed to enhance the standard product search with the field Item Category group and limit the values of this field per Business Role.
Adding the new field to the Product Search
Extending search structureUsing the Genil model browser you can find the corresponding attribute structure for a query. For the product search this is the CRMT_PRIL_QUERY_ADVSEARCH_PROD structure. Via SE11 you can extend this structure using below append.
Adding Search CustomizingWe now have the field available in the search structure but we need to specify where the system needs to search for this attribute. This can be done in the IMG:
Customer Relationship Management -> Master Data -> Products -> Basic Settings -> Add Attributes to Search Structure.
Configuration of viewYou can now add the field to the view configuration of component PRD01QR. There are two views, Search for the generic product search and SearchHelp for the product search pop-up.
Please note that if you do not deactivate the hiding of fields in customizing the additional field will not be visible in the configuration.
Customer Relationship Management -> UI Framework -> UI Framework Definition -> Design Layer -> Deactivate Hiding of Fields.
Now we see the Item Category Group field on the product search, since this will show all available item category Groups including all SAP standards this is not very user friendly. To limit the results we will enhance this standard component and implement a custom customizing table to restrict values based on the business role. Since the list will be much smaller we will also make it a pick list.
Limit the values based on Business Role
Create Customizing table
Since we want to limit the values based on the business role we create a custom table with the following fields. We have also created a field for SEARCH_FIELD, this makes it possible to use the same table for filtering other fields in the same structure.
As an example for this blog we have filled the table with the following values.
Enhance Component, Views and redefine methodWe need to enhance the component PRD01QR and also the Views SearchHelp and Search.
To make the field a pick list we have generated a GET_P method and implemented below code:
rv_value = cl_bsp_dlc_view_descriptor=>field_type_picklist.
In below class we need to redefine method CHANGE_DQUERY_DEF_EXTENSION.
In method we then filter the values with the following sample implementation:
lv_role TYPE string,
lt_prod_src_flt TYPE STANDARD TABLE OF zzip_prd_src_flt,
BEGIN OF ls_src_range,
search_field TYPE zzip_itm_cat_flt-search_field,
search_value TYPE RANGE OF zzip_itm_cat_flt-search_value,
END OF ls_src_range,
ls_range_value LIKE LINE OF ls_src_range-search_value,
lt_src_range LIKE STANDARD TABLE OF ls_src_range.
<lfs_result> TYPE crms_thtmlb_search_field_info,
<lfs_prod_src_flt> TYPE zzip_itm_cat_flt,
<lfs_src_range> LIKE ls_src_range.
* Call SUPER
CALL METHOD super->change_dquery_def_extension
ct_result = ct_result.* Determine Business Role
lv_role = cl_crm_ui_profile=>get_instance( )->get_profile( ).
* Get Product Search Filter conditions - Based on Business Role
SELECT * FROM zzip_prd_src_flt
INTO CORRESPONDING FIELDS OF TABLE lt_prod_src_flt
WHERE business_role = lv_role.
* Continue only if Filter conditions are found!
CHECK sy-subrc = 0.
* Create a range table for each field to be filtered
LOOP AT lt_prod_src_flt ASSIGNING <lfs_prod_src_flt>.
"Read filter range for field READ TABLE lt_src_range
WITH KEY search_field = <lfs_prod_src_flt>-search_field.
"Not found? Then create it! (First filter condition for current field)
IF sy-subrc NE 0.
APPEND INITIAL LINE TO lt_src_range
<lfs_src_range>-search_field = <lfs_prod_src_flt>-search_field.
"Add filter condition
ls_range_value-sign = 'I'.
ls_range_value-option = 'EQ'.
ls_range_value-low = <lfs_prod_src_flt>-search_value.
ls_range_value-high = ''.
APPEND ls_range_value TO <lfs_src_range>-search_value.
* Process Product Search Filter conditions
LOOP AT lt_src_range ASSIGNING <lfs_src_range>.
"Read field to be filtered
READ TABLE ct_result
WITH KEY field = <lfs_src_range>-search_field.
IF sy-subrc = 0.
NOT IN <lfs_src_range>-search_value.
If you have multiple implementations for filtering, you could move this code to a generic class and calling that class in this method.