Skip to content
Skip to content
Menu
SAP ABAP DWIMAN
  • About
SAP ABAP DWIMAN

SAP ABAP – ALV Dock with Approval 2 Columns

By juananda.satria on August 2, 2026August 2, 2026
*&---------------------------------------------------------------------*
*& Report  ZALV_DOCK_APPROVE
*&---------------------------------------------------------------------*
*& DOCUMENT-LEVEL approval: the ENTIRE result set shown in the ALV is
*& one approval object. There is no per-row status and no row selection.
*&
*& Layout - one docking container + 3-row splitter:
*&   Row 1 (fixed px) : title, selection parameters, row count, status
*&   Row 2 (rest)     : ALV grid, display only, no row marks
*&   Row 3 (fixed px) : signature block (fills in as the doc is signed)
*&
*& SUBMIT / APPROVE sit in the ALV toolbar and are enabled/disabled
*& according to the header status.
*&
*& Classic syntax (7.02-safe). No inline declarations.
*&---------------------------------------------------------------------*
REPORT zalv_dock_approve.

TYPE-POOLS: icon.

TABLES: sflight.

*----------------------------------------------------------------------*
* Types
*----------------------------------------------------------------------*
* --- ALV item line: NO status, NO icon. Status is header level.
TYPES: BEGIN OF ty_out,
         carrid   TYPE sflight-carrid,
         connid   TYPE sflight-connid,
         fldate   TYPE sflight-fldate,
         price     TYPE sflight-price,
         currency TYPE sflight-currency,
         seatsocc TYPE sflight-seatsocc,
       END OF ty_out.

* --- The approval document header. In production this is a Z-table.
TYPES: BEGIN OF ty_hdr,
         docno      TYPE char10,      " approval document number
         zstatus    TYPE char12,      " NEW / SUBMITTED / APPROVED
         seltext    TYPE string,      " frozen selection criteria
         rowcount   TYPE i,           " frozen row count
         checksum   TYPE string,      " frozen key checksum
         subm_by    TYPE sy-uname,
         subm_date  TYPE sy-datum,
         subm_time  TYPE sy-uzeit,
         appr_by    TYPE sy-uname,
         appr_date  TYPE sy-datum,
         appr_time  TYPE sy-uzeit,
       END OF ty_hdr.

*----------------------------------------------------------------------*
* Globals
*----------------------------------------------------------------------*
DATA: gt_out TYPE STANDARD TABLE OF ty_out,
      gs_out TYPE ty_out,
      gs_hdr TYPE ty_hdr.

DATA: go_dock      TYPE REF TO cl_gui_docking_container,
      go_split     TYPE REF TO cl_gui_splitter_container,
      go_cont_top  TYPE REF TO cl_gui_container,
      go_cont_grid TYPE REF TO cl_gui_container,
      go_cont_bot  TYPE REF TO cl_gui_container,
      go_grid      TYPE REF TO cl_gui_alv_grid,
      go_dd_top    TYPE REF TO cl_dd_document,
      go_dd_bot    TYPE REF TO cl_dd_document.

DATA: gv_ok_code   TYPE sy-ucomm,
      gv_top_shown TYPE abap_bool,
      gv_bot_shown TYPE abap_bool.

* Header / footer heights in PIXELS (splitter runs in absolute mode)
CONSTANTS: gc_top_height TYPE i VALUE 100,
           gc_bot_height TYPE i VALUE 85.

* Segregation of duties: approver must differ from submitter.
* Set to abap_false only if your business genuinely allows self-approval.
CONSTANTS: gc_sod_check TYPE abap_bool VALUE abap_true.

CONSTANTS: gc_new   TYPE char12 VALUE 'NEW',
           gc_subm  TYPE char12 VALUE 'SUBMITTED',
           gc_appr  TYPE char12 VALUE 'APPROVED'.

*----------------------------------------------------------------------*
* Event handler
*----------------------------------------------------------------------*
CLASS lcl_event_handler DEFINITION.
  PUBLIC SECTION.
    METHODS:
      on_toolbar
        FOR EVENT toolbar OF cl_gui_alv_grid
        IMPORTING e_object e_interactive,
      on_user_command
        FOR EVENT user_command OF cl_gui_alv_grid
        IMPORTING e_ucomm,
      on_print_top_of_page
        FOR EVENT print_top_of_page OF cl_gui_alv_grid,
      on_print_end_of_list
        FOR EVENT print_end_of_list OF cl_gui_alv_grid.
ENDCLASS.

DATA: go_handler TYPE REF TO lcl_event_handler.

*----------------------------------------------------------------------*
* Selection screen
*----------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-b01.
SELECT-OPTIONS: s_carrid FOR sflight-carrid,
                s_fldate FOR sflight-fldate.
SELECTION-SCREEN END OF BLOCK b1.

*----------------------------------------------------------------------*
START-OF-SELECTION.
*----------------------------------------------------------------------*
  PERFORM get_data.

  IF gt_out IS INITIAL.
    MESSAGE 'No data found - nothing to approve' TYPE 'S'
            DISPLAY LIKE 'W'.
    RETURN.
  ENDIF.

  PERFORM load_or_init_header.

  CALL SCREEN 0100.

*&---------------------------------------------------------------------*
*& Form GET_DATA
*&---------------------------------------------------------------------*
FORM get_data.

  DATA: lt_flight TYPE STANDARD TABLE OF sflight,
        ls_flight TYPE sflight.

  CLEAR gt_out.

  SELECT carrid connid fldate price currency seatsocc
    FROM sflight
    INTO CORRESPONDING FIELDS OF TABLE lt_flight
   WHERE carrid IN s_carrid
     AND fldate IN s_fldate.

  LOOP AT lt_flight INTO ls_flight.
    CLEAR gs_out.
    MOVE-CORRESPONDING ls_flight TO gs_out.
    APPEND gs_out TO gt_out.
  ENDLOOP.

  SORT gt_out BY carrid connid fldate.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form LOAD_OR_INIT_HEADER
*&---------------------------------------------------------------------*
* In production: read the approval header from your Z-table using the
* selection criteria (or a document number entered on the selection
* screen). If none exists, the document is NEW.
*&---------------------------------------------------------------------*
FORM load_or_init_header.

  CLEAR gs_hdr.

* --- TODO: SELECT SINGLE from z_appr_hdr here.
*     If found, MOVE-CORRESPONDING into gs_hdr and RETURN.

  gs_hdr-zstatus = gc_new.
  PERFORM build_sel_text CHANGING gs_hdr-seltext.
  DESCRIBE TABLE gt_out LINES gs_hdr-rowcount.
  PERFORM calc_checksum CHANGING gs_hdr-checksum.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form CALC_CHECKSUM
*&---------------------------------------------------------------------*
* Fingerprint of the key fields. Stored at SUBMIT, re-checked at
* APPROVE. If it moved, the data changed between the two steps and the
* approval must not go through silently.
*&---------------------------------------------------------------------*
FORM calc_checksum CHANGING cv_hash TYPE string.

  DATA: ls_out  TYPE ty_out,
        lv_keys TYPE string,
        lv_line TYPE string.

  LOOP AT gt_out INTO ls_out.
    CONCATENATE ls_out-carrid ls_out-connid ls_out-fldate
           INTO lv_line.
    CONCATENATE lv_keys lv_line INTO lv_keys.
  ENDLOOP.

  CALL FUNCTION 'CALCULATE_HASH_FOR_CHAR'
    EXPORTING
      alg  = 'MD5'
      data = lv_keys
    IMPORTING
      hashstring = cv_hash
    EXCEPTIONS
      OTHERS = 1.

  IF sy-subrc <> 0.
*   fallback: at least keep the row count as a weak fingerprint
    DESCRIBE TABLE gt_out LINES gs_hdr-rowcount.
    CLEAR cv_hash.
  ENDIF.

ENDFORM.

*&---------------------------------------------------------------------*
*& Module STATUS_0100 OUTPUT
*&---------------------------------------------------------------------*
MODULE status_0100 OUTPUT.

  SET PF-STATUS 'ST100'.
  SET TITLEBAR  'TB100'.

  IF go_dock IS INITIAL.
    PERFORM build_containers.
    PERFORM build_header.
    PERFORM build_footer.
    PERFORM build_alv.
  ENDIF.

ENDMODULE.

*&---------------------------------------------------------------------*
*& Form BUILD_CONTAINERS
*&---------------------------------------------------------------------*
FORM build_containers.

  CREATE OBJECT go_dock
    EXPORTING
      repid                       = sy-repid
      dynnr                       = sy-dynnr
      side                        = cl_gui_docking_container=>dock_at_left
      extension                   = 2000
      no_autodef_progid_dynnr     = abap_true
    EXCEPTIONS
      cntl_error                  = 1
      cntl_system_error           = 2
      create_error                = 3
      lifetime_error              = 4
      lifetime_dynpro_dynpro_link = 5
      OTHERS                      = 6.
  IF sy-subrc <> 0.
    MESSAGE 'Could not create docking container' TYPE 'E'.
  ENDIF.

  CREATE OBJECT go_split
    EXPORTING
      parent  = go_dock
      rows    = 3
      columns = 1.

* Absolute mode -> heights in pixels. If row 2 collapses on your
* release, drop this call and use percentages instead.
  CALL METHOD go_split->set_row_mode
    EXPORTING mode = cl_gui_splitter_container=>mode_absolute.

  CALL METHOD go_split->set_row_height
    EXPORTING id = 1 height = gc_top_height.

  CALL METHOD go_split->set_row_height
    EXPORTING id = 3 height = gc_bot_height.

  PERFORM lock_sash USING 1.
  PERFORM lock_sash USING 2.

  go_cont_top  = go_split->get_container( row = 1 column = 1 ).
  go_cont_grid = go_split->get_container( row = 2 column = 1 ).
  go_cont_bot  = go_split->get_container( row = 3 column = 1 ).

ENDFORM.

*&---------------------------------------------------------------------*
*& Form LOCK_SASH
*&---------------------------------------------------------------------*
FORM lock_sash USING iv_id TYPE i.

  CALL METHOD go_split->set_row_sash
    EXPORTING id    = iv_id
              type  = cl_gui_splitter_container=>type_movable
              value = cl_gui_splitter_container=>false.

  CALL METHOD go_split->set_row_sash
    EXPORTING id    = iv_id
              type  = cl_gui_splitter_container=>type_sashvisible
              value = cl_gui_splitter_container=>false.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form BUILD_HEADER
*&---------------------------------------------------------------------*
FORM build_header.

  DATA: lv_text TYPE sdydo_text_element,
        lv_icon TYPE iconname,
        lv_num  TYPE char10,
        lv_dat  TYPE char10,
        lv_tim  TYPE char10.

  IF go_dd_top IS INITIAL.
    CREATE OBJECT go_dd_top EXPORTING style = 'ALV_GRID'.
  ENDIF.

  CALL METHOD go_dd_top->initialize_document.

* ---- Line 1 : title + document status
  lv_text = 'Flight Approval Document'.
  CALL METHOD go_dd_top->add_text
    EXPORTING text         = lv_text
              sap_style    = cl_dd_document=>heading
              sap_emphasis = cl_dd_document=>strong.

  CALL METHOD go_dd_top->add_gap EXPORTING width = 25.

  CASE gs_hdr-zstatus.
    WHEN gc_appr.  lv_icon = 'ICON_GREEN_LIGHT'.
    WHEN gc_subm.  lv_icon = 'ICON_YELLOW_LIGHT'.
    WHEN OTHERS.   lv_icon = 'ICON_LIGHT_OUT'.
  ENDCASE.

  CALL METHOD go_dd_top->add_icon
    EXPORTING sap_icon = lv_icon.

  lv_text = gs_hdr-zstatus.
  CALL METHOD go_dd_top->add_text
    EXPORTING text         = lv_text
              sap_emphasis = cl_dd_document=>strong.

  CALL METHOD go_dd_top->new_line.

* ---- Line 2 : selection criteria + row count
  lv_text = gs_hdr-seltext.
  CALL METHOD go_dd_top->add_text
    EXPORTING text = lv_text sap_style = cl_dd_document=>small.

  CALL METHOD go_dd_top->add_gap EXPORTING width = 20.

  WRITE gs_hdr-rowcount TO lv_num LEFT-JUSTIFIED.
  CONCATENATE 'Records in this approval:' lv_num INTO lv_text
         SEPARATED BY space.
  CALL METHOD go_dd_top->add_text
    EXPORTING text         = lv_text
              sap_emphasis = cl_dd_document=>strong.

  CALL METHOD go_dd_top->new_line.

* ---- Line 3 : audit trail
  CLEAR lv_text.
  IF gs_hdr-subm_by IS NOT INITIAL.
    WRITE gs_hdr-subm_date TO lv_dat.
    WRITE gs_hdr-subm_time TO lv_tim.
    CONCATENATE 'Submitted by' gs_hdr-subm_by 'on' lv_dat lv_tim
           INTO lv_text SEPARATED BY space.
  ELSE.
    lv_text = 'Not yet submitted'.
  ENDIF.
  CALL METHOD go_dd_top->add_text
    EXPORTING text = lv_text sap_style = cl_dd_document=>small.

  CALL METHOD go_dd_top->add_gap EXPORTING width = 10.

  CLEAR lv_text.
  IF gs_hdr-appr_by IS NOT INITIAL.
    WRITE gs_hdr-appr_date TO lv_dat.
    WRITE gs_hdr-appr_time TO lv_tim.
    CONCATENATE '| Approved by' gs_hdr-appr_by 'on' lv_dat lv_tim
           INTO lv_text SEPARATED BY space.
    CALL METHOD go_dd_top->add_text
      EXPORTING text = lv_text sap_style = cl_dd_document=>small.
  ENDIF.

  CALL METHOD go_dd_top->merge_document.

  IF gv_top_shown = abap_false.
    CALL METHOD go_dd_top->display_document
      EXPORTING parent = go_cont_top
      EXCEPTIONS OTHERS = 1.
    gv_top_shown = abap_true.
  ELSE.
    CALL METHOD go_dd_top->display_document
      EXPORTING reuse_control = abap_true
                parent        = go_cont_top
      EXCEPTIONS OTHERS = 1.
  ENDIF.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form BUILD_SEL_TEXT
*&---------------------------------------------------------------------*
FORM build_sel_text CHANGING cv_text TYPE string.

  DATA: lv_carr TYPE string,
        lv_date TYPE string,
        lv_lo   TYPE char20,
        lv_hi   TYPE char20.

  IF s_carrid[] IS INITIAL.
    lv_carr = 'All'.
  ELSE.
    READ TABLE s_carrid INDEX 1.
    lv_lo = s_carrid-low.
    IF s_carrid-high IS INITIAL.
      lv_carr = lv_lo.
    ELSE.
      lv_hi = s_carrid-high.
      CONCATENATE lv_lo '-' lv_hi INTO lv_carr SEPARATED BY space.
    ENDIF.
  ENDIF.

  IF s_fldate[] IS INITIAL.
    lv_date = 'All'.
  ELSE.
    READ TABLE s_fldate INDEX 1.
    WRITE s_fldate-low TO lv_lo.
    IF s_fldate-high IS INITIAL.
      lv_date = lv_lo.
    ELSE.
      WRITE s_fldate-high TO lv_hi.
      CONCATENATE lv_lo '-' lv_hi INTO lv_date SEPARATED BY space.
    ENDIF.
  ENDIF.

  CONCATENATE 'Carrier:' lv_carr '|' 'Flight date:' lv_date
         INTO cv_text SEPARATED BY space.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form BUILD_FOOTER
*&---------------------------------------------------------------------*
* One signature block for the whole document. Names and dates fill
* themselves in as the document moves through the statuses.
*&---------------------------------------------------------------------*
FORM build_footer.

  DATA: lo_table TYPE REF TO cl_dd_table_element,
        lo_col1  TYPE REF TO cl_dd_area,
        lo_col2  TYPE REF TO cl_dd_area,
        lv_text  TYPE sdydo_text_element,
        lv_line  TYPE sdydo_text_element,
        lv_dat   TYPE char10.

  lv_line = '____________________________'.

  IF go_dd_bot IS INITIAL.
    CREATE OBJECT go_dd_bot EXPORTING style = 'ALV_GRID'.
  ENDIF.

  CALL METHOD go_dd_bot->initialize_document.

  CALL METHOD go_dd_bot->add_table
    EXPORTING no_of_columns               = 2
              border                      = '0'
              width                       = '100%'
              cell_background_transparent = abap_true
    IMPORTING table                       = lo_table.

  CALL METHOD lo_table->add_column
    EXPORTING width = '50%' IMPORTING column = lo_col1.
  CALL METHOD lo_table->add_column
    EXPORTING width = '50%' IMPORTING column = lo_col2.

* ---- Row 1 : the signer, or a blank line if not signed yet
  IF gs_hdr-subm_by IS NOT INITIAL.
    WRITE gs_hdr-subm_date TO lv_dat.
    CONCATENATE gs_hdr-subm_by '/' lv_dat INTO lv_text
           SEPARATED BY space.
  ELSE.
    lv_text = lv_line.
  ENDIF.
  CALL METHOD lo_col1->add_text EXPORTING text = lv_text.

  IF gs_hdr-appr_by IS NOT INITIAL.
    WRITE gs_hdr-appr_date TO lv_dat.
    CONCATENATE gs_hdr-appr_by '/' lv_dat INTO lv_text
           SEPARATED BY space.
  ELSE.
    lv_text = lv_line.
  ENDIF.
  CALL METHOD lo_col2->add_text EXPORTING text = lv_text.

  CALL METHOD lo_table->new_row.

* ---- Row 2 : roles
  lv_text = 'Submitted by'.
  CALL METHOD lo_col1->add_text
    EXPORTING text = lv_text sap_style = cl_dd_document=>small.

  lv_text = 'Approved by'.
  CALL METHOD lo_col2->add_text
    EXPORTING text = lv_text sap_style = cl_dd_document=>small.

  CALL METHOD go_dd_bot->merge_document.

  IF gv_bot_shown = abap_false.
    CALL METHOD go_dd_bot->display_document
      EXPORTING parent = go_cont_bot
      EXCEPTIONS OTHERS = 1.
    gv_bot_shown = abap_true.
  ELSE.
    CALL METHOD go_dd_bot->display_document
      EXPORTING reuse_control = abap_true
                parent        = go_cont_bot
      EXCEPTIONS OTHERS = 1.
  ENDIF.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form BUILD_ALV
*&---------------------------------------------------------------------*
FORM build_alv.

  DATA: lt_fcat TYPE lvc_t_fcat,
        ls_layo TYPE lvc_s_layo,
        ls_vari TYPE disvariant.

  CREATE OBJECT go_grid
    EXPORTING i_parent = go_cont_grid.

  CREATE OBJECT go_handler.
  SET HANDLER go_handler->on_toolbar           FOR go_grid.
  SET HANDLER go_handler->on_user_command      FOR go_grid.
  SET HANDLER go_handler->on_print_top_of_page FOR go_grid.
  SET HANDLER go_handler->on_print_end_of_list FOR go_grid.

  PERFORM build_fieldcat CHANGING lt_fcat.

* Row selection is meaningless here - the whole list is the document.
  ls_layo-sel_mode   = 'B'.            " single row, navigation only
  ls_layo-no_rowmark = abap_true.      " no selection column
  ls_layo-zebra      = abap_true.
  ls_layo-cwidth_opt = abap_true.

  ls_vari-report = sy-repid.
  ls_vari-handle = 'MAIN'.

  CALL METHOD go_grid->set_table_for_first_display
    EXPORTING is_variant      = ls_vari
              i_save          = 'A'
              is_layout       = ls_layo
    CHANGING  it_fieldcatalog = lt_fcat
              it_outtab       = gt_out.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form BUILD_FIELDCAT
*&---------------------------------------------------------------------*
FORM build_fieldcat CHANGING ct_fcat TYPE lvc_t_fcat.

  DATA: ls_fcat TYPE lvc_s_fcat,
        lv_pos  TYPE i.

  DEFINE add_field.
    lv_pos = lv_pos + 1.
    CLEAR ls_fcat.
    ls_fcat-col_pos   = lv_pos.
    ls_fcat-fieldname = &1.
    ls_fcat-scrtext_l = &2.
    ls_fcat-scrtext_m = &2.
    ls_fcat-scrtext_s = &2.
    ls_fcat-coltext   = &2.
    ls_fcat-outputlen = &3.
    APPEND ls_fcat TO ct_fcat.
  END-OF-DEFINITION.

  add_field 'CARRID'   'Carrier'      8.
  add_field 'CONNID'   'Connection'  10.
  add_field 'FLDATE'   'Flight Date' 12.
  add_field 'PRICE'    'Price'       15.
  add_field 'CURRENCY' 'Curr.'        5.
  add_field 'SEATSOCC' 'Occupied'    10.

  READ TABLE ct_fcat INTO ls_fcat WITH KEY fieldname = 'PRICE'.
  IF sy-subrc = 0.
    ls_fcat-cfieldname = 'CURRENCY'.
    ls_fcat-do_sum     = abap_true.
    MODIFY ct_fcat FROM ls_fcat INDEX sy-tabix.
  ENDIF.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form DO_SUBMIT
*&---------------------------------------------------------------------*
FORM do_submit.

  DATA: lv_answer TYPE char1,
        lv_num    TYPE char10,
        lv_quest  TYPE string.

  IF gs_hdr-zstatus <> gc_new.
    MESSAGE 'Document has already been submitted' TYPE 'S'
            DISPLAY LIKE 'W'.
    RETURN.
  ENDIF.

  WRITE gs_hdr-rowcount TO lv_num LEFT-JUSTIFIED.
  CONCATENATE 'Submit all' lv_num 'records as one approval document?'
         INTO lv_quest SEPARATED BY space.

  PERFORM confirm USING lv_quest CHANGING lv_answer.
  CHECK lv_answer = '1'.

  PERFORM lock_document.
  CHECK sy-subrc = 0.

* ---- freeze the snapshot
  PERFORM calc_checksum CHANGING gs_hdr-checksum.
  DESCRIBE TABLE gt_out LINES gs_hdr-rowcount.

  gs_hdr-zstatus   = gc_subm.
  gs_hdr-subm_by   = sy-uname.
  gs_hdr-subm_date = sy-datum.
  gs_hdr-subm_time = sy-uzeit.

* ------------------------------------------------------------------
* TODO: persist here.
*   - get a document number from NUMBER_GET_NEXT
*   - INSERT the header into z_appr_hdr
*   - INSERT gt_out into z_appr_itm  <-- THE FROZEN SNAPSHOT.
*     This is what makes the approval auditable. Without it you are
*     approving a selection screen, not a set of records.
* ------------------------------------------------------------------

  COMMIT WORK AND WAIT.
  PERFORM unlock_document.

  PERFORM refresh_screen.
  MESSAGE 'Document submitted for approval' TYPE 'S'.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form DO_APPROVE
*&---------------------------------------------------------------------*
FORM do_approve.

  DATA: lv_answer TYPE char1,
        lv_hash   TYPE string,
        lv_count  TYPE i,
        lv_quest  TYPE string.

  IF gs_hdr-zstatus <> gc_subm.
    MESSAGE 'Only a submitted document can be approved' TYPE 'S'
            DISPLAY LIKE 'W'.
    RETURN.
  ENDIF.

* ---- segregation of duties
  IF gc_sod_check = abap_true AND gs_hdr-subm_by = sy-uname.
    MESSAGE 'You cannot approve a document you submitted yourself'
            TYPE 'S' DISPLAY LIKE 'E'.
    RETURN.
  ENDIF.

* ---- authorization
* AUTHORITY-CHECK OBJECT 'Z_APPROVE' ID 'ACTVT' FIELD '43'.
* IF sy-subrc <> 0.
*   MESSAGE 'No approval authorization' TYPE 'S' DISPLAY LIKE 'E'.
*   RETURN.
* ENDIF.

* ---- did the data move between submit and approve?
  PERFORM get_data.
  DESCRIBE TABLE gt_out LINES lv_count.
  PERFORM calc_checksum CHANGING lv_hash.

  IF lv_count <> gs_hdr-rowcount OR lv_hash <> gs_hdr-checksum.
    MESSAGE 'Data changed since submission - resubmit required'
            TYPE 'S' DISPLAY LIKE 'E'.
    PERFORM refresh_screen.
    RETURN.
  ENDIF.

  lv_quest = 'Approve this document in full?'.
  PERFORM confirm USING lv_quest CHANGING lv_answer.
  CHECK lv_answer = '1'.

  PERFORM lock_document.
  CHECK sy-subrc = 0.

  gs_hdr-zstatus   = gc_appr.
  gs_hdr-appr_by   = sy-uname.
  gs_hdr-appr_date = sy-datum.
  gs_hdr-appr_time = sy-uzeit.

* ---- TODO: UPDATE z_appr_hdr with status / approver / timestamp

  COMMIT WORK AND WAIT.
  PERFORM unlock_document.

  PERFORM refresh_screen.
  MESSAGE 'Document approved' TYPE 'S'.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form CONFIRM
*&---------------------------------------------------------------------*
FORM confirm USING iv_question TYPE string
             CHANGING cv_answer TYPE char1.

  DATA: lv_q TYPE string.

  lv_q = iv_question.

  CALL FUNCTION 'POPUP_TO_CONFIRM'
    EXPORTING
      titlebar              = 'Confirm'
      text_question         = lv_q
      text_button_1         = 'Yes'
      text_button_2         = 'No'
      default_button        = '2'
      display_cancel_button = abap_false
    IMPORTING
      answer                = cv_answer
    EXCEPTIONS
      OTHERS                = 1.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form LOCK_DOCUMENT / UNLOCK_DOCUMENT
*&---------------------------------------------------------------------*
* One lock for the whole document, not one per row.
*&---------------------------------------------------------------------*
FORM lock_document.

* CALL FUNCTION 'ENQUEUE_EZ_APPR_HDR'
*   EXPORTING  docno          = gs_hdr-docno
*   EXCEPTIONS foreign_lock   = 1
*              system_failure = 2
*              OTHERS         = 3.
* IF sy-subrc <> 0.
*   MESSAGE 'Document is locked by another user' TYPE 'S'
*           DISPLAY LIKE 'E'.
* ENDIF.

  sy-subrc = 0.

ENDFORM.

FORM unlock_document.

* CALL FUNCTION 'DEQUEUE_EZ_APPR_HDR'
*   EXPORTING docno = gs_hdr-docno.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form REFRESH_SCREEN
*&---------------------------------------------------------------------*
FORM refresh_screen.

  DATA: ls_stable TYPE lvc_s_stbl.

  PERFORM build_header.
  PERFORM build_footer.

  ls_stable-row = abap_true.
  ls_stable-col = abap_true.
  CALL METHOD go_grid->refresh_table_display
    EXPORTING is_stable = ls_stable.

* forces the TOOLBAR event to fire again so button states update
  CALL METHOD go_grid->set_toolbar_interactive.

ENDFORM.

*&---------------------------------------------------------------------*
*& Module USER_COMMAND_0100 INPUT
*&---------------------------------------------------------------------*
MODULE user_command_0100 INPUT.

  DATA: lv_ucomm TYPE sy-ucomm.

  lv_ucomm = gv_ok_code.
  CLEAR gv_ok_code.

  CASE lv_ucomm.
    WHEN 'BACK' OR 'EXIT' OR 'CANC'.
      PERFORM free_controls.
      LEAVE TO SCREEN 0.
  ENDCASE.

ENDMODULE.

*&---------------------------------------------------------------------*
*& Form FREE_CONTROLS
*&---------------------------------------------------------------------*
FORM free_controls.

  IF go_grid IS NOT INITIAL.
    CALL METHOD go_grid->free.
    CLEAR go_grid.
  ENDIF.

  IF go_split IS NOT INITIAL.
    CALL METHOD go_split->free.
    CLEAR go_split.
  ENDIF.

  IF go_dock IS NOT INITIAL.
    CALL METHOD go_dock->free.
    CLEAR go_dock.
  ENDIF.

  CLEAR: go_cont_top, go_cont_grid, go_cont_bot,
         go_dd_top, go_dd_bot, gv_top_shown, gv_bot_shown.

  CALL METHOD cl_gui_cfw=>flush.

ENDFORM.

*&---------------------------------------------------------------------*
*& CLASS lcl_event_handler IMPLEMENTATION
*&---------------------------------------------------------------------*
CLASS lcl_event_handler IMPLEMENTATION.

  METHOD on_toolbar.

    DATA: ls_btn TYPE stb_button.

    CLEAR ls_btn.
    ls_btn-butn_type = 3.                       " separator
    APPEND ls_btn TO e_object->mt_toolbar.

*   ---- SUBMIT : only while the document is NEW
    CLEAR ls_btn.
    ls_btn-function  = 'SUBMIT'.
    ls_btn-icon      = icon_system_save.
    ls_btn-text      = 'Submit'.
    ls_btn-quickinfo = 'Submit the entire list for approval'.
    ls_btn-butn_type = 0.
    IF gs_hdr-zstatus <> gc_new.
      ls_btn-disabled = abap_true.
    ENDIF.
    APPEND ls_btn TO e_object->mt_toolbar.

*   ---- APPROVE : only while the document is SUBMITTED
    CLEAR ls_btn.
    ls_btn-function  = 'APPROVE'.
    ls_btn-icon      = icon_okay.
    ls_btn-text      = 'Approve'.
    ls_btn-quickinfo = 'Approve the entire document'.
    ls_btn-butn_type = 0.
    IF gs_hdr-zstatus <> gc_subm.
      ls_btn-disabled = abap_true.
    ENDIF.
    IF gc_sod_check = abap_true AND gs_hdr-subm_by = sy-uname.
      ls_btn-disabled = abap_true.
    ENDIF.
    APPEND ls_btn TO e_object->mt_toolbar.

  ENDMETHOD.

  METHOD on_user_command.

    CASE e_ucomm.
      WHEN 'SUBMIT'.  PERFORM do_submit.
      WHEN 'APPROVE'. PERFORM do_approve.
    ENDCASE.

  ENDMETHOD.

* --------------------------------------------------------------------
* The splitter header/footer are SCREEN ONLY. These handlers put the
* same content on the printout - which is where a signature block
* normally has to end up.
* --------------------------------------------------------------------
  METHOD on_print_top_of_page.

    WRITE: / 'Flight Approval Document'.
    WRITE: / gs_hdr-seltext.
    WRITE: / 'Records:', gs_hdr-rowcount,
             '  Status:', gs_hdr-zstatus.
    ULINE.

  ENDMETHOD.

  METHOD on_print_end_of_list.

    SKIP 3.
    WRITE: /5 '____________________________',
           60 '____________________________'.
    WRITE: /5 'Submitted by', 60 'Approved by'.

    IF gs_hdr-subm_by IS NOT INITIAL.
      WRITE: /5 gs_hdr-subm_by, gs_hdr-subm_date.
    ENDIF.
    IF gs_hdr-appr_by IS NOT INITIAL.
      WRITE: 60 gs_hdr-appr_by, gs_hdr-appr_date.
    ENDIF.

  ENDMETHOD.

ENDCLASS.

*&---------------------------------------------------------------------*
* WHAT YOU STILL HAVE TO CREATE MANUALLY
*&---------------------------------------------------------------------*
* 1) Screen 0100 (SE51/SE80, type "Normal", layout EMPTY):
*      PROCESS BEFORE OUTPUT.
*        MODULE status_0100.
*      PROCESS AFTER INPUT.
*        MODULE user_command_0100.
*    Element list: GV_OK_CODE, type OK, length 20.
*
* 2) GUI status 'ST100' with BACK / EXIT / CANC only.
*
* 3) Title 'TB100'.  Text symbol text-b01 = 'Selection'.
*
* 4) Two Z-tables (this is the part that actually matters):
*      Z_APPR_HDR - docno, status, seltext, rowcount, checksum,
*                   subm_by/date/time, appr_by/date/time
*      Z_APPR_ITM - docno, posnr, + the key fields of each row
*    plus lock object EZ_APPR_HDR on Z_APPR_HDR.
*&---------------------------------------------------------------------*

Post navigation

SAP ABAP – ALV with Dock Header and Footer

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • SAP ABAP – ALV Dock with Approval 2 Columns
  • SAP ABAP – ALV with Dock Header and Footer
  • SAP ABAP Fast Coding With This Template – Editable ALV With Events
  • SAP ABAP – Generate Fiori URL
  • SAP ABAP – Workflow Agents CDS

Recent Comments

  1. SAP ABAP – Simple Interface FTP Inbound (SAP Consume File From FTP) – SAP ABAP DWIMAN on SAP ABAP – String Encode & Decode BASE64
  2. Upload file – SAP ABAP DWIMAN on F4 Search Help File

Archives

  • August 2026
  • July 2026
  • May 2025
  • August 2024
  • June 2024
  • May 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • May 2023
  • April 2023

Categories

  • Uncategorized
©2026 SAP ABAP DWIMAN | WordPress Theme by SuperbThemes.com