The following solution is intended to demonstrate that we can build an OData service in the backend that handles the CRUD operations ( Create, Read, Delete) for attaching a document to a particular sales order. We will connect in a later post this service to a custom UI5 app that will use an UploadSet control which will help us upload one or more files from our device ( desktop/tablet or phone) and attach them to a particular sales order.
A short disclaimer to everybody who checks the standard apps VA01/VA02 for upload, you might be missing the GOS(Generic Object Services) toolbar, which has to be implemented. This is not mandatory needed for us though.
method DEFINE.
*&---------------------------------------------------------------------*
* TITLE : DEFINE
* AUTHOR : Mihai-Alexandru Zaharescu
* DESCRIPTION : Attachments Implementation: set proprty MIME type for appropriate entities
*----------------------------------------------------------------------*
DATA: lr_entity_typ TYPE REF TO /iwbep/if_mgw_odata_entity_typ,
lr_property TYPE REF TO /iwbep/if_mgw_odata_property.
super->define( ).
* GetAttach
lr_entity_typ = model->get_entity_type( iv_entity_name = 'GetAttach' ) ##NO_TEXT.
IF lr_entity_typ IS BOUND.
lr_property = lr_entity_typ->get_property( iv_property_name = 'MIME_TYPE' ).
lr_property->set_as_content_type( ).
ENDIF.
* File
lr_entity_typ = model->get_entity_type( iv_entity_name = 'File' ) ##NO_TEXT.
IF lr_entity_typ IS BOUND.
lr_property = lr_entity_typ->get_property( iv_property_name = 'MIME_TYPE' ).
lr_property->set_as_content_type( ).
ENDIF.
* CreateFile
lr_entity_typ = model->get_entity_type( iv_entity_name = 'CreateFile' ) ##NO_TEXT.
IF lr_entity_typ IS BOUND.
lr_property = lr_entity_typ->get_property( iv_property_name = 'MIME_TYPE' ).
lr_property->set_as_content_type( ).
ENDIF.
endmethod.
METHOD /iwbep/if_mgw_appl_srv_runtime~create_stream.
* local declaration
TYPES: BEGIN OF ts_data,
file_name TYPE string,
mime_type TYPE string,
END OF ts_data.
DATA: ls_folder_id TYPE soodk,
lv_folder_id TYPE so_obj_id,
lv_slug TYPE string,
lt_vbeln TYPE TABLE OF vbeln,
lv_file_name TYPE char255,
lv_extension TYPE char3,
lt_objhead TYPE soli_tab,
lt_cont_hex TYPE solix_tab,
ls_doc_data TYPE sodocchgi1,
ls_doc_info TYPE sofolenti1,
ls_rolea TYPE borident,
ls_roleb TYPE borident,
ls_data TYPE ts_data.
* Get folder id
CALL FUNCTION 'SO_FOLDER_ROOT_ID_GET'
EXPORTING
region = 'B'
IMPORTING
folder_id = ls_folder_id
EXCEPTIONS
communication_failure = 1
owner_not_exist = 2
system_failure = 3
x_error = 4
OTHERS = 5.
IF sy-subrc IS INITIAL.
lv_folder_id = ls_folder_id.
ENDIF.
*Get sales order number(s) and file name from import variable IV_SLUG
SPLIT iv_slug AT '/' INTO lv_slug lv_file_name.
SPLIT lv_slug AT '|' INTO TABLE lt_vbeln.
*set up document data
ls_doc_data = VALUE #( obj_name = 'MESSAGE'
obj_descr = lv_file_name
obj_langu = sy-langu ).
*Get extension from file name
CALL FUNCTION 'TRINT_FILE_GET_EXTENSION'
EXPORTING
filename = lv_file_name
uppercase = abap_true
IMPORTING
extension = lv_extension.
* set up object head
lt_objhead = VALUE #( ( line = '&SO_FILENAME=' && lv_file_name )
( line = '&SO_FORMAT=BIN' )
( line = '&SO_CONTTYPE=' && is_media_resource-mime_type ) ).
* convert attachment data from xstring to xtab
TRY.
cl_bcs_convert=>xstring_to_xtab(
EXPORTING
iv_xstring = is_media_resource-value
IMPORTING
et_xtab = lt_cont_hex ).
CATCH cx_bcs INTO DATA(lr_cx_bcs).
DATA(lv_csmsg) = lr_cx_bcs->if_message~get_text( ) ##NEEDED.
RETURN.
ENDTRY.
* Create attachment file in system
CALL FUNCTION 'SO_DOCUMENT_INSERT_API1'
EXPORTING
folder_id = lv_folder_id
document_data = ls_doc_data
document_type = lv_extension
IMPORTING
document_info = ls_doc_info
TABLES
object_header = lt_objhead
contents_hex = lt_cont_hex
EXCEPTIONS
folder_not_exist = 1
document_type_not_exist = 2
operation_no_authorization = 3
parameter_error = 4
x_error = 5
enqueue_error = 6
OTHERS = 7.
IF sy-subrc IS NOT INITIAL.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO lv_csmsg.
RETURN.
ENDIF.
* Link sales order(s) with created attachment file
LOOP AT lt_vbeln ASSIGNING FIELD-SYMBOL(<ls_vbeln>).
ls_rolea = VALUE #( objkey = <ls_vbeln>
objtype = 'BUS2032' ).
ls_roleb = VALUE #( objkey = ls_doc_info-doc_id
objtype = ls_doc_info-obj_name ).
CALL FUNCTION 'BINARY_RELATION_CREATE_COMMIT'
EXPORTING
obj_rolea = ls_rolea
obj_roleb = ls_roleb
relationtype = 'ATTA'
EXCEPTIONS
no_model = 1
internal_error = 2
unknown = 3
OTHERS = 4.
IF sy-subrc IS NOT INITIAL.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO lv_csmsg.
RETURN.
ENDIF.
AT LAST.
COMMIT WORK.
ENDAT.
ENDLOOP.
* Fill the export parameter er_entity accordingly
ls_data = VALUE #( file_name = lv_file_name
mime_type = is_media_resource-mime_type ).
copy_data_to_ref(
EXPORTING
is_data = ls_data
CHANGING
cr_data = er_entity ).
ENDMETHOD.
/sap/opu/odata/sap/ZSRV_UPLOAD_SRV/CreateFileSet
method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~DELETE_STREAM.
* local declaration
DATA: lv_doc_id TYPE swo_typeid,
ls_objectd TYPE borident,
lv_csmsg TYPE string ##NEEDED,
lr_attsrv TYPE REF TO cl_gos_document_service.
* retrieve document id
READ TABLE it_key_tab INTO DATA(ls_key) WITH KEY name = 'DOCUMENT_ID'.
IF sy-subrc IS INITIAL.
lv_doc_id = ls_key-value.
ENDIF.
* fetch complete details
SELECT brelguid,instid_a,typeid_a,logsys_a FROM srgbtbrel
INTO TABLE @DATA(lt_srgbtbrel)
WHERE instid_b = @lv_doc_id
AND typeid_b = 'MESSAGE'
AND catid_b = 'BO'.
IF sy-subrc IS NOT INITIAL.
MESSAGE e002(msg002) WITH lv_doc_id INTO lv_csmsg.
RETURN.
ENDIF.
LOOP AT lt_srgbtbrel ASSIGNING FIELD-SYMBOL(<ls_srgbtbrel>).
* formulate object details
ls_objectd = VALUE #( objkey = <ls_srgbtbrel>-instid_a
objtype = <ls_srgbtbrel>-typeid_a
logsys = <ls_srgbtbrel>-logsys_a ).
* delete the attachment
CREATE OBJECT lr_attsrv.
lr_attsrv->delete_attachment(
EXPORTING
is_object = ls_objectd
ip_attachment = lv_doc_id ).
COMMIT WORK.
ENDLOOP.
endmethod.
/sap/opu/odata/sap/ZSRV_UPLOAD_SRV/FileSet(DOCUMENT_ID='FOL42000000000004EXT46000000000112')/$value
method GETATTACHSET_GET_ENTITYSET.
DATA: lt_object_id TYPE RANGE OF ZGETATTACHMENT-object_id,
lt_object_type TYPE RANGE OF ZGETATTACHMENT-object_type,
lt_object_cat TYPE RANGE OF ZGETATTACHMENT-object_cat,
lt_document_id TYPE RANGE OF ZGETATTACHMENT-document_id,
lv_object_id TYPE sibfboriid,
lv_object_type TYPE sibftypeid,
lv_object_cat TYPE sibfcatid,
lv_document_id TYPE documentid.
* Get filter or select option information
DATA(lr_filter) = io_tech_request_context->get_filter( ).
DATA(lt_filter_so) = lr_filter->get_filter_select_options( ).
DATA(lv_filter_st) = lr_filter->get_filter_string( ).
** Check if the supplied filter is supported by standard gateway runtime process
IF lv_filter_st IS NOT INITIAL AND lt_filter_so IS INITIAL.
* if the string of the filter system query option is not automatically converted into
* filter option table (lt_filter_so), then the filtering combination is not supported
* LOG MESSAGE in the application LOG
me->/iwbep/if_sb_dpc_comm_services~log_message(
EXPORTING
iv_msg_type = 'E'
iv_msg_id = '/IWBEP/MC_SB_DPC_ADM'
iv_msg_number = '025' ).
* raise exception
RAISE EXCEPTION TYPE /iwbep/cx_mgw_tech_exception
EXPORTING
textid = /iwbep/cx_mgw_tech_exception=>internal_error.
ENDIF.
* Maps filter table lines to function module parameters
LOOP AT lt_filter_so INTO DATA(ls_filter_so).
CASE ls_filter_so-property.
WHEN 'OBJECT_ID'.
lr_filter->convert_select_option(
EXPORTING
is_select_option = ls_filter_so
IMPORTING
et_select_option = lt_object_id ).
READ TABLE lt_object_id INTO DATA(ls_object_id) INDEX 1.
IF sy-subrc IS INITIAL.
lv_object_id = ls_object_id-low.
ENDIF.
WHEN 'OBJECT_TYPE'.
lr_filter->convert_select_option(
EXPORTING
is_select_option = ls_filter_so
IMPORTING
et_select_option = lt_object_type ).
READ TABLE lt_object_type INTO DATA(ls_object_type) INDEX 1.
IF sy-subrc IS INITIAL.
lv_object_type = ls_object_type-low.
ENDIF.
WHEN 'OBJECT_CAT'.
lr_filter->convert_select_option(
EXPORTING
is_select_option = ls_filter_so
IMPORTING
et_select_option = lt_object_cat ).
READ TABLE lt_object_cat INTO DATA(ls_object_cat) INDEX 1.
IF sy-subrc IS INITIAL.
lv_object_cat = ls_object_cat-low.
ENDIF.
WHEN 'DOCUMENT_ID'.
lr_filter->convert_select_option(
EXPORTING
is_select_option = ls_filter_so
IMPORTING
et_select_option = lt_document_id ).
READ TABLE lt_document_id INTO DATA(ls_document_id) INDEX 1.
IF sy-subrc IS INITIAL.
lv_document_id = ls_document_id-low.
ENDIF.
WHEN OTHERS.
* log message in the application log
me->/iwbep/if_sb_dpc_comm_services~log_message(
EXPORTING
iv_msg_type = 'E'
iv_msg_id = '/IWBEP/MC_SB_DPC_ADM'
iv_msg_number = '020'
iv_msg_v1 = ls_filter_so-property ).
* raise exception
RAISE EXCEPTION TYPE /iwbep/cx_mgw_tech_exception
EXPORTING
textid = /iwbep/cx_mgw_tech_exception=>internal_error.
ENDCASE.
ENDLOOP.
* Get Sales order attachment list
CALL FUNCTION 'ZGET_ATTACHMENT'
EXPORTING
iv_object_id = lv_object_id
iv_object_type = lv_object_type "'BUS2032'
iv_object_cat = lv_object_cat "'BO'
iv_document_id = lv_document_id
IMPORTING
et_entityset = et_entityset
es_response_context = es_response_context.
endmethod.
/sap/opu/odata/sap/ZSRV_UPLOAD_SRV/GetAttachSet?$filter=OBJECT_ID eq '0000000002' and OBJECT_TYPE eq 'BUS2032' and OBJECT_CAT eq 'BO'
METHOD /iwbep/if_mgw_appl_srv_runtime~get_stream.
* local declaration
DATA: lv_doc_id TYPE so_entryid,
ls_doc_data TYPE sofolenti1,
lt_obj_header TYPE STANDARD TABLE OF solisti1,
lt_obj_cont TYPE STANDARD TABLE OF solisti1,
lt_cont_hex TYPE STANDARD TABLE OF solix,
lv_csmsg TYPE string ##NEEDED,
lv_mime_type TYPE w3conttype,
ls_stream TYPE /iwbep/cl_mgw_abs_data=>ty_s_media_resource.
* fetching document id
READ TABLE it_key_tab INTO DATA(ls_key) WITH KEY name = 'DOCUMENT_ID'.
IF sy-subrc IS INITIAL.
lv_doc_id = ls_key-value.
ENDIF.
* fetching attachment data
CALL FUNCTION 'SO_DOCUMENT_READ_API1'
EXPORTING
document_id = lv_doc_id
IMPORTING
document_data = ls_doc_data
TABLES
object_header = lt_obj_header
object_content = lt_obj_cont
contents_hex = lt_cont_hex
EXCEPTIONS
document_id_not_exist = 1
operation_no_authorization = 2
x_error = 3
OTHERS = 4.
IF sy-subrc IS NOT INITIAL.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO lv_csmsg.
RETURN.
ENDIF.
**.. setting header
set_header( is_header = VALUE #( name = 'Content-Disposition'
value = |attachment; filename="{ ls_doc_data-obj_descr }"| ) ) ##NO_TEXT.
* fetch the MIME tyoe
CALL FUNCTION 'SDOK_MIMETYPE_GET'
EXPORTING
extension = ls_doc_data-obj_type
IMPORTING
mimetype = lv_mime_type.
ls_stream-mime_type = lv_mime_type.
* read attachment data and pass it back to UI
TRY.
READ TABLE lt_obj_header ASSIGNING FIELD-SYMBOL(<ls_objhead>)
WITH KEY line = '&SO_FORMAT=BIN'.
IF sy-subrc IS INITIAL.
ls_stream-value = cl_bcs_convert=>xtab_to_xstring( it_xtab = lt_cont_hex ).
ELSE.
ls_stream-value = cl_bcs_convert=>txt_to_xstring( it_soli = lt_obj_cont ).
ENDIF.
CATCH cx_bcs INTO DATA(lr_cx_bcs).
lv_csmsg = lr_cx_bcs->if_message~get_text( ).
RETURN.
ENDTRY.
copy_data_to_ref(
EXPORTING
is_data = ls_stream
CHANGING
cr_data = er_stream ).
ENDMETHOD.
/sap/opu/odata/sap/ZSRV_UPLOAD_SRV/FileSet(DOCUMENT_ID='FOL42000000000004EXT47000000000019')/$value
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
23 | |
8 | |
7 | |
5 | |
5 | |
5 | |
4 | |
4 | |
3 | |
3 |