https://me.sap.com/notes/0003379327
*&---------------------------------------------------------------------*
*& Report Z_ADD_TCODE_TO_ROLE_MENU
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
report z_add_tcode_to_role.
constants: lc_hex01 type x value '01'. "Area menu
data: role type agr_name.
select-options: selrole for role matchcode object agr_single memory id profile_generator.
parameters: tcode type tstc-tcode.
parameters: test type char01 as checkbox default 'X'.
class lcl_appgroups definition final.
public section.
methods:
start.
private section.
" Roles with app groups
types: begin of ty_s_agr_menu_groups
, agr_name type agr_name
, end of ty_s_agr_menu_groups.
types: ty_t_agr_menu_groups type standard table of ty_s_agr_menu_groups.
" TCodes
types: begin of ty_s_appl
, name type sobj_name
, type type usobtype
, end of ty_s_appl.
types: ty_t_appl type standard table of ty_s_appl.
data: mt_agr_menu_group type ty_t_agr_menu_groups.
methods:
select_roles,
process_role
importing iv_role type agr_name
iv_tcode type tstc-tcode
exporting et_return type bapirettab,
get_tcodes_of_cat
importing ir_node type ref to cl_pfcg_menu_modify=>ty_menu_node
it_nodes type cl_pfcg_menu_modify=>tt_menu_node
exporting et_tcodes type ty_t_appl,
find_create_folder
importing iv_role type agr_name
ir_role type ref to cl_pfcg_menu_modify
ir_node type ref to cl_pfcg_menu_modify=>ty_menu_node
iv_node_name type agr_buffi-url
exporting ev_folder_id type agr_hier-object_id
et_return type bapirettab,
add_tcodes
importing iv_role type agr_name
ir_role type ref to cl_pfcg_menu_modify
iv_folder_id type agr_hier-object_id
exporting et_return type bapirettab
changing ct_tcodes type ty_t_appl.
endclass.
data: gr_appgroups type ref to lcl_appgroups
.
initialization.
" In case the report is startet: Check 'PFCG'
if sy-tcode ne 'PFCG'.
call function 'AUTH_CHECK_TCODE'
exporting
tcode = 'PFCG'
exceptions
parameter_error = 1
transaction_not_found = 2
transaction_locked = 3
transaction_is_menu = 4
menu_via_parameter_transaction = 5
not_authorized = 6
others = 7.
if sy-subrc ne 0.
message id sy-msgid type 'I' number sy-msgno with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
leave program.
endif.
endif.
start-of-selection.
create object gr_appgroups.
gr_appgroups->start( ).
class lcl_appgroups implementation.
method start.
data: lr_agr_menu_group type ref to ty_s_agr_menu_groups,
lt_return type bapirettab,
lt_messages type cl_pfcg_menu_tools=>tt_pfcg_msg_log,
lv_tcode type tstc-tcode,
lv_cinfo type tstc-cinfo.
" Check Tcode
select single tcode cinfo from tstc into (lv_tcode, lv_cinfo)
where tcode = tcode.
if sy-subrc ne 0 or lv_cinfo o lc_hex01.
message i010(01) with tcode display like 'E'.
return.
endif.
" Select roles
call method me->select_roles( ).
if mt_agr_menu_group is initial.
message s244(s#).
return.
endif.
" Add TCodes
loop at mt_agr_menu_group reference into lr_agr_menu_group.
call method process_role
exporting
iv_role = lr_agr_menu_group->agr_name
iv_tcode = lv_tcode
importing
et_return = lt_return.
call method cl_pfcg_menu_tools=>message_log_add_msg_for_role
exporting
it_return = lt_return
iv_role = lr_agr_menu_group->agr_name
changing
ct_messages = lt_messages.
endloop.
call method cl_pfcg_menu_tools=>message_log_display
exporting
iv_popup = ' '
iv_fullscreen = 'X'
changing
ct_messages = lt_messages.
endmethod.
method select_roles.
clear: mt_agr_menu_group.
" Read menu entries with app groups
select a~agr_name as agr_name
from agr_define as a inner join agr_flags as f "#EC CI_BUFFJOIN
on a~agr_name = f~agr_name
into corresponding fields of table mt_agr_menu_group
where a~agr_name in selrole
and f~flag_type eq 'COLL_AGR'
and f~flag_value eq space.
sort mt_agr_menu_group.
delete adjacent duplicates from mt_agr_menu_group.
endmethod.
method process_role.
data: lt_return type bapirettab,
lr_role type ref to cl_pfcg_menu_modify,
lt_node type cl_pfcg_menu_modify=>tt_menu_node,
lr_node type ref to cl_pfcg_menu_modify=>ty_menu_node,
ls_node_detail type cl_pfcg_menu_tools=>ty_node_detail,
lv_urltype type urltype,
lv_folder_id type agr_hier-object_id,
lt_tcodes type ty_t_appl,
lv_rejected type abap_bool.
clear: et_return.
" --- Create instance
call method cl_pfcg_menu_modify=>retrieve_for_update
exporting
iv_role = iv_role
importing
er_role = lr_role
et_return = lt_return.
append lines of lt_return to et_return.
if lr_role is initial.
return.
endif.
call method lr_role->menu_add_transaction
exporting
"iv_target_id = iv_folder_id
iv_tcode = iv_tcode
iv_first_node_in_folder = ''
importing
et_return = lt_return.
append lines of lt_return to et_return.
append: value #( type = 'S' id = 'S#' number = '252' message_v1 = 'Add tcode ' message_v2 = iv_tcode message_v3 = '' message_v4 = '' ) to et_return.
* " --- Get Fiori catalogs
* " Read and check target node if tcode is correct
* call method lr_role->menu_get_nodes
* importing
* et_nodes = lt_node.
*
* loop at lt_node reference into lr_node where url_type eq 'CAT_PROVIDER'.
* lv_urltype = lr_node->url_type.
* call method cl_pfcg_menu_tools=>get_node_detail
* exporting
* iv_reporttype = lr_node->reporttype
* iv_tcode = ''
* iv_url_type = lv_urltype
* iv_url = lr_node->url
* iv_folder = space
* importing
* es_node_detail = ls_node_detail.
*
* " Get catalog tcodes
* call method get_tcodes_of_cat
* exporting
* ir_node = lr_node
* it_nodes = lt_node
* importing
* et_tcodes = lt_tcodes.
*
* " Create or find folder on same menu level
* call method find_create_folder
* exporting
* iv_role = iv_role
* ir_role = lr_role
* ir_node = lr_node
* iv_node_name = ls_node_detail-node_name
* importing
* ev_folder_id = lv_folder_id
* et_return = lt_return.
* append lines of lt_return to et_return.
*
* " Add tcodes
* call method add_tcodes
* exporting
* iv_role = iv_role
* ir_role = lr_role
* iv_folder_id = lv_folder_id
* importing
* et_return = lt_return
* changing
* ct_tcodes = lt_tcodes.
* append lines of lt_return to et_return.
* endloop.
read table et_return with key type = 'E' transporting no fields.
if sy-subrc eq 0.
call method lr_role->cancel.
return.
endif.
if test eq 'X'.
call method lr_role->cancel.
return.
endif.
call method cl_pfcg_menu_modify=>save
importing
ev_rejected = lv_rejected
et_return = lt_return.
append lines of lt_return to et_return.
if lv_rejected eq abap_true.
rollback work.
else.
commit work.
endif.
endmethod.
method get_tcodes_of_cat.
clear: et_tcodes.
data: lv_urltype type urltype,
lr_node type ref to cl_pfcg_menu_modify=>ty_menu_node,
ls_node_detail type cl_pfcg_menu_tools=>ty_node_detail,
ls_tcode type ty_s_appl.
loop at it_nodes reference into lr_node where parent_id eq ir_node->object_id.
lv_urltype = lr_node->url_type.
call method cl_pfcg_menu_tools=>get_node_detail
exporting
iv_reporttype = lr_node->reporttype
iv_tcode = lr_node->tcode
iv_url_type = lv_urltype
iv_url = lr_node->url
iv_folder = lr_node->folder
importing
es_node_detail = ls_node_detail.
if ls_node_detail-type eq 'TR'.
ls_tcode-type = ls_node_detail-type.
ls_tcode-name = ls_node_detail-name.
append ls_tcode to et_tcodes.
endif.
endloop.
endmethod.
method find_create_folder.
data: lr_node_folder type ref to cl_pfcg_menu_modify=>ty_menu_node,
lr_text_folder type ref to agr_shiert,
lv_search_text type agr_shiert-text,
lt_nodes type cl_pfcg_menu_modify=>tt_menu_node,
lt_menu_text type cl_pfcg_menu_modify=>ty_t_agr_shiert.
clear: ev_folder_id, et_return.
lv_search_text = iv_node_name.
" Read current menu
call method ir_role->menu_get_nodes
importing
et_nodes = lt_nodes
et_menu_text = lt_menu_text.
loop at lt_nodes reference into lr_node_folder
where parent_id eq ir_node->parent_id
and reporttype is initial
and folder eq 'X'.
read table lt_menu_text reference into lr_text_folder
with key object_id = lr_node_folder->object_id
spras = sy-langu
binary search.
if sy-subrc eq 0.
if lr_text_folder->text eq lv_search_text.
ev_folder_id = lr_text_folder->object_id.
return.
endif.
endif.
endloop.
call method ir_role->menu_add_folder
exporting
iv_target_id = ir_node->object_id
iv_first_node_in_folder = ''
iv_node_text = lv_search_text
importing
ev_new_object_id = ev_folder_id
et_return = et_return.
append: value #( type = 'S' id = 'S#' number = '252' message_v1 = 'Add folder ' message_v2 = lv_search_text message_v3 = '' message_v4 = '' ) to et_return.
endmethod.
method add_tcodes.
data: lt_return type bapirettab,
lr_node type ref to cl_pfcg_menu_modify=>ty_menu_node,
lt_nodes type cl_pfcg_menu_modify=>tt_menu_node,
lr_tcode type ref to ty_s_appl,
lv_tcode type tcode.
clear: et_return.
" Read current menu
call method ir_role->menu_get_nodes
importing
et_nodes = lt_nodes.
" Delete tcodes
loop at lt_nodes reference into lr_node
where parent_id eq iv_folder_id
and tcode is not initial
and folder eq space.
read table ct_tcodes
with key name = lr_node->tcode
transporting no fields.
if sy-subrc eq 0.
delete ct_tcodes index sy-tabix.
else.
call method ir_role->menu_delete_node
exporting
iv_object_id = lr_node->object_id
importing
et_return = lt_return.
append lines of lt_return to et_return.
append: value #( type = 'S' id = 'S#' number = '252' message_v1 = 'Delete tcode ' message_v2 = lr_node->tcode message_v3 = '' message_v4 = '' ) to et_return.
endif.
endloop.
" Add tcodes
loop at ct_tcodes reference into lr_tcode.
lv_tcode = lr_tcode->name.
call method ir_role->menu_add_transaction
exporting
iv_target_id = iv_folder_id
iv_tcode = lv_tcode
iv_first_node_in_folder = ''
importing
et_return = lt_return.
append lines of lt_return to et_return.
append: value #( type = 'S' id = 'S#' number = '252' message_v1 = 'Add tcode ' message_v2 = lv_tcode message_v3 = '' message_v4 = '' ) to et_return.
endloop.
endmethod.
endclass.