⭐프로젝트 : 항공사 예약 정보

j_wisdom_h·2025년 6월 16일
0

SAP

목록 보기
17/19

🔍 개요

SAP ABAP을 활용하여 항공사 예약 정보를 조회하고, 고객 정보를 ALV로 시각화하는 프로그램을 개발했습니다.

주요기능

  • 항공편 조건에 따른 예약정보 조회

  • 취소 여부 필터링

  • 고객 상세 정보 팝업 조회

  • 빠른 예약 고객 Top 5 추출 및 출력

SAP 내부 테스트 테이블(ZSBOOK, SCUSTOM 등)을 기반으로 진행되었으며, 핫스팟 이벤트 및 사용자 정의 툴바, 이중 ALV 출력

📋 사용 기술

분류기술명
언어ABAP
UI 구성SELECTION-SCREEN, ALV (CL_GUI_ALV_GRID)
이벤트 처리핫스팟 이벤트, 툴바 버튼, 사용자 명령어
객체지향 요소이벤트 핸들링 클래스 정의 및 구현
주요 테이블ZSBOOK(예약), SCUSTOM(고객), SCARR(항공사)

🔧 주요 개발 목표

목표설명
조건별 예약 조회항공사 코드 / 항공편 / 출발일 기준으로 예약 정보 필터링
ALV 상태 시각화남은 일수에 따라 상태 아이콘 및 셀 색상 출력
고객 상세 팝업고객 ID 클릭 시 별도 팝업에서 고객정보 출력
Top 5 고객 추출남은 일수 기준 Top 5 고객 추출 및 별도 ALV로 출력
사용자 중심 인터페이스툴바 버튼 클릭 시 기능 이동 가능, 사용자 명령에 따라 화면 제어

프로그램 구조

ZPORTFOLIO_ARS
├─ ZPORTPOLIO_ARS_TOP : 전역변수 선언
├─ ZPORTPOLIO_ARS_SEL : 선택화면(SELECTION-SCREEN)
├─ ZPORTPOLIO_ARS_C01 : ALV 이벤트 클래스
├─ ZPORTPOLIO_ARS_F01 : 데이터 조회, ALV 출력 Form들
├─ ZPORTPOLIO_ARS_I01 : 화면 입력 처리
└─ ZPORTPOLIO_ARS_O01 : ALV 출력 및 화면 구성

💡 핵심 기능 설명

📌 1. 조건별 예약 데이터 조회 (GET_DATA)

SELECTION-SCREEN에서 입력한 항공사, 항공편, 출발일 조건으로 예약 조회

SELECTION-SCREEN BEGIN OF BLOCK BL01 WITH FRAME TITLE TEXT-001.
*   검색조건
PARAMETERS: p_air TYPE sbook-carrid OBLIGATORY,   
            p_conn   TYPE sbook-connid OBLIGATORY,    
            p_date   TYPE sbook-fldate.    
SELECTION-SCREEN END OF BLOCK BL01.

SELECTION-SCREEN BEGIN OF BLOCK BL02 WITH FRAME TITLE TEXT-002.
  SELECT-OPTIONS: s_cust FOR scustom-id NO-EXTENSION.
  PARAMETERS: r1 RADIOBUTTON GROUP rad DEFAULT 'X',
              r2 RADIOBUTTON GROUP rad,
              r3 RADIOBUTTON GROUP rad.
SELECTION-SCREEN END OF BLOCK BL02.

r1/r2/r3 라디오버튼에 따라 전체 / 취소 / 미취소 필터링


START-OF-SELECTION.

  IF r1 = 'X'.
    gv_cancelled = ''.
  ELSEIF r2 = 'X'.
    gv_cancelled = space.  " 취소되지 않은 예약
  ELSEIF r3 = 'X'.
    gv_cancelled = 'X'.    " 취소된 예약
  ENDIF.

  PERFORM get_data.                      " 1단계: 데이터 조회
  PERFORM apply_filter_condition.       " 2단계: 필터 조건별 분류

END-OF-SELECTION.


IF GT_TABLE IS INITIAL.
  MESSAGE '조회할 데이터가 없습니다.' TYPE 'I'.
ELSE.
  CALL SCREEN 100.
ENDIF.

FORM get_data.
  CLEAR gt_table.

  IF r1 = 'X'.
   SELECT
    a~carrid, a~connid, a~fldate, a~bookid, a~customid, a~CUSTTYPE,
    a~loccuram, a~loccurkey, a~order_date, a~cancelled,
    b~carrname,
    c~name      AS custname,
    c~telephone
    INTO CORRESPONDING FIELDS OF TABLE @gt_table
    FROM  zsbook AS a
    INNER JOIN scarr AS b ON a~carrid = b~carrid
    INNER JOIN scustom AS c ON a~customid = c~id
    WHERE a~carrid   = @p_air
      AND a~connid   = @p_conn
      AND a~fldate   = @p_date
      AND a~customid IN @s_cust.

  ELSE.
    SELECT
      a~carrid, a~connid, a~fldate, a~bookid, a~customid, a~CUSTTYPE,
      a~loccuram, a~loccurkey, a~order_date, a~cancelled,
      b~carrname,
      c~name      AS custname,
      c~telephone
      INTO CORRESPONDING FIELDS OF TABLE @gt_table
      FROM  zsbook AS a
      INNER JOIN scarr AS b ON a~carrid = b~carrid
      INNER JOIN scustom AS c ON a~customid = c~id
      WHERE a~carrid   = @p_air
        AND a~connid   = @p_conn
        AND a~fldate   = @p_date
        AND a~customid IN @s_cust
        AND a~cancelled = @gv_cancelled.
   ENDIF.

ENDFORM.

ZSBOOK, SCARR, SCUSTOM 조인 SELECT

📌 2. 남은 일수 계산 + 상태 아이콘 표시 (SET_STATUS_ICON)

예약일과 출발일 차이 계산

남은 일수 100 이상: 초록불, 50 이상: 노랑불, 그 외: 빨강불 표시

특정 조건(>=150)은 셀 강조 색상까지 설정 (CELL COLOR)

전체조회 모드일때 취소된 예약은 빨간색 배경색 지정.


<== gt_table
...
DATA LINECOLOR(4)     TYPE C.   ==> 라인 컬러
DATA CELLSCOL  TYPE LVC_T_SCOL. ==> 셀 컬러
...
==>
FORM apply_filter_condition.
  LOOP AT gt_table INTO gs_table.
    IF r1 = 'X'. " 전체 조회일때
      IF gs_table-cancelled = 'X'.
         gs_table-linecolor = 'C611'.  ==> 라인 컬러
      ENDIF.
    ENDIF.

    PERFORM set_status_icon CHANGING gs_table.
    MODIFY gt_table FROM gs_table.
  ENDLOOP.
ENDFORM.


FORM set_status_icon CHANGING gs_table LIKE gs_table.
  DATA: LS_COLOR TYPE LVC_S_SCOL. 
  DATA: lv_days_left TYPE i.

  lv_days_left =  gs_table-fldate - gs_table-order_date .
  gs_table-days = lv_days_left.

  IF lv_days_left >= 150.
      LS_COLOR-FNAME = 'DAYS'.
      LS_COLOR-COLOR-INT = 1.
      LS_COLOR-COLOR-INV = 1.
      LS_COLOR-COLOR-COL = 5.
      APPEND LS_COLOR TO gs_table-CELLSCOL. ==> 셀 컬러
  ENDIF.

  IF lv_days_left >= 100.
    gs_table-zstatus = ICON_LED_GREEN.  " 초록불
  ELSEIF lv_days_left >= 50.
    gs_table-zstatus = ICON_LED_YELLOW. " 노랑불
  ELSE.
    gs_table-zstatus = ICON_LED_RED.    " 빨강불
  ENDIF.
ENDFORM.

FORM set_layout .
  gs_layout-zebra = 'X'.
  gs_layout-cwidth_opt = 'X'.
  gs_layout-sel_mode   = 'D'.
  gs_layout-info_fname ='LINECOLOR'. " 라인 컬러
  gs_layout-ctab_fname = 'CELLSCOL'. " 셀 컬러
ENDFORM.

📌 3. 고객 ID 핫스팟 클릭 → 고객 상세 팝업 (handle_hotspot_click)

ALV 내 CUSTOMID 필드에 Hotspot 설정

클릭 시 선택한 고객 ID를 gv_cid에 저장 후, SCREEN 200 호출

FORM set_fildcat .
  DEFINE _fcat.
    CLEAR gs_fcat.
    gs_fcat-fieldname  = &1.
    gs_fcat-coltext    = &2.
    gs_fcat-key        = &3.
    gs_fcat-edit       = &4.
    gs_fcat-outputlen  = &5.
    gs_fcat-lowercase  = &6.
    gs_fcat-col_pos    = &7.
    APPEND gs_fcat TO gt_fcat.
  END-OF-DEFINITION.

  _fcat: 'ZSTATUS'   '상태'             ''  '' '3'  ''  '1',
         'CARRID'    'Airline Code'    'X' '' '6'  ''  '2',
         'CARRNAME'  'Airline Name'    'X' '' '20' ''  '3',
         'CONNID'    'Flight No.'      'X' '' '6'  ''  '4',
         'FLDATE'    'Flight Date'     'X' '' '10' ''  '5',
         'BOOKID'    'Booking'         'X' '' '6'  ''  '6',
         'CUSTOMID'  'Cust. No.'       ''  '' '10' ''  '7',
         'CUSTNAME'  'Customer Name'   ''  '' '20' ''  '8',
         'TELEPHONE' 'Telephone No.'   ''  '' '15' ''  '9',
         'CUSTTYPE'  'B/P Type'        ''  '' '4'  ''  '10',
         'LOCCURAM'  'Amount'          ''  '' '10' ''  '11',
         'LOCCURKEY' 'Curr.'           ''  '' '5'  ''  '12',
         'ORDER_DATE' 'Booking Date'   ''  '' '10' ''  '13',
         'DAYS'      'DAYS'            ''  '' '10' ''  '14',
         'CANCELLED' 'Cancelled'       ''  '' '1'  ''  '15'.

* HOTSPOT 필드 설정
  LOOP AT gt_fcat INTO gs_fcat WHERE fieldname = 'CUSTOMID'.
    gs_fcat-hotspot = 'X'.
    MODIFY gt_fcat FROM gs_fcat.
  ENDLOOP.
ENDFORM.

스크린 200
=> Modal dialog box로 설정
=> 스크린페인터로 dictionary/program field 에서 scustom 필드 불러와서 그리기


FORM display_alv_0100 .
  CREATE OBJECT g_event_receiver.
  SET HANDLER g_event_receiver->handle_hotspot_click FOR go_grid.
  SET HANDLER g_event_receiver->HANDEL_TOOLBAR FOR go_grid.
  SET HANDLER g_event_receiver->HANDEL_USER_COMMAND FOR go_grid.

 CALL METHOD GO_GRID->SET_TABLE_FOR_FIRST_DISPLAY
    EXPORTING
      IS_LAYOUT                     = GS_LAYOUT
    CHANGING
      IT_OUTTAB                     = GT_TABLE
      IT_FIELDCATALOG               = GT_FCAT.

ENDFORM.

GO_GRID 에 이벤트 리시버 등록


CLASS lcl_event_receiver DEFINITION DEFERRED.
DATA: g_event_receiver TYPE REF TO lcl_event_receiver.

*--------------------------------------------------
* 클래스 선언
*-------------------------------------------------
CLASS lcl_event_receiver DEFINITION.
  PUBLIC SECTION.

  " 핫스팟 클릭 이벤트 
  METHODS : handle_hotspot_click
    FOR EVENT hotspot_click OF CL_GUI_ALV_GRID
    IMPORTING e_row_id e_column_id.
    
  " 툴바 보여주는용 함수.
  METHODS : HANDEL_TOOLBAR
    FOR EVENT TOOLBAR OF CL_GUI_ALV_GRID
    IMPORTING E_OBJECT.
    
  " 툴바 클릭시 발생하는 ucomm을 갖고 작동하는 함수.
  METHODS : HANDEL_USER_COMMAND
    FOR EVENT USER_COMMAND OF CL_GUI_ALV_GRID
    IMPORTING E_UCOMM.
ENDCLASS.
*--------------------------------------------
* 클래스 구현
*--------------------------------------------
CLASS lcl_event_receiver IMPLEMENTATION.

  METHOD handle_hotspot_click.
    DATA: tmp_gt_table LIKE LINE OF gt_table.
    READ TABLE gt_table INDEX e_row_id-index INTO tmp_gt_table.

    IF sy-subrc = 0.
      gv_cid = tmp_gt_table-customid. "> 선택된 고객id

      CALL SCREEN 200 STARTING AT 16   1
                      ENDING   AT 77  20.
    ENDIF.
  ENDMETHOD.

  METHOD HANDEL_TOOLBAR.
    PERFORM HANDEL_TOOLBAR USING E_OBJECT.
  ENDMETHOD.

  METHOD HANDEL_USER_COMMAND.
    PERFORM HANDEL_USER_COMM USING e_ucomm.
  ENDMETHOD.

ENDCLASS.

콜스크린 실행 결과 모달화면, PBO실행


MODULE status_0200 OUTPUT.

 SET TITLEBAR '200' WITH '고객 정보'.
 SET PF-STATUS 'ZSTAT'.

ENDMODULE.

MODULE set_alv_0200 OUTPUT.

  PERFORM get_customer.

ENDMODULE.


FORM get_customer.

  SELECT SINGLE *
    FROM scustom
    WHERE id = gv_cid.

ENDFORM.

선택된 id기준으로 scustom에서 정보 불러와서 자동으로 스크린에 SET.

📌 4. 툴바 버튼 → 빠른 예약 고객 Top 5 조회 (handle_toolbar)

사용자 정의 툴바 버튼에 SHOW 명령 연결

클릭 시 남은 일수 기준 Top 5 고객 정렬 → ALV 출력 (화면 250)


METHODS : HANDEL_TOOLBAR
  FOR EVENT TOOLBAR OF CL_GUI_ALV_GRID
  IMPORTING E_OBJECT.

CL_GUI_ALV_GRID의 TOOLBAR 이벤트 발생 시 호출.
( e_object 객체를 전달받는 이벤트 핸들러 )



*&---------------------------------------------------------------------*
*& Form HANDEL_TOOLBAR
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> E_OBJECT
*&---------------------------------------------------------------------*
FORM handel_toolbar  USING PO_OBJECT TYPE REF TO CL_ALV_EVENT_TOOLBAR_SET.
  DATA : LS_TOOLBAR TYPE STB_BUTTON. " STB_BUTTON: 툴바 버튼의 속성

  LS_TOOLBAR-ICON = ICON_CUSTOMER.
  LS_TOOLBAR-FUNCTION = 'SHOW'.
  LS_TOOLBAR-TEXT = 'Early Booked Top 5 Customer'.
  APPEND LS_TOOLBAR TO PO_OBJECT->MT_TOOLBAR.

  CLEAR  ls_toolbar.
ENDFORM.
항목설명
e_objectCL_ALV_EVENT_TOOLBAR_SET 클래스의 참조 객체
->해당 객체의 속성에 접근하는 참조 연산자
mt_toolbarSTB_BUTTON 구조의 내부 테이블로 툴바 버튼 목록 저장소
접근 목적ALV 툴바에 버튼을 추가하기 위해 사용됨

SAP는 모든 이벤트마다 하나의 객체를 넘겨주고, 그 객체 내부 필드를 조작해서 원하는 기능을 추가하라는 구조를 채택함.
"버튼 테이블만 채우면 알아서 툴바가 만들어지는" 방식으로 일관성을 유지


FORM handel_user_comm  USING    p_ucomm.
 CASE p_ucomm.
    WHEN 'SHOW'.
      CALL SCREEN 250 STARTING AT 16   5
                      ENDING   AT 62  13.
  ENDCASE.
ENDFORM.

ALV에서 사용자가 버튼을 클릭하거나 특정 동작을 할 때, SY-UCOMM 타입의 기능 코드를 E_UCOMM이라는 이름으로 이벤트 파라미터에 담아 전달.
(여기서는 툴바 클릭시)



MODULE set_alv_0250 OUTPUT.

  IF GO_CUSTOM IS INITIAL.

    PERFORM create_object_instance_250.

    PERFORM get_customer_top5.

    PERFORM set_fildcat_250.

    PERFORM set_layout_250.

    PERFORM display_alv_0250.

  ENDIF.

ENDMODULE.
*&---------------------------------------------------------------------*
*& Form GET_CUSTOMER_TOP5
*&---------------------------------------------------------------------*
*& 전체 예약 데이터(GT_TABLE)에서 고객ID/이름/남은일수 정보 추출
*& → 남은 일수 기준으로 정렬하여 Top 5 고객만 GT_CUST에 저장
*&---------------------------------------------------------------------*
FORM get_customer_top5.

  " 1. 초기화
  CLEAR gt_cust.

  " 2. 예약 테이블 루프 → 고객 정보 구조에 매핑
  LOOP AT gt_table INTO gs_table.
    CLEAR gs_cust.
    MOVE-CORRESPONDING gs_table TO gs_cust.
    APPEND gs_cust TO gt_cust.
  ENDLOOP.

  " 3. 남은 일수(DAYS) 기준 내림차순 정렬
  SORT gt_cust BY days DESCENDING.

  " 4. 상위 5개 항목만 남기고 나머지 삭제
  DELETE gt_cust FROM 6 TO LINES( gt_cust ).

ENDFORM.

*&---------------------------------------------------------------------*
*& Form CREATE_OBJECT_INSTANCE_250
*&---------------------------------------------------------------------*
FORM create_object_instance_250 .

  CREATE OBJECT GO_CUSTOM
    EXPORTING
      CONTAINER_NAME = 'CON1'.   "Custom Control 이름

  CREATE OBJECT GO_GRID2
    EXPORTING
      I_PARENT = GO_CUSTOM.
ENDFORM.

커스텀 컨트롤러 생성 GO_CUSTOM


*&---------------------------------------------------------------------*
*& Form SET_FILDCAT_250
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM set_fildcat_250 .

  DEFINE _fcat2.
    CLEAR GS_FCAT2.
    GS_FCAT2-FIELDNAME  = &1.
    GS_FCAT2-COLTEXT    = &2.
    GS_FCAT2-KEY        = &3.
    GS_FCAT2-OUTPUTLEN  = &4.
    GS_FCAT2-LOWERCASE  = &5.
    APPEND GS_FCAT2 TO GT_FCAT2.
  END-OF-DEFINITION.

  _fcat2: 'CUSTOMID'  '고객ID'    'X'  '8'   '',
          'CUSTNAME'  '고객명'     ''  '25'  '',
          'DAYS'      '남은일수'    ''  '4'   ''.

ENDFORM.
FORM display_alv_0250.
  APPEND cl_gui_alv_grid=>mc_fc_excl_all TO GT_FUNCTIONS.

  CALL METHOD GO_GRID2->SET_TABLE_FOR_FIRST_DISPLAY
    EXPORTING
      IS_LAYOUT       = GS_LAYOUT2
      it_toolbar_excluding = GT_FUNCTIONS
    CHANGING
      IT_OUTTAB       = GT_CUST
      IT_FIELDCATALOG = GT_FCAT2.
ENDFORM.

연산자읽는 법용도예시
->인스턴스 연산자객체 인스턴스의 속성이나 메서드 접근lo_grid->set_table_for_first_display
=>클래스 연산자클래스의 정적(static) 속성/메서드 접근cl_gui_alv_grid=>mc_fc_excl_all



UI_FUNCTIONS : UI_FUNC(function code)로 이루어진 테이블


MC_FC_EXCL_ALL은 SAP가 정의한 기능 코드 상수.

mc_fc_excl_all = '&EXCLALLFC' (상수. 펑션코드).

이 값이 UI_FUNC 타입 테이블 (GT_FUNCTIONS)에 들어가면,
SAP는 “ALV 표준 기능 전부 비활성화”라고 인식

it_toolbar_excluding: 특정 툴바 버튼을 제외하기 위한 목록 → 위에서 'mc_fc_excl_all'을 넣었으므로 모든 버튼이 제거됨

profile
뚜잇뚜잇

0개의 댓글