Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member
0 Kudos

Introduction:



In large implementations with multiple teams working on the same development box with a fixed transport route, more often

there are collisions between the transports involving common objects. This is especially true for large implementations with

multiple rollout strategy where the system is already live and there are simultaneous releases of transports by users

belonging to different groups. Coupled with the fact that these transports can be imported into subsequent systems at certain times

which only the BASIS team is aware of, there needs to be a process for notifying the failed transports to the owners to take

corrective action. This program is an attempt to bridge such confusion arising out of such problems.

Problem statement:



• Important time wasted in analysing a whole bunch of transports when mass import is happening to subsequent

systems.

• Difficult to co relate the correction transport with original failed transport

• Systems like Quality testing and Integration can be in an inconsistent state for a long time due to syntax

errors affecting a number of other users work.

• Without immediate notification coupled with the fact that transport owner might not be present at the given

moment, it becomes difficult to trace who is responsible for the development.

• Creeping of transport failures ( and hence an inconsistent system state) in systems ahead of Quality in the

transport chain


Solution:



1. Immediate notification of the transport errors in Quality and other systems to the transport owner and the team

lead

2. Create a process of Defect management for every transport failure

3. Import all the transports in the same order as imported into ECQ and make sure that the corrected transports are also

present in the import queue. This can be better achieved by having the failed transport number present in the description of

the correction transport

How to send notifications?



Create the program Z_ALERT_TRANSPORT_STATUS – (Can be assigned a

transaction code if needed).
It can achieve the following

1. Notify the transports which are imported into the subsequent systems like Quality, Integration and Production to the

transport owner as he might be unaware when specific imports will occur for these systems

2. Serve as one single report to monitor errors (for BASIS) across subsequent systems right in the development

system

3. Send out Alert mails to individual transport owners about their transports and their statuses

4. Send out an Alert to Team leads (Based on configuration in OOCU_RESP) about their teams transports status and to take

corrective action if necessary.

How this Program can be used?



1. Immediate Notification of status of a transport imported into subsequent system

2. Can be scheduled as a background job after the import job in a specific system to import the transport queue is

scheduled or can be scheduled as a nightly job (Time zone issue!!)

3. All jobs can be scheduled in 1 system only. This program need not be transported to subsequent system as can be

run/scheduled from/in Development system itself.

Program Details and Functioning:



!https://weblogs.sdn.sap.com/weblogs/images/11829/Diagram2.1-Selectionscreen.JPG|height=274|alt=image...!

Diagram1. Selection screen of Program



Report Output




!https://weblogs.sdn.sap.com/weblogs/images/11829/Diagram2.2-ReportOutput.JPG|height=101|alt=image|wi...!

Diagram 2.2 Report Output



Team Alerts:Why team Alert and how is it useful



1. More often the transport owner might be on leave or might have left the project. To take care of these transports, the team leader needs to be notified.

2. Defect creation process: A process for identifying each transport layer and correcting them can be taken through the some defect management system to ensure the visibility of failures. Please note that this mechanism is not an alternative or substitute to proper analysis that should be made by the transport owners prior to release but acts as a feedback on their analysis. Below diagram depicts a possible process that can be followed


!https://weblogs.sdn.sap.com/weblogs/images/11829/Diagram2.3-TransportcorrectionthroughDefectmanageme...!

Diagram2.3-Transport correction through Defect Management process


Assumptions:



1. The SM59 destinations are maintained such that the first 3 letters correspond to the system ID.

2. For a transport step, any code

a. Greater or equal to 8 is treated as ERROR,

b. 4 as Warning and
c.
0 as success.


Implementation Details:


There are 4 basic parts to this solution with an additional step to implement the Team

Alert concept.

1.

Selection of the delta set of transports

which need to be picked up based on when they were imported into a subsequent system. This can be picked up in 2 ways.

a. Based on the information of last changed timestamp for each of the log files created in application server for each transport. However there are some drawbacks like
i. The file path where each of these log files is most likely different based on the operating system. For UNIX it might generally be in directory /usr/sap/trans/cofiles/. And there is a correlation between the file name and the transport number such that the file name can easily be derived.
ii. We cannot know by looking at this last changed timestamp information of the file whether this change was due to import into

which specific system
iii. Need to use C Function calls to get to know the file meta data which can be a bit complex.
b. Establish the last changed date of the transport by looking up table E070 in the remote system. This

is a client independent table so any client in the remote system can be used as a RFC destination. Since this is a cleaner

way the current code is selecting delta transports based on the above logic.
2.

Get the transport statuses

for each of the transports selected in the above step
3.

Send alert/mail to the transport owner

using the Alert Category. If you are not familiar with creation of Alert category you refer to step 3 in setting up Team Alert section below or write code to send user e-mail using any one of SAP provided FMs
4.

Write a report

using ALV grid display (classes)


Step 1:Create a Function group ZS_TRANSPORT_MGMT with a Function Module

Z_GET_TRANSPORT_LOG

as given.This is a copy of the FM TR_LOG_OVERVIEW_REQUEST except that the last part of the display of the log is commented and some export parameters are inserted. Please copy the top include of the Function group TR_LOG_OVERVIEW and include RDDKORRI in your custom Function pool

FUNCTION z_get_transport_log.

*"----


""Local Interface:

*"  IMPORTING

*"     VALUE(IV_TRKORR) LIKE  E070-TRKORR

*"     VALUE(IV_DIR_TYPE) LIKE  TSTRF01-DIRTYPE DEFAULT 'T'

*"     VALUE(IV_DETAILED_CHRONOLOGY) TYPE  C DEFAULT 'X'

*"     REFERENCE(IV_TARGET_SYSTEM) TYPE  TCESYST-SYSNAME DEFAULT SPACE

*"     VALUE(IS_POPUP) TYPE  STRHI_POPUP OPTIONAL

*"  EXPORTING

*"     REFERENCE(EV_PROJECT) TYPE  TRKORR_P

*"     REFERENCE(EV_TRANSPORT_TEXT) TYPE  E07T-AS4TEXT

*"  TABLES

*"      ET_TSTRFCOFIL STRUCTURE  TSTRFCOFIL

*"  EXCEPTIONS

*"      E_WRONG_CALL

*"----


  DATA:  ls_request          TYPE  ctslg_request_info,

         lt_requests         TYPE  ctslg_request_infos,

         ls_settings         TYPE  ctslg_settings,

         ls_system           TYPE  LINE OF ctslg_settings-systems,

         lv_refresh          TYPE  c                VALUE 'X',

         ls_sort_desc        TYPE  ctslg_dl_sort,

         ls_layout           TYPE  strhi_refresh_parameters,

         lv_trkorr           LIKE  e070-trkorr,

         lv_title            TYPE  trwbo_title,

         lv_first_node_text  TYPE  ctslg_first_node_text,

         lv_username         LIKE  e070-as4user.

  DATA:  ls_tstrfcofil       TYPE tstrfcofil,

         ls_ctslg_systems    TYPE ctslg_system.

  • Exit on wrong call

  IF iv_dir_type NA 'PUT'.

    MESSAGE e541(tr) RAISING e_wrong_call.

  ENDIF.

----


  • Start up

  PERFORM tr_log_overview_initialization.

  ls_sort_desc-levels_filled    = 'X'.

  ls_sort_desc-level-int_status = 0.

  ls_sort_desc-level-srcsystem  = 0.

  ls_sort_desc-level-owner      = 0.

  ls_settings-point_to_missing_steps = 'X'.

  IF iv_detailed_chronology = 'X'.

    ls_settings-detailed_depiction = 'X'.

  ENDIF.

  IF iv_target_system NE space.

    ls_system-name = iv_target_system.

    APPEND ls_system TO ls_settings-systems.

  ENDIF.

  •   Collect data according input parameters

  CLEAR: ls_request, lt_requests.

  ls_request-header-trkorr = iv_trkorr.

  CALL FUNCTION 'TRINT_READ_REQUEST_HEADER'

    EXPORTING

      iv_read_e070 = 'X'

      iv_read_e07t = 'X'

    CHANGING

      cs_request   = ls_request-header

    EXCEPTIONS

      OTHERS       = 1.

  IF sy-subrc <> 0.

    ls_request-header-trkorr = iv_trkorr.

  ENDIF.

  CALL FUNCTION 'TR_READ_GLOBAL_INFO_OF_REQUEST'

    EXPORTING

      iv_trkorr   = iv_trkorr

      iv_dir_type = iv_dir_type

      is_settings = ls_settings

    IMPORTING

      es_cofile   = ls_request-cofile

      ev_user     = lv_username

      ev_project  = ls_request-project.

  IF ls_request-header-as4user = space.

    ls_request-header-as4user = lv_username.

  ENDIF.

  ls_request-cofile_filled = 'X'.

  APPEND ls_request TO lt_requests.

  LOOP AT ls_request-cofile-systems INTO ls_ctslg_systems.

  •   For any Virtual systems - ignore the return code status

    IF ls_ctslg_systems-systemid+0(1) EQ 'V'.

      CONTINUE.

    ENDIF.

    CLEAR et_tstrfcofil.

    et_tstrfcofil-tarsystem  = ls_ctslg_systems-systemid.

    et_tstrfcofil-retcode    = ls_ctslg_systems-rc.

    APPEND et_tstrfcofil.

  ENDLOOP.

  ev_project = ls_request-project.

  EV_TRANSPORT_TEXT = ls_request-header-as4text.

ENDFUNCTION.

&----


*& Report   Z_ALERT_TRANSPORT_STATUS

*&

&----


*&

*&

&----


REPORT   z_alert_transport_status.

----


  • Types and Data declarations, Selection screen definition

----


  • Declaration for selection screen select options

TABLES: rfcdisplay,

        e070tc.

CONSTANTS: c_true type C value ‘X’.

  • All types

TYPES: BEGIN OF ty_mail_content,

         z_team_name    TYPE  z_team_name.

        INCLUDE STRUCTURE  zs_transport_mail_info.

TYPES:  END OF ty_mail_content,

       ty_t_char80        type STANDARD TABLE OF char80,

       ty_t_mail_content  TYPE STANDARD TABLE OF ty_mail_content,

       ty_t_alert_content TYPE STANDARD TABLE OF  zs_transport_mail_info,

       ty_report_list     TYPE                    zs_transport_log_info,

       ty_t_report_list   TYPE STANDARD TABLE OF ty_report_list .

  • Global data declarations for data

DATA: gt_report_list  TYPE ty_t_report_list,

      gs_report_list  TYPE ty_report_list,

      gt_mail_content TYPE ty_t_mail_content.

  • Global declarations for ALV grid display report

DATA:

go_alvgrid        TYPE REF TO cl_gui_alv_grid, "ALV Grid instance reference

go_container      TYPE REF TO cl_gui_custom_container,"Custom container

gt_fieldcat       TYPE STANDARD TABLE OF lvc_s_fcat,

gs_layout         TYPE lvc_s_layo,

ok_code           TYPE sy-ucomm.

----


  • Selection Screen for User inputs

----


SELECTION-SCREEN BEGIN OF BLOCK block1 WITH FRAME TITLE text-s01.

SELECT-OPTIONS :

     s_dest FOR rfcdisplay-rfcdest NO INTERVALS, " RFC destination

     s_tkor FOR e070tc-trkorr NO INTERVALS,      " Transport numbers

  •    Date intervals between which the tranpsort was imported into the system

     s_date FOR e070tc-as4date NO-EXTENSION OBLIGATORY DEFAULT sy-datum TO sy-datum,

  •    Time intervals between which the tranpsort was imported into the system

     s_time FOR e070tc-as4time NO-EXTENSION OBLIGATORY DEFAULT '000000' TO '235959'.

  •     Alert flag to send alerts based on Teams via Alert management.

PARAMETERS: p_alert TYPE c AS CHECKBOX,

            p_mail  TYPE c AS CHECKBOX.

SELECTION-SCREEN END OF BLOCK block1

----


  • All form routines

*----


&----


*&      Form  get_changed_transports

&----


  •       text

----


  • pt_mail_content contains the transports imported

  • into the remote systems

----


FORM  get_changed_transports CHANGING

                pt_report_list TYPE ty_t_report_list .

  DATA:

           lt_rfc_db_opt  TYPE STANDARD TABLE OF rfc_db_opt,

           ls_rfc_db_opt  TYPE                   rfc_db_opt,

           lt_rfc_db_fld  TYPE STANDARD TABLE OF  rfc_db_fld,

           lt_tstrfcofil TYPE TABLE OF tstrfcofil,

           ls_tstrfcofil TYPE          tstrfcofil,

           lt_tab512 TYPE STANDARD TABLE OF  tab512,

           ls_tab512 TYPE                    tab512,

           ls_report_list      TYPE  ty_report_list,

           ls_report_list_temp TYPE  ty_report_list,

           lt_report_list TYPE  STANDARD TABLE OF ty_report_list,

           lt_project_team  TYPE TABLE OF ZS_PROJ_USER,

           ls_project_team  TYPE  ZS_PROJ_USER,

           ls_message(120)  TYPE c,

           ls_errorcode(10) TYPE c,

           l_rc(2)          TYPE n,

           l_tkorr   TYPE e070tc-trkorr.

  • Build the where clause for Date

  CLEAR ls_rfc_db_opt.

  CONCATENATE '( AS4DATE GE ''' s_date-low

              ''' AND AS4DATE LE ''' s_date-high ''' )'

        INTO  ls_rfc_db_opt.

  APPEND ls_rfc_db_opt TO lt_rfc_db_opt .

  CLEAR ls_rfc_db_opt.

  ls_rfc_db_opt = 'AND'.

  APPEND ls_rfc_db_opt TO lt_rfc_db_opt .

  • Build the where clause for Time

  CLEAR ls_rfc_db_opt.

  CONCATENATE '( AS4TIME GE ''' s_time-low

              ''' AND AS4TIME LE ''' s_time-high ''' )'

        INTO  ls_rfc_db_opt.

  APPEND ls_rfc_db_opt TO lt_rfc_db_opt .

  • Build the where clause for transport requests specified

  LOOP  AT s_tkor.

    CLEAR l_tkorr .

    l_tkorr = s_tkor-low .

    AT FIRST.

      CLEAR ls_rfc_db_opt.

      ls_rfc_db_opt = 'AND ('.

      APPEND ls_rfc_db_opt TO lt_rfc_db_opt .

    ENDAT.

    AT LAST.

      CONCATENATE 'TRKORR EQ '''

                  l_tkorr  ''' )'

             INTO ls_rfc_db_opt.

      APPEND ls_rfc_db_opt TO lt_rfc_db_opt.

      EXIT.

    ENDAT.

    CONCATENATE 'TRKORR EQ '''

                 l_tkorr

                ''' OR'

           INTO ls_rfc_db_opt.

    APPEND ls_rfc_db_opt TO lt_rfc_db_opt.

  ENDLOOP.

  • For each destination specified get the requests

  • imported based on the above where clause

  • by reading the table E070

  LOOP AT s_dest.

    REFRESH: lt_tab512,

             lt_rfc_db_fld.

    CALL FUNCTION 'RFC_READ_TABLE' DESTINATION s_dest-low

      EXPORTING

        query_table                = 'E070'

  •     DELIMITER                  = ' '

  •     NO_DATA                    = ' '

  •     ROWSKIPS                   = 0

  •     ROWCOUNT                   = 0

      TABLES

        OPTIONS                    = lt_rfc_db_opt

        fields                     = lt_rfc_db_fld

        data                       = lt_tab512

   EXCEPTIONS

     table_not_available        = 1

     table_without_data         = 2

     option_not_valid           = 3

     field_not_valid            = 4

     not_authorized             = 5

     data_buffer_exceeded       = 6

     OTHERS                     = 7

              .

    IF sy-subrc <> 0.

      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno

              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4

         INTO ls_message.

    ENDIF.

  •   Move the generic data contents

  •   to E070 structure

    LOOP AT lt_tab512 INTO ls_tab512.

      CLEAR ls_report_list.

      ls_report_list = ls_tab512-wa.

      ls_report_list-system_moved = s_dest-low.

      APPEND ls_report_list TO lt_report_list.

    ENDLOOP.

  ENDLOOP.

  • Select all users groups as this table will

  • have very few entries(less than 1000)

  SELECT *

    INTO TABLE lt_project_team

    FROM ZS_PROJ_USER.

  IF sy-subrc EQ 0.

    SORT lt_project_team  BY bname.

  ENDIF.

  SORT lt_report_list BY trkorr.

  LOOP AT lt_report_list INTO ls_report_list.

    ls_report_list_temp = ls_report_list.

    AT NEW trkorr.

      REFRESH: lt_tstrfcofil.

      CALL FUNCTION ' Z_GET_TRANSPORT_LOG'

        EXPORTING

          iv_trkorr                    = ls_report_list_temp-trkorr

  •           IV_DIR_TYPE                  = 'T'

  •           IV_DETAILED_CHRONOLOGY       = 'X'

  •           IV_TARGET_SYSTEM             = ' '

  •           IS_POPUP                     =

        IMPORTING

             ev_project                 = ls_report_list_temp-project

             ev_transport_text          = ls_report_list_temp-transport_text

      TABLES

        et_tstrfcofil                = lt_tstrfcofil

  •         EXCEPTIONS

  •           E_WRONG_CALL                 = 1

  •           OTHERS                       = 2

              .

      IF sy-subrc <> 0.

        MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno

                WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4

           INTO ls_message.

      ENDIF.

      CLEAR  ls_project_team .

      READ TABLE lt_project_team  INTO ls_project_team

      WITH KEY bname = ls_report_list_temp-as4user BINARY SEARCH.

    ENDAT.

  •   Group the users

    ls_report_list_temp-z_team_name = ls_project_team -z_team_name.

  •   Assumption that the first 3 characters of the system ID

  •   and SM59 logical destination are the same

    CLEAR ls_tstrfcofil.

    READ TABLE lt_tstrfcofil INTO ls_tstrfcofil

          WITH KEY tarsystem = ls_report_list_temp-system_moved+0(3).

    IF sy-subrc EQ 0.

      ls_report_list_temp-return_code = ls_tstrfcofil-retcode.

      CASE ls_report_list_temp-return_code.

          WHEN'0'.

          ls_report_list_temp-rc_text = 'SUCCESS'(001).

          WHEN'4'.

          ls_report_list_temp-rc_text = 'WARNING'(002).

          WHEN'8'.

          ls_report_list_temp-rc_text = 'ERROR'(003).

        WHEN OTHERS.

          IF ls_report_list_temp-return_code > 8.

            ls_report_list_temp-rc_text = 'ERROR'(003).

          ELSE.

            ls_report_list_temp-rc_text = 'UNKNOWN'(005).

          ENDIF.

      ENDCASE.

    ENDIF.

    MODIFY lt_report_list FROM ls_report_list_temp.

  ENDLOOP.

  pt_report_list[] = lt_report_list[].

ENDFORM.                    " get_changed_transports

&----


*&      Form  display_report

&----


  •       text

----


  •      -->P_GT_REPORT_LIST  text

----


FORM display_report  USING    p_gt_report_list

                              TYPE ty_t_report_list.

  PERFORM build_fieldcatalog  CHANGING gt_fieldcat[].

  CALL SCREEN '0100'.

ENDFORM.                    " display_report

&----


*&      Module  STATUS_0100  OUTPUT

&----


  •       text

----


MODULE status_0100 OUTPUT.

  SET PF-STATUS '1000'.

  SET TITLEBAR 'xxx'.

  PERFORM display_alv_report.

ENDMODULE.                 " STATUS_0100  OUTPUT

&----


*&      Module  USER_COMMAND_0100  INPUT

&----


  •       text

----


MODULE user_command_0100 INPUT.

  CASE ok_code.

    WHEN 'BACK' OR 'EXIT'.

      LEAVE PROGRAM.

    WHEN 'CANC'.

      LEAVE PROGRAM.

  ENDCASE.

ENDMODULE.                 " USER_COMMAND_0100  INPUT

&----


*&      Form  build_fieldcatalog

&----


  •       text

----


  •      <--P_GT_FIELDCAT[]  text

----


FORM build_fieldcatalog  CHANGING p_gt_fieldcat TYPE lvc_t_fcat.

  CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'

   EXPORTING

  •   I_BUFFER_ACTIVE              =

      i_structure_name             = 'ZS_TRANSPORT_LOG_INFO'

  •   I_CLIENT_NEVER_DISPLAY       = 'X'

  •   I_BYPASSING_BUFFER           =

  •   I_INTERNAL_TABNAME           =

    CHANGING

      ct_fieldcat                  = p_gt_fieldcat

   EXCEPTIONS

     inconsistent_interface       = 1

     program_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.

ENDFORM.                    " build_fieldcatalog

&----


*&      Form  add_field_info

&----


  •       text

----


  • -->  p1        text

  • <--  p2        text

----


FORM add_field_info USING pa_fname

                          pa_coltxt.

  DATA: ls_field_cat LIKE LINE OF gt_fieldcat,

        l_lines      LIKE sy-index.

  DESCRIBE TABLE gt_fieldcat LINES l_lines.

  l_lines = l_lines + 1.

  CLEAR ls_field_cat.

  ls_field_cat-fieldname = pa_fname.

  ls_field_cat-col_pos   = l_lines.

  ls_field_cat-coltext   = pa_coltxt.

  APPEND ls_field_cat TO gt_fieldcat.

ENDFORM.                    " add_field_info

&----


*&      Form  display_alv_report

&----


  •       text

----


  • -->  p1        text

  • <--  p2        text

----


FORM display_alv_report .

  DATA: ls_variant  TYPE disvariant." Variant

  IF go_container IS INITIAL.

    ls_variant-report =  cl_abap_syst=>get_current_program( )..

  •     Creating custom container instance

    CREATE OBJECT go_container

      EXPORTING

        container_name              = 'CO_GRID_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 EQ 0.

  •        Creating ALV Grid instance

      CREATE OBJECT go_alvgrid

        EXPORTING

          i_parent          = go_container

        EXCEPTIONS

          error_cntl_create = 1

          error_cntl_init   = 2

          error_cntl_link   = 3

          error_dp_create   = 4

          OTHERS            = 5   .

      IF sy-subrc EQ 0.

        MOVE c_true

            TO : gs_layout-cwidth_opt,

                 gs_layout-zebra.

        CALL METHOD go_alvgrid->set_table_for_first_display

          EXPORTING

            is_layout                     = gs_layout

            i_bypassing_buffer            =  c_true

            is_variant                    = ls_variant

            i_save                        = 'A'

            i_default                     = 'X'

          CHANGING

            it_outtab                     = gt_report_list[]

            it_fieldcatalog               = gt_fieldcat[]

          EXCEPTIONS

            invalid_parameter_combination = 1

            program_error                 = 2

            too_many_lines                = 3

            OTHERS                        = 4.

      ENDIF.

    ENDIF.

  ENDIF.

ENDFORM.                    " display_alv_report

&----


*&      Form  send_alert

&----


  •       text

----


  •      -->P_GT_REPORT_LIST  text

----


FORM send_alert  USING    p_gt_mail_content TYPE ty_t_mail_content .

  DATA : ls_mail_content      TYPE              ty_mail_content,

         ls_mail_content_temp TYPE              ty_mail_content,

         lt_mail_content      TYPE              ty_t_mail_content,

         ls_alert_list   TYPE               ZS_TRANSPORT_MAIL_INFO,

         lt_alert_list   TYPE               ty_t_alert_content.

  DATA: lt_abap_container TYPE sweconttab,

        lo_container     TYPE REF TO if_swf_cnt_container.

  • Set the contianer elements and send an alert

  • Set From Date

  CALL FUNCTION 'SWC_ELEMENT_SET'

    EXPORTING

      element       = 'FROM_DATE'

      field         = s_date-low

    TABLES

      container     = lt_abap_container

    EXCEPTIONS

      type_conflict = 1

      OTHERS        = 2.

  IF sy-subrc <> 0.

    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno

            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

  ENDIF.

  • Set To Date

  CALL FUNCTION 'SWC_ELEMENT_SET'

    EXPORTING

      element       = 'TO_DATE'

      field         = s_date-high

    TABLES

      container     = lt_abap_container

    EXCEPTIONS

      type_conflict = 1

      OTHERS        = 2.

  IF sy-subrc <> 0.

    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno

            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

  ENDIF.

  • Convert it to a BOR contianer

  TRY.

      CALL METHOD

        cl_swf_cnt_container=>if_swf_cnt_conversion~create_from_bor_container

        EXPORTING

          values    = lt_abap_container

        RECEIVING

          container = lo_container.

    CATCH cx_swf_utl_obj_create_failed .

  ENDTRY.

  • Delete entries which donot have the  team names assigned

  lt_mail_content[]  = p_gt_mail_content[].

  DELETE lt_mail_content WHERE z_team_name IS INITIAL.

  SORT lt_mail_content BY z_team_name.

  • Iterate through the enties and send alert

  • per PROJECT team maintained in table ZS_PROJ_USER

  LOOP AT lt_mail_content INTO ls_mail_content.

    ls_mail_content_temp = ls_mail_content.

    AT NEW z_team_name.

      CLEAR : ls_alert_list,

              lt_alert_list[].

  •      CLEAR: lt_char80[].

    ENDAT.

    MOVE-CORRESPONDING ls_mail_content_temp  TO ls_alert_list.

    APPEND ls_alert_list TO lt_alert_list.

    AT END OF z_team_name.

      TRY.

  •         Set Team name

          CALL METHOD lo_container->if_swf_cnt_element_access_1~element_set_value

            EXPORTING

              name  = 'PROJECT_TEAM_NAME'

              value = ls_mail_content_temp-z_team_name.

        CATCH cx_root.

      ENDTRY.

      SORT lt_alert_list BY tarsystem as4date as4time.

      PERFORM send_team_alert USING space

                                    lt_alert_list

                                    lo_container.

    ENDAT.

  ENDLOOP.

ENDFORM.                    " send_alert

&----


*&      Form  send_team_alert

&----


  •       text

----


  • -->  p1        text

  • <--  p2        text

----


FORM send_team_alert USING p_uname

                           pt_alert_list  TYPE ty_t_alert_content

                           pa_container   TYPE REF TO if_swf_cnt_container.

  DATA: l_alert_id TYPE  salrtextid,

        ls_recipients TYPE          salrtsrcp,

        lt_recipients TYPE TABLE OF salrtsrcp.

  • Set reciepient

  IF p_uname IS NOT INITIAL.

    ls_recipients-uname = p_uname.

    APPEND ls_recipients TO lt_recipients.

  ENDIF.

  TRY.

  •     Set Transport list

      CALL METHOD pa_container->if_swf_cnt_element_access_1~element_set_value

        EXPORTING

          name  = 'TRANSPORT_LIST'

          value = pt_alert_list[].

    CATCH cx_root.

  ENDTRY.

  • Raise Alert via the API

  CALL FUNCTION 'SALRT_CREATE_API'

    EXPORTING

      ip_category                  = 'RT_TRANSPORT_STATUS_ALERTS'

  •       IP_ALIAS                     =

  •       IP_EXPIRATION_TIME           =

  •       IP_EXPIRATION_DATE           =

      ip_wait_on_commit            = ' '

  •       IP_APPLICATION_GUID          =

  •       IP_GET_SYNC_EXCEPTIONS       = ' '

      ii_container                 = pa_container

   IMPORTING

     ep_alert_id                  =  l_alert_id

    TABLES

      it_recipients               =  lt_recipients

  •     it_activities                 = lt_activities

  •    it_container                  = pim_container

  •     it_roles                      = pim_roles

   EXCEPTIONS

     alert_category_unknown       = 1

     alert_no_recipients          = 2

     alert_error_unknown          = 3

     destination_undefined        = 4

     communication_failure        = 5

     system_failure               = 6

     OTHERS                       = 7.

  IF sy-subrc NE 0.

  ENDIF.

ENDFORM.                    " send_team_alert

&----


*&      Form  build_mail_content

&----


  •       text

----


  •      -->P_GT_REPORT_LIST  text

  •      <--P_GT_MAIL_CONTENT  text

----


FORM build_mail_content  USING    p_gt_report_list  TYPE ty_t_report_list

                         CHANGING p_gt_mail_content TYPE ty_t_mail_content.

  DATA: ls_report_list TYPE ty_report_list,

        ls_mail_list TYPE ty_mail_content.

  LOOP AT p_gt_report_list INTO ls_report_list.

    CLEAR ls_mail_list.

    ls_mail_list-z_team_name =   ls_report_list-z_team_name. 

    ls_mail_list-trkorr      =   ls_report_list-trkorr.

    ls_mail_list-korrdev     =   ls_report_list-korrdev.

    ls_mail_list-as4user     =   ls_report_list-as4user.

    ls_mail_list-as4date     =   ls_report_list-as4date.

    ls_mail_list-as4time     =   ls_report_list-as4time.

    ls_mail_list-tarsystem   =   ls_report_list-system_moved+0(3).

    ls_mail_list-project     =   ls_report_list-project.

    ls_mail_list-rc_text     =   ls_report_list-rc_text.

    APPEND  ls_mail_list TO p_gt_mail_content.

  ENDLOOP.

ENDFORM.                    " build_mail_content

&----


*&      Form  send_mail

&----


  •       text

----


  •      -->P_GT_MAIL_CONTENT  text

----


FORM send_mail  USING    p_gt_mail_content TYPE ty_t_mail_content.

  DATA : ls_mail_content     TYPE                   ty_mail_content,

         ls_mail_content_temp TYPE                  ty_mail_content,          lt_mail_content      TYPE                

ty_t_mail_content,

         ls_alert_list   TYPE                 ZS_TRANSPORT_MAIL_INFO,

         lt_alert_list   TYPE                 ty_t_alert_content.

  DATA: lt_abap_container TYPE sweconttab,

        lo_container     TYPE REF TO if_swf_cnt_container.

  • Set the container elements and send an alert

  • Set From Date

  CALL FUNCTION 'SWC_ELEMENT_SET'

    EXPORTING

      element       = 'FROM_DATE'

      field         = s_date-low

    TABLES

      container     = lt_abap_container

    EXCEPTIONS

      type_conflict = 1

      OTHERS        = 2.

  IF sy-subrc <> 0.

    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno

            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

  ENDIF.

  • Set To Date

  CALL FUNCTION 'SWC_ELEMENT_SET'

    EXPORTING

      element       = 'TO_DATE'

      field         = s_date-high

    TABLES

      container     = lt_abap_container

    EXCEPTIONS

      type_conflict = 1

      OTHERS        = 2.

  IF sy-subrc <> 0.

    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno

            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

  ENDIF.

  • Convert it to a BOR contianer

  TRY.

      CALL METHOD

        cl_swf_cnt_container=>if_swf_cnt_conversion~create_from_bor_container

        EXPORTING

          values    = lt_abap_container

        RECEIVING

          container = lo_container.

    CATCH cx_swf_utl_obj_create_failed .

  ENDTRY.

  • Delete entries which don’t have the  team names assigned

  lt_mail_content[]  = p_gt_mail_content[].

  SORT lt_mail_content BY as4user.

  • Iterate through the enties and send alert

  • per PROJECT team maintained in table ZS_PROJ_USER

  LOOP AT lt_mail_content INTO ls_mail_content.

    ls_mail_content_temp = ls_mail_content.

    AT NEW as4user.

      CLEAR : ls_alert_list,

              lt_alert_list[].

  •      CLEAR: lt_char80[].

    ENDAT.

    MOVE-CORRESPONDING ls_mail_content_temp  TO ls_alert_list.

    APPEND ls_alert_list TO lt_alert_list.

    AT END OF as4user.

      SORT lt_alert_list BY tarsystem as4date as4time.

      PERFORM send_team_alert USING ls_mail_content_temp-as4user

                                    lt_alert_list

                                    lo_container.

    ENDAT.

  ENDLOOP.

ENDFORM.

----


  • Main Program

*----


START-OF-SELECTION.

  • Get all the request information based on user inputs

  PERFORM get_changed_transports

        CHANGING gt_report_list.

END-OF-SELECTION.

  • Display report if data is found

  IF gt_report_list[] IS NOT INITIAL.

  •   Send Alert via alert management.

    IF  p_alert EQ  zcl_constants=>c_true or

        p_mail  eq  zcl_constants=>c_true.

        perform build_mail_content

                       using gt_report_list

                    changing gt_mail_content.

    ENDIF.

    IF  p_alert EQ  zcl_constants=>c_true.

       PERFORM send_alert USING gt_mail_content.

    endif.

    if p_mail  eq  zcl_constants=>c_true.

       PERFORM send_mail USING gt_mail_content.

    endif.

  •   Display report

    PERFORM display_report USING

            gt_report_list.

  ELSE.

  •   Display message in case no data is selected.

    WRITE 'No transports selected for the given parameters'(004).

  ENDIF.





How to set up Team Alert ?


For Team Alert concept an additional 2 tables are required or the team name can be maintained in any field or User master. In this specific case Ihave created 2 tables for this purpose and these are used in the program above

Database Table Name: ZS_PROJ_TEAM



Component

Component Type

Data Type

Length

Dec

Description

MANDT

MANDT

CLNT

3

0

Client

Z_TEAM_NAME

Z_TEAM_NAME

CHAR

20

0

Project Team name

Z_TEAM_DESCRIP

Z_TEAM_DESC

CHAR

50

0

Project Team description




Database Table Name: ZS_PROJ_USER



Component

Component Type

Data Type

Length

Dec

Description

MANDT

MANDT

CLNT

3

0

Client

BNAME

XUBNAME

CHAR

12

0

User Name in User Master Record

Z_TEAM_NAME

Z_TEAM_NAME

CHAR

20

0

Project Team name




Four steps need to be done in order to set up Team Alert in Development System where the job is scheduled.
1. Create a Team name with Description
a. Go to SM30 and give the table name as ZS_PROJ_TEAM
b. Insert the Team name and description if not already present.
c. Go to SM30 and give the table name as ZS_PROJ_USER
d. Insert entry for each user for the team to which they belong
e. You can also insert the team members who have left the programme to track their transports belonging to you team.

2. Transaction: PFAC. Create a Rule of category ‘R’ “Agent Determination : Responsibilities”
a. Create a container element with ‘PROJ_TEAM_NAME

3. Create an Alert Category from transaction ‘ALRTCATDEF’
a. Give appropriate description
b. Create 4 container elements
i. TRANSPORT_LIST of type ZS_TRANSPORT_MAIL_INFO.
ii. FROM_DATE of type SY-DATUM
iii. TO_DATE of type SY_DATUM
iv. PROJ_TEAM_NAME of type PROJECT_TEAM_NAME.
c. Specify the rule created in Step 2 above and bind the container element PROJ_TEAM_NAME between the Alert category and Rule.
d. Give appropriate content in the long text and title so that these apper on the alert displaying the Transport List with status.

4. Maintain Responsibilities in transaction OOCU_RESP.
a. Give rule number XXXXXXXX present in the alert category you have defined and click on change(Pen) button


!https://weblogs.sdn.sap.com/weblogs/images/11829/Diagram2.4-MaintainResponsibilities-I.JPG|height=11...!

Diagram 2.4 - Maintain Responsibilities – I


Create a responsibility for the Alert ..ideally each team can create a responsibility for themselves


Diagram 2.5 - Maintain Responsibilities - II

5. Create a User (Ideally the Team leader) for this responsibility who will receive notification about the transport statuses for each of the team members



Diagram 2.6 - Maintain Responsibilities - III


Possible Enhancements:


1. At present this program has been designed keeping in mind that only the subsequent systems in the Transport layer and not client specific imports. This can be enhanced to check the status codes based on individual clients.
Hint:Check structure ls_request in FM Z_GET_TRANSPORT_LOG

2. Make this as one consolidated report to monitor and review transports across SAP systems landscape from just one SAP client. i.e. Monitor and Alert transport statuses for users across systems like SCM, SRM, CRM, BW and XI just by executing or scheduling the job in SAP core development system as long as relevant SM59 destinations are maintained for each of these systems in Dev box.

2 Comments