REPORT z_list_user_profiles.
*---------------------------------------------------------------------*
* This program lists the user's auth. profiles.                       *
*---------------------------------------------------------------------*
* Author : Michel PIOUD - Updated 20-Nov-07                           *
* HomePage : http://www.oocities.org/mpioud                          *
*---------------------------------------------------------------------*
CONSTANTS :
  c_x VALUE 'X'.
*---------------------------------------------------------------------*
TYPE-POOLS: slis.                      " ALV Global types

TYPES :
  BEGIN OF ty_user,
    bname     TYPE usr04-bname,        " SAP User name
    name_last TYPE addr3_val-name_last," User name
    class     TYPE usr02-class,        " User group
    profile   TYPE ust04-profile,      " Profile
    ptext     TYPE usr11-ptext,        " Texts authorizations
    samprof   TYPE char1,
  END OF ty_user.

*---------------------------------------------------------------------*
DATA:
  g_bname type ust04-bname,            " User Name
  g_class type usr02-class,            " User group
  g_profn type ust10c-profn,           " Profile
  gt_user TYPE TABLE OF ty_user.
*---------------------------------------------------------------------*
SELECTION-SCREEN :
BEGIN OF LINE, COMMENT 20(10) v_1 FOR FIELD s_bname.        "#EC NEEDED
SELECT-OPTIONS s_bname FOR g_bname.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN :
BEGIN OF LINE, COMMENT 20(10) v_2 FOR FIELD s_profil.       "#EC NEEDED
SELECT-OPTIONS s_profil FOR g_profn.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN :
BEGIN OF LINE, COMMENT 20(10) v_3 FOR FIELD s_class.        "#EC NEEDED
SELECT-OPTIONS s_class FOR g_class.
SELECTION-SCREEN END OF LINE.

*---------------------------------------------------------------------*
INITIALIZATION.

  v_1 = 'User'.
  v_2 = 'Profile'.
  v_3 = 'User group'.

*---------------------------------------------------------------------*
START-OF-SELECTION.

  PERFORM f_read_data.

*---------------------------------------------------------------------*
END-OF-SELECTION.

  PERFORM f_display_data.

*---------------------------------------------------------------------*
*      Form  f_read_data
*---------------------------------------------------------------------*
FORM f_read_data.

  CONSTANTS :
    lc_aktivated  VALUE 'A',
    lc_generprof  VALUE 'G',
    lc_colectprof VALUE 'C'.

  TYPES :
    BEGIN OF ty_usr10,
      profn TYPE usr10-profn,          " Profile
      typ   TYPE usr10-typ,            " Type of Profile
    END OF ty_usr10,

    BEGIN OF ty_usr11,
      profn TYPE usr11-profn,          " Profile
      ptext TYPE usr11-ptext,          " Profile text
    END OF ty_usr11,

    BEGIN OF ty_name,
      bname      TYPE usr21-bname,
      name_first TYPE adrp-name_first,
      name_last  TYPE adrp-name_last,
    END OF ty_name.

  DATA :
    ls_usr10 TYPE ty_usr10,
    lt_usr10 TYPE SORTED TABLE OF ty_usr10
             WITH NON-UNIQUE KEY profn,
    ls_usr11 TYPE ty_usr11,
    lt_usr11 TYPE SORTED TABLE OF ty_usr11
             WITH NON-UNIQUE KEY profn,

    ls_name TYPE ty_name,
    lt_name TYPE SORTED TABLE OF ty_name
            WITH UNIQUE KEY bname,

    lt_user TYPE TABLE OF ty_user.

  FIELD-SYMBOLS <user> TYPE ty_user.

* Read user data
  SELECT t~bname profile class
    INTO CORRESPONDING FIELDS OF TABLE gt_user
    FROM ust04 AS t
    JOIN usr02 AS r ON t~bname = r~bname
   WHERE t~bname IN s_bname
     AND profile IN s_profil
     AND class   IN s_class.

  IF gt_user[] IS NOT INITIAL.
    lt_user[] = gt_user[].
    SORT lt_user BY profile.
    DELETE ADJACENT DUPLICATES FROM lt_user COMPARING profile.
*   Read profile
    SELECT profn typ
      INTO TABLE lt_usr10
      FROM usr10
       FOR ALL ENTRIES IN lt_user
     WHERE profn = lt_user-profile
       AND aktps = lc_aktivated.
*   Read profile text
    SELECT profn ptext
      INTO TABLE lt_usr11
      FROM usr11
       FOR ALL ENTRIES IN lt_user
     WHERE profn = lt_user-profile
       AND langu = sy-langu
       AND aktps = lc_aktivated.

    lt_user[] = gt_user[].
    SORT lt_user BY bname.
    DELETE ADJACENT DUPLICATES FROM lt_user COMPARING bname.
*   Read user name
    SELECT bname name_first name_last
      INTO TABLE lt_name
      FROM usr21 AS u
      JOIN adrp AS a
        ON u~persnumber = a~persnumber
       FOR ALL ENTRIES IN lt_user
     WHERE bname = lt_user-bname.

  ENDIF.

  LOOP AT gt_user ASSIGNING <user>.
*   Get profile type
    READ TABLE lt_usr10 WITH KEY profn = <user>-profile INTO ls_usr10.
    IF sy-subrc IS INITIAL.
      IF ls_usr10-typ = lc_colectprof.
        <user>-samprof = c_x.
      ELSEIF ls_usr10-typ = lc_generprof.
        <user>-samprof = lc_generprof.
      ENDIF.
    ENDIF.

*   Get the profile texts.
    READ TABLE lt_usr11 WITH KEY profn = <user>-profile INTO ls_usr11.
    IF sy-subrc IS INITIAL.
      <user>-ptext = ls_usr11-ptext.
    ENDIF.

*   Get user name
    READ TABLE lt_name WITH KEY bname = <user>-bname
                              INTO ls_name.
    IF sy-subrc IS INITIAL.
      CONCATENATE ls_name-name_last ls_name-name_first
             INTO <user>-name_last SEPARATED BY space.
    ELSE.
      <user>-name_last = <user>-bname.
    ENDIF.

  ENDLOOP.

ENDFORM.                               " F_READ_DATA
*---------------------------------------------------------------------*
*      Form  f_display_data
*---------------------------------------------------------------------*
FORM f_display_data.

  DEFINE m_fieldcat.
    add 1 to ls_fieldcat-col_pos.
    ls_fieldcat-fieldname   = &1.
    ls_fieldcat-ref_tabname = &2.
    append ls_fieldcat to lt_fieldcat.
  END-OF-DEFINITION.

  DEFINE m_sort.
    add 1 to ls_sort-spos.
    ls_sort-fieldname = &1.
    ls_sort-up        = &2.
    ls_sort-group     = &3.
    append ls_sort to lt_sort.
  END-OF-DEFINITION.

  DATA:
    ls_fieldcat TYPE slis_fieldcat_alv,
    lt_fieldcat TYPE slis_t_fieldcat_alv,
    lt_sort     TYPE slis_t_sortinfo_alv,
    ls_sort     TYPE slis_sortinfo_alv,
    ls_layout   TYPE slis_layout_alv.

  m_fieldcat 'BNAME'     'UST04'.
  m_fieldcat 'NAME_LAST' 'ADDR3_VAL'.
  m_fieldcat 'CLASS'     'USR02'.
  m_fieldcat 'PROFILE'   'UST04'.
  m_fieldcat 'PTEXT'     'USR11'.
  m_fieldcat 'SAMPROF'   'USR10'.

  m_sort 'BNAME'     c_x 'UL'.
  m_sort 'NAME_LAST' c_x ''.
  m_sort 'PROFILE'   c_x ''.

  ls_layout-group_change_edit = c_x.
  ls_layout-colwidth_optimize = c_x.
  ls_layout-zebra             = c_x.
  ls_layout-cell_merge        = c_x.
  ls_layout-detail_popup      = c_x.
  ls_layout-get_selinfos      = c_x.

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program      = sy-cprog
      i_callback_user_command = 'USER_COMMAND'
      is_layout               = ls_layout
      it_fieldcat             = lt_fieldcat
      it_sort                 = lt_sort
    TABLES
      t_outtab                = gt_user.

ENDFORM.                               " F_DISPLAY_DATA
*---------------------------------------------------------------------*
*       FORM USER_COMMAND                                             *
*---------------------------------------------------------------------*
FORM user_command USING u_ucomm     TYPE sy-ucomm
                        us_selfield TYPE slis_selfield.     "#EC CALLED

  DEFINE m_bdc_dynpro.
    clear ls_bdcdata.
    ls_bdcdata-program  = &1.
    ls_bdcdata-dynpro   = &2.
    ls_bdcdata-dynbegin = c_x.
    ls_bdcdata-fnam     = 'BDC_OKCODE'.
    ls_bdcdata-fval     = &3.
    append ls_bdcdata to lt_bdcdata.
  END-OF-DEFINITION.

  DEFINE m_bdc_field.
    clear ls_bdcdata.
    ls_bdcdata-fnam = &1.
    ls_bdcdata-fval = &2.
    append ls_bdcdata to lt_bdcdata.
  END-OF-DEFINITION.

  DATA :
    ls_user TYPE ty_user,
    lt_message TYPE TABLE OF bdcmsgcoll,
    ls_bdcdata TYPE bdcdata,
    lt_bdcdata TYPE TABLE OF bdcdata.

  CASE u_ucomm.
    WHEN '&IC1'.
      READ TABLE gt_user INDEX us_selfield-tabindex INTO ls_user.
      CHECK sy-subrc EQ 0.
      CASE us_selfield-fieldname.
        WHEN 'PROFILE'.
          CALL FUNCTION 'SUSR_PROF_DISPLAY_WITH_AUTHS'
            EXPORTING
              profile = ls_user-profile.
        WHEN OTHERS.
          m_bdc_dynpro 'SAPLSUU5' '0050' '=SHOW'.
          m_bdc_field  'USR02-BNAME' ls_user-bname.

          m_bdc_dynpro 'SAPLSUU5' '0100' '=PROF'.

          CALL TRANSACTION 'SU01' USING lt_bdcdata MODE 'E'
                          MESSAGES INTO lt_message.
          READ TABLE lt_message WITH KEY msgid = '01'
                                         msgnr = '495'
                            TRANSPORTING NO FIELDS.
          CHECK sy-subrc EQ 0.
*         You are not authorized to display users
          MESSAGE i495(01).
      ENDCASE.
  ENDCASE.

ENDFORM.                               " USER_COMMAND
***************** END OF PROGRAM Z_LIST_USER_PROFILES *****************