"! Change transport system API CLASS zcl_abapgit_cts_api DEFINITION PUBLIC FINAL CREATE PRIVATE GLOBAL FRIENDS zcl_abapgit_factory. PUBLIC SECTION. INTERFACES: zif_abapgit_cts_api. PROTECTED SECTION. PRIVATE SECTION. DATA: mv_confirm_transp_msgs_called TYPE abap_bool. "! Returns the transport request / task the object is currently locked in "! @parameter iv_program_id | Program ID "! @parameter iv_object_type | Object type "! @parameter iv_object_name | Object name "! @parameter rv_transport | Transport request / task "! @raising zcx_abapgit_exception | Object is not locked in a transport METHODS get_current_transport_for_obj IMPORTING !iv_program_id TYPE pgmid DEFAULT 'R3TR' !iv_object_type TYPE trobjtype !iv_object_name TYPE sobj_name RETURNING VALUE(rv_transport) TYPE trkorr RAISING zcx_abapgit_exception . "! Returns the transport request / task that includes the object (even if not locked) "! @parameter iv_program_id | Program ID "! @parameter iv_object_type | Object type "! @parameter iv_object_name | Object name "! @parameter rv_transport | Transport request / task "! @raising zcx_abapgit_exception | Object is not locked in a transport METHODS get_current_transport_from_db IMPORTING !iv_program_id TYPE pgmid DEFAULT 'R3TR' !iv_object_type TYPE trobjtype !iv_object_name TYPE sobj_name RETURNING VALUE(rv_transport) TYPE trkorr RAISING zcx_abapgit_exception . "! Check if the object is currently locked in a transport "! @parameter iv_program_id | Program ID "! @parameter iv_object_type | Object type "! @parameter iv_object_name | Object name "! @parameter rv_locked | Object is locked "! @raising zcx_abapgit_exception | Object type is not lockable METHODS is_object_locked_in_transport IMPORTING !iv_program_id TYPE pgmid DEFAULT 'R3TR' !iv_object_type TYPE trobjtype !iv_object_name TYPE sobj_name RETURNING VALUE(rv_locked) TYPE abap_bool RAISING zcx_abapgit_exception . "! Check if the object type is lockable "! @parameter iv_program_id | Program ID "! @parameter iv_object_type | Object type "! @parameter rv_lockable | Lockable METHODS is_object_type_lockable IMPORTING !iv_program_id TYPE pgmid DEFAULT 'R3TR' !iv_object_type TYPE trobjtype RETURNING VALUE(rv_lockable) TYPE abap_bool . "! Check if the object type can be transported "! @parameter iv_program_id | Program ID "! @parameter iv_object_type | Object type "! @parameter rv_transportable | Transportable METHODS is_object_type_transportable IMPORTING !iv_program_id TYPE pgmid DEFAULT 'R3TR' !iv_object_type TYPE trobjtype RETURNING VALUE(rv_transportable) TYPE abap_bool . ENDCLASS. CLASS zcl_abapgit_cts_api IMPLEMENTATION. METHOD get_current_transport_for_obj. DATA: lv_object_lockable TYPE abap_bool, lv_locked TYPE abap_bool, lv_transport_request TYPE trkorr, lv_task TYPE trkorr, lv_tr_object_name TYPE trobj_name. lv_tr_object_name = iv_object_name. CALL FUNCTION 'TR_CHECK_OBJECT_LOCK' EXPORTING wi_pgmid = iv_program_id wi_object = iv_object_type wi_objname = lv_tr_object_name IMPORTING we_lockable_object = lv_object_lockable we_locked = lv_locked we_lock_order = lv_transport_request we_lock_task = lv_task EXCEPTIONS empty_key = 1 no_systemname = 2 no_systemtype = 3 unallowed_lock_order = 4 OTHERS = 5. IF sy-subrc <> 0. zcx_abapgit_exception=>raise_t100( ). ENDIF. IF lv_locked = abap_false. zcx_abapgit_exception=>raise( |Object { iv_program_id }-{ iv_object_type }-{ iv_object_name } is not locked| ). ENDIF. IF lv_object_lockable = abap_false. zcx_abapgit_exception=>raise( |Object type { iv_program_id }-{ iv_object_type } not lockable| ). ENDIF. rv_transport = lv_transport_request. ENDMETHOD. METHOD get_current_transport_from_db. " This method is used for objects that are included in transports but not locked " for example, namespaces (NSPC) SELECT SINGLE a~trkorr FROM e070 AS a JOIN e071 AS b ON a~trkorr = b~trkorr INTO rv_transport WHERE ( a~trstatus = 'D' OR a~trstatus = 'L' ) AND a~trfunction <> 'G' AND b~pgmid = iv_program_id AND b~object = iv_object_type AND b~obj_name = iv_object_name. ENDMETHOD. METHOD is_object_locked_in_transport. DATA: ls_object_key TYPE e071, lv_type_check_result TYPE c LENGTH 1, ls_lock_key TYPE tlock_int, lv_lock_flag TYPE c LENGTH 1. ls_object_key-pgmid = iv_program_id. ls_object_key-object = iv_object_type. ls_object_key-obj_name = iv_object_name. CALL FUNCTION 'TR_CHECK_TYPE' EXPORTING wi_e071 = ls_object_key IMPORTING pe_result = lv_type_check_result we_lock_key = ls_lock_key. IF lv_type_check_result <> 'L'. zcx_abapgit_exception=>raise( |Object type { iv_program_id }-{ iv_object_type } not lockable| ). ENDIF. CALL FUNCTION 'TRINT_CHECK_LOCKS' EXPORTING wi_lock_key = ls_lock_key IMPORTING we_lockflag = lv_lock_flag EXCEPTIONS empty_key = 1 OTHERS = 2. IF sy-subrc <> 0. zcx_abapgit_exception=>raise_t100( ). ENDIF. rv_locked = boolc( lv_lock_flag <> space ). ENDMETHOD. METHOD is_object_type_lockable. DATA: ls_object_key TYPE e071, lv_type_check_result TYPE c LENGTH 1. ls_object_key-pgmid = iv_program_id. ls_object_key-object = iv_object_type. ls_object_key-obj_name = '_'. " Dummy value #2071 CALL FUNCTION 'TR_CHECK_TYPE' EXPORTING wi_e071 = ls_object_key IMPORTING pe_result = lv_type_check_result. rv_lockable = boolc( lv_type_check_result = 'L' ). ENDMETHOD. METHOD is_object_type_transportable. DATA: ls_object_key TYPE e071, lv_type_check_result TYPE c LENGTH 1. ls_object_key-pgmid = iv_program_id. ls_object_key-object = iv_object_type. ls_object_key-obj_name = '_'. " Dummy value #2071 CALL FUNCTION 'TR_CHECK_TYPE' EXPORTING wi_e071 = ls_object_key IMPORTING pe_result = lv_type_check_result. rv_transportable = boolc( lv_type_check_result CA 'RTL' ). ENDMETHOD. METHOD zif_abapgit_cts_api~create_transport_entries. DATA lt_tables TYPE tredt_objects. DATA lt_table_keys TYPE STANDARD TABLE OF e071k. DATA lv_with_dialog TYPE abap_bool. cl_table_utilities_brf=>create_transport_entries( EXPORTING it_table_ins = it_table_ins it_table_upd = it_table_upd it_table_del = it_table_del iv_tabname = iv_tabname CHANGING ct_e071 = lt_tables ct_e071k = lt_table_keys ). " cl_table_utilities_brf=>write_transport_entries does not allow passing a request CALL FUNCTION 'TR_OBJECTS_CHECK' TABLES wt_ko200 = lt_tables EXCEPTIONS cancel_edit_other_error = 1 show_only_other_error = 2 OTHERS = 3. IF sy-subrc <> 0. zcx_abapgit_exception=>raise_t100( ). ENDIF. IF iv_transport IS INITIAL. lv_with_dialog = abap_true. ENDIF. CALL FUNCTION 'TRINT_OBJECTS_CHECK_AND_INSERT' EXPORTING iv_order = iv_transport iv_with_dialog = lv_with_dialog CHANGING ct_ko200 = lt_tables ct_e071k = lt_table_keys EXCEPTIONS OTHERS = 1. IF sy-subrc <> 0. zcx_abapgit_exception=>raise_t100( ). ENDIF. ENDMETHOD. METHOD zif_abapgit_cts_api~get_r3tr_obj_for_limu_obj. CLEAR ev_object. CLEAR ev_obj_name. CALL FUNCTION 'GET_R3TR_OBJECT_FROM_LIMU_OBJ' EXPORTING p_limu_objtype = iv_object p_limu_objname = iv_obj_name IMPORTING p_r3tr_objtype = ev_object p_r3tr_objname = ev_obj_name EXCEPTIONS no_mapping = 1 OTHERS = 2. IF sy-subrc <> 0 OR ev_obj_name IS INITIAL. zcx_abapgit_exception=>raise( |No R3TR Object found for { iv_object } { iv_obj_name }| ). ENDIF. ENDMETHOD. METHOD zif_abapgit_cts_api~get_transports_for_list. DATA lv_request TYPE trkorr. DATA lt_tlock TYPE SORTED TABLE OF tlock WITH NON-UNIQUE KEY object hikey. DATA ls_object_key TYPE e071. DATA lv_type_check_result TYPE c LENGTH 1. DATA ls_lock_key TYPE tlock_int. DATA ls_transport LIKE LINE OF rt_transports. FIELD-SYMBOLS LIKE LINE OF it_items. FIELD-SYMBOLS LIKE LINE OF lt_tlock. * Workarounds to improve performance, note that IT_ITEMS might * contain 1000s of rows, see standard logic in function module * TR_CHECK_OBJECT_LOCK * avoid database lookups in TLOCK for each item, SELECT * FROM tlock INTO TABLE lt_tlock. IF sy-subrc <> 0. RETURN. ENDIF. LOOP AT it_items ASSIGNING . CLEAR lv_request. ls_object_key-pgmid = 'R3TR'. ls_object_key-object = -obj_type. ls_object_key-obj_name = -obj_name. CALL FUNCTION 'TR_CHECK_TYPE' EXPORTING wi_e071 = ls_object_key IMPORTING we_lock_key = ls_lock_key pe_result = lv_type_check_result. IF lv_type_check_result = 'L'. LOOP AT lt_tlock ASSIGNING WHERE object = ls_lock_key-obj AND hikey >= ls_lock_key-low AND lokey <= ls_lock_key-hi. "#EC PORTABLE lv_request = -trkorr. EXIT. ENDLOOP. ELSEIF is_object_type_transportable( -obj_type ) = abap_true. lv_request = get_current_transport_from_db( iv_object_type = -obj_type iv_object_name = -obj_name ). ENDIF. IF lv_request IS NOT INITIAL. ls_transport-obj_type = -obj_type. ls_transport-obj_name = -obj_name. ls_transport-trkorr = lv_request. INSERT ls_transport INTO TABLE rt_transports. ENDIF. ENDLOOP. ENDMETHOD. METHOD zif_abapgit_cts_api~get_transport_for_object. IF is_item-obj_type IS NOT INITIAL AND is_item-obj_name IS NOT INITIAL. IF is_object_type_lockable( is_item-obj_type ) = abap_true AND is_object_locked_in_transport( iv_object_type = is_item-obj_type iv_object_name = is_item-obj_name ) = abap_true. rv_transport = get_current_transport_for_obj( iv_object_type = is_item-obj_type iv_object_name = is_item-obj_name ). ELSEIF is_object_type_transportable( is_item-obj_type ) = abap_true. rv_transport = get_current_transport_from_db( iv_object_type = is_item-obj_type iv_object_name = is_item-obj_name ). ENDIF. ENDIF. ENDMETHOD. METHOD zif_abapgit_cts_api~insert_transport_object. CALL FUNCTION 'RS_CORR_INSERT' EXPORTING object = iv_obj_name object_class = iv_object devclass = iv_package master_language = iv_language mode = iv_mode global_lock = abap_true suppress_dialog = abap_true EXCEPTIONS cancelled = 1 permission_failure = 2 unknown_objectclass = 3 OTHERS = 4. IF sy-subrc <> 0. zcx_abapgit_exception=>raise_t100( ). ENDIF. ENDMETHOD. METHOD zif_abapgit_cts_api~is_chrec_possible_for_package. IF iv_package IS NOT INITIAL. rv_possible = zcl_abapgit_factory=>get_sap_package( iv_package )->are_changes_recorded_in_tr_req( ). ENDIF. ENDMETHOD. METHOD zif_abapgit_cts_api~read_description. SELECT SINGLE as4text FROM e07t INTO rv_description WHERE trkorr = iv_trkorr AND langu = sy-langu ##SUBRC_OK. ENDMETHOD. METHOD zif_abapgit_cts_api~read_user. SELECT SINGLE as4user FROM e070 INTO rv_uname WHERE trkorr = iv_trkorr ##SUBRC_OK. ENDMETHOD. METHOD zif_abapgit_cts_api~confirm_transport_messages. TYPES: BEGIN OF ty_s_message, id TYPE symsgid, ty TYPE symsgty, no TYPE symsgno, v1 TYPE symsgv, v2 TYPE symsgv, v3 TYPE symsgv, v4 TYPE symsgv, END OF ty_s_message. DATA ls_message TYPE ty_s_message. FIELD-SYMBOLS: TYPE STANDARD TABLE. IF mv_confirm_transp_msgs_called = abap_true. RETURN. ENDIF. " remember the call to avoid duplicates in GT_CONFIRMED_MESSAGES mv_confirm_transp_msgs_called = abap_true. " Auto-confirm certain messages (requires SAP Note 1609940) PERFORM dummy IN PROGRAM saplstrd IF FOUND. "load function group STRD once into memory ASSIGN ('(SAPLSTRD)GT_CONFIRMED_MESSAGES') TO . IF sy-subrc <> 0. RETURN. ENDIF. " Object can only be created in package of namespace ls_message-id = 'TR'. ls_message-no = '007'. INSERT ls_message INTO TABLE . " Original system set to "SAP" ls_message-id = 'TR'. ls_message-no = '013'. INSERT ls_message INTO TABLE . " Make repairs in foreign namespaces only if they are urgent ls_message-id = 'TR'. ls_message-no = '852'. INSERT ls_message INTO TABLE . " Make repairs in foreign namespaces only if they are urgent ls_message-id = 'TK'. ls_message-no = '016'. INSERT ls_message INTO TABLE . rv_messages_confirmed = abap_true. ENDMETHOD. ENDCLASS.