Steps to create a custom query in POWL
Author: Varsha
The steps to create a custom query are shown with an example.
Example Requirement: To provide a link in POWL to the users so that they can display the list of
Shopping Carts belonging to the user’s company code.
Create and implement the custom Feeder class.
Create and Maintain the feeder class in the SPRO settings as shown below:
The following path in SAP SRM system
SAP Implementation Guide SRM Server Cross-Application Basic Settings POWL and Advanced
Search Adjust POWL Layout, Search Criteria, and Pushbuttons
Select an existing feeder and click on copy with all the dependent objects and create a Z Feeder
type.
To know the feeder class associated with the work list (feeder type) we need to identify the
application id and the work list associated with the application.
Go to T-code: POWL_TYPER to see the all the application id associated with the work list. Select the
application id relevant to the work list (TYPE column in the below screenshot).
With the work list find the feeder class. Go to T-code: POWL_TYPE to see the work list (shown in the
screenshot below).
Select the relevant feeder type in the figure above and go to details to see the feeder class.
Create a copy of the feeder class (ex: /SAPSRM/CL_CLL_PWL_A_SC) as ZCL_CLL_PWL_XXX.
Link the custom feeder class - ZCL_CLL_PWL_XXX to a custom work list (feeder type)
ZSAPSRM_FEEDER_XXX in the T-code: POWL_TYPE
Select the work lists (feeder type highlighted above) go to details and enter the feeder class name
and save it.
Link the application id (SAPSRM_E_CHECKSTATUS) to work list (feeder type) ZSAPSRM_FEEDER_XXX
in the T-code: POWL_TYPER. Go to t-code and make a new entry for the existing application and add
the Z feeder type to it.
Link a Z query id ex: ZSAPSRM_E_CHECKSTATUS_XXX to the work list (feeder type) in the
screenshot below ZSAPSRM_FEEDER_XXX in the T-code: POWL_QUERY.
After completing the above steps a link will be shown in the POWL with the define query.
Follow the steps below to create a database search for the custom query
Open the custom feeder class: ZCL_CLL_PWL_XXX. The search agent is initialized in the feeder class.
Redefine the method: INIT_SEARCH_AGENT and create the method: GET_INSTANCE_SEARCH_AGENT
and CREATE_CUST_MESS_HANDLER.
Feeder Class ZCL_CLL_PWL_XXX
protected section.
*"* protected components of class ZCL_CLL_PWL_XXX
methods INIT_SEARCH_AGENT
redefinition .
private section.
*"* private components of class ZCL_CLL_PWL_XXX
methods GET_INSTANCE_AGENT
importing
!IV_OBJECT_TYPE type /SAPSRM/IDX_OBJTYP
!IV_OBJECT_NAME type OBJNAME
!IV_SCENARIO type /SAPSRM/AGENT_SCENARIO
!IV_SRH_SERV_TYPE type /SAPSRM/SEARCH_SERVICE_TYPE optional
exporting
!EO_INSTANCE type ref to /SAPSRM/IF_SRC_AGENT
raising
/SAPSRM/CX_SRC_AGENT_INST_FAIL .
class-methods CREATE_CUST_MESS_HANDLER
importing
!IV_OBJECT_TYPE type /SAPSRM/IDX_OBJTYP
!IV_OBJECT_NAME type OBJNAME
!IV_MSGTY type SYMSGTY optional
returning
value(RO_MESSAGE_HANDLER) type ref to /SAPSRM/IF_PDO_MSG_CONSUMER .
Source Code
METHOD init_search_agent.
DATA lv_oname TYPE objname.
DATA lt_messages_sa_ex TYPE bbpt_pd_messages.
DATA lo_src_agent_inst_fail TYPE REF TO /sapsrm/cx_src_agent_inst_fail.
* IF mo_src_agent IS INITIAL.
CLEAR mo_src_agent.
lv_oname = mv_object_type.
TRY.
* Create proper search agent according to customizing
CALL METHOD get_instance_agent
EXPORTING
iv_object_type = /sapsrm/if_src_agent_c=>gc_idx_objtyp_bo
iv_object_name = lv_oname
iv_scenario = /sapsrm/if_src_agent_c=>gc_scenario_local
IMPORTING
eo_instance = mo_src_agent.
CATCH /sapsrm/cx_src_agent_inst_fail INTO lo_src_agent_inst_fail.
CALL METHOD lo_src_agent_inst_fail->mo_message_handler->get_messages
IMPORTING
et_messages = lt_messages_sa_ex.
CALL METHOD me->map_messages
EXPORTING
it_messages_action = lt_messages_sa_ex.
ENDTRY.
ENDMETHOD.
METHOD get_instance_agent.
DATA: lo_object TYPE REF TO object,
lv_agent TYPE seoclsname,
ls_message TYPE /sapsrm/s_src_message,
lt_messages TYPE /sapsrm/t_src_message,
lv_msg_dummy TYPE c,
lv_msgid TYPE symsgid,
lo_message_handler TYPE REF TO /sapsrm/if_pdo_msg_consumer,
lx_cust_miss TYPE REF TO /sapsrm/cx_src_agent_cust_miss,
lx_agent_fail TYPE REF TO /sapsrm/cx_src_agent_inst_fail,
lx_casting_error TYPE REF TO cx_sy_assign_cast_error.
lv_msgid = /sapsrm/if_src_agent_c=>gc_agent_msgid.
* Create the search agent and put it in this method.
* Created a copy of /SAPSRM/CL_SRC_AGENT
lv_agent = 'ZCL_SRC_AGENT_XXX'.
* Create proper agent according to customizing
TRY.
CREATE OBJECT lo_object
TYPE
(lv_agent)
EXPORTING
iv_object_type = iv_object_type
iv_object_name = iv_object_name
iv_scenario = iv_scenario
iv_srh_serv_type = iv_srh_serv_type.
CATCH /sapsrm/cx_src_agent_inst_fail INTO lx_agent_fail.
IF lx_agent_fail->mo_message_handler IS INITIAL.
lo_message_handler = /sapsrm/cl_src_agent_factory=>create_agent_fact_
mess_handler( iv_object_type = iv_object_type
iv_object_name = iv_object_name ).
ELSE.
lo_message_handler = lx_agent_fail->mo_message_handler.
ENDIF.
RAISE EXCEPTION TYPE /sapsrm/cx_src_agent_inst_fail
EXPORTING
previous = lx_agent_fail->previous
mo_message_handler = lo_message_handler
mv_object_type = iv_object_type
mv_object_name = iv_object_name
mv_scenario = iv_scenario.
ENDTRY.
* cast the general object to the agent
TRY.
eo_instance ?= lo_object.
CATCH cx_sy_assign_cast_error INTO lx_casting_error.
MESSAGE e012(/sapsrm/pdo_so_agent) INTO lv_msg_dummy.
ls_message-msgid = /sapsrm/if_src_agent_c=>gc_agent_msgid.
ls_message-msgno = 012.
ls_message-msgty = /sapsrm/if_src_agent_c=>gc_msgty_e.
APPEND ls_message TO lt_messages.
lo_message_handler = /sapsrm/cl_src_agent_factory=>create_agent_fact_me
ss_handler(
iv_object_type = iv_object_type
iv_object_name = iv_object_name
it_messages = lt_messages ).
RAISE EXCEPTION TYPE /sapsrm/cx_src_agent_inst_fail
EXPORTING
previous = lx_casting_error
mo_message_handler = lo_message_handler
mv_object_type = iv_object_type
mv_object_name = iv_object_name
mv_scenario = iv_scenario.
ENDTRY.
ENDMETHOD.
Find the search agent base class (/SAPSRM/CL_SRC_AGENT) for the feeder /SAPSRM/CL_CLL_PWL_A_SC
and create a copy of the search agent class as ZCL_SRC_AGENT_XXXX.
Following methods need to be created in the custom search agent class:
Search agent class ZCL_SRC_AGENT_XXXX
public section.
*"* public components of class ZCL_SRC_AGENT_COCO_SC
*"* do not include other source files here!!!
interfaces /SAPSRM/IF_SRC_AGENT .
interfaces /SAPSRM/IF_SRC_SERVICE .
methods CONSTRUCTOR
importing
!IV_OBJECT_TYPE type /SAPSRM/IDX_OBJTYP
!IV_OBJECT_NAME type OBJNAME
!IV_SCENARIO type /SAPSRM/AGENT_SCENARIO
!IV_SRH_SERV_TYPE type /SAPSRM/SEARCH_SERVICE_TYPE optional
!IO_RESULT_DEF type ref to CL_ABAP_TABLEDESCR optional
raising
/SAPSRM/CX_SRC_AGENT_INST_FAIL .
private section.
*"* private components of class ZCL_SRC_AGENT_XXXX
*"* do not include other source files here!!!
interface /SAPSRM/IF_SRC_AGENT_C load .
class-methods CREATE_AGENT_SRH_MESS_HANDER
importing
!IV_MSGNO type SYMSGNO
!IV_MSGTY type SYMSGTY default /SAPSRM/IF_SRC_AGENT_C=>GC_MSGTY_E
exporting
!EO_MESSAGE_HANDLER type ref to /SAPSRM/IF_PDO_MSG_CONSUMER
changing
!CT_MESSAGES type /SAPSRM/T_SRC_MESSAGE
raising
/SAPSRM/CX_SRC_AGENT_SRH_ERROR .
class-methods GET_INSTANCES
importing
!IV_OBJECT_TYPE type /SAPSRM/IDX_OBJTYP
!IV_OBJECT_NAME type OBJNAME
!IO_SRC_AGENT type ref to /SAPSRM/IF_SRC_AGENT
!IV_SRH_SERV_TYPE type /SAPSRM/SEARCH_SERVICE_TYPE optional
!IV_SCENARIO type /SAPSRM/AGENT_SCENARIO optional
returning
value(RT_INSTANCES) type /SAPSRM/T_SRC_INSTANCE
raising
/SAPSRM/CX_SRC_SRV_INST_FAILED .
class-methods CREATE_CUST_MESS_HANDLER
importing
!IV_OBJECT_TYPE type /SAPSRM/IDX_OBJTYP
!IV_OBJECT_NAME type OBJNAME
!IV_MSGTY type SYMSGTY optional
!IV_CUST_MSGNO type SYMSGNO
returning
value(RO_MESSAGE_HANDLER) type ref to /SAPSRM/IF_PDO_MSG_CONSUMER .
class-methods CREATE_SERV_FACT_MESS_HANDLER
importing
!IV_OBJECT_TYPE type /SAPSRM/IDX_OBJTYP
!IV_OBJECT_NAME type OBJNAME
!IV_MSGTY type SYMSGTY optional
!IT_MESSAGES type /SAPSRM/T_SRC_MESSAGE optional
returning
value(RO_MESSAGE_HANDLER) type ref to /SAPSRM/IF_PDO_MSG_CONSUMER
raising
/SAPSRM/CX_SRC_SRV_INST_FAILED .
Source Code
METHOD CREATE_AGENT_SRH_MESS_HANDER.
DATA: ls_message TYPE /sapsrm/s_src_message,
lt_messages TYPE /sapsrm/t_src_message,
lv_msgid TYPE symsgid,
lx_abort TYPE REF TO /sapsrm/cx_pdo_abort.
lv_msgid = /sapsrm/if_src_agent_c=>gc_agent_msgid.
ls_message-msgid = lv_msgid.
ls_message-msgno = iv_msgno.
ls_message-msgty = iv_msgty.
APPEND ls_message TO lt_messages.
IF NOT LINES( ct_messages ) IS INITIAL.
APPEND LINES OF ct_messages TO lt_messages.
REFRESH ct_messages.
ENDIF.
APPEND LINES OF lt_messages TO ct_messages.
TRY.
eo_message_handler = /sapsrm/cl_src_service_base=>create_message_handle
r( it_messages = ct_messages ).
CATCH /sapsrm/cx_pdo_abort INTO lx_abort.
RAISE EXCEPTION TYPE /sapsrm/cx_src_agent_srh_error
EXPORTING
previous = lx_abort.
ENDTRY.
ENDMETHOD.
METHOD create_cust_mess_handler.
DATA: ls_message TYPE /sapsrm/s_src_message,
lt_messages TYPE /sapsrm/t_src_message.
ls_message-msgid = /sapsrm/if_src_agent_c=>gc_agent_msgid.
ls_message-msgno = iv_cust_msgno.
ls_message-msgty = iv_msgty.
APPEND ls_message TO lt_messages.
ro_message_handler = create_serv_fact_mess_handler(
iv_object_type = iv_object_type
iv_object_name = iv_object_name ).
ENDMETHOD.
METHOD create_serv_fact_mess_handler.
DATA: lv_msg_dummy TYPE c,
ls_message TYPE /sapsrm/s_src_message,
lt_messages TYPE /sapsrm/t_src_message,
lx_pdo_abort TYPE REF TO /sapsrm/cx_pdo_abort,
lv_msgid TYPE symsgid.
lv_msgid = /sapsrm/if_src_agent_c=>gc_agent_msgid.
* for where used check
MESSAGE e003(/sapsrm/pdo_so_agent) WITH iv_object_type iv_object_name INTO
lv_msg_dummy.
ls_message-msgid = lv_msgid.
ls_message-msgno = 003.
ls_message-msgty = iv_msgty.
ls_message-msgv1 = iv_object_type.
ls_message-msgv2 = iv_object_name.
APPEND ls_message TO lt_messages.
IF lines( it_messages ) <> 0.
APPEND LINES OF it_messages TO lt_messages.
ENDIF.
TRY.
ro_message_handler = /sapsrm/cl_src_service_base=>create_message_handle
r( it_messages = lt_messages ).
CATCH /sapsrm/cx_pdo_abort INTO lx_pdo_abort.
RAISE EXCEPTION TYPE /sapsrm/cx_src_srv_inst_failed
EXPORTING
previous = lx_pdo_abort
mv_object_type = iv_object_type
mv_object_name = iv_object_name.
ENDTRY.
ENDMETHOD.
METHOD get_instances.
**********************************************************************
* This method provides the instance of the custom service provider
**********************************************************************
DATA: lo_object TYPE REF TO object,
lv_active_service TYPE /sapsrm/search_service_type,
ls_service TYPE /sapsrm/s_src_instance,
ls_c_src_rd TYPE /sapsrm/c_src_rd,
ls_message TYPE /sapsrm/s_src_message,
lt_messages TYPE /sapsrm/t_src_message,
lv_msg_dummy TYPE c,
lv_msgid TYPE symsgid.
DATA: lt_services TYPE /sapsrm/t_src_instance,
lt_c_src_svs TYPE /sapsrm/t_c_src_services,
lt_c_src_rds TYPE /sapsrm/t_c_src_rfc_dests,
lt_template_ids TYPE /sapsrm/t_esh_template_ids.
DATA: lo_message_handler TYPE REF TO /sapsrm/if_pdo_msg_consumer,
lx_cust_miss TYPE REF TO /sapsrm/cx_src_agent_cust_miss,
lx_root TYPE REF TO cx_root,
lx_esh_invalid_input TYPE REF TO /sapsrm/cx_esh_invalid_input,
lx_esh_cust_miss TYPE REF TO /sapsrm/cx_esh_cust_miss.
FIELD-SYMBOLS: <ls_cust_service> TYPE /sapsrm/c_src_sv,
<ls_c_src_svs> TYPE /sapsrm/c_src_sv.
lv_msgid = /sapsrm/if_src_agent_c=>gc_agent_msgid.
* Read the Customizing of the service provider
TRY.
/sapsrm/cl_src_agent_cust=>get_cust_serv_provs(
EXPORTING
iv_object_type = iv_object_type
iv_object_name = iv_object_name
IMPORTING
et_c_src_svs = lt_c_src_svs ).
CATCH /sapsrm/cx_src_agent_cust_miss INTO lx_cust_miss.
* for where used check
MESSAGE e006(/sapsrm/pdo_so_agent) INTO lv_msg_dummy.
lo_message_handler = create_cust_mess_handler(
iv_object_type = iv_object_type
iv_object_name = iv_object_name
iv_cust_msgno = 006 ).
RAISE EXCEPTION TYPE /sapsrm/cx_src_srv_inst_failed
EXPORTING
previous = lx_cust_miss
mo_message_handler = lo_message_handler
mv_object_type = iv_object_type
mv_object_name = iv_object_name.
ENDTRY.
READ TABLE lt_c_src_svs ASSIGNING <ls_c_src_svs> WITH KEY object_name = iv
_object_name
service = 'DB'.
IF sy-subrc EQ 0.
<ls_c_src_svs>-service_provider = 'ZCL_SRC_SRV_DB_XXXX'.
ENDIF.
*****Check if the below code needs to be there selectively
* Get the TREX template ids
TRY.
/sapsrm/cl_esh_xtr_customizing=>get_esh_template_ids(
EXPORTING
iv_object_type = iv_object_type
iv_object_name = iv_object_name
IMPORTING
et_template_ids = lt_template_ids ).
CATCH /sapsrm/cx_esh_invalid_input INTO lx_esh_invalid_input.
MESSAGE e007(/sapsrm/pdo_so_agent) INTO lv_msg_dummy.
lo_message_handler = create_cust_mess_handler(
iv_object_type = iv_object_type
iv_object_name = iv_object_name
iv_cust_msgno = 007 ).
RAISE EXCEPTION TYPE /sapsrm/cx_src_srv_inst_failed
EXPORTING
previous = lx_esh_invalid_input
mo_message_handler = lo_message_handler
mv_object_type = iv_object_type
mv_object_name = iv_object_name.
CATCH /sapsrm/cx_esh_cust_miss INTO lx_esh_cust_miss.
MESSAGE e007(/sapsrm/pdo_so_agent) INTO lv_msg_dummy.
ENDTRY.
* Obtain active search service (DB or TREX)
CALL METHOD /sapsrm/cl_src_service_factory=>determine_active_service
EXPORTING
iv_object_type = iv_object_type
iv_object_name = iv_object_name
iv_srh_serv_type = iv_srh_serv_type
it_template_ids = lt_template_ids
IMPORTING
ev_active_service = lv_active_service.
**********We do not need RFC search service for SC
* Delete inactive services
DELETE lt_c_src_svs
WHERE service <> lv_active_service AND
service <> /sapsrm/if_src_agent_c=>gc_search_service_type_rfc.
TRY.
LOOP AT lt_c_src_svs ASSIGNING <ls_cust_service>.
IF <ls_cust_service>-
service = /sapsrm/if_src_agent_c=>gc_search_service_type_rfc.
ELSE.
IF iv_scenario IS INITIAL
OR iv_scenario = /sapsrm/if_src_agent_c=>gc_scenario_combined
OR iv_scenario = /sapsrm/if_src_agent_c=>gc_scenario_local.
CREATE OBJECT lo_object
TYPE
(<ls_cust_service>-service_provider)
EXPORTING
iv_object_type = iv_object_type
iv_object_name = iv_object_name
iv_service = lv_active_service
iv_search_fields = <ls_cust_service>-search_fields
iv_result_fields = <ls_cust_service>-result_fields
it_template_ids = lt_template_ids
io_src_agent = io_src_agent
iv_rfc_dest = space
iv_log_sys = space.
ls_service-instance ?= lo_object.
INSERT ls_service INTO TABLE lt_services.
ENDIF.
ENDIF.
ENDLOOP.
IF sy-subrc <> 0.
lo_message_handler = create_serv_fact_mess_handler(
iv_object_type = iv_object_type
iv_object_name = iv_object_name ).
RAISE EXCEPTION TYPE /sapsrm/cx_src_srv_inst_failed
EXPORTING
mo_message_handler = lo_message_handler
mv_object_type = iv_object_type
mv_object_name = iv_object_name.
ENDIF.
CATCH cx_root INTO lx_root.
lo_message_handler = create_serv_fact_mess_handler(
iv_object_type = iv_object_type
iv_object_name = iv_object_name ).
RAISE EXCEPTION TYPE /sapsrm/cx_src_srv_inst_failed
EXPORTING
previous = lx_root
mo_message_handler = lo_message_handler
mv_object_type = iv_object_type
mv_object_name = iv_object_name.
ENDTRY.
* fill the results into the return table
rt_instances = lt_services.
ENDMETHOD.
Find the DB search service class (/SAPSRM/CL_SRC_SRV_DB_SC) and create a copy
(ZCL_SRC_SRV_DB_XXXX) of that for Example the Shopping cart DB search service class is
/SAPSRM/CL_SRC_SRV_DB_SC.
Find the PDO search service class (SAPSRM/CL_PDO_SO_SEARCH_SC_2) and create a copy of this
ZCL_PDO_SO_SEARCH_XXXX.
Change the method EXECUTE_SEARCH_INTERNAL_ITEM of the class ZCL_SRC_SRV_DB_XXXX to set the
PDO search class as the new custom PDO search class (ZCL_PDO_SO_SEARCH_XXXX).
Redefine the method: EXECUTE_SEARCH of class ZCL_PDO_SO_SEARCH_XXXX. The search criteria are
set in this method. Hence based on customer requirements has to be search needs to be implemented
in this method which would provide you the desired search results.
Search Service class ZCL_SRC_SRV_DB_XXXX
METHOD EXECUTE_SEARCH_INTERNAL_ITEM.
**********************************************************************
* In this method set the PDO search class as the search service.
**********************************************************************
DATA: * Set the custom PDO search class as the search service
lo_object_item_sc TYPE REF TO ZCL_PDO_SO_SEARCH_XXXX,
lo_message_handler TYPE REF TO /sapsrm/if_pdo_msg_consumer,
ls_guid_list TYPE bbp_guid,
lt_guid_list TYPE bbpt_guid_list,
lv_contains_errors TYPE abap_bool,
lr_search_res_item_t TYPE REF TO data.
FIELD-SYMBOLS: <ls_result> TYPE ANY,
<lt_result> TYPE ANY TABLE,
<ls_search_res> TYPE ANY,
<lt_search_res> TYPE ANY TABLE.
lv_contains_errors = abap_false.
ASSIGN mr_result_line->* TO <ls_result>.
ASSIGN mr_result_table->* TO <lt_result>.
CHECK <ls_result> IS ASSIGNED AND <lt_result> IS ASSIGNED.
* Create temporary table with the same structure as result table
CREATE DATA lr_search_res_item_t LIKE <lt_result>.
ASSIGN lr_search_res_item_t->* TO <lt_search_res>.
CHECK <lt_search_res> IS ASSIGNED.
** get the search service
* Set our implemented PDO class object for the search
CREATE OBJECT lo_object_item_sc.
lo_object_item ?= lo_object_item_sc.
* set search parameters
CALL METHOD lo_object_item->set_search_values
EXPORTING
is_search_criteria_sc = ms_search_criteria
is_search_cuf_h = ms_search_cuf_header
is_search_cuf_i = ms_search_cuf_item.
* do the search
CALL METHOD lo_object_item->execute_search
EXPORTING
iv_user = iv_user
IMPORTING
et_guid_list = lt_guid_list
CHANGING
co_message_handler = lo_message_handler.
* message handling
IF lo_message_handler IS BOUND.
me->map_handler_mess_to_mess_tab(
EXPORTING
io_message_handler = lo_message_handler
IMPORTING
ev_contains_errors = lv_contains_errors
CHANGING
ct_search_messages = et_messages ).
ENDIF.
* error handling
IF lv_contains_errors = abap_true.
RAISE EXCEPTION TYPE /sapsrm/cx_src_srv_srh_error
EXPORTING
mo_message_handler = lo_message_handler.
ENDIF.
* enrich the results with details
LOOP AT lt_guid_list INTO ls_guid_list.
CALL METHOD lo_object_item->get_result
EXPORTING
iv_line_guid = ls_guid_list
iv_langu = iv_language
IMPORTING
et_search_result = <lt_search_res>.
LOOP AT <lt_search_res> ASSIGNING <ls_search_res>.
MOVE-CORRESPONDING <ls_search_res> TO <ls_result>.
INSERT <ls_result> INTO TABLE <lt_result>.
ENDLOOP.
ENDLOOP.
er_search_result = mr_result_table.
ENDMETHOD.