REPORT ZZBGS092 LINE-COUNT 50 LINE-SIZE 132.
*----------------------------------------------------------------------*
* Description: Program generating an overview of profiles and authori- *
*              zations. The list is build as a tree list, with         *
*              splitting up composite profiles in single profiles.     *
*              Single profiles are split into authorization.           *
*              Authorization are printed with the both object name and *
*              Auth name.                                              *
*                                                                      *
* Implementing:The program uses recursion. Due to the amount of data   *
*              it was nessesary to keep the data in internal tables    *
*              filled and released as stack tables.                    *
*                                                                      *
* Customizing: None.                                                   *
*                                                                      *
* Change of    None.                                                   *
* release:                                                             *
*                                                                      *
* SAP Releases:2.2x - 3.0x                                             *
*                                                                      *
* Programmer:  Benny G. Sørensen                                       *
* Date:        September 1996                                          *
*                                                                      *
* Submitting:  By transaction SA38 or by batch job scheduling.         *
*                                                                      *
* Authori- :   None                                                    *
* zation                                                               *
*                                                                      *
* Parametre:   P_mandt : Client                                        *
*              P_user  : Userid                                        *
*              P_modbe : Userid for creator                            *
*              P_profn : Profile                                       *
*                                                                      *
* Select-options :                                                     *
*-------------------------------Corrections----------------------------*
* Date        Userid     Correction                                    *
* 21-12-1996  BGS        Bug: Missing refresh of Ustack and Pstack     *
*----------------------------------------------------------------------*

*----------------------------------------------------------------------*
* Tables:                                                              *
*----------------------------------------------------------------------*
TABLES: USR10      "User master authorization profil
       ,USR12      "User master authorization values
       ,USR11      "Usermaster text for profiles (USR10)
       ,USR13      "Korttekster til authorizations
       ,TOBJ       "Objects
       ,USR04      "User
       ,USR03      "User
       .
SELECT-OPTIONS P_MANDT FOR USR10-MANDT DEFAULT SY-MANDT.
PARAMETERS:    P_USER  LIKE USR04-BNAME DEFAULT SY-UNAME.
SELECT-OPTIONS P_MODBE FOR USR10-MODBE.
SELECT-OPTIONS P_PROFN FOR USR10-PROFN.
SELECT-OPTIONS P_AKTPS FOR USR10-AKTPS DEFAULT 'A'.
SELECT-OPTIONS P_TYP   FOR USR10-TYP.
PARAMETERS:    P_SHWAUT AS CHECKBOX DEFAULT 'X'.
PARAMETERS:    P_SHWVAL AS CHECKBOX DEFAULT 'X'.

*----------------------------------------------------------------------*
* CONSTANTS                                                            *
*----------------------------------------------------------------------*
DATA: _ADDPOS     TYPE I VALUE 4
     ,_SINGLEPROF VALUE 'S'
     ,_COLECTPROF VALUE 'C'
     ,_AKTIVATED  VALUE 'A'
     ,_INWORK     VALUE 'P'
     ,_FINESEL    VALUE 'F'
     ,_ROUGHSEL   VALUE 'R'
     ,_AUTHLNG    LIKE SY-FDPOS VALUE 12
     ,_PROFLNG    LIKE SY-FDPOS VALUE 12
     ,_OBJLNG     LIKE SY-FDPOS VALUE 10
     ,_FLDLNG     LIKE SY-FDPOS VALUE 10
     ,_MAXCPF     TYPE I VALUE 300
     ,_MAXPRO     TYPE I VALUE 170
     ,_MAXUSR     TYPE I VALUE 300
     ,OK          TYPE I VALUE 0
     .
*----------------------------------------------------------------------*
* Variables                                                            *
*----------------------------------------------------------------------*
DATA: W_OFF       TYPE I
     ,W_NRAUT     TYPE I
     ,W_STACK     TYPE P
     ,W_COLUMN    TYPE P
     ,W_ROWS      TYPE I
     .

FIELD-SYMBOLS: <TEXT>.

*----------------------------------------------------------------------*
* Internal tables                                                      *
*----------------------------------------------------------------------*
DATA:   MAXSET TYPE I VALUE 100.
DATA:   BEGIN OF TABSET OCCURS 30,    
          SFIELD LIKE TOBJ-FIEL1,
          VON(18),
          BIS(18),
        END OF TABSET.

DATA: BEGIN OF TUSR10 OCCURS 0.        "Selected profiles
        INCLUDE STRUCTURE USR10.
DATA: END OF TUSR10.

DATA: BEGIN OF USTACK OCCURS 0.        "Stacked profiles
        INCLUDE STRUCTURE USR10.
DATA:   NUMBER  TYPE P
       ,COLUMN  TYPE P.
DATA: END OF USTACK.

DATA: BEGIN OF PSTACK OCCURS 30,       "Stacked profiles/authorizations
        MANDT   LIKE USR10-MANDT
       ,PROFN   LIKE USR10-PROFN
       ,OBJCT   LIKE USR12-OBJCT
       ,AUTH    LIKE USR12-AUTH
       ,AKTPS   LIKE USR10-AKTPS
       ,NUMBER  TYPE P
       ,COLUMN  TYPE P
     ,END OF PSTACK.

DATA: BEGIN OF PROFILE.
        INCLUDE STRUCTURE USR10.
DATA: END OF PROFILE.

DATA:   BEGIN OF TABUSR OCCURS 30,    "Int. Tab. 
          PROFILE LIKE USR10-PROFN,
          SAMPROF(1),
          PTEXT   LIKE USR11-PTEXT,
        END OF TABUSR.

*----------------------------------------------------------------------*
* Event: TOP-OF-PAGE                                                   *
*----------------------------------------------------------------------*
TOP-OF-PAGE.
  WRITE:/02 SY-ULINE.
  IF P_USER NE SPACE.
    WRITE:/02 'For brugerid: ', USR04-BNAME, USR03-NAME1.
    WRITE:/02 SY-ULINE.
  ENDIF.
  WRITE:/02(80) SPACE               COLOR COL_HEADING
       ,/01(16) 'Compositeprofile'  COLOR 1
       , 21(13) 'Singleprofile'     COLOR 2
       , 41(13) 'Authorization'     COLOR 6
       , 61(12) 'Object'            COLOR 5
       , 81     'PF6 = Retur'       COLOR 7
       .
  WRITE:/02 SY-ULINE.

*----------------------------------------------------------------------*
* Event: INITALIZATION                                                 *
*----------------------------------------------------------------------*
INITIALIZATION.


*----------------------------------------------------------------------*
* Event: START-OF-SELECTION                                            *
* Read and process all profiles wether nor it is a composite or single *
* profile. Select only active profiles and only profiles in user selec-*
* tions.                                                               *
*----------------------------------------------------------------------*
START-OF-SELECTION.
DATA: USRFILL TYPE I
     ,RC      LIKE SY-SUBRC.

   W_STACK = 0.
   REFRESH: PSTACK, USTACK.

   DESCRIBE TABLE P_PROFN LINES W_ROWS.
   CONDENSE P_USER.              "If P_USER entered by user, select
                                 "only that users allocated profiles
   IF P_USER NE SPACE AND W_ROWS = 0.
     PERFORM GET_USER_PROFILES.
   ENDIF.

   SELECT * FROM USR10 CLIENT SPECIFIED INTO TABLE TUSR10
     WHERE MANDT IN P_MANDT
       AND AKTPS IN P_AKTPS
       AND MODBE IN P_MODBE
       AND PROFN IN P_PROFN
       AND TYP   IN P_TYP.

   COMMIT WORK.
   IF SY-SUBRC = OK.
     LOOP AT TUSR10.
       CLEAR: USTACK, PSTACK.
       REFRESH: PSTACK, USTACK.
       MOVE-CORRESPONDING TUSR10 TO USTACK.
       ADD 1 TO W_STACK.
       USTACK-NUMBER = W_STACK.
       USTACK-COLUMN = 2.
       APPEND USTACK.

       PERFORM SPLIT_AUTHS_INTO_ITEMS.  "Recursive form

       DELETE USTACK INDEX W_STACK.
       CLEAR USTACK.
       SUBTRACT 1 FROM W_STACK.
       COMMIT WORK.
       NEW-PAGE.
     ENDLOOP.
   ELSE.
     WRITE:/02 'No Profiles matching criteria found'(020)
           COLOR COL_HEADING.
   ENDIF.

*----------------------------------------------------------------------*
* EVENT: AT PF                                                         *
*----------------------------------------------------------------------*
AT PF6.
  LEAVE TO TRANSACTION 'ZAUT'.

*----------------------------------------------------------------------*
* EVENT: END-OF-SELECTION                                              *
*----------------------------------------------------------------------*
END-OF-SELECTION.
  Write:/02(80) sy-uline.
  WRITE:/02(80) 'Profile list finished' COLOR COL_HEADING.

*----------------------------------------------------------------------*
* FORM: If the parameter P_USER  is entered, only profiles for this    *
* user are selected and only for one specified client                  *
*----------------------------------------------------------------------*
FORM GET_USER_PROFILES.
  PERFORM READ_USR04 USING P_USER RC USRFILL.
  IF RC NE OK.
     MESSAGE ID 'FT' TYPE 'E' NUMBER '001'
             WITH 'User does not exists in client ' P_MANDT-LOW.
  ENDIF.

  REFRESH P_PROFN.                    "Get all profiles attached
  LOOP AT TABUSR.                     "to the user and save it
     P_PROFN-SIGN   = 'I'.            "in the internal table
     P_PROFN-OPTION = 'EQ'.           "P_PROFN.
     P_PROFN-LOW    = TABUSR-PROFILE. "
     APPEND P_PROFN.                  "
  ENDLOOP.                            "
ENDFORM.

*----------------------------------------------------------------------*
* FORM: Split_Auths_Into_Items                                         *
* This form is called recursivly until AUTHS only hold authorizations, *
* meaning when single profile type = S. Note that the printing position*
* are calculated depending on the hierarcy level.                      *
*----------------------------------------------------------------------*
FORM SPLIT_AUTHS_INTO_ITEMS.
DATA: COLUMN  TYPE P
     ,AUTHORIZATION(23) TYPE C
     ,RC LIKE SY-SUBRC.

  CLEAR W_COLUMN.
  READ TABLE USTACK INDEX W_STACK.
  MOVE-CORRESPONDING USTACK TO PROFILE.
  MOVE USTACK-COLUMN TO COLUMN.
  POSITION COLUMN.

  SELECT SINGLE * FROM USR11 CLIENT SPECIFIED
    WHERE  MANDT  = PROFILE-MANDT
      AND  LANGU  = SY-LANGU
      AND  PROFN  = PROFILE-PROFN
      AND  AKTPS  = PROFILE-AKTPS  .
  IF SY-SUBRC NE OK.
    CLEAR USR11.
    USR11-PTEXT = 'No description found'.
  ENDIF.

  CASE PROFILE-TYP.
    When 'C'.                         "Composite profile
      WRITE: PROFILE-PROFN COLOR 1
           , USR11-PTEXT COLOR COL_NORMAL, /.
      PERFORM FILL_TABPRO.
      LOOP AT PSTACK WHERE NUMBER = W_STACK.
        SELECT SINGLE * FROM USR10 CLIENT SPECIFIED
          WHERE MANDT = PSTACK-MANDT
            AND AKTPS = PSTACK-AKTPS
            AND PROFN = PSTACK-PROFN.

        IF SY-SUBRC = OK.
          W_COLUMN = PSTACK-COLUMN .
          CLEAR USTACK.
          MOVE-CORRESPONDING USR10 TO USTACK.
          ADD 1 TO W_STACK.
          USTACK-NUMBER = W_STACK.
          USTACK-COLUMN = W_COLUMN.
          APPEND USTACK.
          PERFORM SPLIT_AUTHS_INTO_ITEMS.
          DELETE USTACK INDEX W_STACK.
          LOOP AT PSTACK WHERE NUMBER = W_STACK.
            DELETE PSTACK.
          ENDLOOP.
          SUBTRACT 1 FROM W_STACK.
        ELSE.
          W_COLUMN = COLUMN + _ADDPOS.
          POSITION W_COLUMN.
          WRITE: PSTACK-PROFN COLOR 2, '%'.
        ENDIF.
      ENDLOOP.

    When 'S'.                         "Single profile
      WRITE: PROFILE-PROFN COLOR 2
            ,USR11-PTEXT COLOR COL_NORMAL, /.

      IF P_SHWAUT = 'X'.
        PERFORM FILL_TABPRO.
        LOOP AT PSTACK WHERE NUMBER = W_STACK.

          SELECT SINGLE * FROM  USR13 CLIENT SPECIFIED
            WHERE  MANDT  = PSTACK-MANDT
              AND  LANGU  = SY-LANGU
              AND  OBJCT  = PSTACK-OBJCT
              AND  AUTH   = PSTACK-AUTH
              AND  AKTPS  = PSTACK-AKTPS .
          IF SY-SUBRC NE OK.
            CLEAR USR13.
            USR13-ATEXT = 'No description found'.
          ENDIF.

          W_COLUMN = PSTACK-COLUMN.
          POSITION W_COLUMN.
          WRITE:  PSTACK-AUTH COLOR 6.
          W_COLUMN = COLUMN + _ADDPOS + _PROFLNG + 2.
          POSITION W_COLUMN.
          WRITE:   PSTACK-OBJCT COLOR 5
                 , USR13-ATEXT COLOR COL_NORMAL, /.
          IF P_SHWVAL = 'X'.
            PERFORM READ_USR12 USING PSTACK-OBJCT PSTACK-AUTH
                                     PSTACK-AKTPS RC.
            LOOP AT TABSET.
              POSITION W_COLUMN.
              WRITE: TABSET-SFIELD, TABSET-VON, TABSET-BIS,/.
            ENDLOOP.
          ENDIF.
        ENDLOOP.
      ENDIF.
    WHEN OTHERS.
      PERFORM ERRORHANDLING USING 21 TEXT-021.
  ENDCASE.
ENDFORM. "Split_Auths_Into_Items

*----------------------------------------------------------------------*
* FORM: ErrorHandling                                                  *
* If any error occurs the program terminates.                          *
*----------------------------------------------------------------------*
FORM ERRORHANDLING USING ERRORNUMBER ERRORTEXT.
  WRITE:/02 ERRORNUMBER, ERRORTEXT COLOR 7.
  stop.
Endform. "ErrorHandling

*---------------------------------------------------------------------*
* FORM FILL_TABPRO                                                    *
* The splitting up of AUTHS field depend on wether profile-typ is     *
* Composite or single profile. If Composite we split for each 12      *
* Character, if Single profile we split for each 22 character, because*
* an authorization id consist of both object and authorization Id.    *
*---------------------------------------------------------------------*
FORM FILL_TABPRO.

*   Composite profile consist only of single-profiles
    IF PROFILE-TYP = _COLECTPROF.
      CLEAR PSTACK.
      W_OFF = 2.
      W_NRAUT = PROFILE-NRAUT / 12.
      IF W_NRAUT > _MAXCPF. W_NRAUT = 0. ENDIF.
      DO W_NRAUT TIMES.
        ASSIGN PROFILE-AUTHS+W_OFF(_PROFLNG) TO <TEXT>.
        WRITE <TEXT> TO PSTACK-PROFN.
        PSTACK-NUMBER = W_STACK.
        PSTACK-MANDT  = PROFILE-MANDT.
        PSTACK-AKTPS  = PROFILE-AKTPS.
        PSTACK-COLUMN = USTACK-COLUMN + _ADDPOS.
        APPEND PSTACK.
        W_OFF = W_OFF + _PROFLNG.
      ENDDO.
*   Single profile consist only of authorizations
    ELSE.
      IF PROFILE-TYP = _SINGLEPROF.
        CLEAR PSTACK.
        W_OFF = 2.
        W_NRAUT = PROFILE-NRAUT / 22.
        IF W_NRAUT > _MAXPRO. W_NRAUT = 0. ENDIF.
        DO W_NRAUT TIMES.
          ASSIGN PROFILE-AUTHS+W_OFF(_OBJLNG) TO <TEXT>.
          WRITE <TEXT> TO PSTACK-OBJCT.
          W_OFF = W_OFF + _OBJLNG.
          ASSIGN PROFILE-AUTHS+W_OFF(_AUTHLNG) TO <TEXT>.
          WRITE <TEXT> TO PSTACK-AUTH.
          W_OFF = W_OFF + _AUTHLNG.
          PSTACK-MANDT  = PROFILE-MANDT.
          PSTACK-AKTPS  = PROFILE-AKTPS.
          PSTACK-NUMBER = W_STACK.
          PSTACK-COLUMN = USTACK-COLUMN + _ADDPOS.
          APPEND PSTACK.
        ENDDO.
      ENDIF.
    ENDIF.
ENDFORM.

*---------------------------------------------------------------------*
* FORM : Read_USR12                                                   *
*---------------------------------------------------------------------*
FORM READ_USR12 USING VALUE(OBJECT) VALUE(AUTH) VALUE(AKTPAS) RC.
  DATA: INTFLAG TYPE I VALUE 0,
        OFF     TYPE I,
        VTYP,
        LNG     TYPE I,
        CLNG(2),
        GLNG(2),
        SETFILL LIKE SY-TFILL.
FIELD-SYMBOLS: <TEXT>.
*
  CLEAR USR12.
  RC = 0.

  IF AKTPAS = _AKTIVATED OR AKTPAS = _INWORK.
    SELECT SINGLE * FROM USR12       "Expl. Aktiv- od. Pflegeversion
           WHERE OBJCT  = OBJECT
           AND   AUTH    = AUTH
           AND   AKTPS  = AKTPAS.
  ELSE.
    SELECT SINGLE * FROM USR12        "Wenn nicht, dann zuerst Pflege-
           WHERE OBJCT  = OBJECT
           AND   AUTH    = AUTH
           AND   AKTPS  = _INWORK.
    IF SY-SUBRC <> 0.
      SELECT SINGLE * FROM USR12      "Nicht vorh., dann Aktivv. lesen
             WHERE OBJCT  = OBJECT
             AND   AUTH    = AUTH
             AND   AKTPS  = _AKTIVATED.
    ENDIF.
  ENDIF.

  IF SY-SUBRC = 0.
        SETFILL = 0.
        REFRESH TABSET.
        CLEAR TABSET.
        OFF = 2.
* Werte aufschluesseln und in die int. Tab. tabset laden
        ASSIGN USR12-VALS+OFF(1) TO <TEXT>.
        WRITE <TEXT> TO VTYP.
* Var. Teil bis zum FF (= Endezeichen) lesen
        WHILE VTYP <> '  ' AND OFF < USR12-LNG.
          OFF = OFF + 1.
* vtyp steht fuer Schluessel, ob es sich um Feldnamen, Einzelwert,
* Anfang Intervall oder Ende Intervall handelt.
          CASE VTYP.
            WHEN 'F'.                 "Feldname
              OFF = OFF + 5.
              ASSIGN USR12-VALS+OFF(2) TO <TEXT>.
              WRITE <TEXT> TO CLNG.
              LNG = CLNG.
              OFF = OFF + 2.
              ASSIGN USR12-VALS+OFF(_FLDLNG) TO <TEXT>.
              WRITE <TEXT> TO TABSET-SFIELD.
              OFF = OFF + _FLDLNG.
            WHEN 'E'.                 "Einzelwert
              ASSIGN USR12-VALS+OFF(LNG) TO <TEXT>.
              WRITE <TEXT> TO TABSET-VON.
              IF TABSET-VON = SPACE.
                TABSET-VON = ''' '''.  
              ENDIF.
              APPEND TABSET.
              SETFILL = SETFILL + 1.
              TABSET-VON = SPACE.
              TABSET-BIS = SPACE.
              OFF = OFF + LNG.
            WHEN 'G'.             
              ASSIGN USR12-VALS+OFF(2) TO <TEXT>.
              WRITE <TEXT> TO CLNG.
              GLNG = CLNG.
              OFF = OFF + 2.
              ASSIGN USR12-VALS+OFF(LNG) TO <TEXT>.
              IF INTFLAG = 0.
                WRITE <TEXT> TO TABSET-VON.
                WRITE '*' TO TABSET-VON+GLNG.
              ELSE.
                WRITE <TEXT> TO TABSET-BIS.
                WRITE '*' TO TABSET-BIS+GLNG.
                INTFLAG = 0.
              ENDIF.
              APPEND TABSET.
              SETFILL = SETFILL + 1.
              TABSET-VON = SPACE.
              TABSET-BIS = SPACE.
              OFF = OFF + LNG.
            WHEN 'V'.                 
              INTFLAG = 1.
              ASSIGN USR12-VALS+OFF(LNG) TO <TEXT>.
              WRITE <TEXT> TO TABSET-VON.
              IF TABSET-VON = SPACE.  
                TABSET-VON = ''' '''.
              ENDIF.
              OFF = OFF + LNG.
            WHEN 'B'.                 
              INTFLAG = 0.
              ASSIGN USR12-VALS+OFF(LNG) TO <TEXT>.
              WRITE <TEXT> TO TABSET-BIS.
              IF TABSET-BIS = SPACE.  
                TABSET-BIS = ''' '''.
              ENDIF.
              APPEND TABSET.
              SETFILL = SETFILL + 1.
              TABSET-VON = SPACE.
              TABSET-BIS = SPACE.
              OFF = OFF + LNG.
          ENDCASE.
          ASSIGN USR12-VALS+OFF(1) TO <TEXT>.
          WRITE <TEXT> TO VTYP.
        ENDWHILE.
  ELSE.
    RC = SY-SUBRC.
  ENDIF.
ENDFORM.


*---------------------------------------------------------------------*
* FORM : Read_USR04                                                   *
*---------------------------------------------------------------------*
FORM READ_USR04 USING VALUE(USER) RC USRFILL.
  CLEAR USR04.
  RC = 0.
  SELECT SINGLE * FROM USR04  CLIENT SPECIFIED
         WHERE  MANDT = P_MANDT-LOW
           AND  BNAME = USER.
  IF SY-SUBRC = 0.
    SELECT SINGLE * FROM USR03  CLIENT SPECIFIED
           WHERE  MANDT = P_MANDT-LOW
             AND  BNAME = USER.
    PERFORM FILL_TABUSR USING USRFILL.
  ELSE.
    REFRESH TABUSR.
    CLEAR TABUSR.
    USRFILL = 0.
    RC = 4.
  ENDIF.
ENDFORM.

*---------------------------------------------------------------------*
* FORM : write_vline                                                  *
*---------------------------------------------------------------------*
FORM FILL_TABUSR USING USRFILL.
DATA: NRPRO TYPE I,
      OFF   TYPE I.
*
  REFRESH TABUSR.
  CLEAR TABUSR.
  USRFILL = 0.
  OFF = 2.
  NRPRO = USR04-NRPRO / 12.                             
  IF NRPRO > _MAXUSR. NRPRO = 0. ENDIF.
  DO NRPRO TIMES.
    ASSIGN USR04-PROFS+OFF(_PROFLNG) TO <TEXT>.
    WRITE <TEXT> TO TABUSR-PROFILE.
    APPEND TABUSR.
    USRFILL = USRFILL + 1.
    OFF = OFF + _PROFLNG.
  ENDDO.
ENDFORM.

*---------------------------------------------------------------------*
* FORM : write_vline                                                  *
*---------------------------------------------------------------------*
FORM WRITE_VLINE USING MODE POS.
    IF MODE NE 'T'.
      FORMAT INTENSIFIED.
    ENDIF.
    POSITION POS.
    WRITE: SY-VLINE.
    IF MODE NE 'T'.
      FORMAT RESET.
    ENDIF.
ENDFORM.