Co-authored by Elisabeth Sánchez-Andrade Potter and Karsten Schreyer
In this blog post, we’ll describe how you can use the BAdI method SET_OUTPUT_DATA of BAdI EDOC_ADAPTOR to download an attachment from the Attachment List of a source document and to add it to the standard XML file generated for an electronic document in the eDocument Cockpit (EDOC_COCKPIT).
We’ll use Portugal eInvoice as reference example to describe the procedure.
METHOD if_edoc_adaptor~set_output_data.
DATA : ls_object TYPE sibflporb,
lt_rel_options TYPE obl_t_relt,
ls_rel_options TYPE obl_s_relt,
lt_links TYPE obl_t_link,
ls_links TYPE obl_s_link,
lv_doc_id TYPE sofolenti1-doc_id,
lt_cont_bin TYPE TABLE OF solisti1,
lt_cont_solix TYPE TABLE OF solix,
ls_doc_data TYPE sofolenti1,
lv_doc_size TYPE i,
lv_xstring TYPE xstring,
ls_additional_document TYPE edo_pt_additional_document_ref.
FIELD-SYMBOLS <output_data> TYPE edo_pt_invoice_type.
ls_rel_options-low = 'ATTA'. "Attachments
ls_rel_options-sign = 'I'.
ls_rel_options-option = 'EQ'.
APPEND ls_rel_options TO lt_rel_options.
ls_object-instid = iv_source_key.
ls_object-catid = 'BO'.
CASE iv_source_type.
WHEN cl_edoc_source_sd_invoice=>gc_src_sd_invoice.
ls_object-typeid = 'VBRK'.
WHEN cl_edoc_source_fi_invoice=>gc_src_fi_invoice.
ls_object-typeid = 'BKPF'.
WHEN OTHERS.
RETURN.
ENDCASE.
REFRESH lt_links[].
ASSIGN cs_output_data TO <output_data>.
TRY.
* Get all links of the source document from table SRGBTBREL
CALL METHOD cl_binary_relation=>read_links_of_binrels
EXPORTING
is_object = ls_object
it_relation_options = lt_rel_options
ip_role = 'GOSAPPLOBJ'
IMPORTING
et_links = lt_links. "Table with Relationship Records
CATCH cx_obl_parameter_error.
RETURN.
CATCH cx_obl_internal_error.
RETURN.
CATCH cx_obl_model_error.
RETURN.
ENDTRY.
LOOP AT lt_links INTO ls_links.
lv_doc_id = ls_links-instid_b.
REFRESH lt_cont_bin[].
REFRESH lt_cont_solix[].
CLEAR ls_additional_document.
* Read attachment from source document
CALL FUNCTION 'SO_DOCUMENT_READ_API1'
EXPORTING
document_id = lv_doc_id
IMPORTING
document_data = ls_doc_data
TABLES
contents_hex = lt_cont_solix
object_content = lt_cont_bin
EXCEPTIONS
document_id_not_exist = 1
operation_no_authorization = 2
x_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
RETURN.
ENDIF.
ENDLOOP.
The data type of the attachment’s content is a RAWSTRING. That means that the file needs to be converted to an XSTRING. In our Portugal example, we have binary data and convert it with function module “SCMS_BINARY_TO_XSTRING” to the XSTRING. If you have the file in a STRING you can use “SCMS_STRING_TO_XSTRING” instead.
* Convert the binary data to xstring
CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
EXPORTING
input_length = lv_doc_size
IMPORTING
buffer = lv_xstring
TABLES
binary_tab = lt_cont_solix
EXCEPTIONS
failed = 1
OTHERS = 2.
IF sy-subrc <> 0.
RETURN.
ENDIF.
Countries/regions which are using a UBL format to submit electronic invoices can use XML tag AdditionalDocumentReference > Attachment > EmbeddedDocumentBinaryObject > Content. Some additional attributes can be provided in tag EmbeddedDocumentBinaryObject as well.
* Add the file to the attachment of the XML
ls_additional_document-id-base-base-content = ls_doc_data-doc_id.
ls_additional_document-attachment-embedded_document_binary_objec-base-content = lv_xstring.
ls_additional_document-attachment-embedded_document_binary_objec-base-filename = ls_doc_data-obj_descr.
ls_additional_document-attachment-embedded_document_binary_objec-base-format = ls_doc_data-obj_type.
ls_additional_document-attachment-embedded_document_binary_objec-base-mime_code = 'application/pdf'.
APPEND ls_additional_document TO <output_data>-additional_document_reference.
When you display the XML file of the electronic document in the eDocument Cockpit (EDOC_COCKPIT), you see the added attachment in the XML file, as follows:
Select entry and choose Display
Here you can find the complete source code:
METHOD if_edoc_adaptor~set_output_data.
DATA : ls_object TYPE sibflporb,
lt_rel_options TYPE obl_t_relt,
ls_rel_options TYPE obl_s_relt,
lt_links TYPE obl_t_link,
ls_links TYPE obl_s_link,
lv_doc_id TYPE sofolenti1-doc_id,
lt_cont_bin TYPE TABLE OF solisti1,
lt_cont_solix TYPE TABLE OF solix,
ls_doc_data TYPE sofolenti1,
lv_doc_size TYPE I,
lv_xstring TYPE xstring,
ls_additional_document TYPE edo_pt_additional_document_ref.
FIELD-SYMBOLS <output_data> TYPE edo_pt_invoice_type.
Ls_rel_options-low = ‘ATTA’. “Attachments
ls_rel_options-sign = ‘I’.
ls_rel_options-option = ‘EQ’.
APPEND ls_rel_options TO lt_rel_options.
Ls_object-instid = iv_source_key.
Ls_object-catid = ‘BO’.
CASE iv_source_type.
WHEN cl_edoc_source_sd_invoice=>gc_src_sd_invoice.
Ls_object-typeid = ‘VBRK’.
WHEN cl_edoc_source_fi_invoice=>gc_src_fi_invoice.
Ls_object-typeid = ‘BKPF’.
WHEN OTHERS.
RETURN.
ENDCASE.
REFRESH lt_links[].
ASSIGN cs_output_data TO <output_data>.
TRY.
* Get all links of the source document from table SRGBTBREL
CALL METHOD cl_binary_relation=>read_links_of_binrels
EXPORTING
is_object = ls_object
it_relation_options = lt_rel_options
ip_role = ‘GOSAPPLOBJ’
IMPORTING
et_links = lt_links. “Table with Relationship Records
CATCH cx_obl_parameter_error.
RETURN.
CATCH cx_obl_internal_error.
RETURN.
CATCH cx_obl_model_error.
RETURN.
ENDTRY.
LOOP AT lt_links INTO ls_links.
Lv_doc_id = ls_links-instid_b.
REFRESH lt_cont_bin[].
REFRESH lt_cont_solix[].
CLEAR ls_additional_document.
* Read attachment from source document
CALL FUNCTION ‘SO_DOCUMENT_READ_API1’
EXPORTING
document_id = lv_doc_id
IMPORTING
document_data = ls_doc_data
TABLES
contents_hex = lt_cont_solix
object_content = lt_cont_bin
EXCEPTIONS
document_id_not_exist = 1
operation_no_authorization = 2
x_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
RETURN.
ENDIF.
Lv_doc_size = ls_doc_data-doc_size.
* Convert the binary data to xstring
CALL FUNCTION ‘SCMS_BINARY_TO_XSTRING’
EXPORTING
input_length = lv_doc_size
IMPORTING
buffer = lv_xstring
TABLES
binary_tab = lt_cont_solix
EXCEPTIONS
failed = 1
OTHERS = 2.
IF sy-subrc <> 0.
RETURN.
ENDIF.
* Add the file to the attachment of the XML
ls_additional_document-id-base-base-content = ls_doc_data-doc_id.
Ls_additional_document-attachment-embedded_document_binary_objec-base-content = lv_xstring.
Ls_additional_document-attachment-embedded_document_binary_objec-base-filename = ls_doc_data-obj_descr.
Ls_additional_document-attachment-embedded_document_binary_objec-base-format = ls_doc_data-obj_type.
Ls_additional_document-attachment-embedded_document_binary_objec-base-mime_code = ‘application/pdf’.
APPEND ls_additional_document TO <output_data>-additional_document_reference.
ENDLOOP.
ENDMETHOD.
In today’s blog post, we have covered the following: