[ABAP] Transportauftrag als ZIP-Datei speichern

SELECTION-SCREEN BEGIN OF LINE.
  SELECTION-SCREEN COMMENT (20) lbl1 FOR FIELD p_trkorr.
  PARAMETERS: p_trkorr LIKE e070-trkorr OBLIGATORY.
SELECTION-SCREEN END OF LINE.

INITIALIZATION.

  lbl1 = 'Transport-Auftrag:'.

START-OF-SELECTION.
  TRY.
      DATA: lv_req TYPE trwbo_request.

* (Nach-)Lesen von Einzelbestandteilen eines Auftrags
      CALL FUNCTION 'TR_READ_REQUEST'
        EXPORTING
          iv_read_e070     = abap_true
          iv_read_e07t     = abap_true
          iv_trkorr        = p_trkorr
        CHANGING
          cs_request       = lv_req
        EXCEPTIONS
          error_occured    = 1
          no_authorization = 2
          OTHERS           = 3.

      IF sy-subrc = 0.
*D Änderbar
*L Änderbar, geschützt
*O Freigabe gestartet
*R Freigegeben
*N Freigegeben (Importschutz für reparierte Objekte aktiv)
        IF lv_req-h-trstatus = 'R'.

          DATA: lv_trans_cofile_dir TYPE stpa-file.
          DATA: lv_trans_data_dir TYPE stpa-file.

* intern: Pfade der Transportverzeichnisse
          CALL FUNCTION 'TRINT_FI_GET_DIRECTORY_NAMES'
            EXPORTING
              iv_dir_type          = 'T'
            IMPORTING
              ev_data_dir          = lv_trans_data_dir
              ev_cofiles_dir       = lv_trans_cofile_dir
            EXCEPTIONS
              get_dir_trans_failed = 1
              build_path_failed    = 2
              OTHERS               = 3.

          IF sy-subrc = 0.
* Name
            DATA(lv_syst) = |{ p_trkorr(3) }|.
            DATA(lv_num) = |{ p_trkorr+4 }|.
            DATA(lv_name) = |{ lv_num }.{ lv_syst }|.

* Cofile lesen
            DATA: lv_xstr_cofile TYPE xstring.
            DATA(lv_cofile) = |{ lv_trans_cofile_dir }/K{ lv_name }|.

            OPEN DATASET lv_cofile FOR INPUT IN BINARY MODE.
            READ DATASET lv_cofile INTO lv_xstr_cofile.
            CLOSE DATASET lv_cofile.

* Data lesen
            DATA: lv_xstr_data TYPE xstring.
            DATA(lv_data) = |{ lv_trans_data_dir }/R{ lv_name }|.

            OPEN DATASET lv_data FOR INPUT IN BINARY MODE.
            READ DATASET lv_data INTO lv_xstr_data.
            CLOSE DATASET lv_data.

* Zip
            DATA(o_zip) = NEW cl_abap_zip( ).

            o_zip->add( name    = |K{ lv_name }|
                        content = lv_xstr_cofile ).

            o_zip->add( name    = |R{ lv_name }|
                        content = lv_xstr_data ).

            DATA(lv_xstr_zip) = o_zip->save( ).

* SOLIX
            DATA(it_raw_data) = cl_bcs_convert=>xstring_to_solix( EXPORTING iv_xstring = lv_xstr_zip ).

            DATA: lv_action TYPE i.
            DATA: lv_filename TYPE string.
            DATA: lv_fullpath TYPE string.
            DATA: lv_path TYPE string.

            DATA(lv_default) = |{ lv_req-h-as4text }_{ p_trkorr }|.

* alle Vorkommen, die nicht [a-zA-Z0-9_] entsprechen, durch '_' ersetzen
            REPLACE ALL OCCURRENCES OF REGEX '[^\w]+' IN lv_default WITH '_'.

* Save-Dialog
            cl_gui_frontend_services=>file_save_dialog( EXPORTING default_file_name = lv_default
                                                                  default_extension = 'zip'
                                                                  file_filter       = |{ cl_gui_frontend_services=>filetype_all }|
                                                        CHANGING  filename          = lv_filename
                                                                  path              = lv_path
                                                                  fullpath          = lv_fullpath
                                                                  user_action       = lv_action ).

            IF lv_action EQ cl_gui_frontend_services=>action_ok.

* Datei lokal speichern
              cl_gui_frontend_services=>gui_download( EXPORTING filename     = lv_fullpath
                                                                filetype     = 'BIN'
                                                                bin_filesize = xstrlen( lv_xstr_zip )
                                                      CHANGING  data_tab     = it_raw_data ).
            ENDIF.

          ELSE.
            WRITE: / |Systemverzeichnisse nicht gefunden.|.
          ENDIF.
        ELSE.
          WRITE: / |Auftrag { p_trkorr } nicht frei gegeben.|.
        ENDIF.

      ELSE.
        MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO DATA(lv_msg).
        WRITE: / lv_msg.
      ENDIF.
    CATCH cx_root INTO DATA(e_txt).
      WRITE: / e_txt->get_text( ).
  ENDTRY.