Nesneye ait ekli dosya mail gönderme veya indirme

FI belgesine ait ekli dosyaların mail gönderilemesi veya bilgisayara indirilmesi

*&---------------------------------------------------------------------*
*& Report  ZGB_FI_ATTACH_SEND_MAIL
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT zfi_r_attach_send_mail.

INCLUDE zfi_i_attach_send_mail_top.
INCLUDE zfi_i_attach_send_mail_cls.
INCLUDE zfi_i_attach_send_mail_evt.
INCLUDE zfi_i_attach_send_mail_frm.
INCLUDE zfi_i_attach_send_mail_mdl.

*&---------------------------------------------------------------------*
*&  Include           ZGB_I_FI_ATTACH_SEND_MAIL_TOP
*&---------------------------------------------------------------------*
TABLES bkpf.

CLASS lcl_event_receiver DEFINITION DEFERRED.

* zfi_s_attach_send_mail yapısı aşağıdaki değişkenlerden oluşuyor.
* BUKRS
* BELNR
* GJAHR

DATA gt_tab       TYPE TABLE OF zfi_s_attach_send_mail,
           gs_tab       LIKE LINE OF  gt_tab,
           gt_fcat      TYPE          lvc_t_fcat,
           gv_code      LIKE          sy-ucomm,
           gv_save_code LIKE          sy-ucomm,
           gr_grid      TYPE REF TO   cl_gui_alv_grid,
           gr_docking   TYPE REF TO   cl_gui_docking_container,
           gt_fieldcat  TYPE          lvc_t_fcat,
           gs_layout    TYPE          lvc_s_layo,
           gs_variant   TYPE          disvariant,
           gr_receiver  TYPE REF TO   lcl_event_receiver.

SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001."text-001 Seçim parametreleri
  SELECT-OPTIONS s_bukrs FOR bkpf-bukrs,
                   s_belnr FOR bkpf-belnr,
                   s_gjahr FOR bkpf-gjahr.
SELECTION-SCREEN END OF BLOCK b1.

*&---------------------------------------------------------------------*
*&  Include           ZGB_I_FI_ATTACH_SEND_MAIL_CLS
*&---------------------------------------------------------------------*
*---------------------------------------------------------------------
**       CLASS lcl_event_receiver DEFINITION
*---------------------------------------------------------------------*
CLASS lcl_event_receiver DEFINITION.
  PUBLIC SECTION.
*   CL_GUI_ALV_GRID sınıfı ile oluşturulan ALV Grid için toolbar methodu
*   ile buton eklenebilir. Bu eklenen butonlara basıldığında yapılacak
*   işlemler ise user_command metodu içerisinde yapılır. O sebeple yerel
*   sınıfımız içerisine aşağıdaki şekilde bu iki metodumuzu ekliyoruz.
    METHODS handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
      IMPORTING e_object e_interactive,

      handle_user_command FOR EVENT user_command OF cl_gui_alv_grid
        IMPORTING e_ucomm.
ENDCLASS.                    "lcl_event_receiver DEFINITION
*---------------------------------------------------------------------
**       CLASS lcl_event_receiver IMPLEMENTATION
*---------------------------------------------------------------------*
CLASS lcl_event_receiver IMPLEMENTATION.
  METHOD handle_toolbar.

    CONSTANTS c_menu_and_default_button TYPE VALUE 1,
                c_menu                    TYPE VALUE 2,
                c_separator               TYPE VALUE 3,
                c_radio_button            TYPE VALUE 4,
                c_checkbox                TYPE VALUE 5,
                c_menu_entry              TYPE VALUE 6.

    DATAls_toolbar  TYPE stb_button.
*   Bu kısımda ALV Grid ekranında ALV için gelen standart butonlarla
*   bizim butonumuz arasına ayraç koyuyoruz.
    CLEAR ls_toolbar.
    MOVE c_separator            TO ls_toolbar-butn_type.
    APPEND ls_toolbar           TO e_object->mt_toolbar.

*   Daha sonra Mail Göndermek için aşağıda MAIL adında bir buton
*   ekliyoruz. Butona istersek aşağıdaki şekilde icon, metin
*   ekleyebiliriz. Koşullara göre butonun disabled değişkeni
*   ile aktif veya deaktif olmasını sağlayabiliriz. Hatta
*   kullanıcı rapora girerken yetki kontrolü yaparak bu butonları
*   kullanıcının bu işleme yetkisi var ise ekleyebilir yok ise
*   hiç ALV ekranında göstermeme gibi bir durumu sağlayabiliriz.
    CLEAR ls_toolbar.
    MOVE `MAIL`                 TO ls_toolbar-function.
    MOVE icon_mail              TO ls_toolbar-icon.
    MOVE `Mail Gönder`          TO ls_toolbar-quickinfo.
    MOVE `Mail Gönder`          TO ls_toolbar-text.
    MOVE ` `                    TO ls_toolbar-disabled.
    APPEND ls_toolbar           TO e_object->mt_toolbar.

*   Aşağıda yukarıdaki anlattığım şekilde bir ayraç ve dosyaları
*   bilgisayardaki yerel bir klasöre indirmek için INDIR adında
*   bir buton ekliyoruz.
    CLEAR ls_toolbar.
    MOVE c_separator            TO ls_toolbar-butn_type.
    APPEND ls_toolbar           TO e_object->mt_toolbar.

    CLEAR ls_toolbar.
    MOVE `INDIR`                TO ls_toolbar-function.
    MOVE icon_system_save       TO ls_toolbar-icon.
    MOVE `Ekli Dosyaları İndir` TO ls_toolbar-quickinfo.
    MOVE `Ekli Dosyaları İndir` TO ls_toolbar-text.
    MOVE ` `                    TO ls_toolbar-disabled.
    APPEND ls_toolbar           TO e_object->mt_toolbar.

  ENDMETHOD.                    "handle_user_command
  METHOD handle_user_command.
*   HANDLE_TOOLBAR metodu ile eklemiş olduğumuz butonlara basıldığında
*   yapılacak olan işlem ler için aşağıdaki şekilde bir alt program
*   oluşturdum. Alt program oluşturmadan bu metod altında da işlemler
*   yapılabilir.
    PERFORM f_user_command USING e_ucomm.
  ENDMETHOD.
ENDCLASS.                    "lcl_event_receiver IMPLEMENTATION


*&---------------------------------------------------------------------*
*&  Include           ZGB_I_FI_ATTACH_SEND_MAIL_EVT
*&---------------------------------------------------------------------*
START-OF-SELECTION.
  PERFORM get_data.

END-OF-SELECTION.
  IF gt_tab[] IS NOT INITIAL.
*   ALV ekranını CL_GUI_ALV_GRID sınıfı ile oluştuyorsak mutlaka ekran
*   kullanmalıyız. İstenilirse ekran içerisine CUSTOM_CONTROL eklenilebilir
*   ALV Grid CUSTOM_CONTROL`un içerisinde gösterilebilir. Ben ekranda sadece
*   ALV Grid`i göstereceğim için CL_GUI_DOCKING_CONTAINER sınıfını kullandım.
*   Ekrana herhangi bir kontrol eklemedim.
    CALL SCREEN 0100.
  ELSE.
*    Seçim kriterlerine uygun veri bulunamadı
    MESSAGE text-002 TYPE `S`.
  ENDIF.

*&---------------------------------------------------------------------*
*&  Include           ZGB_I_FI_ATTACH_SEND_MAIL_FRM
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*&      Form  DISPLAY_ALV_REPORT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_GT_DATA  text
*      <--P_GT_FIELDCAT  text
*      <--P_GS_LAYOUT  text
*----------------------------------------------------------------------*
FORM display_alv_report CHANGING pt_outtab
                                 pt_fieldcat TYPE lvc_t_fcat
                                 ps_layout   TYPE lvc_s_layo.

  gs_variant-report sy-repid.
* ALV Grid için kullanılacak olan CL_GUI_DOCKING_CONTAINER sınıfı
* için nesne oluşturuluyor. Bu kısımda eğer ekrana CUSTOM_CONTROL
* ekleseydik CL_GUI_CUSTOM_CONTAINER sınıfı tipinde tanımlamış
* olduğumuz bir obje oluşturmalı ve bu objenin CONTAINER_NAME
* alanına ekranda oluşturmuş olduğumuz CUSTOM_CONTROL`un adını
* girmeliyiz.
  CREATE OBJECT gr_docking
    EXPORTING
      ratio `95`
      side  cl_gui_docking_container=>dock_at_top.

* ALV Grid için kullanılacak container aşağıda ALV Grid için oluşturulan
* nesneye atanıyor.
  CREATE OBJECT gr_grid
    EXPORTING
      i_parent gr_docking.

* Aşağıdaki alt programlar ile ALV Grid için gerekli olan field catalog ve
* LAYOUT alanları dolduruluyor.
  PERFORM build_fieldcat TABLES pt_fieldcat.
  PERFORM build_layout   CHANGING ps_layout.

  CALL METHOD gr_grid->set_table_for_first_display
    EXPORTING
      is_layout       ps_layout
      is_variant      gs_variant
      i_save          `A`
    CHANGING
      it_fieldcatalog pt_fieldcat
      it_outtab       pt_outtab.

* ALV Grid için kendi eklediğimiz metodların kullanılabilir olması için
* bizim yerel sınıfımızla aynı tipte olan bir nesne oluşturuluyor ve
* bu nesne içerisinde tanımladığımız metodlar ALV Grid için SET ediliyor.
  CREATE OBJECT gr_receiver.
  SET HANDLER gr_receiver->handle_toolbar      FOR gr_grid.
  SET HANDLER gr_receiver->handle_user_command FOR gr_grid.

* ALV Grid`e TOOLBAR metodunu eklediğimizde butonların ekrana gelmesi
* için aşağıdaki şekilde SET_TOOLBAR_INTERACTIVE metodunun kullanılması
* gerekiyor.
  CALL METHOD gr_grid->set_toolbar_interactive.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  BUILD_FIELDCAT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_PT_FIELDCAT  text
*----------------------------------------------------------------------*
FORM build_fieldcat TABLES pt_fcat   TYPE lvc_t_fcat.

  CALL FUNCTION `LVC_FIELDCATALOG_MERGE`
    EXPORTING
      i_structure_name       `ZGB_S_FI_ATTACH_SEND_MAIL`
    CHANGING
      ct_fieldcat            pt_fcat[]
    EXCEPTIONS
      inconsistent_interface 1
      program_error          2
      OTHERS                 3.

  IF sy-subrc <> 0.
* Implement suitable error handling here
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  BUILD_LAYOUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_PS_LAYOUT  text
*----------------------------------------------------------------------*
FORM build_layout CHANGING ps_layout TYPE lvc_s_layo.

  ps_layout-cwidth_opt `X`.
  ps_layout-sel_mode   `A`.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  F_USER_COMMAND
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_E_UCOMM  text
*----------------------------------------------------------------------*
FORM f_user_command USING p_ucomm TYPE sy-ucomm.

  DATA lt_rows  TYPE lvc_t_row,
         ls_row   LIKE LINE OF lt_rows,
         lv_lines TYPE i,
         lv_hata  TYPE xfeld.

  CLEAR gs_tab.
* ALV Grid`e eklenen butonlarla alakalı işlemleri seçilen satır
* için yapmamız gerekiyor. ALV Grid`de seçilen satırlar GET_SELECTED_ROW
* metodu ile belirleniyor.
  CALL METHOD gr_grid->get_selected_rows
    IMPORTING
      et_index_rows lt_rows.

* Ekranda kullanıcının birden fazla satır seçmesini istemediğimden aşağıda
* satır seçilip seçilmediğini kontrol ediyorum. Fakat ben ekranda birden fazla
* satır seçilmesini istemediğimden çoklu satır seçildiğinde de hata veriyorum.
  DESCRIBE TABLE lt_rows LINES lv_lines.

  IF lt_rows[] IS INITIAL.
    lv_hata `X`.
    MESSAGE `Satır seçiniz` TYPE `S` DISPLAY LIKE `E`.
  ELSEIF lv_lines GT 1.
    lv_hata `X`.
    MESSAGE `Yalnız tek satır seçiniz` TYPE `S` DISPLAY LIKE `E`.
  ENDIF.

  CHECK lv_hata IS INITIAL.

  READ TABLE lt_rows INTO ls_row INDEX 1.
  READ TABLE gt_tab INTO gs_tab INDEX ls_row-index.
* Eğer kullanıcı tek satır seçmiş ise MAIL gönderimi veya indirme
* işlemi yapılabilir.
  CASE p_ucomm.
    WHEN `MAIL`.
      PERFORM send_mail USING gs_tab.
    WHEN `INDIR`.
      PERFORM download_attach_files USING gs_tab.
  ENDCASE.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  GET_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM get_data.

  SELECT bukrs belnr gjahr FROM bkpf INTO TABLE gt_tab
    WHERE bukrs IN s_bukrs AND
          belnr IN s_belnr AND
          gjahr IN s_gjahr.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  SEND_MAIL
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_LT_ROWS  text
*----------------------------------------------------------------------*
FORM send_mail USING ps_tab TYPE zgb_s_fi_attach_send_mail.

  DATA lr_send_request   TYPE REF TO   cl_bcs,
         lr_document       TYPE REF TO   cl_document_bcs,
         lr_recipient      TYPE REF TO   if_recipient_bcs,
         lr_sender         TYPE REF TO   if_sender_bcs,
         lr_bcs_exception  TYPE REF TO   cx_bcs,
         lt_main_text      TYPE          bcsy_text,
         lv_sent_to_all    TYPE          os_boolean,
         ls_address        TYPE          bapiaddr3,
         lv_text           TYPE          string,
         lt_connections    TYPE TABLE OF bdn_con,
         ls_connection     TYPE          bdn_con,
         lt_objcont        TYPE TABLE OF soli,
         lv_subject        TYPE          so_obj_des,
         ls_hd_display     TYPE          sood2,
         lv_type           TYPE          soodk-objtp,
         lv_attach_subject TYPE          sood-objdes,
         lt_solix          TYPE          solix_tab,
         lv_docid          TYPE          sofolenti1-doc_id,
         ls_data           TYPE          sofolenti1,
         lv_objlen         TYPE          sood-objlen,
         lv_mail           TYPE          adr6-smtp_addr.

* Ben maili raporu çalıştıran kullanıcıya göndermek istediğimden
* aşağıdaki fonksiyon ile kullanıcının adres bilgilerini okuyarak
* bu kullanıcı için tanımlanmış bir mail adresi olup olmadığını
* kontrol ediyorum.
  CALL FUNCTION `EMMA_USER_GET_DETAIL`
    EXPORTING
      username sy-uname
    IMPORTING
      address  ls_address.
*    TABLES
*      RETURN         = .

  IF ls_address-e_mail IS INITIAL.

    MESSAGE `Mail adresi bulunamadı` TYPE `E`.

  ELSE.
* Eğer kullanıcı için mail adresi tanımlanmış ise seçilen FI belgesi
* için dosya eklenip eklenmediği aşağıdaki alt program ile kontrol ediliyor.
    PERFORM get_attachment_files TABLES lt_connections
                                 USING  ps_tab.

    CHECK lt_connections[] IS NOT INITIAL.
* Eğer dosya eklenmiş ise mail gönderebiliriz.
    TRY.
* Mail gönderimi için bu raporda CL_BCS sınıfını kullanacağız. İlk olarak
* CL_BCS sınıfı ile tanımlanmış olan nesnemizi aşağıdaki şekilde oluşturuyoruz.
        lr_send_request cl_bcs=>create_persistent).

* Aşağıda HTML biçiminde mail içeriğini hazırlıyoruz. Yukarıdaki fonksiyon ile
* kullanıcının ana verisinde eğer ad ve soyad girilmiş ise FULLNAME değişkeninde
* kullanıcının adının ve soyadının birleşimi geliyor.
        CLEAR lv_text.
        CONCATENATE `<p> Sayın` ls_address-fullname `, </p>` INTO lv_text
          SEPARATED BY space.
        APPEND lv_text TO lt_main_text.

* Daha sonra bir paragraf boşluk bırakıyoruz.
        CLEAR lv_text.
        lv_text `<p> </p>`.
        APPEND lv_text TO lt_main_text.

* Aşağıda mail içeriği için yeni bir paragraf oluşturuluyor.
        CLEAR lv_text.
        CONCATENATE `<p>` ps_tab-bukrs `şirket kodu` ps_tab-gjahr `mali yılı için oluşturulan`
          ps_tab-belnr `numaralı belgeye ait dökümanlar yukarıdaki ektedir. </p>`
          INTO lv_text SEPARATED BY space.
        APPEND lv_text TO lt_main_text.

        CLEAR lv_text.
        lv_text `<p> </p>`.
        APPEND lv_text TO lt_main_text.

        CLEAR lv_text.
        lv_text `<p> İyi çalışmalar. </p>`.
        APPEND lv_text TO lt_main_text.

* Mail içeriği oluşturuldu. Mailin konusu lv_subject alanına yazılıyor.
        lv_subject `FI Ekli Dosyalar`.

* Mail için döküman oluşturuluyor ve bu dökümana mail içeriği için hangi
* tipin kullanılacağı, mail içeriği için oluşturduğumuz tablo ve mail konusu
* aşağıdaki şekilde atanıyor. Biz HTML yapısını kullandık istenilirse farklı
* tipler de kullanılabilir.
        lr_document cl_document_bcs=>create_document(
          i_type    `HTM`
          i_text    lt_main_text
          i_subject lv_subject ).

* Aşağıda belge için bulunan dökümanlar maile ek olarak ekleniyor.
        LOOP AT lt_connections INTO ls_connection.

          CLEAR lv_typelv_attach_subjectlv_docidls_datalv_objlen.
          REFRESH lt_solix.

          lv_docid ls_connection-loio_id.
* Bu fonksiyon ile ekli dosyanın içeriği lt_solix değişkenine atanıyor. Fonksiyonda
* kullanılan document_id ile diğer fonksiyondan document_id olarak dönen loio_id
* alanı aynı tipte olmadığından ls_connection-loio_id lv_docid değişkenine aktarıldı.
          CALL FUNCTION `SO_DOCUMENT_READ_API1`
            EXPORTING
              document_id                lv_docid
            IMPORTING
              document_data              ls_data
            TABLES
              contents_hex               lt_solix[]
            EXCEPTIONS
              document_id_not_exist      1
              operation_no_authorization 2
              x_error                    3
              OTHERS                     4.

          IF sy-subrc <> 0.
* Implement suitable error handling here
          ENDIF.

          IF lt_solix[] IS NOT INITIAL.
* Eğer ekli dosyanın içeriğini lt_solix değişkenine atabildiyse aşağıda mail için
* oluşturmuş olduğumuz lr_document nesnesine bu dosyayı add_attachment metodu ile
* ekliyoruz. Maile ekli dosya ekler iken dosyanın hangi tipte olduğunu, dosya tanımını
* ve içeriğini veriyoruz. Dosya tipi yukarıdaki fonksiyondaki ls_data içerisindeki
* obj_type değişkeninde mevcut(txt,xls,pdf vs.). Dosyanın tanımı olarak ekli dökümanın
* tanımını kullanıyoruz. Döküman boyutu isteğe bağlı olarak girilebilir ls_data içerisindeki
* doc_size dosya boyutunu veriyor. Yukarıdaki fonksiyon ile dökümanın içeriğini lt_solix
* tablosuna atmıştık. Aşağıdaki şekilde add_attachment metodu kullanılarak maile eki ekliyoruz.
* Biz mail içeriği için BINARY formatını kullandığımızdan i_att_content_hex değişkenine
* tablomuzu atadık. Eğer ASCI formatını kullansaydık tablomuzu add_attachment içerisindeki
* I_ATT_CONTENT_TEXT parametresine vermeliydik.
            lv_type           ls_data-obj_type.
            lv_attach_subject ls_connection-descript.
            lv_objlen         ls_data-doc_size.

            lr_document->add_attachment(
              i_attachment_type    lv_type
              i_attachment_subject lv_attach_subject
              i_attachment_size    lv_objlen
              i_att_content_hex    lt_solix[] ).

          ENDIF.

        ENDLOOP.
* Mail içeriği ve ekli dökümanlar nesnemize atanıyor.
        lr_send_request->set_documentlr_document ).

* Mail gönderilecek olan mail adresi add_recipient metodu ile ekleniyor. Mail birden fazla
* kişiye gönderilebilir. Mail gönderilmek istenen her adres aşağıdaki şekilde eklenebilir.
        lr_recipient cl_cam_address_bcs=>create_internet_addressls_address-e_mail ).
        CALL METHOD lr_send_request->add_recipient
          EXPORTING
            i_recipient lr_recipient
            i_express   `X`.

* Aşağıdaki şekilde istenilirse mailin gönderileceği adres atanabilir. Ben bu kısmı kullanmadım.
*        lv_mail   = `xxx@xxx.com.tr`.
*        lr_sender = cl_cam_address_bcs=>create_internet_address( lv_mail ).
*        lr_send_request->set_sender( lr_sender ).

        CALL METHOD lr_send_request->set_send_immediately`X` ).

        lv_sent_to_all lr_send_request->sendi_with_error_screen `X` ).

        IF lv_sent_to_all IS NOT INITIAL.
          MESSAGE s022(so).
        ELSE.
          MESSAGE s023(soDISPLAY LIKE `E`.
        ENDIF.

      CATCH cx_bcs INTO lr_bcs_exception.
        MESSAGE i865(soWITH lr_bcs_exception->error_type.
    ENDTRY.

  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  DOWNLOAD_ATTACH_FILES
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_LT_ROWS  text
*----------------------------------------------------------------------*
FORM download_attach_files USING ps_tab TYPE zgb_s_fi_attach_send_mail.

  DATA lt_connections TYPE TABLE OF bdn_con,
         ls_connection  TYPE          bdn_con,
         lt_objcont     TYPE TABLE OF soli,
         ls_hd_display  TYPE          sood2,
         lv_filename    TYPE          string,
         lv_folder      TYPE          string,
         lv_index       TYPE          i,
         ls_folder_id   TYPE          soodk,
         ls_object_id   TYPE          soodk.

* Aşağıdaki metod ile kullanıcıya dosyaların indirilmesi için kullanılacak olan
* klasör seçtiriliyor.
  CALL METHOD cl_gui_frontend_services=>directory_browse
    EXPORTING
      window_title         `Klasör seçiniz`
    CHANGING
      selected_folder      lv_folder
    EXCEPTIONS
      cntl_error           1
      error_no_gui         2
      not_supported_by_gui 3
      OTHERS               4.

  IF sy-subrc <> 0.
  ENDIF.

  CHECK lv_folder IS NOT INITIAL.
* Eğer kullanıcı klasörü seçerse ileme devam ediliyor ve ekli dosyalar mail gönderimindeki
* gibi get_attachment_files alt programı ile getiriliyor.
  PERFORM get_attachment_files TABLES lt_connections
                               USING  ps_tab.

  CHECK lt_connections[] IS NOT INITIAL.

  LOOP AT lt_connections INTO ls_connection.

    CLEAR ls_hd_displaylv_filenamelv_indexls_folder_idls_object_id.
    REFRESH lt_objcont.

    ls_folder_id-objtp ls_connection-loio_id(3).
    ls_folder_id-objyr ls_connection-loio_id+3(2).
    ls_folder_id-objno ls_connection-loio_id+5(12).

    ls_object_id-objtp ls_connection-loio_id+17(3).
    ls_object_id-objyr ls_connection-loio_id+20(2).
    ls_object_id-objno ls_connection-loio_id+22(12).
* Bu kısımda mail gönderimindeki gibi SO_DOCUMENT_READ_API1 fonksiyonu ve ardından
* GUI_DOWNLOAD fonksiyonu kullanılabilirdi. Ben SO_OBJECT_READ ve SO_OBJECT_DOWNLOAD
* fonksiyonlarını kullandım. Yukarıda SO_OBJECT_READ fonksiyonuna verilmesi gereken
* parametreler dolduruluyor. Daha sonra fonksiyona veriliyor ve ls_hd_display, lt_objcont
* değişkenleri fonksiyondan döndürülüyor.
    CALL FUNCTION `SO_OBJECT_READ`
      EXPORTING
        folder_id                  ls_folder_id
        object_id                  ls_object_id
      IMPORTING
*       OBJECT_FL_DISPLAY          =
        object_hd_display          ls_hd_display
*       OBJECT_RC_DISPLAY          =
      TABLES
        objcont                    lt_objcont[]
      EXCEPTIONS
        active_user_not_exist      1
        communication_failure      2
        component_not_available    3
        folder_not_exist           4
        folder_no_authorization    5
        object_not_exist           6
        object_no_authorization    7
        operation_no_authorization 8
        owner_not_exist            9
        parameter_error            10
        substitute_not_active      11
        substitute_not_defined     12
        system_failure             13
        x_error                    14
        OTHERS                     15.

    IF sy-subrc <> 0.
* Implement suitable error handling here
    ENDIF.

    IF lt_objcont[] IS NOT INITIAL.
* Eğer lt_objcont değişkeni boş değil ise dosya adının önüne hangi belgeye ait olduğunun anlaşılması
* için şirket kodu belge numarası ve mali yıl ekleniyor.
      CONCATENATE ps_tab-bukrs ps_tab-belnr ps_tab-gjahr ls_connection-descript INTO lv_filename.
*      CONCATENATE lv_filename ls_connection-docuclass INTO lv_filename SEPARATED BY `.`.
* Dosyanın oluşturulan adının önüne seçilen klasörün yolu eklenerek dosyanın yolu oluşturuluyor.
      CONCATENATE lv_folder lv_filename INTO lv_filename SEPARATED BY ``.
* FILE_EXIST alt programı ile klasör içerisinde aynı isimde bir dosya olup olmadığı kontrol ediliyor.
      PERFORM file_exist USING    ls_