I would like to explain about how to Attach File to ODATA . This blog Post is mainly useful for beginners.
Please follow the below steps to Create attachments.
Step: 1 Go to SEGW T-code and create new project.
Click on Create button .The Popup will open.
Step:2 Give the ‘Project name’ and ‘Description’ ‘Package’ and click on Continue.
Step:3 Right click on Data Model ->create->Entity Type and Give the Entity type name and check Create Default Entity set and click on ‘Continue’.
Step:4 The entity for attachments is to be marked as ‘Media Type’ .
Step: 5 Now Create properties for the above Entity Type and must Select the key for your structure  and Click on ‘Generate runtime objects‘ button and the message shows generated successfully as below.
Step: 6 Click on methods–>inherited–>Redefine and write the logic.
The model provider extension class should redefine DEFINE method to handle this Media Type entity.
METHOD define.

    super->define( ).

   DATA: lo_entity   TYPE REF TO /iwbep/if_mgw_odata_entity_typ,
          lo_entity1  TYPE REF TO /iwbep/if_mgw_odata_entity_typ,
          lo_property TYPE REF TO /iwbep/if_mgw_odata_property.

    lo_entity = model->get_entity_type( iv_entity_name = 'Attachment' ).

    IF lo_entity IS BOUND.
      lo_property = lo_entity->get_property( iv_property_name = 'Delivery' ).
      lo_property = lo_entity->get_property( iv_property_name = 'Filename' ).
      lo_property = lo_entity->get_property( iv_property_name = 'Mimetype' ).
      lo_property = lo_entity->get_property( iv_property_name = 'Value' ).

      lo_property->set_as_content_type( ).
    ENDIF.

  ENDMETHOD.

 

Data Provider

The three main methods GET_ENTITYSET (attachment list), GET_STREAM, CREATE_STREAM and implemented in a utility class which is expected to be reused from each service requiring object services attachments.

 

CREATE_STREAM

This method will upload the any types of files attachment.

   METHOD /iwbep/if_mgw_appl_srv_runtime~create_stream.
*--upload input attachments and saving in business content server for further process.
*--data declarations

    DATA: lt_objhead           TYPE STANDARD TABLE OF soli,
          ls_objhead           TYPE soli,
          ls_object            TYPE borident,
          lt_xdata             TYPE solix_tab,
          ls_xdata             TYPE soli,
          lt_data              TYPE soli_tab,
          ls_folmem_k          TYPE sofmk,
          ls_note              TYPE borident,
          ls_obj_id            TYPE soodk,
          ls_fol_id            TYPE soodk,
          ls_obj_data          TYPE sood1,
          lv_ep_note           TYPE borident-objkey,
          lv_tmp_fn            TYPE string,
          lv_tmp_des           TYPE string,
          lv_offset            TYPE i,
          lv_size              TYPE i,
          lv_temp_len          TYPE i,
          lv_offset_old        TYPE i,
          lv_extension         TYPE string,
          lv_reqstring         TYPE string,
          lv_key               TYPE swo_typeid,
          lv_type              TYPE swo_objtyp,
          lv_task              TYPE char4,
          lo_message_container TYPE REF TO /iwbep/if_message_container,
          lv_text              TYPE bapiret2,
          lv_corid             TYPE string,
          ls_data              TYPE zcl_zattch_file_mpc=>ts_attachment.

    CONSTANTS: lc_hex_null TYPE x LENGTH 1 VALUE '20'.

    DATA(lv_xstring)  = is_media_resource-value.
    DATA(lv_mimetype) = is_media_resource-mime_type.

*--splitting input file name into file name and extension.
    SPLIT iv_slug AT '/' INTO  lv_corid lv_tmp_fn.
    SPLIT lv_tmp_fn AT '.' INTO lv_tmp_fn lv_extension.


*--call function to convert xsrting to binary
    CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
      EXPORTING
        buffer          = lv_xstring
        append_to_table = 'X'
      IMPORTING
        output_length   = lv_size
      TABLES
        binary_tab      = lt_xdata.

*--change hex data to text data
    CALL FUNCTION 'SO_SOLIXTAB_TO_SOLITAB'
      EXPORTING
        ip_solixtab = lt_xdata
      IMPORTING
        ep_solitab  = lt_data.

*--call function to get folder id
    CALL FUNCTION 'SO_FOLDER_ROOT_ID_GET'
      EXPORTING
        region                = 'B'
      IMPORTING
        folder_id             = ls_fol_id
      EXCEPTIONS
        communication_failure = 1
        owner_not_exist       = 2
        system_failure        = 3
        x_error               = 4
        OTHERS                = 5.

    IF sy-subrc = 0.
      ls_obj_data-objsns   = 'O'.
      ls_obj_data-objla    = sy-langu.
      ls_obj_data-objdes   = lv_tmp_fn.
      ls_obj_data-file_ext = lv_extension.
      ls_obj_data-objlen   = lv_size.
      TRANSLATE ls_obj_data-file_ext TO UPPER CASE.
      TRANSLATE lv_tmp_fn TO UPPER CASE.

      CONCATENATE lv_tmp_fn '.' lv_extension INTO lv_tmp_des.
      TRANSLATE ls_obj_data-objdes TO UPPER CASE.
      ls_objhead = lv_tmp_des.
      APPEND ls_objhead TO lt_objhead.

*--insert document into business content server.

      CALL FUNCTION 'SO_OBJECT_INSERT'
        EXPORTING
          folder_id                  = ls_fol_id
          object_type                = 'EXT'
          object_hd_change           = ls_obj_data
        IMPORTING
          object_id                  = ls_obj_id
        TABLES
          objhead                    = lt_objhead
          objcont                    = lt_data
        EXCEPTIONS
          active_user_not_exist      = 1
          communication_failure      = 2
          component_not_available    = 3
          dl_name_exist              = 4
          folder_not_exist           = 5
          folder_no_authorization    = 6
          object_type_not_exist      = 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 .
        COMMIT WORK.
        lv_key = lv_corid.
        ls_object-objkey  = lv_key.
        ls_object-objtype = 'ZPC'.
        ls_folmem_k-foltp = ls_fol_id-objtp.
        ls_folmem_k-folyr = ls_fol_id-objyr.
        ls_folmem_k-folno = ls_fol_id-objno.
        ls_folmem_k-doctp = ls_obj_id-objtp.
        ls_folmem_k-docyr = ls_obj_id-objyr.
        ls_folmem_k-docno = ls_obj_id-objno.
        lv_ep_note        = ls_folmem_k.
        ls_note-objkey    = lv_ep_note.
        ls_note-objtype    = 'MESSAGE'.

        CALL FUNCTION 'BINARY_RELATION_CREATE_COMMIT'
          EXPORTING
            obj_rolea    = ls_object
            obj_roleb    = ls_note
            relationtype = 'ATTA'
          EXCEPTIONS
            OTHERS       = 1.

        IF sy-subrc NE 0.
          lv_text-message = 'Error during file upload'.
          lo_message_container = /iwbep/if_mgw_conv_srv_runtime~get_message_container( ).
          lo_message_container->add_message(
          EXPORTING
                  iv_msg_type = 'E'
                  iv_msg_id = 'ZPC'
                  iv_msg_number = '000'
                  iv_msg_text = lv_text-message
                  ).
          RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
            EXPORTING
              textid            = /iwbep/cx_mgw_busi_exception=>business_error
              message_container = lo_message_container.

          EXIT.
        ELSE.
          ls_data-delivery = lv_corid.
          copy_data_to_ref( EXPORTING is_data = ls_data
                            CHANGING  cr_data = er_entity ).


        ENDIF.
      ENDIF.
    ENDIF.
  ENDMETHOD.

 

GET_STREAM

This method will display the content of attachment

 

METHOD /iwbep/if_mgw_appl_srv_runtime~get_stream.

  DATA : ls_stream      TYPE ty_s_media_resource,
         ls_header      TYPE ihttpnvp,
         lv_docid       TYPE sofolenti1-doc_id,
         lt_objcon      TYPE TABLE OF solisti1,
         ls_text        TYPE solisti1,
         content_hex    TYPE TABLE OF solix,
         ls_content_hex TYPE solix,
         lv_data        TYPE xstring,
         lv_xstring     TYPE xstring,
         lv_string      TYPE string,
         ls_doc_data    TYPE sofolenti1,
         lv_mimetype    TYPE mimetypes-type,
         lv_file_ext(5) TYPE c.

  DATA: lv_name_utf8    TYPE string, "SAP Note 2076935
        lv_filename_str TYPE string.

  DATA: ls_docid_str TYPE soentryi1,
        ls_filter    TYPE sofor,
        ls_folder    TYPE sofdk,
        ls_object    TYPE soodk,
        ls_obj_hd    TYPE sood2,
        lt_objhead   TYPE STANDARD TABLE OF soli,
        ls_objhead   TYPE soli,
        lv_filesize  TYPE so_obj_len,
        lt_split     TYPE TABLE OF string,
        lv_lines     TYPE i,
        ls_extension TYPE string,
        lv_extension TYPE sdok_fnext,
        ls_filename  TYPE string,
        lv_cor_value TYPE srgbtbrel-instid_a,
        lv_file_te   TYPE so_obj_des.

  READ TABLE  it_key_tab INTO DATA(ls_cor) INDEX 1.
  IF sy-subrc = 0.
    lv_cor_value = ls_cor-value.
  ENDIF.
  READ TABLE  it_key_tab INTO DATA(ls_file) INDEX 2.
  IF sy-subrc = 0.
    lv_file_te = ls_file-value.
  ENDIF.


  IF lv_cor_value IS NOT INITIAL AND lv_file_te IS NOT INITIAL.
    SELECT  instid_b
           FROM srgbtbrel INTO TABLE @DATA(lt_docid)
           WHERE reltype = 'ATTA'
             AND instid_a  = @lv_cor_value
             AND typeid_a = 'ZPC'.
  ENDIF.

  IF lt_docid IS NOT INITIAL.

    LOOP AT lt_docid INTO DATA(ls_doc_id)
                     WHERE instid_b IS NOT INITIAL.

      CLEAR: ls_stream, lv_docid,lt_objcon.
      lv_docid = ls_doc_id-instid_b.

      CALL FUNCTION 'SO_DOCUMENT_READ_API1'
        EXPORTING
          document_id                = lv_docid
        IMPORTING
          document_data              = ls_doc_data
        TABLES
          object_content             = lt_objcon
          contents_hex               = content_hex
        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 ls_doc_data-obj_descr = lv_file_te.

        ls_filter-sndi = abap_true.
        MOVE lv_docid TO ls_docid_str.
        MOVE-CORRESPONDING ls_docid_str TO ls_folder.
        MOVE-CORRESPONDING ls_docid_str TO ls_object.

        CALL FUNCTION 'SO_OBJECT_READ'
          EXPORTING
            filter                     = ls_filter
            folder_id                  = ls_folder
            object_id                  = ls_object
          IMPORTING
            object_hd_display          = ls_obj_hd
          TABLES
            objhead                    = lt_objhead
          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.
          RETURN.
        ENDIF.
        LOOP AT lt_objhead INTO ls_objhead
        WHERE table_line CP '&SO_FILENAME=*'.
          SPLIT ls_objhead AT '.' INTO TABLE lt_split.
          IF sy-subrc IS INITIAL..
            lv_lines = lines( lt_split ).
            IF lv_lines <> 0.
              READ TABLE lt_split INTO ls_extension INDEX lv_lines.
*
              IF lv_extension <> ls_obj_hd-file_ext.
                SELECT SINGLE type INTO lv_mimetype FROM sdokmime_c
                WHERE extension = lv_extension.
                IF sy-subrc <> 0.
                  SELECT SINGLE type INTO lv_mimetype FROM sdokmime
                  WHERE extension = lv_extension.
                ENDIF.
              ENDIF.
            ENDIF.
          ENDIF.
          EXIT.
        ENDLOOP.

        IF sy-subrc <> 0.
*     common processing, calculate mime-type
          CALL FUNCTION 'SDOK_MIMETYPE_GET'
            EXPORTING
              extension = ls_doc_data-obj_type
            IMPORTING
              mimetype  = lv_mimetype.
        ENDIF.


        IF content_hex IS NOT INITIAL.
*
          LOOP AT content_hex INTO ls_content_hex.
            CONCATENATE lv_xstring ls_content_hex-line INTO lv_xstring IN BYTE MODE.
          ENDLOOP.
*     ---------------------------------------------------------------
*     it turned out that the stream is too long; old applications
*     (e.g. office 2003) just ignored that, the new ones (e.g. office
*     2010) fail in displaying that
*     ---------------------------------------------------------------
          MOVE lv_xstring(ls_doc_data-doc_size) TO lv_xstring.
          ls_stream-value = lv_xstring.
          ls_stream-mime_type = lv_mimetype.
*
        ELSEIF lt_objcon IS NOT INITIAL.
*
          CLEAR: lv_string.
          LOOP AT lt_objcon INTO ls_text.
            CONCATENATE lv_string ls_text-line cl_abap_char_utilities=>newline INTO lv_string.
          ENDLOOP.
*
          CALL FUNCTION 'HR_KR_STRING_TO_XSTRING'
            EXPORTING
*             CODEPAGE_TO      = '8500'
              unicode_string   = lv_string
*             OUT_LEN          =
            IMPORTING
              xstring_stream   = lv_xstring
            EXCEPTIONS
              invalid_codepage = 1
              invalid_string   = 2
              OTHERS           = 3.
          IF sy-subrc <> 0.
* Implement suitable error handling here
          ENDIF.
          ls_stream-value = lv_xstring.
          ls_stream-mime_type = lv_mimetype.

        ENDIF.
        TRANSLATE ls_doc_data-obj_type TO LOWER CASE.
        lv_file_ext = ls_doc_data-obj_type.

        IF lv_mimetype IS INITIAL.

          CALL FUNCTION 'SDOK_MIMETYPE_GET'
            EXPORTING
              extension = lv_file_ext
            IMPORTING
              mimetype  = lv_mimetype.
          ls_stream-mime_type = lv_mimetype.
        ELSE.
          ls_stream-mime_type = lv_mimetype.
        ENDIF.

        CONCATENATE ls_doc_data-obj_descr '.' lv_file_ext INTO ls_filename.
        ls_header-name = 'Content-Disposition'.
        IF  ls_stream-mime_type NE 'application/pdf' .
          lv_filename_str = ls_filename.
          lv_name_utf8 = cl_http_utility=>if_http_utility~escape_url( unescaped =  lv_filename_str ).
          REPLACE ALL OCCURRENCES OF '%2e' IN lv_name_utf8 WITH '.'.
          CONCATENATE 'attachment; filename*=UTF-8''''' lv_name_utf8 INTO ls_header-value.
          set_header( is_header = ls_header ).
        ENDIF.

        EXIT.
      ENDIF.
    ENDLOOP.

    copy_data_to_ref( EXPORTING is_data = ls_stream
                      CHANGING  cr_data = er_stream ).

  ENDIF.

ENDMETHOD.

 

GET_ENTITYSET

This method would retrieve the list of attachments for a business object.

  METHOD attachmentset_get_entityset.

**Data Declaration
    DATA: ls_select_opt        TYPE /iwbep/s_cod_select_option,
          lr_corid             TYPE RANGE OF CHAR10,
          ls_entity            TYPE zcl_zattch_file_mpc=>ts_attachment,
          ls_doc_data          TYPE sofolenti1,
          lv_docid             TYPE sofolenti1-doc_id,
          lo_message_container TYPE REF TO /iwbep/if_message_container,
          lv_text              TYPE bapiret2.

**Get Filter Data
    DATA(lt_filters) = io_tech_request_context->get_filter( )->get_filter_select_options( ).

**Prepare data from filter options
    LOOP AT lt_filters ASSIGNING FIELD-SYMBOL(<ls_filter>).
      CASE <ls_filter>-property.
        WHEN 'DELIVERY'.
          ls_select_opt = <ls_filter>-select_options[ 1 ].
          IF sy-subrc = 0.
            DATA(lv_corid)  = ls_select_opt-low.
          ENDIF.
      ENDCASE.
    ENDLOOP.

**Range tables for input data
    IF lv_corid NE ''.
      lr_corid = VALUE #( ( sign = 'I' option = 'EQ' low = lv_corid ) ).
    ENDIF.


**Get Correction ID attachments

    SELECT instid_a,
           instid_b
            FROM srgbtbrel INTO TABLE @DATA(lt_docs)
            WHERE reltype = 'ATTA'
              AND instid_a IN @lr_corid
              AND typeid_a = 'ZPC'.

    IF lt_docs IS NOT INITIAL.

      LOOP AT lt_docs ASSIGNING FIELD-SYMBOL(<ls_doc>)
                      WHERE instid_b IS NOT INITIAL.

        CLEAR: ls_doc_data,lv_docid.
        lv_docid = <ls_doc>-instid_b.

        CALL FUNCTION 'SO_DOCUMENT_READ_API1'
          EXPORTING
            document_id                = lv_docid
          IMPORTING
            document_data              = ls_doc_data
          EXCEPTIONS
            document_id_not_exist      = 1
            operation_no_authorization = 2
            x_error                    = 3
            OTHERS                     = 4.

        IF sy-subrc <> 0.
          CONTINUE.
        ENDIF.

        ls_entity-DELIVERY = <ls_doc>-instid_a.
        ls_entity-filename = ls_doc_data-obj_descr.
        ls_entity-mimetype = ls_doc_data-obj_type.
        APPEND  ls_entity TO et_entityset.
        CLEAR:ls_entity.

      ENDLOOP.
    ENDIF.

ENDMETHOD.

 

Save and Activate the entity sets.

Step:11 Add and Maintain the service:

Go for the t-code ‘ /IWFND/MAINT_SERVICE‘ to add the service.

Click on ‘Add service‘ to add service.

 

Step:12  Give system name and click on ‘Get service‘ and the project will be found and select project click on ‘Add selected service‘. It will automatically maintained the service.

 

Step: 13  After it will shows technical service with some details and Click on Continue button.

Step: 14 Go back to maintain services and select the project and ‘Load Metadata‘ & Click on ‘Sap Gateway Client‘.

Step: 15 .It will shows the HTTP Request with Request URI and select the entity set name as below.

Click on Add Header Button and enter  Header name ‘slug’ and enter Header Value abc/Test.docx click on continue button.

Click on Add file and select file

Step:17  click on ‘POST‘ radio button for create.

(Status code: ‘201‘) as below.

 

Conclusion:    

I hope this blog Post helps to to attach multiple files with different file extensions via OData Service
Hope this useful to you. Thanks
Sara Sampaio

Sara Sampaio

Author Since: March 10, 2022

0 0 votes
Article Rating
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x