Thursday, 25 August 2016

PO Ack Audit report

This report searches for POs receiving multiple acknowledgements and PO receiving no acknowledgements and send them as email attachment. The program is designed to run in background as well as foreground.


REPORT  /XXXXXX/ssd005 NO STANDARD PAGE HEADING.

INCLUDE /XXXXXX/ssd005_top.            " Data Declarations
INCLUDE /XXXXXX/ssd005_sel.            " Selection Screen Definition
INCLUDE /XXXXXX/ssd005_routine.        " Subroutines

***********************************************************************
* INITIALIZATION
***********************************************************************
INITIALIZATION.
* Include to implement LCL_EMAIL class
  INCLUDE /XXXXXX/ssd005_lcl_email_imp.

***********************************************************************
*  Validations                                                        *
***********************************************************************
AT SELECTION-SCREEN ON s_ekorg.
  PERFORM validate_pur_org.

AT SELECTION-SCREEN ON s_bukrs.
  PERFORM validate_com_code.

AT SELECTION-SCREEN ON s_ebeln.
  PERFORM validate_pur_order.

AT SELECTION-SCREEN ON s_lifnr.
  PERFORM validate_vendor.

AT SELECTION-SCREEN ON s_ekgrp.
  PERFORM validate_pur_group .

AT SELECTION-SCREEN ON p_ebtyp.
  PERFORM validate_confm_cat.

AT SELECTION-SCREEN on s_bsart.
  PERFORM validate_ord_type.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_layout.
  PERFORM sub_f4_layout USING    if_salv_c_layout=>restrict_none
                        CHANGING p_layout.
***********************************************************************
* START-OF-SELECTION
***********************************************************************
START-OF-SELECTION.
  PERFORM get_data.

***********************************************************************
* END-OF-SELECTION
***********************************************************************
END-OF-SELECTION.
  PERFORM process_data.
  if gt_po_data is not INITIAL.
  if sy-batch 'X'.
    CALL SCREEN 9001.
    CALL SCREEN 9002.
  ELSEIF SY-BATCH ' '.
*create screen, go to layout, create custom control, provide name CONTAINER
  CALL SCREEN 9000.

  ENDIF.
  else.
    MESSAGE text-T13 type 'I'.
    LEAVE LIST-PROCESSING.
  endif.

**********************************************************************
include /XXXXXX/SSD005_TOP

**********************************************************************
***********************************************************************
* Type Declarations
***********************************************************************
TYPES:
* Strcture type to declare selection screen
  BEGIN OF t_sel,
    ekorg TYPE ekko-ekorg,              " Purchasing organization
    ekgrp TYPE ekko-ekgrp,              " Purchasing Group
    bukrs TYPE ekko-bukrs,              " Company code
    lifnr TYPE ekko-lifnr,              " Vendor Account Number
    aedat TYPE ekko-aedat,              " Created on
    ebeln TYPE ekko-ebeln,              " Purchase Order
    ebtyp TYPE ekes-ebtyp,              " Confirmation Category
    mail  TYPE ad_smtpadr,              " Email Address
    bsart type ekko-bsart,             
  END OF t_sel,

  BEGIN OF t_po_data,
    ebeln TYPE ebeln,                  " Purchase Order
    aedat TYPE paedt,                  " Created on
    lifnr TYPE lifnr,                  " Vendor Account Number
    ebelp TYPE ebelp,                  " Item
    matnr TYPE matnr,                  " Material
    menge TYPE bstmg,                  " Quantity
  END OF t_po_data,

  BEGIN OF t_ekes,
    ebeln TYPE ebeln,                  " Purchase Order
    ebelp TYPE ebelp,                  " Item
    etens TYPE etens,                  " Sequential Number
    ebtyp TYPE ebtyp,                  " Confirmation Category
  END OF t_ekes.

***********************************************************************
* Work areas
***********************************************************************
DATA:
* Work area to declare selection screen
  gw_sel        TYPE t_sel,
  gw_ekes       TYPE t_ekes,
  gw_po_data    TYPE t_po_data,
  gw_po_ack     TYPE t_po_data,
  gw_no_po_ack  TYPE t_po_data,
  gw_count      TYPE i,
  gw_key        TYPE salv_s_layout_key.

***********************************************************************
* Internal tables
***********************************************************************
DATA:
  gt_ekes   TYPE STANDARD TABLE
              OF t_ekes,
  gt_po_data TYPE STANDARD TABLE
               OF t_po_data,
  gt_po_ack TYPE STANDARD TABLE
               OF t_po_data,
  gt_po_ack_tmp TYPE STANDARD TABLE
               OF t_po_data,
  gt_no_po_ack TYPE STANDARD TABLE
               OF t_po_data.

* Define local class
CLASS lcl_email DEFINITION FINAL.
  PUBLIC SECTION.
    CLASS-METHODSsend_email IMPORTING
                               im_name            TYPE any
                               im_typ             TYPE char1
                               im_title           TYPE any
                               im_langu           TYPE sylangu
                               im_format          TYPE char1
                               im_attachment_type TYPE soodk-objtp
                               im_doc_type        TYPE so_obj_tp.
          ENDCLASS.                    "lcl_email DEFINITION

DATA:
  go_custom TYPE REF TO cl_gui_custom_container,
  go_docking1 type ref to cl_gui_docking_container,
  go_docking2 type ref to cl_gui_docking_container,
  go_split  TYPE REF TO cl_gui_splitter_container,
  go_grid1  TYPE REF TO cl_gui_container,
  go_grid2  TYPE REF TO cl_gui_container,
  go_salv1  TYPE REF TO cl_salv_table,
  go_salv2  TYPE REF TO cl_salv_table,
  go_email  TYPE REF TO lcl_email,
  go_layout TYPE REF TO cl_salv_layout,
  go_func1  TYPE REF TO cl_salv_functions,
  go_func2  TYPE REF TO cl_salv_functions,

  go_display1   type ref to cl_salv_display_settings,
  go_display2   type ref to cl_salv_display_settings.
**********************************************************************
include /XXXXXX/SSD005_SEL

**********************************************************************
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-t01.
SELECT-OPTIONS:
  s_ekorg FOR gw_sel-ekorg,            " Purchasing Organization
  s_ekgrp FOR gw_sel-ekgrp,            " Purchasing Group
  s_bukrs FOR gw_sel-bukrs,            " Company code
  s_lifnr FOR gw_sel-lifnr,            " Vendor
  s_aedat FOR gw_sel-aedat,            " PO Date
  s_ebeln FOR gw_sel-ebeln,            " Purchase Order
  s_bsart FOR gw_sel-bsart.            " DEVK9A02KT 14-06-2016
PARAMETERS
  p_ebtyp TYPE ekes-ebtyp              " Confirmation Category
               DEFAULT 'AB' OBLIGATORY.
SELECTION-SCREEN END OF BLOCK b1.

SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE text-t02.
SELECT-OPTIONS
  s_mail FOR gw_sel-mail               " Recipient Address
             NO INTERVALS.
SELECTION-SCREEN END OF BLOCK b2.

SELECTION-SCREEN BEGIN OF BLOCK b3 WITH FRAME TITLE text-t10.
PARAMETERS
  p_layout TYPE disvariant-variant.    " Layout
SELECTION-SCREEN END OF BLOCK b3.


**********************************************************************
include /XXXXXX/SSD005_ROUTINE

**********************************************************************
*&--------------------------------------------------------------------*
*&      Module  STATUS_9000  OUTPUT
*---------------------------------------------------------------------*
*       text
*---------------------------------------------------------------------*
MODULE status_9000 OUTPUT.
*Click on PF status to create it,expand application, provide SAVE, BACK, EXIT, EXIT
  SET PF-STATUS 'ST9000'.
*Click title to create it, provide meaningful title
  SET TITLEBAR 'TI9000'.


  IF go_custom IS INITIAL.

*      if cl_gui_alv_grid=>offline( ) is initial.

    CREATE OBJECT go_custom
      EXPORTING
        container_name              'CONTAINER'
      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 ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*            WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.


*      create object go_grid1
*exporting i_parent = go_custom.
*
*      else.
*        create object go_grid1
*exporting i_parent = go_docking1.
*
*
*    ENDIF.
  ENDIF.

  IF go_split IS INITIAL.
    CREATE OBJECT go_split
      EXPORTING
        parent            go_custom
        rows              2
        columns           1
      EXCEPTIONS
        cntl_error        1
        cntl_system_error 2
        OTHERS            3.
    IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*            WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.
  ENDIF.

  CALL METHOD go_split->get_container
    EXPORTING
      row       1
      column    1
    RECEIVING
      container go_grid1.
  CALL METHOD go_split->get_container
    EXPORTING
      row       2
      column    1
    RECEIVING
      container go_grid2.
*TRY.
  CALL METHOD cl_salv_table=>factory
    EXPORTING
*     list_display = IF_SALV_C_BOOL_SAP=>FALSE
      r_container  go_grid1
    IMPORTING
      r_salv_table go_salv1
    CHANGING
      t_table      gt_no_po_ack.
* CATCH cx_salv_msg .
*ENDTRY.
* Get Object Reference to the Tool Bar Functions
  CALL METHOD go_salv1->get_functions
    RECEIVING
      value go_func1.

* Activate all ALV Tool Bar Functions
  CALL METHOD go_func1->set_all
    EXPORTING
      value if_salv_c_bool_sap=>true.

  go_display1 go_salv1->get_display_settings).
  go_display1->set_list_headertext-t16 ).

* This is for the ALV Layout Functions
* -----------------------------------------
* Get the Object Reference for the ALV Layout
  CALL METHOD go_salv1->get_layout
    RECEIVING
      value go_layout.
* Set the Key
  gw_key-report sy-repid.
  go_layout->set_keygw_key ).
* Set the Save Layout Option
  go_layout->set_save_restriction(
                      if_salv_c_layout=>restrict_none ).
* Activate Option of Saving Default Setting
  go_layout->set_defaultabap_true ).
* If there is a Selection Screen Entry for Layout then Set The Layout
  IF NOT p_layout IS INITIAL.
    go_layout->set_initial_layoutp_layout ).
  ENDIF.

*TRY.
  CALL METHOD cl_salv_table=>factory
    EXPORTING
*     list_display   = IF_SALV_C_BOOL_SAP=>FALSE
      r_container    go_grid2
*     container_name =
    IMPORTING
      r_salv_table   go_salv2
    CHANGING
      t_table        gt_po_ack.
* CATCH cx_salv_msg .
*ENDTRY.

* Get Object Reference to the Tool Bar Functions
  CALL METHOD go_salv2->get_functions
    RECEIVING
      value go_func2.

* Activate all ALV Tool Bar Functions
  CALL METHOD go_func2->set_all
    EXPORTING
      value if_salv_c_bool_sap=>true.

  go_display2 go_salv2->get_display_settings).
  go_display2->set_list_headertext-t15 ).

  CALL METHOD go_salv1->display.
  CALL METHOD go_salv2->display.
  PERFORM send_mail.
ENDMODULE.                             " STATUS_9000  OUTPUT

*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_9000  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE user_command_9000 INPUT.
  CASE sy-ucomm.
    WHEN 'BACK' OR 'EXIT'.
      LEAVE TO SCREEN 0.
  ENDCASE.
ENDMODULE.                             " USER_COMMAND_9000  INPUT

*&---------------------------------------------------------------------*
*&      Module  STATUS_9001  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE status_9001 OUTPUT.
  SET PF-STATUS 'ST9001'.
  SET TITLEBAR 'TI9001'.

  IF cl_gui_alv_grid=>offlineIS INITIAL.
    IF go_docking1 IS INITIAL.
      CREATE OBJECT go_docking1
        EXPORTING
          repid     sy-repid
          ratio     50
          dynnr     '9001'
          side      cl_gui_docking_container=>dock_at_top
          extension 100.

    ENDIF.



  ENDIF.


*CREATE OBJECT go_split
*      EXPORTING
*        parent  = go_docking1
*        rows    = 2
*        columns = 1.


* TRY.
  CALL METHOD cl_salv_table=>factory
    EXPORTING
      r_container  go_docking1
    IMPORTING
      r_salv_table go_salv1
    CHANGING
      t_table      gt_no_po_ack.
* CATCH cx_salv_msg .
*ENDTRY.
* Get Object Reference to the Tool Bar Functions
  CALL METHOD go_salv1->get_functions
    RECEIVING
      value go_func1.

* Activate all ALV Tool Bar Functions
  CALL METHOD go_func1->set_all
    EXPORTING
      value if_salv_c_bool_sap=>true.

  go_display1 go_salv1->get_display_settings).
  go_display1->set_list_headertext-t16 ).

* This is for the ALV Layout Functions
* -----------------------------------------
* Get the Object Reference for the ALV Layout
  CALL METHOD go_salv1->get_layout
    RECEIVING
      value go_layout.
* Set the Key
  gw_key-report sy-repid.
  go_layout->set_keygw_key ).
* Set the Save Layout Option
  go_layout->set_save_restriction(
                      if_salv_c_layout=>restrict_none ).
* Activate Option of Saving Default Setting
  go_layout->set_defaultabap_true ).
* If there is a Selection Screen Entry for Layout then Set The Layout
  IF NOT p_layout IS INITIAL.
    go_layout->set_initial_layoutp_layout ).
  ENDIF.

  CALL METHOD go_salv1->display.
ENDMODULE.                 " STATUS_9001  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_9001  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE user_command_9001 INPUT.

  CASE sy-ucomm.
    WHEN 'BACK' OR 'EXIT'.
      LEAVE TO SCREEN 0.
  ENDCASE.

ENDMODULE.                 " USER_COMMAND_9001  INPUT

*---------------------------------------------------------------------*
*  Form  GET_DATA                                                     *
*---------------------------------------------------------------------*
*  This subroutine is used to retrieve data from purchase order tables*
*---------------------------------------------------------------------*
FORM get_data .
* Read data from EKKO and EKPO by passing values from the selectionscreen
  SELECT ekko~ebeln
         ekko~aedat
         ekko~lifnr
         ekpo~ebelp
         ekpo~matnr
         ekpo~menge
    INTO TABLE gt_po_data
    FROM ekko INNER JOIN  ekpo
      ON ekko~ebeln EQ ekpo~ebeln
   WHERE ekko~ebeln IN s_ebeln
     AND ekko~bukrs IN s_bukrs
     AND ekko~bsart IN s_bsart    
     AND ekko~aedat IN s_aedat
     AND ekko~lifnr IN s_lifnr
     AND ekko~ekorg IN s_ekorg
     AND ekko~ekgrp IN s_ekgrp.
  IF sy-subrc EQ 0.
    SORT gt_po_data.
  ENDIF.
  IF gt_po_data IS NOT INITIAL.
    SELECT ebeln
           ebelp
           etens
           ebtyp
      INTO TABLE gt_ekes
      FROM ekes
      FOR ALL ENTRIES IN gt_po_data
      WHERE ebeln EQ gt_po_data-ebeln
        AND ebelp EQ gt_po_data-ebelp
        AND ebtyp EQ p_ebtyp.
  ENDIF.
ENDFORM.                               " GET_DATA

*---------------------------------------------------------------------*
*  Form  SEND_MAIL                                                    *
*---------------------------------------------------------------------*
*  This form is used for sending mail                                 *
*---------------------------------------------------------------------*
FORM send_mail .
  CREATE OBJECT go_email.
  IF go_email IS BOUND.
    CALL METHOD go_email->send_email
      EXPORTING
        im_name            s_mail
        im_typ             'U'
        im_title           text-t03
        im_langu           sy-langu
        im_format          'E'
        im_attachment_type 'XLS'
        im_doc_type        'RAW'.
  ENDIF.
ENDFORM.                               " SEND_MAIL

*---------------------------------------------------------------------*
*  Form  PROCESS_DATA                                                 *
*---------------------------------------------------------------------*
*  This subroutine is used for populating final data                  *
*---------------------------------------------------------------------*
FORM process_data .

  LOOP AT gt_po_data INTO gw_po_data.
    READ TABLE gt_ekes INTO gw_ekes WITH KEY ebeln gw_po_data-ebeln
                                            ebelp gw_po_data-ebelp
                                      BINARY SEARCH.
    IF sy-subrc EQ 0.
*Logic to ppopulate multiple ack
      LOOP AT gt_ekes INTO gw_ekes FROM sy-tabix.
        IF gw_ekes-ebeln gw_po_data-ebeln
        AND gw_ekes-ebelp gw_po_data-ebelp.
          gw_count gw_count + 1.
          gw_po_ack-ebeln gw_po_data-ebeln.
          gw_po_ack-ebelp gw_po_data-ebelp.
          gw_po_ack-aedat gw_po_data-aedat.
          gw_po_ack-matnr gw_po_data-matnr.
          gw_po_ack-menge gw_po_data-menge.
          gw_po_ack-lifnr gw_po_data-lifnr.
          APPEND gw_po_ack TO gt_po_ack_tmp.
          AT END OF ebelp.
            IF gw_count > 1.
              APPEND LINES OF gt_po_ack_tmp TO gt_po_ack.
              CLEARgw_countgw_po_ack.
              REFRESH gt_po_ack_tmp.
            ELSE.
              CLEARgw_countgw_po_ack.
              REFRESH gt_po_ack_tmp.
            ENDIF.
          ENDAT.
        ELSE.
          CLEARgw_countgw_po_ack.
          REFRESH gt_po_ack_tmp.
          EXIT.
        ENDIF.
      ENDLOOP.

    ELSE.
*Logic for no ack
      gw_no_po_ack-ebeln gw_po_data-ebeln.
      gw_no_po_ack-ebelp gw_po_data-ebelp.
      gw_no_po_ack-aedat gw_po_data-aedat.
      gw_no_po_ack-matnr gw_po_data-matnr.
      gw_no_po_ack-menge gw_po_data-menge.
      gw_no_po_ack-lifnr gw_po_data-lifnr.
      APPEND gw_no_po_ack TO gt_no_po_ack.
      CLEAR gw_no_po_ack.
    ENDIF.

  ENDLOOP.

ENDFORM.                               " PROCESS_DATA

*---------------------------------------------------------------------*
*  Form  SUB_VALIDATE_PUR_GROUP                                       *
*---------------------------------------------------------------------*
*  This subroutine is for validating purchasing group                 *
*---------------------------------------------------------------------*
FORM validate_pur_group .
  IF NOT s_ekgrp  IS INITIAL.
    SELECT SINGLE ekgrp
      FROM t024
      INTO gw_sel-ekgrp
      WHERE ekgrp IN s_ekgrp[].
    IF sy-subrc <> 0.
      MESSAGE text-t04 TYPE 'E'.
    ENDIF.
  ENDIF.
ENDFORM.                               " VALIDATE_PUR_GROUP

*---------------------------------------------------------------------*
*  Form VALIDATE_COMP_CODE                                            *
*---------------------------------------------------------------------*
*  This subroutine is used to validate company code                   *
*---------------------------------------------------------------------*
FORM validate_com_code .
  IF NOT s_bukrs  IS INITIAL.
    SELECT SINGLE bukrs
      INTO gw_sel-bukrs
      FROM t001
     WHERE bukrs IN s_bukrs[].
    IF sy-subrc <> 0.
      MESSAGE text-t05 TYPE 'E'.
    ENDIF.
  ENDIF.
ENDFORM.                               " VALIDATE_COM_CODE

*---------------------------------------------------------------------*
*  Form  VALIDATE_VENDOR                                              *
*---------------------------------------------------------------------*
*  This subroutine is used to validate vendor account no              *
*---------------------------------------------------------------------*
FORM validate_vendor .
  IF NOT s_lifnr  IS INITIAL.
    SELECT SINGLE lifnr
      INTO gw_sel-lifnr
      FROM lfa1
     WHERE lifnr IN s_lifnr[].
    IF sy-subrc <> 0.
      MESSAGE text-t06 TYPE 'E'.
    ENDIF.
  ENDIF.
ENDFORM.                               " VALIDATE_VENDOR

*---------------------------------------------------------------------*
*  Form  VALIDATE_PUR_ORDER                                           *
*---------------------------------------------------------------------*
*  This subroutine is used to validate purchase order                 *
*---------------------------------------------------------------------*
FORM validate_pur_order .
  IF NOT s_ebeln  IS INITIAL.
    SELECT SINGLE ebeln
      INTO gw_sel-ebeln
      FROM ekko
     WHERE ebeln IN s_ebeln[].
    IF sy-subrc <> 0.
      MESSAGE text-t07 TYPE 'E'.
    ENDIF.
  ENDIF.
ENDFORM.                               " VALIDATE_PUR_ORDER

*---------------------------------------------------------------------*
*  Form  VALIDATE_PUR_ORG                                             *
*---------------------------------------------------------------------*
*  This subroutine is used to validate purchasing organisation        *
*---------------------------------------------------------------------*
FORM validate_pur_org .
  IF NOT s_ekorg  IS INITIAL.
    SELECT SINGLE ekorg
      INTO gw_sel-ekorg
      FROM t024e
     WHERE ekorg IN s_ekorg[].
    IF sy-subrc <> 0.
      MESSAGE text-t08 TYPE 'E'.
    ENDIF.
  ENDIF.
ENDFORM.                               " VALIDATE_PUR_ORG

*---------------------------------------------------------------------*
*  Form  VALIDATE_CONFM_CAT                                           *
*---------------------------------------------------------------------*
*  This subroutine is used to validate confirmation category          *
*---------------------------------------------------------------------*
FORM validate_confm_cat .
  IF NOT p_ebtyp  IS INITIAL.
    SELECT SINGLE ebtyp
      INTO gw_sel-ebtyp
      FROM t163e
     WHERE ebtyp EQ p_ebtyp.
    IF sy-subrc <> 0.
      MESSAGE text-t09 TYPE 'E'.
    ENDIF.
  ENDIF.
ENDFORM.                    " VALIDATE_CONFM_CAT

*---------------------------------------------------------------------*
*   Form  SUB_F4_LAYOUT                                               *
*---------------------------------------------------------------------*
*   This subroutine is for providing f4 help for layout               *
*---------------------------------------------------------------------*
*   -->P_IF_SALV_C_LAYOUT=>RESTRICT_NON  text                         *
*   <--P_P_LAYOUT  text                                               *
*---------------------------------------------------------------------*
FORM sub_f4_layout USING    im_restrict TYPE salv_de_layout_restriction
                  CHANGING  ch_layout   TYPE disvariant-variant.

  DATA:
    lw_layout TYPE salv_s_layout_info,
    lw_key    TYPE salv_s_layout_key.

  lw_key-report sy-repid.
  lw_layout cl_salv_layout_service=>f4_layouts(
               s_key    lw_key
               restrict im_restrict ).

  ch_layout lw_layout-layout.

ENDFORM.                               " SUB_F4_LAYOUT

*&---------------------------------------------------------------------*
*&      Form  VALIDATE_ORD_TYPE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM validate_ord_type .
  IF NOT s_bsart  IS INITIAL.
    SELECT bsart UP TO ROWS
      INTO gw_sel-bsart
      FROM t161
     WHERE bsart IN s_bsart[].
      IF sy-subrc <> 0.
        MESSAGE text-t14 TYPE 'E'.
      ENDIF.
    ENDSELECT.
  ENDIF.
ENDFORM.                               " VALIDATE_ORD_TYPE
*&---------------------------------------------------------------------*
*&      Module  STATUS_9002  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE status_9002 OUTPUT.
  SET PF-STATUS 'ST9002'.
  SET TITLEBAR 'TI9001'.
  IF cl_gui_alv_grid=>offlineIS INITIAL.
    IF go_docking2 IS INITIAL.
      CREATE OBJECT go_docking2
        EXPORTING
          repid     sy-repid
          dynnr     '9001'
          side      cl_gui_docking_container=>dock_at_bottom
          extension 1000.

    ENDIF.
  ENDIF.
*TRY.
  CALL METHOD cl_salv_table=>factory
    EXPORTING
*     list_display   = IF_SALV_C_BOOL_SAP=>FALSE
      r_container    go_docking2
*     container_name =
    IMPORTING
      r_salv_table   go_salv2
    CHANGING
      t_table        gt_po_ack.
* CATCH cx_salv_msg .
*ENDTRY.

* Get Object Reference to the Tool Bar Functions
  CALL METHOD go_salv2->get_functions
    RECEIVING
      value go_func2.

* Activate all ALV Tool Bar Functions
  CALL METHOD go_func2->set_all
    EXPORTING
      value if_salv_c_bool_sap=>true.

  go_display2 go_salv2->get_display_settings).
  go_display2->set_list_headertext-t15 ).

  PERFORM send_mail.
  CALL METHOD go_salv2->display.

ENDMODULE.                 " STATUS_9002  OUTPUT

*&---------------------------------------------------------------------*
*&  Include           /XXXXXX/SSD005_LCL_EMAIL_IMP
*&---------------------------------------------------------------------*
*----------------------------------------------------------------------*
*       CLASS lcl_email IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_email IMPLEMENTATION.

  METHOD send_email.
    DATA:
      lt_messages        TYPE STANDARD TABLE OF solisti1,
      lt_receivers       TYPE STANDARD TABLE OF somlrec90,
      lt_field_cat       TYPE lvc_t_fcat,

      la_message         LIKE LINE OF lt_messages,
      la_title           TYPE sodocchgi1,

      lt_choice          TYPE if_salv_bs_xml=>t_type_xml_choice,
      ls_choice          TYPE if_salv_bs_xml=>s_type_xml_choice,
      r_result_data      TYPE REF TO cl_salv_ex_result_data_table,
      lr_data            TYPE REF TO data,
      l_xml              TYPE xstring,
      l_version          TYPE string,
      l_just             TYPE text6,
      l_value            TYPE text200,

      r_columns          TYPE REF TO cl_salv_columns_table,
      r_aggregations     TYPE REF TO cl_salv_aggregations,
      r_table            TYPE REF TO data,
      r_filters          TYPE REF TO cl_salv_filters,

      lo_send_request    TYPE REF TO cl_bcs,
      lo_document        TYPE REF TO cl_document_bcs,
      lo_recipient       TYPE REF TO if_recipient_bcs,
      lo_bcs_exception   TYPE REF TO cx_bcs,
      lo_sender          TYPE REF TO cl_sapuser_bcs,
      lv_currency        TYPE waers,
      lv_unit            TYPE meins,
      lv_receiver        TYPE so_name,
      lv_email_subject   TYPE so_obj_des,
      lv_gentext         TYPE itex132,
      lv_binary_content  TYPE solix_tab,
      lv_binary_content2 TYPE solix_tab,
      lv_size            TYPE so_obj_len,
      lv_size2           TYPE so_obj_len,
      lv_length          TYPE i,
      lv_sent_to_all     TYPE os_boolean,
      lv_distlst         TYPE so_obj_nam,
      lv_mailto          TYPE ad_smtpadr,
      lv_email_sent      TYPE os_boolean,
      lv_user            TYPE sy-uname,
      lv_attach_name     TYPE so_obj_des.

    FIELD-SYMBOLS :
      <field_cat>       LIKE LINE OF lt_field_cat.

*Attachment for no Ack
* Convert ALV in current layout to Excel and send as attachement

    IF go_salv1 IS BOUND.
      CALL METHOD go_salv1->get_columns
        RECEIVING
          value r_columns.
    ENDIF.

    lt_field_cat cl_salv_controller_metadata=>get_lvc_fieldcatalog(
      r_columns      r_columns
      r_aggregations r_aggregations ).

    SORT lt_field_cat BY no_out col_pos.

    LOOP AT lt_field_cat ASSIGNING <field_cat>
                                WHERE no_out  ' '
                                AND   hotspot 'X'.
      CLEAR <field_cat>-hotspot.
      MODIFY lt_field_cat FROM <field_cat> TRANSPORTING hotspot.
    ENDLOOP.

* Use Excel .XLSX format.
    lt_choice cl_salv_export_xml_dialog=>get_gui_spreadsheet_formats(  ).
    READ TABLE lt_choice INTO ls_choice
         WITH KEY xml_type '10'.

    GET REFERENCE OF gt_no_po_ack INTO lr_data.


    r_result_data cl_salv_ex_util=>factory_result_data_table(
     r_data                      lr_data
     t_fieldcatalog              lt_field_cat ).

    CASE cl_salv_bs_a_xml_base=>get_version).
      WHEN if_salv_bs_xml=>version_25.
        l_version                if_salv_bs_xml=>version_25.
      WHEN if_salv_bs_xml=>version_26.
        l_version                if_salv_bs_xml=>version_26.
    ENDCASE.

    CALL METHOD cl_salv_bs_tt_util=>if_salv_bs_tt_util~transform
      EXPORTING
        xml_type      ls_choice-xml_type
        xml_version   l_version
        r_result_data r_result_data
        xml_flavour   if_salv_bs_c_tt=>c_tt_xml_flavour_export
      IMPORTING
        xml           l_xml.
* convert the text string into UTF-16LE binary data including
* byte-order-mark. Mircosoft Excel prefers these settings
* all this is done by new class cl_bcs_convert (see note 1151257)

    CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
      EXPORTING
        buffer        l_xml
      IMPORTING
        output_length lv_length
      TABLES
        binary_tab    lv_binary_content.
    lv_size lv_length.
*Attachment for with Ack
* Convert ALV in current layout to Excel and send as attachement

    FREE r_columns.
    IF go_salv2 IS BOUND.
      CALL METHOD go_salv2->get_columns
        RECEIVING
          value r_columns.
    ENDIF.

    FREE r_aggregations.
    REFRESH lt_field_cat.
    lt_field_cat cl_salv_controller_metadata=>get_lvc_fieldcatalog(
      r_columns      r_columns
      r_aggregations r_aggregations ).

    SORT lt_field_cat BY no_out col_pos.

    LOOP AT lt_field_cat ASSIGNING <field_cat>
                                WHERE no_out  ' '
                                AND   hotspot 'X'.
      CLEAR <field_cat>-hotspot.
      MODIFY lt_field_cat FROM <field_cat> TRANSPORTING hotspot.
    ENDLOOP.

* Use Excel .XLSX format.
    REFRESH lt_choice.
    CLEAR ls_choice.
    lt_choice cl_salv_export_xml_dialog=>get_gui_spreadsheet_formats(  ).
    READ TABLE lt_choice INTO ls_choice
         WITH KEY xml_type '10'.

    GET REFERENCE OF gt_po_ack INTO lr_data.

    CALL METHOD r_result_data->free.
    r_result_data cl_salv_ex_util=>factory_result_data_table(
     r_data                      lr_data
     t_fieldcatalog              lt_field_cat ).
    CLEAR l_version.
    CASE cl_salv_bs_a_xml_base=>get_version).
      WHEN if_salv_bs_xml=>version_25.
        l_version                if_salv_bs_xml=>version_25.
      WHEN if_salv_bs_xml=>version_26.
        l_version                if_salv_bs_xml=>version_26.
    ENDCASE.
    CLEARl_xmllv_length.
    CALL METHOD cl_salv_bs_tt_util=>if_salv_bs_tt_util~transform
      EXPORTING
        xml_type      ls_choice-xml_type
        xml_version   l_version
        r_result_data r_result_data
        xml_flavour   if_salv_bs_c_tt=>c_tt_xml_flavour_export
      IMPORTING
        xml           l_xml.

    CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
      EXPORTING
        buffer        l_xml
      IMPORTING
        output_length lv_length
      TABLES
        binary_tab    lv_binary_content2.

*        CALL private mehtod TO START email transmission USING bcs_class
    lv_size2 lv_length.
*        lv_receiver = im_name.
    lv_email_subject im_title.
*  Email body

  la_message-line text-001 .
  APPEND la_message to lt_messages.
*  Send email

    TRY .
*     -------- create persistent send request ------------------------
        lo_send_request cl_bcs=>create_persistent).

*     -------- create and set document with attachment ---------------
        lo_document cl_document_bcs=>create_document(
          i_type    im_doc_type
          i_text    lt_messages
          i_subject lv_email_subject ).                   "#EC NOTEXT

*            IF im_attachment_name IS INITIAL.
        lv_attach_name text-t11.
*            ENDIF.


*            IF im_content_hex IS NOT INITIAL.
**     Add the document as and attachment to email document object
        lo_document->add_attachment(
          i_attachment_type    im_attachment_type
          i_attachment_subject lv_attach_name
          i_attachment_size    lv_size
          i_att_content_hex    lv_binary_content
          ).
*            ENDIF.
**     Add the document as and attachment to email document object
        lv_attach_name text-t12.
        lo_document->add_attachment(
          i_attachment_type    im_attachment_type
          i_attachment_subject lv_attach_name
          i_attachment_size    lv_size2
          i_att_content_hex    lv_binary_content2
          ).
*            ENDIF.
*     add document object to send request
        lo_send_request->set_documentlo_document ).

* --------- Set the sender to the User Running the Report ---------
        lo_sender cl_sapuser_bcs=>createsy-uname ).
        lo_send_request->set_senderlo_sender ).

        LOOP AT s_mail[] INTO s_mail.
          lv_mailto s_mail-low.

          CHECK lv_mailto IS NOT INITIAL.
          lo_recipient cl_cam_address_bcs=>create_internet_addresslv_mailto ).
          CLEAR lv_mailto.

*     add recipient object to send request
          CALL METHOD lo_send_request->add_recipient
            EXPORTING
              i_recipient lo_recipient
              i_express   'X'.
          FREElo_recipient.
        ENDLOOP.
*     ---------- send document ---------------------------------------
        lv_email_sent lo_send_request->sendi_with_error_screen 'X' ).

        COMMIT WORK.

        IF lv_email_sent IS INITIAL.
          MESSAGE i500(sbcomsWITH s_mail-low.
        ELSE.
          MESSAGE s022(so).
        ENDIF.
*   ------------ exception handling ----------------------------------
*   replace this rudimentary exception handling with your own one !!!
      CATCH cx_bcs INTO lo_bcs_exception.
        MESSAGE i865(soWITH lo_bcs_exception->error_type.

    ENDTRY.
  ENDMETHOD.                           "send_email

ENDCLASS.                              "lcl_email IMPLEMENTATION