Procedo a dar mi primer aporte a este nuestro foro.
La cuestión es que hace unos días salió la necesidad de adjuntar una imagen de un escaneo a un cliente y que fuese visible desde la transacción XD03 o XD02, en la vista de anexos. Viendo la variedad de código desfuncional colgado en la red, me adentré a investigar por mi cuenta he hice la siguiente plantilla, donde he despersonalizado los errores:
DATA: lt_list TYPE TABLE OF epsfili,
ls_list TYPE epsfili,
lv_read TYPE string,
lv_file TYPE string,
lv_path TYPE epsf-epsdirnam,
ls_xstring TYPE xstring,
lv_doc_name TYPE string,
lv_extension TYPE string,
lt_file TYPE STANDARD TABLE OF soli,
lv_length TYPE i,
lv_full_path TYPE string,
ls_object TYPE borident,
lt_content TYPE STANDARD TABLE OF soli,
ls_obj_id TYPE soodk,
ls_obj_data TYPE sood1,
lv_desc TYPE so_obj_des,
lt_objhead TYPE STANDARD TABLE OF soli,
lv_offset TYPE i,
ls_fol_id TYPE soodk,
ls_folmem_k TYPE sofmk,
ls_note TYPE borident,
lv_ep_note TYPE borident-objkey,
lv_name TYPE epsfilnam,
lo_exc TYPE REF TO zcx_error_rf.
FIELD-SYMBOLS: <fs_file> TYPE soli.
"Directorio donde se encuentra el fichero
lv_path = '/rfdir/ourput'.
lv_file = '/rfdir/ourput/'.
CALL FUNCTION 'EPS_GET_DIRECTORY_LISTING'
EXPORTING
dir_name = lv_path
TABLES
dir_list = lt_list
EXCEPTIONS
invalid_eps_subdir = 1
sapgparam_failed = 2
build_directory_failed = 3
no_authorization = 4
read_directory_failed = 5
too_many_read_errors = 6
empty_directory_list = 7
OTHERS = 8.
IF sy-subrc <> 0.
"Error
ENDIF.
"Extensión del archivo a adjuntar. Se puede poner casi cualquiera
lv_extension = '.jpg'.
CONCATENATE reservation '_' kunnr lv_extension INTO lv_name.
READ TABLE lt_list INTO ls_list WITH KEY name = lv_name.
IF sy-subrc = 0.
CONCATENATE lv_file ls_list-name INTO lv_read.
OPEN DATASET lv_read FOR INPUT IN BINARY MODE.
TRY.
READ DATASET lv_read INTO ls_xstring.
lv_doc_name = ls_list-name.
TRANSLATE lv_doc_name TO UPPER CASE.
* Convertimos el xstring con los datos binario en una tabla con los datos binarios.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = ls_xstring
IMPORTING
output_length = lv_length
TABLES
binary_tab = lt_file.
MOVE lv_doc_name TO lv_full_path.
"Nombre del archivo a adjuntar . Ejemplo: "archivo.jpg"
CONCATENATE lv_file reservation '_' kunnr lv_extension INTO lv_file.
MOVE lv_full_path TO lv_desc.
"Campos clave del cliente. Aquí iria concatenado si tiene mas de un campo clave la tabla de maestro
ls_object-objkey = kunnr.
"Tabla de maestro del cliente
ls_object-objtype = 'KNA1'.
CALL FUNCTION 'SO_CONVERT_CONTENTS_BIN'
EXPORTING
it_contents_bin = lt_file[]
IMPORTING
et_contents_bin = lt_content[].
CALL FUNCTION 'SO_FOLDER_ROOT_ID_GET'
EXPORTING
region = 'B'
IMPORTING
folder_id = ls_fol_id
EXCEPTIONS
OTHERS = 1.
ls_obj_data-objsns = 'O'.
ls_obj_data-objla = sy-langu.
ls_obj_data-objdes = lv_desc.
"Extensión del archivo
ls_obj_data-file_ext = 'jpg'.
ls_obj_data-objlen = lines( lt_content ) * 255.
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_content
EXCEPTIONS
active_user_not_exist = 35
folder_not_exist = 6
object_type_not_exist = 17
owner_not_exist = 22
parameter_error = 23
OTHERS = 1000.
IF sy-subrc = 0 AND ls_object-objkey IS NOT INITIAL.
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.
CONCATENATE ls_fol_id ls_obj_id INTO lv_ep_note.
ls_note-objtype = 'MESSAGE'.
ls_note-objkey = lv_ep_note.
CALL FUNCTION 'BINARY_RELATION_CREATE'
EXPORTING
obj_rolea = ls_object
obj_roleb = ls_note
relationtype = 'ATTA'
EXCEPTIONS
OTHERS = 1.
CALL FUNCTION 'BINARY_RELATION_CREATE_COMMIT'
EXPORTING
obj_rolea = ls_object
obj_roleb = ls_note
relationtype = 'ATTA'
EXCEPTIONS
OTHERS = 1.
IF sy-subrc IS INITIAL.
* DELETE DATASET wl_read."Si se quiere eliminar el archivo después
ELSE.
"Error
ENDIF.
ELSE.
"Error
ENDIF.
CATCH cx_sy_file_open.
"Error
ENDTRY.
CLOSE DATASET lv_read.
ELSE.
"Error
ENDIF.
Espero que les sirva de ayuda