
◾ 모듈 : BC
◾ 기능 설명 : 사용자 권한 부여 증빙 관리 (ITGC 권한부여 이력 증명)
🔰 New Syntax 사용◾ 사용 예시 :
1. 사용자에게 사전에 ZBC_CTRL_ROLE 테이블 정의된 롤 부여 시, 해당 부여에 대한 증빙자료(URL) 를 팝업으로 요청
2. 부여한 권한 중 디버깅 수정 권한이 있을 경우, 해당 부여 이력의 증빙을 토대로 데이터 변경(SE16N_CD_KEY, SM20) 로그에 대한 자동 매핑
테이블 ZBC_CTRL_ROLE 을 통해, 증빙을 요청할 특정 롤을 설정할 수 있다.
- 해당 테이블에 등록한 롤 중,
디버깅 수정 롤에 대해서는 TAG 에DEBUG_EDIT을 붙여야 데이터 변경 이력에 대한 증빙이 자동으로 매핑된다.
(디버깅 수정 롤_TAG-DEBUG_EDIT 은 반드시 1개여야 한다.)
<수정 이력>
◾ (수정1) 2026.01.12 - SE16N_CD_KEY 데이터 셀렉트 조건 수정
◾ (수정2) 2026.03.12 - SE16N_CD_KEY 데이터 셀렉트 조건 수정2
◾ (수정2) 2026.03.12 - SM20 셀렉트 조건 수정
◾ (수정2) 2026.03.12 - 테이블 키 필드 추가 및 권한 회수 이력 로직 개선
◾ (수정2) 2026.03.12 - 권한 회수 일자, 수기 입력 기능 추가
***********************************************************************
* Report : ZBC_EVID_CONTROL *
* Module/Sub-Module : BC *
* Description : Role Assignment Evidence Control Program *
***********************************************************************
* MODIFICATION LOG *
* *
* DATE AUTHORS DESCRIPTION *
* ---------- ------------------ ------------------------------------- *
* 2024.10.09 YHJ Initial Release *
* 2024.10.24 YHJ Feature improvements *
* 2026.01.12 YHJ Edit SE16N_CD_KEY Select Join *
* *
***********************************************************************
REPORT ZBC_EVID_CONTROL.
*----------------------------------------------------------------------*
* TYPE-POOLS
*----------------------------------------------------------------------*
TYPE-POOLS: SLIS, ICON.
*----------------------------------------------------------------------*
* TABLES
*----------------------------------------------------------------------*
TABLES: SSCRFIELDS, ZBC_EVID_DATA.
*----------------------------------------------------------------------*
* DATA
*----------------------------------------------------------------------*
DATA: BEGIN OF GT_EVID OCCURS 0,
SEL(1) TYPE C.
INCLUDE STRUCTURE ZBC_EVID_DATA.
DATA: END OF GT_EVID.
DATA: BEGIN OF GT_CTRL_ROLE OCCURS 0,
SEL(1) TYPE C.
INCLUDE STRUCTURE ZBC_CTRL_ROLE.
DATA: END OF GT_CTRL_ROLE.
DATA: BEGIN OF GT_SE16N OCCURS 0,
SEL(1) TYPE C,
LINECOLOR(4) TYPE C,
EVID_URL TYPE AGR_URL,
TARGET_ROLE LIKE GT_EVID-TARGET_ROLE,
ACT_DATE LIKE GT_EVID-ACT_DATE,
ACT_TIME LIKE GT_EVID-ACT_TIME,
REVOKE_DATE LIKE GT_EVID-REVOKE_DATE,
REVOKE_TIME LIKE GT_EVID-REVOKE_TIME.
INCLUDE STRUCTURE SE16N_CD_KEY.
DATA: END OF GT_SE16N.
DATA: BEGIN OF GT_SM20 OCCURS 0,
SEL(1) TYPE C,
LINECOLOR(4) TYPE C,
EVID_URL TYPE AGR_URL,
TARGET_ROLE LIKE GT_EVID-TARGET_ROLE,
ACT_DATE LIKE GT_EVID-ACT_DATE,
ACT_TIME LIKE GT_EVID-ACT_TIME,
REVOKE_DATE LIKE GT_EVID-REVOKE_DATE,
REVOKE_TIME LIKE GT_EVID-REVOKE_TIME.
INCLUDE TYPE RSAU_S_RESULT.
DATA: END OF GT_SM20.
DATA: FUNCTXT TYPE SMP_DYNTXT.
DATA: GT_EVENT TYPE SLIS_T_EVENT WITH HEADER LINE.
DATA: GV_COUNT TYPE I,
GV_MENU LIKE SY-UCOMM.
*----------------------------------------------------------------------*
* SELECTION-SCREEN
*----------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE t101.
SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE t201.
SELECT-OPTIONS: S_DATE FOR SY-DATUM NO-EXTENSION.
SELECTION-SCREEN END OF BLOCK b2.
SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN BEGIN OF BLOCK b3 WITH FRAME TITLE t301.
SELECT-OPTIONS: S_USER FOR SY-UNAME,
S_AGRN FOR ZBC_EVID_DATA-TARGET_ROLE.
SELECTION-SCREEN SKIP 1.
PARAMETERS: P_ACTUSR LIKE SY-UNAME.
SELECTION-SCREEN SKIP 1.
PARAMETERS: P_AURL TYPE AGR_URL.
SELECTION-SCREEN END OF BLOCK b3.
SELECTION-SCREEN SKIP 1.
PARAMETERS: P_EDIT AS CHECKBOX DEFAULT ''.
SELECTION-SCREEN END OF BLOCK b1.
SELECTION-SCREEN: FUNCTION KEY 1, FUNCTION KEY 2, FUNCTION KEY 3, FUNCTION KEY 4.
AT SELECTION-SCREEN.
PERFORM MENU_SELECT.
AT SELECTION-SCREEN OUTPUT.
PERFORM MODIFY_SCREEN.
CLEAR: P_EDIT.
*----------------------------------------------------------------------*
* INITIALIZATION *
*----------------------------------------------------------------------*
INITIALIZATION.
PERFORM MENU_BAR.
MOVE 'ITGC - SAP Data Change / Debug Evidence Control' TO t101.
MOVE '' TO t201.
MOVE 'Other Option' TO t301.
*----------------------------------------------------------------------*
* START-OF-SELECTION.
*----------------------------------------------------------------------*
START-OF-SELECTION.
"### 백그라운드 수행
IF SY-BATCH = 'X'.
"### 프론트 수행
ELSE.
CLEAR: GV_MENU, GV_COUNT.
GV_MENU = SY-UCOMM.
PERFORM SELECT_DATA.
PERFORM VIEW_DATA.
ENDIF.
*----------------------------------------------------------------------*
* END-OF-SELECTION.
*----------------------------------------------------------------------*
END-OF-SELECTION.
*&---------------------------------------------------------------------*
*& ZBC_ITGC_EVID_CTRL_F01
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Form MODIFY_SCREEN
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM MODIFY_SCREEN .
%_S_DATE_%_APP_%-TEXT = 'Date'.
%_S_USER_%_APP_%-TEXT = 'Target User'.
%_S_AGRN_%_APP_%-TEXT = 'Target Role'.
%_P_ACTUSR_%_APP_%-TEXT = 'Changed User'.
%_P_AURL_%_APP_%-TEXT = 'Evid. URL String'.
%_P_EDIT_%_APP_%-TEXT = ' Evid. URL Edit'.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form MENU_BAR
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM MENU_BAR .
FUNCTXT-ICON_ID = ICON_ANNOTATION.
FUNCTXT-QUICKINFO = 'FILL_BLANK_URL'.
FUNCTXT-ICON_TEXT = 'Fill Blanked URL'.
SSCRFIELDS-FUNCTXT_01 = FUNCTXT.
FUNCTXT-ICON_ID = ICON_PROTOCOL.
FUNCTXT-QUICKINFO = 'EVID_SE16N_CD'.
FUNCTXT-ICON_TEXT = 'Evid. SE16N_CD'.
SSCRFIELDS-FUNCTXT_02 = FUNCTXT.
FUNCTXT-ICON_ID = ICON_PROTOCOL.
FUNCTXT-QUICKINFO = 'EVID_SM20'.
FUNCTXT-ICON_TEXT = 'Evid. SM20'.
SSCRFIELDS-FUNCTXT_03 = FUNCTXT.
FUNCTXT-ICON_ID = ICON_REPORT.
FUNCTXT-QUICKINFO = 'CONTROL_ROLE'.
FUNCTXT-ICON_TEXT = 'Control Role'.
SSCRFIELDS-FUNCTXT_04 = FUNCTXT.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form MENU_SELECT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM MENU_SELECT .
CLEAR: GV_MENU.
GV_MENU = SY-UCOMM.
CASE GV_MENU.
"### FILL URL 메뉴
"### URL 이 비어있는 항목에 증빙을 추가할 수 있도록, 수정 모드 제공
WHEN 'FC01'.
"### ZBC_EVID_DATA-EVID_URL 이 비어있는 데이터만 셀렉트
PERFORM SELECT_DATA_FC01.
"### 해당 데이터를 담은채로 VIEW 폼으로 보냄
PERFORM VIEW_DATA.
"### EVID_SE16N_CD 메뉴
WHEN 'FC02'.
"### 입력조건 S_DATE 체크
"### SAL_DATE LOW(시작일) 값이 비어있을 경우, 실행 차단
IF S_DATE-LOW IS INITIAL.
MESSAGE 'Please Enter the Start Date' TYPE 'E'.
ENDIF.
PERFORM SELECT_DATA_SE16N.
PERFORM VIEW_SE16N_CD.
"### EVID_SM20 메뉴
WHEN 'FC03'.
PERFORM SELECT_DATA_SM20.
PERFORM VIEW_SM20.
"### CONTROL ROLE 메뉴
"### ZBC_CONTROL_ROLE 테이블 - 제어 롤 목록 추가/삭제/수정
WHEN 'FC04'.
PERFORM VIEW_CONTROL_ROLE_TABLE.
ENDCASE.
ENDFORM.
*------------------------------------------------------------------*
* FORM SET_PF_STATUS
*------------------------------------------------------------------*
FORM SET_PF_STATUS USING PI_EXTAB TYPE SLIS_T_EXTAB.
DATA: BEGIN OF LT_EXCL OCCURS 0,
MENU(20) TYPE C.
DATA: END OF LT_EXCL.
CASE GV_MENU.
WHEN SPACE.
IF P_EDIT IS INITIAL.
LT_EXCL-MENU = '&DATA_SAVE'. APPEND LT_EXCL.
ELSE.
LT_EXCL-MENU = 'F_ADJ'. APPEND LT_EXCL.
ENDIF.
SET PF-STATUS 'S110' EXCLUDING LT_EXCL.
WHEN 'FC01'.
LT_EXCL-MENU = 'F_ADJ'. APPEND LT_EXCL.
LT_EXCL-MENU = 'M_EDIT'. APPEND LT_EXCL.
LT_EXCL-MENU = 'DELE'. APPEND LT_EXCL.
SET PF-STATUS 'S110' EXCLUDING LT_EXCL.
WHEN 'FC02'.
LT_EXCL-MENU = 'F_ADJ'. APPEND LT_EXCL.
LT_EXCL-MENU = 'M_EDIT'. APPEND LT_EXCL.
LT_EXCL-MENU = '&DATA_SAVE'. APPEND LT_EXCL.
LT_EXCL-MENU = 'DELE'. APPEND LT_EXCL.
SET PF-STATUS 'S110' EXCLUDING LT_EXCL.
WHEN 'FC03'.
LT_EXCL-MENU = 'F_ADJ'. APPEND LT_EXCL.
LT_EXCL-MENU = 'M_EDIT'. APPEND LT_EXCL.
LT_EXCL-MENU = '&DATA_SAVE'. APPEND LT_EXCL.
LT_EXCL-MENU = 'DELE'. APPEND LT_EXCL.
SET PF-STATUS 'S110' EXCLUDING LT_EXCL.
WHEN 'FC04'.
"### Control Role 메뉴에는 자체 저장 버튼이 있으므로, SAP Std SAVE 버튼은 Inactive 처리
IF P_EDIT IS INITIAL.
LT_EXCL-MENU = 'SAVE'. APPEND LT_EXCL.
ENDIF.
SET PF-STATUS 'S100' EXCLUDING LT_EXCL.
WHEN OTHERS.
ENDCASE.
ENDFORM.
*------------------------------------------------------------------*
* FORM USER_COMMAND_DISP
*------------------------------------------------------------------*
FORM USER_COMMAND_DISP USING PI_UCOMM LIKE SY-UCOMM
PI_SELFIELD TYPE SLIS_SELFIELD.
DATA: TT_EVID LIKE TABLE OF ZBC_EVID_DATA WITH HEADER LINE.
CASE PI_UCOMM.
"### EVID URL 증빙 저장
WHEN '&DATA_SAVE'.
CLEAR: TT_EVID, TT_EVID[].
"### GV_MENU = 'FC01' 일 경우, FILL_BLANK_URL 모드에서 저장
IF GV_MENU = 'FC01'.
LOOP AT GT_EVID WHERE EVID_URL IS NOT INITIAL.
MOVE-CORRESPONDING GT_EVID TO TT_EVID. APPEND TT_EVID.
MODIFY ZBC_EVID_DATA FROM TABLE TT_EVID.
"### FILL_BLANK_URL 모드일 시, EVID_URL 이 비어있는 항목만 출력되어야 하므로,
"### EVID_URL 이 입력된 항목은 GT_EVID 에서 DELETE 한다.
DELETE GT_EVID.
ENDLOOP.
MESSAGE 'Saved Data' TYPE 'S'.
ELSE.
LOOP AT GT_EVID.
MOVE-CORRESPONDING GT_EVID TO TT_EVID. APPEND TT_EVID.
MODIFY ZBC_EVID_DATA FROM TABLE TT_EVID.
ENDLOOP.
MESSAGE 'Saved Data' TYPE 'S'.
ENDIF.
"### ALV 더블 클릭 이벤트
WHEN '&IC1'.
DATA: HTTP_URL TYPE STRING.
"### EVID_URL 필드에 대해서, 더블클릭 시, 브라우저로 URL 오픈 (기본 크롬 설정)
"### 단 URL 수정 모드일때 및 Fill Blank URL 모드일때는 제외.
IF PI_SELFIELD-FIELDNAME = 'EVID_URL'
AND PI_SELFIELD-VALUE NE SPACE
AND P_EDIT IS INITIAL
AND GV_MENU NE 'FC01'.
HTTP_URL = PI_SELFIELD-VALUE.
CALL METHOD CL_GUI_FRONTEND_SERVICES=>EXECUTE
EXPORTING
APPLICATION = 'chrome.exe'
PARAMETER = HTTP_URL.
ENDIF.
"### 새로고침 버튼
WHEN '&NTE'.
CLEAR: GT_EVID, GT_EVID[].
CASE GV_MENU.
WHEN SPACE.
PERFORM SELECT_DATA.
WHEN 'FC01'.
PERFORM SELECT_DATA_FC01.
WHEN 'FC02'.
PERFORM SELECT_DATA_SE16N.
WHEN 'FC03'.
PERFORM SELECT_DATA_SM20.
ENDCASE.
WHEN 'F_ADJ'.
CLEAR: TT_EVID, TT_EVID[].
LOOP AT GT_EVID WHERE SEL = 'X'.
IF GT_EVID-MANUAL_EDIT IS INITIAL.
MESSAGE '권한 회수 일자 강제 조정은 수기 입력건에 대해서만 가능합니다.' TYPE 'S' DISPLAY LIKE 'E'.
ENDIF.
DATA(LV_TABKEY) = |{ SY-MANDT }%{ GT_EVID-TARGET_ROLE }%{ GT_EVID-TARGET_USER }%{ GT_EVID-VAILD_FROM }%{ GT_EVID-VAILD_TO }%|.
DATA: LT_T1 LIKE TABLE OF CDPOS WITH HEADER LINE,
LT_T2 LIKE TABLE OF CDHDR WITH HEADER LINE.
SELECT * INTO CORRESPONDING FIELDS OF TABLE @LT_T1
FROM CDPOS AS A
LEFT OUTER JOIN CDHDR AS B ON A~CHANGENR = B~CHANGENR
WHERE A~TABKEY LIKE @LV_TABKEY
AND B~USERNAME = @GT_EVID-CHG_USER
AND B~UDATE = @GT_EVID-ACT_DATE
AND B~UTIME = @GT_EVID-ACT_TIME
AND A~CHNGIND = 'I'.
READ TABLE LT_T1 INDEX 1.
SELECT * INTO CORRESPONDING FIELDS OF TABLE @LT_T2
FROM CDHDR AS A
LEFT OUTER JOIN CDPOS AS B ON A~CHANGENR = B~CHANGENR
WHERE B~TABKEY LIKE @LV_TABKEY
AND B~CHANGENR > @LT_T1-CHANGENR
AND B~CHNGIND = 'D'.
READ TABLE LT_T2 INDEX 1.
"### Change Document 셀렉트가 정상적이라면,
IF SY-SUBRC = 0.
"### 만약 셀렉트한 Change Document 가 1건 이상이면, LT_CDDATA UDATE, UTIME 을 오름차순으로 정리하여,
"### 가장 빠른 UDATE, UTIME (INDEX 1) 를 REVOKE DATE, TIME 으로 설정. (같은 유효기간의 롤을 중복으로 가질수 없기 때문)
GT_EVID-REVOKE_DATE = LT_T2-UDATE.
GT_EVID-REVOKE_TIME = LT_T2-UTIME.
GT_EVID-MANUAL_EDIT = ''.
MODIFY GT_EVID.
ENDIF.
MOVE-CORRESPONDING GT_EVID TO TT_EVID. APPEND TT_EVID.
ENDLOOP.
MODIFY ZBC_EVID_DATA FROM TABLE TT_EVID.
WHEN 'DELE'.
DATA: LV_CNT(4) TYPE I,
LV_TEXT TYPE STRING,
LV_ANS TYPE C.
"### ALV 에서 선택한 항목에 대해서만 삭제 작업
LV_CNT = REDUCE #( INIT i = 0 FOR LS IN GT_EVID
WHERE ( SEL = 'X' )
NEXT I += 1 ).
LV_TEXT = |Sure to Delete { LV_CNT } Entry?|.
"### 삭제 확인 팝업
CALL FUNCTION 'POPUP_TO_CONFIRM'
EXPORTING
TITLEBAR = 'DELETE ENTRY'
TEXT_QUESTION = LV_TEXT
TEXT_BUTTON_1 = 'YES'
TEXT_BUTTON_2 = 'NO'
DISPLAY_CANCEL_BUTTON = SPACE
IMPORTING
ANSWER = LV_ANS.
"### ITSM 삭제 YES
IF LV_ANS = '1'.
LOOP AT GT_EVID WHERE SEL = 'X'.
DELETE FROM ZBC_EVID_DATA WHERE ACT_DATE = GT_EVID-ACT_DATE
AND ACT_TIME = GT_EVID-ACT_TIME
AND TARGET_USER = GT_EVID-TARGET_USER
AND TARGET_ROLE = GT_EVID-TARGET_ROLE.
ENDLOOP.
DELETE GT_EVID WHERE SEL = 'X'.
ENDIF.
WHEN 'M_EDIT'.
DATA: LT_POPUP LIKE SVAL OCCURS 0 WITH HEADER LINE.
DATA: LV_RET TYPE C.
DATA(LV_SEL) = 0.
LOOP AT GT_EVID WHERE SEL = 'X'.
LV_SEL += 1.
ENDLOOP.
IF LV_SEL = 1.
CLEAR: TT_EVID, TT_EVID[].
READ TABLE GT_EVID WITH KEY SEL = 'X'.
DATA(LV_TABIX) = SY-TABIX.
LT_POPUP-TABNAME = 'ZBC_EVID_DATA'.
LT_POPUP-FIELDNAME = 'REVOKE_DATE'.
LT_POPUP-FIELDTEXT = 'Revoke Date'.
APPEND LT_POPUP. CLEAR LT_POPUP.
LT_POPUP-TABNAME = 'ZBC_EVID_DATA'.
LT_POPUP-FIELDNAME = 'REVOKE_TIME'.
LT_POPUP-FIELDTEXT = 'Revoke Time'.
APPEND LT_POPUP. CLEAR LT_POPUP.
"### 팝업 출력
CALL FUNCTION 'POPUP_GET_VALUES'
EXPORTING
POPUP_TITLE = 'Revoke Edit'
IMPORTING
RETURNCODE = LV_RET
TABLES
FIELDS = LT_POPUP
EXCEPTIONS
ERROR_IN_FIELDS = 1
OTHERS = 2.
IF LV_RET IS INITIAL.
READ TABLE LT_POPUP WITH KEY FIELDNAME = 'REVOKE_DATE'. GT_EVID-REVOKE_DATE = LT_POPUP-VALUE.
IF LT_POPUP-VALUE < GT_EVID-ACT_DATE.
MESSAGE '권한 회수 날짜는 부여 날짜보다 빠를 수 없습니다.' TYPE 'S' DISPLAY LIKE 'E'.
REJECT.
ENDIF.
READ TABLE LT_POPUP WITH KEY FIELDNAME = 'REVOKE_TIME'. GT_EVID-REVOKE_TIME = LT_POPUP-VALUE.
GT_EVID-MANUAL_EDIT = 'X'.
MODIFY GT_EVID INDEX LV_TABIX.
MOVE-CORRESPONDING GT_EVID TO TT_EVID. APPEND TT_EVID.
MODIFY ZBC_EVID_DATA FROM TABLE TT_EVID.
ENDIF.
ELSE.
MESSAGE '수기 수정은 1건 단위로만 가능합니다.' TYPE 'S'.
ENDIF.
ENDCASE.
"### ALV 리프레시 설정
PI_SELFIELD-REFRESH = 'X'.
PI_SELFIELD-COL_STABLE = 'X'.
PI_SELFIELD-ROW_STABLE = 'X'.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form SELECT_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM SELECT_DATA .
IF P_ACTUSR IS INITIAL. P_ACTUSR = '%'. ENDIF.
IF P_AURL IS INITIAL. P_AURL = '%'. ENDIF.
CLEAR: GT_EVID, GT_EVID[].
SELECT * INTO CORRESPONDING FIELDS OF TABLE GT_EVID
FROM ZBC_EVID_DATA
WHERE ACT_DATE IN S_DATE
AND TARGET_USER IN S_USER
AND TARGET_ROLE IN S_AGRN
AND CHG_USER LIKE P_ACTUSR
AND EVID_URL LIKE P_AURL.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form SELECT_DATA_FC01
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM SELECT_DATA_FC01 .
"### FC01 (FILL_BLANK_URL 메뉴) 데이터 셀렉트
CLEAR: GT_EVID, GT_EVID[].
SELECT * INTO CORRESPONDING FIELDS OF TABLE GT_EVID
FROM ZBC_EVID_DATA
WHERE EVID_URL = SPACE.
"### SELET DATA SORT
SORT GT_EVID BY ACT_DATE ACT_TIME TARGET_USER TARGET_ROLE.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form SELECT_DATA_SE16N
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM SELECT_DATA_SE16N .
CLEAR: GT_SE16N, GT_SE16N[].
"### ZBC_CTRL_ROLE 테이블의 증빙 제어 롤 중,
"### DEBUG_EDIT 태그가 있는 롤을 디버깅 롤로 인식하여 증빙 검색
"### DEBUG_EDIT 태그는 모든 롤 중에, 단 한개에만 존재 가능.
SELECT SINGLE VALUE INTO @DATA(TV_DEBUG_ROLE)
FROM ZBC_CTRL_ROLE
WHERE ITEM = 'ROLE'
AND TAG = 'DEBUG_EDIT'.
"### JOIN 조건 개선
SELECT a~*,
b~EVID_URL,
b~TARGET_ROLE,
b~ACT_DATE,
b~ACT_TIME,
b~REVOKE_DATE,
b~REVOKE_TIME
FROM SE16N_CD_KEY AS A
LEFT OUTER JOIN ZBC_EVID_DATA AS B ON A~UNAME = B~TARGET_USER
AND ( ( ( A~SDATE = B~ACT_DATE AND A~SDATE = B~REVOKE_DATE ) AND A~STIME BETWEEN B~ACT_TIME AND B~REVOKE_TIME )
OR ( ( A~SDATE > B~ACT_DATE AND A~SDATE = B~REVOKE_DATE ) AND A~STIME <= B~REVOKE_TIME )
OR ( ( A~SDATE > B~ACT_DATE AND A~SDATE < B~REVOKE_DATE ) )
OR ( ( A~SDATE = B~ACT_DATE AND A~SDATE < B~REVOKE_DATE ) AND A~STIME >= B~ACT_TIME ) )
AND B~TARGET_ROLE = @TV_DEBUG_ROLE
WHERE A~SDATE IN @S_DATE
INTO CORRESPONDING FIELDS OF TABLE @GT_SE16N.
"### EVID_URL 이 없는 필드는 노란색 하이라이트 표시
LOOP AT GT_SE16N WHERE EVID_URL IS INITIAL.
GT_SE16N-LINECOLOR = 'C300'.
MODIFY GT_SE16N.
ENDLOOP.
SORT GT_SE16N BY SDATE STIME TAB UNAME.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form SELECT_DATA_SM20
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM SELECT_DATA_SM20 .
DATA: S_ITAB TYPE TABLE OF RSPARAMS WITH HEADER LINE.
DATA: TT_SM20 TYPE RSAU_T_RESULT WITH HEADER LINE,
LR_DATA TYPE REF TO DATA.
DATA: LT_EVID LIKE TABLE OF ZBC_EVID_DATA WITH HEADER LINE.
FIELD-SYMBOLS : <FS_TABLE> TYPE ANY TABLE,
<FS_LINE> TYPE ANY.
CL_SALV_BS_RUNTIME_INFO=>SET( EXPORTING DISPLAY = ABAP_FALSE
METADATA = ABAP_FALSE
DATA = ABAP_TRUE ).
S_ITAB-SELNAME = 'EVENTS'.
S_ITAB-SIGN = 'I'.
S_ITAB-OPTION = 'EQ'.
S_ITAB-LOW = 'CUL'.
APPEND S_ITAB. CLEAR: S_ITAB.
S_ITAB-SELNAME = 'TCODE'.
S_ITAB-SIGN = 'I'.
S_ITAB-OPTION = 'NE'.
S_ITAB-LOW = 'SE16N'.
APPEND S_ITAB. CLEAR: S_ITAB.
"### SAL_DATE HIGH(종료일) 이 없을 경우 시작일과 같도록 강제 설정
IF S_DATE-HIGH IS INITIAL.
S_DATE-HIGH = S_DATE-LOW.
ENDIF.
"### SAL_DATE LOW(시작일) 값이 비어있을 경우, 실행 차단
IF S_DATE-LOW IS INITIAL.
MESSAGE 'Please Enter the Start Date' TYPE 'E'.
ENDIF.
"### ABAP MEMORY 를 사용하여 데이터 가져오기
SUBMIT RSAU_READ_LOG WITH STRTDATE = S_DATE-LOW
WITH ENDDATE = S_DATE-HIGH
WITH P_SELE = 1
WITH SELECTION-TABLE S_ITAB
AND RETURN.
TRY.
CL_SALV_BS_RUNTIME_INFO=>GET_DATA_REF( IMPORTING R_DATA = LR_DATA ).
ASSIGN LR_DATA->* TO <FS_TABLE>.
CATCH CX_SALV_BS_SC_RUNTIME_INFO.
MESSAGE 'Unable to retrieve ALV data' TYPE 'E'.
ENDTRY.
CL_SALV_BS_RUNTIME_INFO=>CLEAR_ALL( ).
"### Field Symbols 데이터를 LT_SM20 인터널 테이블로 옮겨 담기
LOOP AT <FS_TABLE> ASSIGNING <FS_LINE>.
MOVE-CORRESPONDING <FS_LINE> TO TT_SM20.
APPEND TT_SM20. CLEAR TT_SM20.
ENDLOOP.
"### ZBC_CTRL_ROLE 테이블의 증빙 제어 롤 중,
"### DEBUG_EDIT 태그가 있는 롤을 디버깅 롤로 인식하여 증빙 검색
"### DEBUG_EDIT 태그는 모든 롤 중에, 단 한개에만 존재 가능.
SELECT SINGLE VALUE INTO @DATA(TV_DEBUG_ROLE)
FROM ZBC_CTRL_ROLE
WHERE ITEM = 'ROLE'
AND TAG = 'DEBUG_EDIT'.
"### LT_SM20 테이블 매핑을 위해 ZBC_EVID_DATA 테이블 로드
SELECT * INTO CORRESPONDING FIELDS OF TABLE @LT_EVID
FROM ZBC_EVID_DATA
WHERE ACT_DATE IN @S_DATE
AND TARGET_ROLE = @TV_DEBUG_ROLE.
"### 데이터 옮겨담기 전, GT_SM20 테이블 클리어
CLEAR: GT_SM20, GT_SM20[].
"### TT_SM20 데이터를 GT_SM20(ALV 테이블)로 옮겨 담기
LOOP AT TT_SM20.
MOVE-CORRESPONDING TT_SM20 TO GT_SM20.
"### ZBC_EVID_DATA 테이블 데이터를 LT_EVID 테이블에 매핑
LOOP AT LT_EVID WHERE TARGET_USER = TT_SM20-SLGUSER AND ( ACT_TIME < TT_SM20-SAL_TIME AND REVOKE_TIME > TT_SM20-SAL_TIME ).
GT_SM20-EVID_URL = LT_EVID-EVID_URL.
GT_SM20-TARGET_ROLE = LT_EVID-TARGET_ROLE.
GT_SM20-ACT_DATE = LT_EVID-ACT_DATE.
GT_SM20-ACT_TIME = LT_EVID-ACT_TIME.
GT_SM20-REVOKE_DATE = LT_EVID-REVOKE_DATE.
GT_SM20-REVOKE_TIME = LT_EVID-REVOKE_TIME.
ENDLOOP.
"### EVID_URL 이 없는 필드는 노란색 하이라이트 표시
IF GT_SM20-EVID_URL IS INITIAL.
GT_SM20-LINECOLOR = 'C300'.
ENDIF.
APPEND GT_SM20. CLEAR GT_SM20.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form VIEW_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM VIEW_DATA .
DATA: L_POS TYPE I VALUE 0.
DATA: LT_FIELDCAT TYPE SLIS_T_FIELDCAT_ALV WITH HEADER LINE,
LT_LAYOUT TYPE SLIS_LAYOUT_ALV.
"### Build Field Catalog
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'ACT_DATE'.
LT_FIELDCAT-SELTEXT_M = 'Grant Date'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 8.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'ACT_TIME'.
LT_FIELDCAT-SELTEXT_M = 'Grant Time'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 8.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'TARGET_USER'.
LT_FIELDCAT-SELTEXT_M = 'Target User'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 12.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'TARGET_ROLE'.
LT_FIELDCAT-SELTEXT_M = 'Target Role'.
LT_FIELDCAT-OUTPUTLEN = 20.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'CHG_USER'.
LT_FIELDCAT-SELTEXT_M = 'Changed User'.
LT_FIELDCAT-OUTPUTLEN = 12.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'EVID_URL'.
LT_FIELDCAT-SELTEXT_M = 'Evid. URL'.
LT_FIELDCAT-OUTPUTLEN = 80.
LT_FIELDCAT-HOTSPOT = 'X'.
LT_FIELDCAT-LOWERCASE = 'X'.
LT_FIELDCAT-EMPHASIZE = 'C500'.
"### 미등록 URL 입력 모드라면, URL 필드가 수정가능하게 EDIT 오픈
IF SY-UCOMM = 'FC01' OR P_EDIT = 'X'.
LT_FIELDCAT-EDIT = 'X'.
LT_FIELDCAT-EMPHASIZE = ''.
LT_FIELDCAT-HOTSPOT = ''.
ENDIF.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'REVOKE_DATE'.
LT_FIELDCAT-SELTEXT_M = 'Revoke Date'.
LT_FIELDCAT-OUTPUTLEN = 8.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'REVOKE_TIME'.
LT_FIELDCAT-SELTEXT_M = 'Revoke Time'.
LT_FIELDCAT-OUTPUTLEN = 8.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'MANUAL_EDIT'.
LT_FIELDCAT-SELTEXT_M = 'Flag'.
LT_FIELDCAT-OUTPUTLEN = 4.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'VAILD_FROM'.
LT_FIELDCAT-SELTEXT_M = 'From'.
LT_FIELDCAT-OUTPUTLEN = 10.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'VAILD_TO'.
LT_FIELDCAT-SELTEXT_M = 'To'.
LT_FIELDCAT-OUTPUTLEN = 10.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
"### ALV Layout 설정
LT_LAYOUT-BOX_FIELDNAME = 'SEL'.
* LT_LAYOUT-INFO_FIELDNAME = 'LINECOLOR'.
IF SY-UCOMM IS INITIAL AND P_EDIT IS INITIAL. LT_LAYOUT-COLWIDTH_OPTIMIZE = 'X'. ENDIF.
* LT_LAYOUT-ZEBRA = 'X'.
LT_LAYOUT-BOX_TABNAME = 'GT_EVID'.
"### 위에 설정된 Field Catalog 와 Layout 을 사용하여 ALV 리스트 출력 펑션 콜
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_CALLBACK_PROGRAM = SY-REPID
I_CALLBACK_USER_COMMAND = 'USER_COMMAND_DISP'
I_CALLBACK_PF_STATUS_SET = 'SET_PF_STATUS'
"I_GRID_TITLE = GV_ALV_HEADER
"I_CALLBACK_TOP_OF_PAGE = 'TOP-OF-PAGE'
IT_EVENTS = GT_EVENT[]
IT_FIELDCAT = LT_FIELDCAT[]
IS_LAYOUT = LT_LAYOUT
"I_SAVE = 'A'
TABLES
T_OUTTAB = GT_EVID
EXCEPTIONS
PROGRAM_ERROR = 1
OTHERS = 2.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form VIEW_CONTROL_ROLE_TABLE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM VIEW_CONTROL_ROLE_TABLE .
DATA: L_POS TYPE I VALUE 0.
DATA: LT_FIELDCAT TYPE SLIS_T_FIELDCAT_ALV WITH HEADER LINE,
LT_LAYOUT TYPE SLIS_LAYOUT_ALV.
CLEAR: GT_CTRL_ROLE, GT_CTRL_ROLE[].
SELECT * INTO CORRESPONDING FIELDS OF TABLE GT_CTRL_ROLE
FROM ZBC_CTRL_ROLE.
SORT GT_CTRL_ROLE BY ITEM VALUE.
"### Build Field Catalog
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'ITEM'.
LT_FIELDCAT-SELTEXT_M = 'ITEM'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 10.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'VALUE'.
LT_FIELDCAT-SELTEXT_M = 'VALUE'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 20.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'TAG'.
LT_FIELDCAT-SELTEXT_M = 'Tag'.
LT_FIELDCAT-OUTPUTLEN = 15.
IF SY-UCOMM = 'FC04' AND P_EDIT = 'X'.
LT_FIELDCAT-EDIT = 'X'.
ENDIF.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'TEXT'.
LT_FIELDCAT-SELTEXT_M = 'Short Desc'.
LT_FIELDCAT-OUTPUTLEN = 50.
IF SY-UCOMM = 'FC04' AND P_EDIT = 'X'.
LT_FIELDCAT-EDIT = 'X'.
ENDIF.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
"### ALV Layout 설정
LT_LAYOUT-BOX_FIELDNAME = 'SEL'.
* LT_LAYOUT-INFO_FIELDNAME = 'LINECOLOR'.
* LT_LAYOUT-COLWIDTH_OPTIMIZE = 'X'.
* LT_LAYOUT-ZEBRA = 'X'.
LT_LAYOUT-BOX_TABNAME = 'GT_CTRL_ROLE'.
"### 위에 설정된 Field Catalog 와 Layout 을 사용하여 ALV 리스트 출력 펑션 콜
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_CALLBACK_PROGRAM = SY-REPID
I_CALLBACK_USER_COMMAND = 'USER_COMMAND_CTRL_ROLE'
I_CALLBACK_PF_STATUS_SET = 'SET_PF_STATUS'
"I_GRID_TITLE = GV_ALV_HEADER
"I_CALLBACK_TOP_OF_PAGE = 'TOP-OF-PAGE'
"IT_EXCLUDING = LT_EXCL[]
"IT_EVENTS = LT_EVENT[]
IT_FIELDCAT = LT_FIELDCAT[]
IS_LAYOUT = LT_LAYOUT
"I_SAVE = 'A'
TABLES
T_OUTTAB = GT_CTRL_ROLE
EXCEPTIONS
PROGRAM_ERROR = 1
OTHERS = 2.
ENDFORM.
*------------------------------------------------------------------*
* FORM USER_COMMAND_CTRL_ROLE
*------------------------------------------------------------------*
FORM USER_COMMAND_CTRL_ROLE USING PI_UCOMM LIKE SY-UCOMM
PI_SELFIELD TYPE SLIS_SELFIELD.
CASE PI_UCOMM.
"### ITEM 신규 추가
WHEN 'ADD_ITEM'.
"### 팝업을 통해 신규 ITEM 정보를 받아온다.
DATA: LT_POPUP LIKE SVAL OCCURS 0 WITH HEADER LINE.
DATA: LT_ADD LIKE TABLE OF ZBC_CTRL_ROLE WITH HEADER LINE.
DATA: LT_LOC LIKE TABLE OF ZBC_CTRL_ROLE WITH HEADER LINE.
DATA: LV_RET TYPE C.
LT_POPUP-TABNAME = 'ZBC_CTRL_ROLE'.
LT_POPUP-FIELDNAME = 'ITEM'.
LT_POPUP-FIELDTEXT = 'ITEM'.
LT_POPUP-FIELD_OBL = 'X'.
LT_POPUP-VALUE = 'ROLE'.
APPEND LT_POPUP. CLEAR LT_POPUP.
LT_POPUP-TABNAME = 'ZBC_CTRL_ROLE'.
LT_POPUP-FIELDNAME = 'VALUE'.
LT_POPUP-FIELDTEXT = 'VALUE'.
LT_POPUP-FIELD_OBL = 'X'.
APPEND LT_POPUP. CLEAR LT_POPUP.
LT_POPUP-TABNAME = 'ZBC_CTRL_ROLE'.
LT_POPUP-FIELDNAME = 'TAG'.
LT_POPUP-FIELDTEXT = 'Tag'.
APPEND LT_POPUP. CLEAR LT_POPUP.
LT_POPUP-TABNAME = 'ZBC_CTRL_ROLE'.
LT_POPUP-FIELDNAME = 'TEXT'.
LT_POPUP-FIELDTEXT = 'Short Desc'.
APPEND LT_POPUP. CLEAR LT_POPUP.
"### 팝업 출력
CALL FUNCTION 'POPUP_GET_VALUES'
EXPORTING
POPUP_TITLE = 'Add ITEM'
IMPORTING
RETURNCODE = LV_RET
TABLES
FIELDS = LT_POPUP
EXCEPTIONS
ERROR_IN_FIELDS = 1
OTHERS = 2.
"### 데이터를 정상적으로 입력하고, POPUP Confirm 을 눌렀다면, 저장
IF LV_RET IS INITIAL.
LT_ADD-MANDT = SY-MANDT.
READ TABLE LT_POPUP WITH KEY FIELDNAME = 'ITEM'. LT_ADD-ITEM = LT_POPUP-VALUE.
READ TABLE LT_POPUP WITH KEY FIELDNAME = 'VALUE'. LT_ADD-VALUE = LT_POPUP-VALUE.
READ TABLE LT_POPUP WITH KEY FIELDNAME = 'TAG'. LT_ADD-TAG = LT_POPUP-VALUE.
READ TABLE LT_POPUP WITH KEY FIELDNAME = 'TEXT'. LT_ADD-TEXT = LT_POPUP-VALUE.
APPEND LT_ADD.
"### 태그 중, DEBUG_EDIT 태그는 유일한 태그이다.
"### 따라서, 이미 DEBUG_EDIT 태그가 붙은 롤이 있다면, 더 이상 DEBUG_EDIT 태그를 붙일 수 없다.
IF LT_ADD-TAG = 'DEBUG_EDIT'.
READ TABLE GT_CTRL_ROLE WITH KEY TAG = 'DEBUG_EDIT'.
IF SY-SUBRC = 0.
MESSAGE |DEBUG_EDIT Role already Exists| TYPE 'E'.
EXIT.
ENDIF.
ENDIF.
"### 입력한 아이템이 ROLE 이라면, 실제 해당 ROLE 이 있는지 유효성 체크
IF LT_ADD-ITEM = 'ROLE'.
SELECT SINGLE AGR_NAME INTO @DATA(TV_AGR)
FROM AGR_DEFINE
WHERE AGR_NAME = @LT_ADD-VALUE.
"### 해당 ROLE 이 없다면 EXIT.
IF SY-SUBRC <> 0.
MESSAGE |{ LT_ADD-VALUE } Role does not exist.| TYPE 'E'.
EXIT.
ENDIF.
ENDIF.
"### 최종적으로 기존 아이템과 중복값 체크
READ TABLE GT_CTRL_ROLE WITH KEY MANDT = LT_ADD-MANDT
ITEM = LT_ADD-ITEM
VALUE = LT_ADD-VALUE.
"### 셀렉트 데이터가 없다면, 신규값이므로 테이블에 MODI, 인터널테이블에 APPEND
IF SY-SUBRC <> 0.
MODIFY ZBC_CTRL_ROLE FROM TABLE LT_ADD.
MOVE-CORRESPONDING LT_ADD TO GT_CTRL_ROLE. APPEND GT_CTRL_ROLE.
SORT GT_CTRL_ROLE.
MESSAGE 'Saved ITEM' TYPE 'S'.
ELSE.
MESSAGE 'This ITEM already Exists.' TYPE 'E'.
ENDIF.
ENDIF.
"### ITEM 삭제
WHEN 'DEL_ITEM'.
DATA: LV_CNT(3) TYPE I,
LV_TEXT TYPE STRING,
LV_ANS TYPE C.
"### ALV 에서 선택한 항목에 대해서만 삭제 작업
LV_CNT = REDUCE #( INIT i = 0 FOR LS IN GT_CTRL_ROLE
WHERE ( SEL = 'X' )
NEXT I += 1 ).
LV_TEXT = |Sure to Delete { LV_CNT } item?|.
"### 삭제 확인 팝업
CALL FUNCTION 'POPUP_TO_CONFIRM'
EXPORTING
TITLEBAR = 'DELETE ITEM'
TEXT_QUESTION = LV_TEXT
TEXT_BUTTON_1 = 'YES'
TEXT_BUTTON_2 = 'NO'
DISPLAY_CANCEL_BUTTON = SPACE
IMPORTING
ANSWER = LV_ANS.
"### ITSM 삭제 YES
IF LV_ANS = '1'.
LOOP AT GT_CTRL_ROLE WHERE SEL = 'X'.
DELETE FROM ZBC_CTRL_ROLE WHERE ITEM = GT_CTRL_ROLE-ITEM
AND VALUE = GT_CTRL_ROLE-VALUE.
ENDLOOP.
DELETE GT_CTRL_ROLE WHERE SEL = 'X'.
ENDIF.
WHEN 'SAVE'.
DATA: TT_CTRL_ROLE LIKE TABLE OF ZBC_CTRL_ROLE WITH HEADER LINE.
DATA: P_REF TYPE REF TO CL_GUI_ALV_GRID.
DATA: P_EDITED(1) TYPE C.
CLEAR: TT_CTRL_ROLE, TT_CTRL_ROLE[].
"### ALV 에 프론트로 입력된 값을 인터널 테이블로 로드
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
E_GRID = P_REF.
"### ALV 에서 프론트로 입력된 값이 정상적으로 변경되었는지 확인 후, 인터널 테이블로 로드
CALL METHOD P_REF->CHECK_CHANGED_DATA
IMPORTING
E_VALID = P_EDITED.
"### 변경된 사항이 있다면, 데이터 저장 프로세스
IF P_EDITED = 'X'.
LOOP AT GT_CTRL_ROLE.
MOVE-CORRESPONDING GT_CTRL_ROLE TO TT_CTRL_ROLE. APPEND TT_CTRL_ROLE.
MODIFY ZBC_CTRL_ROLE FROM TABLE TT_CTRL_ROLE.
ENDLOOP.
MESSAGE 'Saved Data' TYPE 'S'.
ENDIF.
ENDCASE.
"### ALV 리프레시 설정
PI_SELFIELD-REFRESH = 'X'.
PI_SELFIELD-COL_STABLE = 'X'.
PI_SELFIELD-ROW_STABLE = 'X'.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form VIEW_SE16N_CD
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM VIEW_SE16N_CD .
DATA: L_POS TYPE I VALUE 0.
DATA: LT_FIELDCAT TYPE SLIS_T_FIELDCAT_ALV WITH HEADER LINE,
LT_LAYOUT TYPE SLIS_LAYOUT_ALV.
"### ALV Header 출력 용, 엔트리 카운트
CLEAR: GV_COUNT.
GV_COUNT = LINES( GT_SE16N ).
IF LT_SE16N[] IS NOT INITIAL.
"### Build Field Catalog
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'MANDT'.
LT_FIELDCAT-SELTEXT_M = 'MANDT'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 4.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'ID'.
LT_FIELDCAT-SELTEXT_M = 'ID'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 20.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'TAB'.
LT_FIELDCAT-SELTEXT_M = 'TAB'.
LT_FIELDCAT-OUTPUTLEN = 15.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'UNAME'.
LT_FIELDCAT-SELTEXT_M = 'UNAME'.
LT_FIELDCAT-OUTPUTLEN = 10.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'SDATE'.
LT_FIELDCAT-SELTEXT_M = 'SDATE'.
LT_FIELDCAT-OUTPUTLEN = 8.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'STIME'.
LT_FIELDCAT-SELTEXT_M = 'STIME'.
LT_FIELDCAT-OUTPUTLEN = 8.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'CLNTDEP'.
LT_FIELDCAT-SELTEXT_M = 'CLNTDEP'.
LT_FIELDCAT-OUTPUTLEN = 3.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'INDX_GUID'.
LT_FIELDCAT-SELTEXT_M = 'INDX_GUID'.
LT_FIELDCAT-OUTPUTLEN = 3.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'EVID_URL'.
LT_FIELDCAT-SELTEXT_M = 'EVID URL'.
LT_FIELDCAT-HOTSPOT = 'X'.
LT_FIELDCAT-OUTPUTLEN = 50.
LT_FIELDCAT-EMPHASIZE = 'C500'.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'TARGET_ROLE'.
LT_FIELDCAT-SELTEXT_M = 'Role'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 25.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'ACT_DATE'.
LT_FIELDCAT-SELTEXT_M = 'Grant Date'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 8.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'ACT_TIME'.
LT_FIELDCAT-SELTEXT_M = 'Grant Time'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 8.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'REVOKE_DATE'.
LT_FIELDCAT-SELTEXT_M = 'Revoke Date'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 8.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'REVOKE_TIME'.
LT_FIELDCAT-SELTEXT_M = 'Revoke Time'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 8.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
"### ALV Layout 설정
LT_LAYOUT-BOX_FIELDNAME = 'SEL'.
LT_LAYOUT-INFO_FIELDNAME = 'LINECOLOR'.
LT_LAYOUT-COLWIDTH_OPTIMIZE = 'X'.
* LT_LAYOUT-ZEBRA = 'X'.
LT_LAYOUT-BOX_TABNAME = 'GT_SE16N'.
"### 위에 설정된 Field Catalog 와 Layout 을 사용하여 ALV 리스트 출력 펑션 콜
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_CALLBACK_PROGRAM = SY-REPID
I_CALLBACK_USER_COMMAND = 'USER_COMMAND_DISP'
I_CALLBACK_PF_STATUS_SET = 'SET_PF_STATUS'
"I_GRID_TITLE = GV_ALV_HEADER
I_CALLBACK_TOP_OF_PAGE = 'TOP-OF-PAGE'
I_HTML_HEIGHT_TOP = 6
"IT_EXCLUDING = LT_EXCL[]
"IT_EVENTS = LT_EVENT[]
IT_FIELDCAT = LT_FIELDCAT[]
IS_LAYOUT = LT_LAYOUT
"I_SAVE = 'A'
TABLES
T_OUTTAB = GT_SE16N
EXCEPTIONS
PROGRAM_ERROR = 1
OTHERS = 2.
ELSE.
MESSAGE 'No Data' TYPE 'S'.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form VIEW_SM20
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM VIEW_SM20 .
DATA: L_POS TYPE I VALUE 0.
DATA: LT_FIELDCAT TYPE SLIS_T_FIELDCAT_ALV WITH HEADER LINE,
LT_LAYOUT TYPE SLIS_LAYOUT_ALV.
"### ALV Header 출력 용, 엔트리 카운트
CLEAR: GV_COUNT.
GV_COUNT = LINES( GT_SM20 ).
IF LT_DATA[] IS NOT INITIAL.
"### Build Field Catalog
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'SID'.
LT_FIELDCAT-SELTEXT_M = 'System'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 4.
LT_FIELDCAT-JUST = 'C'.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'INSTANCE'.
LT_FIELDCAT-SELTEXT_M = 'SERVER'.
LT_FIELDCAT-OUTPUTLEN = 20.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'SAL_DATE'.
LT_FIELDCAT-SELTEXT_M = 'DATE'.
LT_FIELDCAT-OUTPUTLEN = 10.
LT_FIELDCAT-JUST = 'C'.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'SAL_TIME'.
LT_FIELDCAT-SELTEXT_M = 'TIME'.
LT_FIELDCAT-OUTPUTLEN = 10.
LT_FIELDCAT-JUST = 'C'.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'SLGMAND'.
LT_FIELDCAT-SELTEXT_M = 'Client'.
LT_FIELDCAT-OUTPUTLEN = 4.
LT_FIELDCAT-JUST = 'C'.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'MSG'.
LT_FIELDCAT-SELTEXT_M = 'MSG ID'.
LT_FIELDCAT-OUTPUTLEN = 4.
LT_FIELDCAT-JUST = 'C'.
LT_FIELDCAT-EMPHASIZE = 'C600'.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'SLGUSER'.
LT_FIELDCAT-SELTEXT_M = 'USER'.
LT_FIELDCAT-OUTPUTLEN = 12.
LT_FIELDCAT-JUST = 'C'.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'SLGLTRM2'.
LT_FIELDCAT-SELTEXT_M = 'Terminal'.
LT_FIELDCAT-OUTPUTLEN = 10.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'TERM_IPV6'.
LT_FIELDCAT-SELTEXT_M = 'IP'.
LT_FIELDCAT-OUTPUTLEN = 10.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'SLGTC'.
LT_FIELDCAT-SELTEXT_M = 'Tcode'.
LT_FIELDCAT-OUTPUTLEN = 10.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'SLGREPNA'.
LT_FIELDCAT-SELTEXT_M = 'Program'.
LT_FIELDCAT-OUTPUTLEN = 10.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'PARAM3'.
LT_FIELDCAT-SELTEXT_M = 'Log'.
LT_FIELDCAT-OUTPUTLEN = 10.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'EVID_URL'.
LT_FIELDCAT-SELTEXT_M = 'EVID URL'.
LT_FIELDCAT-HOTSPOT = 'X'.
LT_FIELDCAT-OUTPUTLEN = 50.
LT_FIELDCAT-EMPHASIZE = 'C500'.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'TARGET_ROLE'.
LT_FIELDCAT-SELTEXT_M = 'Role'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 25.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'ACT_DATE'.
LT_FIELDCAT-SELTEXT_M = 'Grant Date'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 8.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'ACT_TIME'.
LT_FIELDCAT-SELTEXT_M = 'Grant Time'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 8.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'REVOKE_DATE'.
LT_FIELDCAT-SELTEXT_M = 'Revoke Date'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 8.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'REVOKE_TIME'.
LT_FIELDCAT-SELTEXT_M = 'Revoke Time'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 8.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
"### ALV Layout 설정
LT_LAYOUT-BOX_FIELDNAME = 'SEL'.
LT_LAYOUT-INFO_FIELDNAME = 'LINECOLOR'.
LT_LAYOUT-COLWIDTH_OPTIMIZE = 'X'.
* LT_LAYOUT-ZEBRA = 'X'.
* LT_LAYOUT_CTAB_FNAME = 'CELLTAB'.
LT_LAYOUT-BOX_TABNAME = 'GT_SM20'.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_CALLBACK_PROGRAM = SY-REPID
I_CALLBACK_USER_COMMAND = 'USER_COMMAND_DISP'
I_CALLBACK_PF_STATUS_SET = 'SET_PF_STATUS'
"I_GRID_TITLE = GV_ALV_HEADER
I_CALLBACK_TOP_OF_PAGE = 'TOP-OF-PAGE'
I_HTML_HEIGHT_TOP = 5
IT_FIELDCAT = LT_FIELDCAT[]
IS_LAYOUT = LT_LAYOUT
"I_SAVE = 'A'
TABLES
T_OUTTAB = GT_SM20.
ELSE.
MESSAGE 'No Data' TYPE 'S'.
ENDIF.
ENDFORM.
*-------------------------------------------------------------------*
* Form TOP-OF-PAGE *
*-------------------------------------------------------------------*
* ALV Report Header *
*-------------------------------------------------------------------*
FORM TOP-OF-PAGE.
*ALV Header declarations
DATA: LT_HEADER TYPE SLIS_T_LISTHEADER,
LS_HEADER TYPE SLIS_LISTHEADER.
"### 여백 라인 삽입
* WA_HEADER-TYP = 'S'.
* WA_HEADER-INFO = ''.
* APPEND WA_HEADER TO T_HEADER.
* CLEAR WA_HEADER.
IF S_DATE IS NOT INITIAL.
IF S_DATE-HIGH IS INITIAL OR S_DATE-LOW = S_DATE-HIGH.
LS_HEADER-TYP = 'S'.
LS_HEADER-INFO = |Date : { S_DATE-LOW+0(4) }.{ S_DATE-LOW+4(2) }.{ S_DATE-LOW+6(2) }|.
ELSE.
LS_HEADER-TYP = 'S'.
LS_HEADER-INFO = |Date : { S_DATE-LOW+0(4) }.{ S_DATE-LOW+4(2) }.{ S_DATE-LOW+6(2) } ~ { S_DATE-HIGH+0(4) }.{ S_DATE-HIGH+4(2) }.{ S_DATE-HIGH+6(2) }|.
ENDIF.
APPEND LS_HEADER TO LT_HEADER.
CLEAR: LS_HEADER.
LS_HEADER-TYP = 'S'.
LS_HEADER-INFO = |Count : { GV_COUNT }|.
APPEND LS_HEADER TO LT_HEADER.
CLEAR: LS_HEADER.
ENDIF.
CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
EXPORTING
IT_LIST_COMMENTARY = LT_HEADER
I_ALV_FORM = 'X'.
ENDFORM. "TOP-OF-PAGE.
해당 BAdI 에 대한 정보는 다음 Notes 를 참고하기 바란다.
- SAP Notes 1750161 - User administration: Saving additional information (BAdI BADI_IDENTITY_UPDATE)
Tcode : SE18
BAdI Name : BADI_IDENTITY_UPDATE
-> 상단에서 Enhancement Spot - SUID_IDENTITY 확인
Tcode : SE19
-> Create Implementation
-> New BAdI
-> Enhancement Spot : SUID_IDENTITY 입력 후, Create
-> Enhancement Implementation : ZBC_USER_SAVE (자유 입력 가능)
-> Short Text : SAP User Save BAdI (자유 입력 가능)
-> BAdI Implementation : ZCL_IDENTITY_UPDATE (자유 입력 가능)
-> Implementation Class : ZCL_IP_IDENTITY_UPDATE (자유 입력 가능)
-> BAdI Definition : BADI_IDENTITY_UPDATE
-> 왼쪽 메뉴트리의 방금 생성한 BAdI 밑에 Implementation Class 더블클릭
-> 해당 Implementing Class 에 속한 Method 들을 확인할 수 있다.
-> 여기서 ~SAVE 메소드를 더블클릭하여 오픈한 다음, 아래 소스 코드 입력
method IF_BADI_IDENTITY_UPDATE~SAVE.
"### SAP NOTES 1750161 - User administration: Saving additional information (BAdI BADI_IDENTITY_UPDATE)
"### 롤 관련 업데이트 사항이 있을시, (프로파일 부여/조정은 SPACE 값)
IF IT_BADI_IDENTITY_ROLES IS NOT INITIAL.
DATA: LT_CTRL_ROLE TYPE TABLE OF ZBC_CTRL_ROLE
LS_CTRL_ROLE LIKE LINE OF LT_CTRL_ROLE.
DATA: LT_POPUP TYPE TABLE OF SVAL,
LS_POPUP LIKE LINE OF LT_POPUP.
DATA: LS_ROLE TYPE LINE OF SUID_TT_BADI_ROLES,
LS_ROLE_ACT TYPE LINE OF SUID_TT_AGR_USERS,
LS_ROLE_BEF TYPE LINE OF SUID_TT_AGR_USERS,
LS_ROLE_DEL TYPE LINE OF SUID_TT_AGR_USERS.
DATA: LT_ROLE_ACT TYPE TABLE OF AGR_USERS,
LT_ROLE_BEF TYPE TABLE OF AGR_USERS,
LT_ROLE_DEL TYPE TABLE OF AGR_USERS.
DATA: LV_RET TYPE C,
LV_CNT TYPE N.
DATA: LT_EVID TYPE TABLE OF ZBC_EVID_DATA,
LS_EVID LIKE LINE OF LT_EVID
"### 권한 증빙 제어 롤 리스트 셀렉트
SELECT * INTO CORRESPONDING FIELDS OF TABLE LT_CTRL_ROLE
FROM ZBC_CTRL_ROLE.
"### 부여하는 권한 중, 권한 증빙 제어 롤이 있는 확인
LOOP AT IT_BADI_IDENTITY_ROLES INTO LS_ROLE.
"### 기초 데이터 준비
LT_ROLE_BEF[] = LS_ROLE-BEFORE_IMAGE[].
LT_ROLE_ACT[] = LS_ROLE-ACTUAL[].
LT_ROLE_DEL[] = LT_ROLE_BEF[].
"### 기존(BEF) 롤 리스트에서 신규(ACT) 롤 리스트를 비교하여, 삭제된 롤 리스트 생성.
LOOP AT LT_ROLE_ACT INTO LS_ROLE_ACT.
DELETE LT_ROLE_DEL WHERE AGR_NAME = LS_ROLE_ACT-AGR_NAME
AND UNAME = LS_ROLE_ACT-UNAME
AND FROM_DAT = LS_ROLE_ACT-FROM_DAT
AND TO_DAT = LS_ROLE_ACT-TO_DAT
AND CHANGE_DAT = LS_ROLE_ACT-CHANGE_DAT
AND CHANGE_TIM = LS_ROLE_ACT-CHANGE_TIM.
ENDLOOP.
"### 사전 설정된 증빙 제어 롤 리스트 가져오기
LOOP AT LT_CTRL_ROLE INTO LS_CTRL_ROLE WHERE ITEM = 'ROLE'.
"### 사용자에게 부여하는 롤 중에, 권한 증빙 제어 롤이 있다면, EVID URL 증빙 요구
LOOP AT LT_ROLE_ACT INTO LS_ROLE_ACT WHERE AGR_NAME = LS_CTRL_ROLE-VALUE.
"### 권한 증빙 제어 롤 중,
"### 기존에 제어 롤을 보유하고 있고, 수정 사항이 없다면, 바이패스하도록 설정.
READ TABLE LT_ROLE_BEF INTO LS_ROLE_BEF WITH KEY AGR_NAME = LS_ROLE_ACT-AGR_NAME
UNAME = LS_ROLE_ACT-UNAME
FROM_DAT = LS_ROLE_ACT-FROM_DAT
TO_DAT = LS_ROLE_ACT-TO_DAT
CHANGE_DAT = LS_ROLE_ACT-CHANGE_DAT
CHANGE_TIM = LS_ROLE_ACT-CHANGE_TIM.
IF SY-SUBRC = 0.
CONTINUE.
ENDIF.
"### 권한 부여 증빙 팝업 설정
"### 디버깅 수정권한 부여 증빙 URL 입력
CLEAR: LT_POPUP, LS_POPUP. REFRESH: LT_POPUP.
"### => 권한 부여 대상 SAP ID
LS_POPUP-TABNAME = 'USR02'.
LS_POPUP-FIELDNAME = 'BNAME'.
LS_POPUP-FIELDTEXT = 'Target User'.
LS_POPUP-FIELD_ATTR = '03'.
LS_POPUP-VALUE = LS_ROLE_ACT-UNAME.
APPEND LS_POPUP TO LT_POPUP. CLEAR: LS_POPUP.
"### => 권한 부여 대상 롤
LS_POPUP-TABNAME = 'AGR_DEFINE'.
LS_POPUP-FIELDNAME = 'AGR_NAME'.
LS_POPUP-FIELDTEXT = 'Target Role'.
LS_POPUP-FIELD_ATTR = '03'.
LS_POPUP-VALUE = LS_ROLE_ACT-AGR_NAME.
APPEND LS_POPUP TO LT_POPUP. CLEAR: LS_POPUP.
"### => 권한 부여 대상 롤 유효기간 시작일
LS_POPUP-TABNAME = 'AGR_USERS'.
LS_POPUP-FIELDNAME = 'FROM_DAT'.
LS_POPUP-FIELDTEXT = 'Vaild From'.
LS_POPUP-FIELD_ATTR = '03'.
LS_POPUP-VALUE = LS_ROLE_ACT-FROM_DAT.
APPEND LS_POPUP TO LT_POPUP. CLEAR: LS_POPUP.
"### => 권한 부여 대상 롤 유효기간 종료일
LS_POPUP-TABNAME = 'AGR_USERS'.
LS_POPUP-FIELDNAME = 'TO_DAT'.
LS_POPUP-FIELDTEXT = 'Vaild To'.
LS_POPUP-FIELD_ATTR = '03'.
LS_POPUP-VALUE = LS_ROLE_ACT-TO_DAT.
APPEND LS_POPUP TO LT_POPUP. CLEAR: LS_POPUP.
"### => 증빙 URL
LS_POPUP-TABNAME = 'IWURL'.
LS_POPUP-FIELDNAME = 'URL'.
LS_POPUP-FIELDTEXT = 'Evid. URL'.
APPEND LS_POPUP TO LT_POPUP. CLEAR: LS_POPUP.
"### 팝업 출력
CALL FUNCTION 'POPUP_GET_VALUES'
EXPORTING
POPUP_TITLE = 'Evidence of Role Assignment'
IMPORTING
RETURNCODE = LV_RET
TABLES
FIELDS = LT_POPUP
EXCEPTIONS
ERROR_IN_FIELDS = 1
OTHERS = 2.
"### 해당 BAdI 특성 상, 유효값 설정을 할 수 없기 때문에, 취소, 공백 입력도 허용
"### == SAP Notes 1750161 내용 ==
"### = The save process can no longer be canceled. The output of messages of the type E, A, or X is therefore not permitted.
"### = You can no longer change the user data that is to be saved.
"### = A COMMIT WORK or ROLLBACK WORK must not be executed.
"### 팝업 응답 중, URL 필드 읽기
READ TABLE LT_POPUP[] INTO LS_POPUP WITH KEY FIELDNAME = 'URL'.
"### 해당 데이터를 종합하여, LT_EVID 테이블에 저장
CLEAR: LT_EVID, LT_EVID[], LS_EVID.
LS_EVID-MANDT = SY-MANDT.
LS_EVID-ACT_DATE = LS_ROLE_ACT-CHANGE_DAT.
LS_EVID-ACT_TIME = LS_ROLE_ACT-CHANGE_TIM.
LS_EVID-TARGET_USER = LS_ROLE_ACT-UNAME.
LS_EVID-TARGET_ROLE = LS_ROLE_ACT-AGR_NAME.
LS_EVID-VAILD_FROM = LS_ROLE_ACT-FROM_DAT.
LS_EVID-VAILD_TO = LS_ROLE_ACT-TO_DAT.
LS_EVID-CHG_USER = IS_BADI_TIMESTAMP-UNAME.
LS_EVID-EVID_URL = LS_POPUP-VALUE.
APPEND LS_EVID TO LT_EVID. CLEAR: LS_EVID.
"### LT_EVID 데이터를 ZBC_EVID_DATA 테이블에 MODI
MODIFY ZBC_EVID_DATA FROM TABLE LT_EVID.
ENDLOOP.
"### 관한 증빙 제어 롤 회수 시, 회수 일자 기록 로직
CLEAR: LS_ROLE_BEF, LS_ROLE_ACT.
"### 삭제된 롤 리스트에 대해, 회수 일자 기록
LOOP AT LT_ROLE_DEL INTO LS_ROLE_DEL WHERE AGR_NAME = LS_CTRL_ROLE-VALUE.
SELECT * INTO CORRESPONDING FIELDS OF TABLE LT_EVID
FROM ZBC_EVID_DATA
WHERE ACT_DATE = LS_ROLE_DEL-CHANGE_DAT
AND ACT_TIME = LS_ROLE_DEL-CHANGE_TIM
AND TARGET_USER = LS_ROLE_DEL-UNAME
AND TARGET_ROLE = LS_ROLE_DEL-AGR_NAME
AND VAILD_FROM = LS_ROLE_DEL-FROM_DAT
AND VAILD_TO = LS_ROLE_DEL-TO_DAT.
IF SY-SUBRC = 0.
READ TABLE LT_EVID INTO LS_EVID INDEX 1.
LS_EVID-REVOKE_DATE = IS_BADI_TIMESTAMP-DATUM.
LS_EVID-REVOKE_TIME = IS_BADI_TIMESTAMP-UZEIT.
APPEND LS_EVID TO LT_EVID. CLEAR LS_EVID.
"### 회수 일자/시간이 기록된 데이터를 ZBC_EVID_DATA 테이블에 MODIFY
MODIFY ZBC_EVID_DATA FROM TABLE LT_EVID.
ENDIF.
ENDLOOP.
ENDLOOP.
ENDLOOP.
ENDIF.
endmethod.
| Field | Key | InitV | Data Element | DType | Len | Desc |
|---|---|---|---|---|---|---|
| MANDT | X | X | MANDT | |||
| ACT_DATE | X | X | DATUM | |||
| ACT_TIME | X | X | UZEIT | |||
| TARGET_USER | X | X | BNAME | |||
| TARGET_ROLE | X | X | AGR_NAME | |||
| VAILD_FROM | X | X | DATUM | |||
| VAILD_TO | X | X | DATUM | |||
| CHG_USER | BNAME | |||||
| EVID_URL | AGR_URL | |||||
| REVOKE_DATE | DATUM | |||||
| REVOKE_TIME | UZEIT | |||||
| MANUAL_EDIT | CHAR | 1 | 수기 입력 플래그 |
| Field | Key | InitV | Data Element | DType | Len | Desc |
|---|---|---|---|---|---|---|
| MANDT | X | X | MANDT | |||
| ITEM | X | X | CHAR20 | |||
| VALUE | X | X | CHAR30 | |||
| TAG | CHAR20 | |||||
| TEXT | CHAR50 |
ADD_ITEM
-> Function Text : ADD_ITEM
-> Icon Name : ICON_CREATE
-> Icon Text / Info. Text : ADD ITEM
DEL_ITEM
-> Function Text : DEL_ITEM
-> Icon Name : ICON_DELETE
-> Icon Text / Info. Text : DELETE ITEM
&ETA
-> Function Text : 세부사항
-> Icon Name : ICON_SELECT_DETAIL
분리자 라인 (Edit -> Insert -> separator line)
&ALL
-> Function Text : 모두 선택
-> Icon Name : ICON_SELECT_ALL
&SAL
-> Function Text : 모두 선택 해제
-> Icon Name : ICON_DESELECT_ALL
분리자 라인
&OUP
-> Function Text : 오름차순 정렬
-> Icon Name : ICON_SORT_UP
&ODN
-> Function Text : 내림차순 정렬
-> Icon Name : ICON_SORT_DOWN
&ILT
-> Function Text : 필터 설정
-> Icon Name : ICON_FILTER
분리자 라인
&XXL
-> Function Text : 스프레드시트
-> Icon Name : ICON_XXL
%PC
-> Function Text : 로컬 파일
-> Icon Name : ICON_EXPORT
분리자 라인
&NTE
-> Function Text : 새로 고침
-> Icon Name : ICON_REFRESH
분리자 라인
F_ADJ
-> Function Text : F_ADJ
-> Icon Name : ICON_INTENSIFY_CRITICAL
-> Icon Text / Info. Text : Revoke Adjust
M_EDIT
-> Function Text : M_EDIT
-> Icon Name : ICON_ANNOTATION
-> Icon Text / Info. Text : Revoke Edit
분리자 라인
DELE
-> Function Text : DELE
-> Icon Name : ICON_DELETE
-> Icon Text / Info. Text : DELETE