SAP BW - Customer Exit Reconstruct

* https://blogs.sap.com/2013/04/08/bex-userexits-reloaded/

DATA:
  I_VNAM        TYPE  RSZGLOBV-VNAM,
  I_VARTYP      TYPE  RSZGLOBV-VARTYP,
  I_IOBJNM      TYPE  RSZGLOBV-IOBJNM,
  I_S_COB_PRO   TYPE  RSD_S_COB_PRO,
  I_S_RKB1D     TYPE  RSR_S_RKB1D,
  I_T_VAR_RANGE TYPE  RRS0_T_VAR_RANGE,
  I_STEP        TYPE  I.

DATA:
  E_T_RANGE     TYPE  RSR_T_RANGESID,
  E_NO_SCREEN   TYPE  RS_BOOL,
  E_CHECK_AGAIN TYPE  RS_BOOL,
  ET_RANGE      TYPE  RSR_T_RANGESID.

INTERFACE YIF_USER_EXIT.
  METHODS INITIALIZE IMPORTING I_VARTYP      TYPE RSZGLOBV-VARTYP
                               I_IOBJNM      TYPE RSZGLOBV-IOBJNM
                               I_S_COB_PRO   TYPE RSD_S_COB_PRO
                               I_S_RKB1D     TYPE RSR_S_RKB1D
                               I_T_VAR_RANGE TYPE RRS0_T_VAR_RANGE.
  METHODS SECURITY_CHECK RETURNING VALUE(R_T_RANGETYPE RSR_T_RANGESID.
  METHODS FIRST_CHECK  EXPORTING VALUE(DISPLAY)   TYPE RS_BOOL
                                 VALUE(RECHECK)   TYPE RS_BOOL
                       RETURNING VALUE(R_T_RANGETYPE RSR_T_RANGESID.
  METHODS SECOND_CHECK RETURNING VALUE(R_T_RANGETYPE RSR_T_RANGESID.
  METHODS FINAL_CHECK  RETURNING VALUE(R_T_RANGETYPE RSR_T_RANGESID.
ENDINTERFACE.

CLASS YCX_USER_EXIT_EXCEPTION DEFINITION INHERITING FROM CX_DYNAMIC_CHECK.
  PUBLIC SECTION.
    INTERFACES IF_T100_MESSAGE.
    METHODS CONSTRUCTOR IMPORTING TEXTID   LIKE IF_T100_MESSAGE=>T100KEY OPTIONAL
                                  PREVIOUS LIKE PREVIOUS OPTIONAL
                                  TEXT1    TYPE SSTRING OPTIONAL
                                  TEXT2    TYPE SSTRING OPTIONAL
                                  TEXT3    TYPE SSTRING OPTIONAL
                                  TEXT4    TYPE SSTRING OPTIONAL.
    CONSTANTS:
      BEGIN OF NO_CONFIGURATION,
        MSGID TYPE SYMSGID VALUE 'SABAPDEMOS',
        MSGNO TYPE SYMSGNO VALUE '888',
        ATTR1 TYPE SCX_ATTRNAME VALUE 'TEXT1',
        ATTR2 TYPE SCX_ATTRNAME VALUE 'TEXT2',
        ATTR3 TYPE SCX_ATTRNAME VALUE 'TEXT3',
        ATTR4 TYPE SCX_ATTRNAME VALUE 'TEXT4',
      END OF NO_CONFIGURATION,
      BEGIN OF INSTANTIATON_FAILED,
        MSGID TYPE SYMSGID VALUE 'SABAPDEMOS',
        MSGNO TYPE SYMSGNO VALUE '888',
        ATTR1 TYPE SCX_ATTRNAME VALUE 'TEXT1',
        ATTR2 TYPE SCX_ATTRNAME VALUE 'TEXT2',
        ATTR3 TYPE SCX_ATTRNAME VALUE 'TEXT3',
        ATTR4 TYPE SCX_ATTRNAME VALUE 'TEXT4',
      END OF INSTANTIATON_FAILED.

    DATA TEXT1 TYPE SSTRING .
    DATA TEXT2 TYPE SSTRING .
    DATA TEXT3 TYPE SSTRING .
    DATA TEXT4 TYPE SSTRING .
ENDCLASS.

CLASS YCX_USER_EXIT_EXCEPTION IMPLEMENTATION.
  METHOD CONSTRUCTOR.
    SUPER->CONSTRUCTOR(
       EXPORTING
         PREVIOUS PREVIOUS ).

    ME->TEXT1 TEXT1 .
    ME->TEXT2 TEXT2 .
    ME->TEXT3 TEXT3 .
    ME->TEXT4 TEXT4 .

    IF TEXTID IS INITIAL.
      IF_T100_MESSAGE~T100KEY IF_T100_MESSAGE=>DEFAULT_TEXTID.
    ELSE.
      IF_T100_MESSAGE~T100KEY TEXTID.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

CLASS YCL_USER_EXIT_FACTORY DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS FACTORY IMPORTING VNAM              TYPE RSZVNAM
                                    OBJ               TYPE RSD_S_COB_PRO
                                    REP               TYPE RSR_S_RKB1D
                                    STEP              TYPE I
                          RETURNING VALUE(R_INSTANCETYPE REF TO YIF_USER_EXIT RAISING YCX_USER_EXIT_EXCEPTION.

    CONSTANTS VAR TYPE LENGTH VALUE '1'.
    CONSTANTS IOBJ TYPE LENGTH VALUE '2'.
    CONSTANTS IPROV TYPE LENGTH VALUE '3'.
    CONSTANTS REP TYPE LENGTH VALUE '4'.
ENDCLASS.

CLASS YCL_USER_EXIT_FACTORY IMPLEMENTATION.
  METHOD FACTORY.

    CONSTANTS TABNM TYPE TABNAME VALUE 'YBWVAR'.
    DATA SEL_COND TYPE STRING.
    DATA LOOP_COND TYPE STRING.
    DATA VAR_REF TYPE REF TO DATA.
    FIELD-SYMBOLS <VAR_TAB> TYPE STANDARD TABLE.
    FIELD-SYMBOLS <VAR_LINE> TYPE ANY.

    TYPES:
      BEGIN OF VAR_CLS_TYPE,
        OBJNM  TYPE LENGTH 30,
        OBJTY  TYPE LENGTH 1,
        CLSNAM TYPE SEOCLSNAME,
        VNAM   TYPE RSZVNAM,
        ACTIVE TYPE RS_BOOL,
      END OF VAR_CLS_TYPE.

    SEL_COND COND #WHEN VNAM IS NOT INITIAL THEN |OBJNM VNAM AND ACTIVE RS_C_TRUE|
                   ELSE |OBJNM IN | &&
                        |({ OBJ-IOBJNM },|  && "Check by InfoObject
                        |{ OBJ-INFOPROV },| && "Check by InfoProvider
                        |{ REP-COMPID } | && "Check by Query
                        |AND ACTIVE RS_C_TRUE| ).
    TRY .
        CREATE DATA VAR_REF TYPE REF TO (TABNM).
        ASSIGN VAR_REF->TO <VAR_TAB>.
      CATCH CX_SY_CREATE_DATA_ERROR.
        RAISE EXCEPTION TYPE YCX_USER_EXIT_EXCEPTION
          EXPORTING
            TEXTID YCX_USER_EXIT_EXCEPTION=>INSTANTIATON_FAILED.
    ENDTRY.
    TRY .
        SELECT FROM (TABNMINTO TABLE @<VAR_TAB> WHERE (SEL_COND).
        IF SY-SUBRC <> 0.
          RAISE EXCEPTION TYPE YCX_USER_EXIT_EXCEPTION
            EXPORTING
              TEXTID YCX_USER_EXIT_EXCEPTION=>NO_CONFIGURATION.
        ENDIF.
      CATCH CX_SY_DYNAMIC_OSQL_SYNTAX.
        RAISE EXCEPTION TYPE YCX_USER_EXIT_EXCEPTION
          EXPORTING
            TEXTID YCX_USER_EXIT_EXCEPTION=>INSTANTIATON_FAILED.
    ENDTRY.

    SORT <VAR_TAB> BY VALUE ABAP_SORTORDER_TABNAME 'OBJNM' NAME 'OBJTY'NAME 'VNAM').

    CASE STEP.
      WHEN OR OR 2.
        LOOP_COND |OBJTY { YCL_USER_EXIT_FACTORY=>VAR }|.
        LOOP AT <VAR_TAB> ASSIGNING <VAR_LINE> WHERE (LOOP_COND).
          EXIT.
        ENDLOOP.
      WHEN 3.
        "Full check
        LOOP_COND |OBJTY { YCL_USER_EXIT_FACTORY=>IOBJ } |   &&
                    |OR OBJTY { YCL_USER_EXIT_FACTORY=>IPROV } | &&
                    |OR OBJTY { YCL_USER_EXIT_FACTORY=>REP } | &&
                    |AND VNAM ` `|.
        LOOP AT <VAR_TAB> ASSIGNING <VAR_LINE> WHERE (LOOP_COND).
          EXIT.
        ENDLOOP.
        IF SY-SUBRC <> 0.
*          "Partial check
*          LOOP_COND = |( OBJTY = { YCL_USER_EXIT_FACTORY=>IOBJ } |   &&
*                      |OR OBJTY = { YCL_USER_EXIT_FACTORY=>IPROV } | &&
*                      |OR OBJTY = { YCL_USER_EXIT_FACTORY=>REP } ) |.
*          LOOP AT <VAR_TAB> ASSIGNING <VAR_LINE> WHERE (LOOP_COND).
*
*          ENDLOOP.
        ENDIF.
      WHEN OTHERS.
        RAISE EXCEPTION TYPE YCX_USER_EXIT_EXCEPTION
          EXPORTING
            TEXTID YCX_USER_EXIT_EXCEPTION=>NO_CONFIGURATION.
    ENDCASE.

    IF <VAR_LINE> IS NOT ASSIGNED.
      RAISE EXCEPTION TYPE YCX_USER_EXIT_EXCEPTION
        EXPORTING
          TEXTID YCX_USER_EXIT_EXCEPTION=>NO_CONFIGURATION.
    ENDIF.

    ASSIGN COMPONENT 'CLSNAM' OF STRUCTURE <VAR_LINE> TO FIELD-SYMBOL(<VAR_CLS>).
*    DATA(VAR_CLS) = VALUE VAR_CLS_TYPE( OBJNM  = I_VNAM
*                                        CLSNAM = 'YBW_VA0001'
*                                        ACTIVE = RS_C_TRUE ).
    TRY .
        CREATE OBJECT R_INSTANCE TYPE (<VAR_CLS>).
      CATCH CX_SY_CREATE_OBJECT_ERROR INTO DATA(EXP).
        RAISE EXCEPTION TYPE YCX_USER_EXIT_EXCEPTION
          EXPORTING
            TEXTID YCX_USER_EXIT_EXCEPTION=>INSTANTIATON_FAILED.
    ENDTRY.
  ENDMETHOD.
ENDCLASS.

CLASS YBW_VAR_ABSTRACT DEFINITION ABSTRACT.
  PUBLIC SECTION.
    INTERFACES YIF_USER_EXIT.
    ALIASES INITIALIZE     FOR YIF_USER_EXIT~INITIALIZE.
    ALIASES SECURITY_CHECK FOR YIF_USER_EXIT~SECURITY_CHECK.
    ALIASES FIRST_CHECK    FOR YIF_USER_EXIT~FIRST_CHECK.
    ALIASES SECOND_CHECK   FOR YIF_USER_EXIT~SECOND_CHECK.
    ALIASES FINAL_CHECK    FOR YIF_USER_EXIT~FINAL_CHECK.
  PROTECTED SECTION.
    DATA M_VARTYP      TYPE RSZGLOBV-VARTYP.
    DATA M_IOBJNM      TYPE RSZGLOBV-IOBJNM.
    DATA M_S_COB_PRO   TYPE RSD_S_COB_PRO.
    DATA M_S_RKB1D     TYPE RSR_S_RKB1D.
    DATA M_T_VAR_RANGE TYPE RRS0_T_VAR_RANGE.
ENDCLASS.

CLASS YBW_VAR_ABSTRACT IMPLEMENTATION.
  METHOD INITIALIZE.
    M_VARTYP      I_VARTYP      .
    M_IOBJNM      I_IOBJNM      .
    M_S_COB_PRO   I_S_COB_PRO   .
    M_S_RKB1D     I_S_RKB1D     .
    M_T_VAR_RANGE I_T_VAR_RANGE .
  ENDMETHOD.
  METHOD SECURITY_CHECK.
  ENDMETHOD.
  METHOD FIRST_CHECK.
  ENDMETHOD.
  METHOD SECOND_CHECK.
  ENDMETHOD.
  METHOD FINAL_CHECK.
  ENDMETHOD.
ENDCLASS.

CLASS YBW_VA0001 DEFINITION INHERITING FROM YBW_VAR_ABSTRACT.
  PUBLIC SECTION.
    METHODS SECURITY_CHECK REDEFINITION.
    METHODS FIRST_CHECK REDEFINITION.
    METHODS SECOND_CHECK REDEFINITION.
    METHODS FINAL_CHECK REDEFINITION.
ENDCLASS.

CLASS YBW_VA0001 IMPLEMENTATION.
  METHOD SECURITY_CHECK.
    R_T_RANGE VALUE #).
  ENDMETHOD.
  METHOD FIRST_CHECK.
    R_T_RANGE VALUE #).
  ENDMETHOD.
  METHOD SECOND_CHECK.
    R_T_RANGE VALUE #).
  ENDMETHOD.
  METHOD FINAL_CHECK.

  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  I_VNAM        'YBWVA0001'.
  I_VARTYP      '3'.
*  I_IOBJNM      = ''.
*  I_S_COB_PRO   = ''.
*  I_S_RKB1D     = ''.
*  I_T_VAR_RANGE = ''.
  I_STEP        '1'.

  DATA LDO_VARIABLE TYPE REF TO YIF_USER_EXIT.

  TRY .
      LDO_VARIABLE YCL_USER_EXIT_FACTORY=>FACTORYEXPORTING VNAM I_VNAM
                                                               OBJ  I_S_COB_PRO
                                                               REP  I_S_RKB1D
                                                               STEP I_STEP ).
      LDO_VARIABLE->INITIALIZEI_VARTYP        I_VARTYP
                                I_IOBJNM        I_IOBJNM
                                I_S_COB_PRO     I_S_COB_PRO
                                I_S_RKB1D       I_S_RKB1D
                                I_T_VAR_RANGE   I_T_VAR_RANGE ).

      E_T_RANGE COND #WHEN I_STEP THEN LDO_VARIABLE->SECURITY_CHECK)
                          WHEN I_STEP THEN LDO_VARIABLE->FIRST_CHECKIMPORTING DISPLAY E_NO_SCREEN RECHECK E_CHECK_AGAIN )
                          WHEN I_STEP THEN LDO_VARIABLE->SECOND_CHECK)
                          WHEN I_STEP THEN LDO_VARIABLE->FINAL_CHECK).
    CATCH YCX_USER_EXIT_EXCEPTION INTO DATA(EXP).
      MESSAGE 'error' TYPE 'I'.
*      CALL FUNCTION 'RRMS_MESSAGE_HANDLING'
*        EXPORTING
*          I_CLASS  = EXP->IF_T100_MESSAGE~T100KEY-MSGID
*          I_TYPE   = RS_C_ERROR
*          I_NUMBER = EXP->IF_T100_MESSAGE~T100KEY-MSGNO
*          I_MSGV1  = EXP->IF_T100_MESSAGE~T100KEY-ATTR1
*          I_MSGV2  = EXP->IF_T100_MESSAGE~T100KEY-ATTR2
*          I_MSGV3  = EXP->IF_T100_MESSAGE~T100KEY-ATTR3
*          I_MSGV4  = EXP->IF_T100_MESSAGE~T100KEY-ATTR4
*        EXCEPTIONS
*          DUMMY    = 1
*          OTHERS   = 2.
*      RAISE CUSTOMIZE_EXCEPTION.
*      IF SY-SUBRC <> 0.
*        RAISE UNKNOW.
*      ENDIF.
  ENDTRY.

Comments