How To Create a Test Defect Transaction Type II
Continuation of document: http://scn.sap.com/docs/DOC-73548
Configure UI
The new Test Defect transaction type is now working. But there are still some features missing which we will have to add or change.
We presuppose that you have already created an Enhancement Set for you client as described in SOLMAN_SETUP -> IT Service Management -> Step 6 “Configure UI”.
Related Test Case
First of all let’s go into “Configure Page” mode and create an own Configuration dedicated to our YMTD by copying the standard SMIN:
The result may look like this:
Now lets customize the “Display Assignment Block” entries on the right side. Most important is the component AIC_IM_SMT_TCST. Here our customizing proposal:
This assignment block is a really nice linkage between ticket and test case:
All marked red entries are links to other objects:
- “Run” executes the test object in the satellite system
- “Template ID” opens the project in SOLAR02
- “Status Text” opens the status maintenance dialog of the step of test package in the SAP Gui
- “Test Case Title” opens the test document
Hard Stuff
But there is still an interference of the operational incident in the “Relationships” group of the “General Data” assignment block. As told at the beginning or part 1, the natural document relation of a test defect, which is created during testing, is a change document, notably a Defect Correction (YMTM). So we need to enhance this assignment block.
New Configuration
Let’s start the UI Component Workbench (transaction BSP_WD_CMPWB), open component AIC_INCIDENT_H and then view AIC_INCIDENT_H/IncidentHeaderEF. First of all we copy the standard default configuration (it’s the very first entry) to a new one dedicated to the test defect:
Now we can remove the interfering fields:
We keep the Knowledge Article link, knowledge is always good 🙂
Adding Context Node
First step, we open the context node tree and add a new one (right mouse button)
We select all (I did it this way; may be it is enough for our purpose to select only one entry):
No Value Attributes and no Custom Controller;
Save, choosing the right package and transport requests.
Inheritance
The generated context node class YCL_1S_AIC_INCIDENTHEADER_CN00 (name can be different) is rather useless.
So we close the UI Component Workbench and open this class in transaction SE24 and change the inheritance to a more useful family replacing the generated superclass CL_BSP_WD_CONTEXT_NODE with the far more powerful CL_CRM_SRQM_BTDOCFLOW_CN.
The result is syntactical incorrect because of a collision between own methods or attributes and inherited ones (*_UTCTIME, ON_NEW_FOCUS, BASE_ENTITY_NAME). Simply delete all own methods or attributes which collide; we will redefine them if needed. Also the syntax check forces you to redefine the Method GET_TABLE_LINE_SAMPLE; but the redefinition can be empty.
Now you can activate successfully the context node class and if you reopen the context node in the transaction BSP_WD_CMPWB you will see that it has changed it’s character.
Creating Relation
This is one of the darkest corners because a decisive information is missing in the documentation.
Open the IMG activity “Extend Model for Business Transactions with New Relations” (GENIL_040; SM30 CRMV_ORLALL_BTIL); we decide that we will search and allow any type of change documents, so that also projects which don’t use the phase TEST but do the testing in phase Development With Release are able to link test defects with corresponding open change documents (yes, that’s life…).
Now we use an interface to document all the constant values we use, so we add this relation name to our interface:
From now on we will use the constant attribute ysv1i_if_itsm_constant=>c_docflow_rel_cds.
In the Class Builder (SE24) open class CL_CRM_DOCFLOW_RUN_BTIL and create a subclass (Edit -> Create Subclass)
Viciously it’s not documented that this class MUST end with _RUN_BTIL!
In the new class create the constructor (Edit -> Create Constructor), adopt the signature of the super and call it:
Redefine the method GET_MULTI_ID:
METHOD get_multi_id.
DATA: lv_first TYPE crmt_boolean VALUE true,
lv_obj TYPE crmt_ext_obj_name,
lv_reltype TYPE binreltyp,
lv_relation TYPE crmt_relation_name.
DATA: lv_customer_relation TYPE crmt_boolean,
lv_filter_value TYPE string,
lv_is_shown TYPE crmt_boolean,
lr_badi_docflow_filter TYPE REF TO crm_docflow_filter.
DATA: ls_docflow_key TYPE crmst_docflow_log_key.
DATA: lr_cont_obj TYPE REF TO if_genil_container_object.
FIELD-SYMBOLS: <ls_docflow> TYPE crmt_doc_flow_wrk,
<lt_docflow> TYPE crmt_doc_flow_wrkt.
***
CALL METHOD ir_cont_obj->get_key
IMPORTING
es_key = ls_docflow_key.
ASSIGN ir_api_data->* TO <lt_docflow>.
IF ls_docflow_key IS NOT INITIAL.
CALL METHOD me->get_single_id
EXPORTING
ir_cont_obj = ir_cont_obj
ir_api_data = ir_api_data
iv_ref_guid = iv_ref_guid
iv_ref_kind = iv_ref_kind.
ELSE.
CALL METHOD ir_cont_obj->get_parent_relation
IMPORTING
ev_relation_name = lv_relation.
* is it our relation? If no call super and exit
IF lv_relation <> ysv1i_if_itsm_constant=>c_docflow_rel_cds.
CALL METHOD super->get_multi_id
EXPORTING
ir_cont_obj = ir_cont_obj
ir_api_data = ir_api_data
iv_ref_guid = iv_ref_guid
iv_ref_kind = iv_ref_kind.
ELSE.
* our own relation, so process it
ls_docflow_key–ref_guid = iv_ref_guid.
LOOP AT <lt_docflow> ASSIGNING <ls_docflow>.
CHECK me->change_documents( iv_ref_guid = iv_ref_guid iv_ref_kind = iv_ref_kind is_doc_flow = <ls_docflow> ) = true.
CALL METHOD me->fill_container
EXPORTING
iv_first = lv_first
is_doc_flow = <ls_docflow>
ir_cont_obj = ir_cont_obj
iv_ref_kind = iv_ref_kind
iv_ref_guid = iv_ref_guid
iv_relation = lv_relation.
lv_first = false.
ENDLOOP.
ENDIF.
ENDIF.
ENDMETHOD.
And create method CHANGE_DOCUMENTS
METHOD change_documents.
* we just call inherited request_for_changes and revert the result
rv_result = me->request_for_changes(
is_doc_flow = is_doc_flow
iv_ref_guid = iv_ref_guid
iv_ref_kind = iv_ref_kind ).
IF rv_result = abap_true.
rv_result = abap_false.
ELSE.
rv_result = abap_true.
ENDIF.
ENDMETHOD.
If the method REQUEST_FOR_CHANGES is private, please implement note 2254826.
Finally announce this new class to the BTIL with IMG activity “Define Custom Handler Classes for Business Transaction Model” (GENIL_BT_002, SM30 CRMV_OBJ_BTIL_C):
I don’t know the deep reason for this peekaboo, but the suffix _RUN_BTIL will automatically be added.
Click Event
First we need an attribute with the name of the component as initial value:
Now we can add the click event handler for the event which we name TOTM:
The event will automatically have the suffix ON_EH added. The method is such:
METHOD eh_ontotm.
* Added by wizard: Handler for event ‘TOTM’
me->navigate_to_docflow( iv_docflow_name = me->gv_docflow_tm ).
ENDMETHOD.
The Plugs
We have now to create the machine which connects the new field with the search routine.
First we add an attribute for the popup:
Then we go back into the UI Component Workbench, open from our view the “Outbound Plugs” node and create a new one (context menu -> create):
As usual, the prefix OP_ will be automatically added. With a double-click on the OP_FINDCD method and insert this coding:
METHOD op_findcd.
* Added by wizard: Outbound plug ‘FINDCD’
DATA: lv_title TYPE string.
IF me->mr_cd_vh_popup IS NOT BOUND.
lv_title = cl_wd_utilities=>get_otr_text_by_alias( ‘CRM_UIU_SRV_REQ_MGMT_RFC/TASK_SRVO_SEARCH’ ). “#EC NOTEXT
me->mr_cd_vh_popup = comp_controller->window_manager->create_popup(
iv_interface_view_name = ‘AIC_CMCD_S/MainWindow’
iv_usage_name = ‘YCUAIDocumentS‘
iv_title = lv_title
). “#EC NOTEXT
ENDIF.
me->mr_cd_vh_popup->set_window_width( iv_width = ‘1024’ ). “#EC NOTEXT
me->mr_cd_vh_popup->set_on_close_event(
iv_view = me
iv_event_name = ‘SELCD‘
).
me->mr_cd_vh_popup->set_display_mode( if_bsp_wd_popup=>c_display_mode_surrounded ).
me->mr_cd_vh_popup->open( iv_inbound_plug = ‘POPUP’ ). “#EC NOTEXT
ENDMETHOD.
We change the visibility of the method OP_FINDCD to public:
The two red formatted literals indicates two things we still have to create: the component usage and the event.
Component Usage
In the UI Component Workbench switch to the “Runtime Repository Editor”, go into edit more and add a usage by using the context menu:
Insert the literal exactly as spelled in the OP_FINDCD method:
Don’t forget to save.
Event
Go back to the Component Structure Browser and add the event (context menu):
And add this coding (as usual, check the spelling of the literals!):
METHOD eh_onselcd.
* Added by wizard: Handler for event ‘SELCD’
DATA:
*new
lr_srqm_btdocflow_cnode TYPE REF TO ycl_1s_aic_incidentheader_cn00, “context node class
lr_collection TYPE REF TO if_bol_bo_col,
lr_entity TYPE REF TO cl_crm_bol_entity,
lr_entity_parent TYPE REF TO cl_crm_bol_entity,
lr_docflow TYPE REF TO cl_crm_bol_entity,
lt_object_id TYPE crmt_object_id_tab,
lv_object_id LIKE LINE OF lt_object_id,
lv_value TYPE string
.
lr_entity = me->get_leading_entity( ).
CHECK lr_entity IS BOUND.
lr_collection =
cl_crm_srqm_uiu_utils=>get_object_from_vhelp(
ir_valuehelp_popup = me->mr_cd_vh_popup
iv_outbound_plug = ‘SINGLESELECTION’
). “#EC NOTEXT
CHECK lr_collection IS BOUND AND lr_collection->size( ) NE 0.
lr_entity ?= lr_collection->get_current( ).
lr_srqm_btdocflow_cnode ?= me->get_context_node( ‘YYBTDOCFLOWTM’ ). “#EC NOTEXT
CHECK lr_srqm_btdocflow_cnode IS BOUND.
lr_srqm_btdocflow_cnode->set_docflow_object(
ir_entity = lr_entity
).
ENDMETHOD.
Initialization
Now we are ready to put all the things together by initializing our context with the right values.
We redefine our initialization method:
And insert this coding into the method:
METHOD if_bsp_model~init.
*CALL METHOD SUPER->IF_BSP_MODEL~INIT
* EXPORTING
* ID =
* OWNER =
* .
INCLUDE crm_object_types_con.
DATA:
ls_selection_param LIKE LINE OF me->mt_selection_param.
CLEAR me->mt_selection_param.
super->if_bsp_model~init( id = id
owner = owner ).
CLEAR ls_selection_param.
ls_selection_param–attr_name = if_crm_uiu_common_const=>gc_attr_object_type.
ls_selection_param–sign = ‘I’.
ls_selection_param–option = ‘EQ’.
ls_selection_param–low = gc_object_type–service.
APPEND ls_selection_param TO me->mt_selection_param.
me->mv_relation_name = ysv1i_if_itsm_constant=>c_docflow_rel_cds.
me->mv_valuehelp_op = ‘OP_FINDCD‘. “our outbound plug
me->mv_onclick_event = ‘TOTM‘. “our click event
me->mv_filter_inactive_entity = abap_true.
ENDMETHOD.
We redefine also the method ON_NEW_FOCUS and insert this coding:
METHOD on_new_focus.
CALL METHOD super->on_new_focus
EXPORTING
focus_bo = focus_bo.
me->collection_wrapper->get_first( ).
ENDMETHOD.
Fruits of the Effort
We are ready to insert the new fields into the UI. Open the Configuration tab of the UI Component Workbench, select the right configuration, go into Edit mode, press “Show Available Fields” and also “Show Technical Details”:
The mouse hover of the “Technical Name” can be helpful to identify the right fields: //YYBTDDOCFLOWTM/OBJECTID, //YYBTDDOCFLOWTM/DESCRIPTION and //YYBTDDOCFLOWTM/LOCKED_TO; simply drag & drop them one by one to the right side and adapt their field properties, a window which can be opened by “Show field properties” or by ALT+Click into the field.
Please note that you can add fields only when the Properties window is closed. You can move then the three fields to place them directly under group “Relationships”.
The result should be:
Save.
Enjoy your work
Good work!