Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
elisabethsanchez-andradep
Product and Topic Expert
Product and Topic Expert
3,848

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.

Prerequisite

    • The legal format and the authority’s platforms support the handling of attachments.
    • You have created your attachment and you have added it to the attachment list of the relevant source document.

Procedure

  1. Go to transaction SE18 and search for BAdI EDOC_ADAPTOR. In our example for Portugal, ensure that the GENERIC_FILTER parameter for the BAdI implementation is set as INVOICE. Double-click on the COUNTRY filter. In the Display Filter Value dialog, enter your country code as Value 1 and select = as Comparator 1. In our example, select PT - Portugal. Note: For other countries/regions, you need to fill in other values. You can find this information in the corresponding country/region-specific SAP Notes.
  2. Create your own implementation, in our example ZEI_EDOC_ADAPTOR_PT_INV.
  3. Double-click method IF_EDOC_ADAPTOR~SET_OUTPUT_DATA and add the relevant code. The following source code reads the attachments from the attachment list of the source documents. Note that the code can be different, depending on your business case.

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.

Result

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 the SAP S/4HANA Cloud, ABAP environment, you can use the equivalent BAdI ES_EDOCUMENT_CLOUD (with method SET_OUTPUT_DATA) for the same purpose.

Summary

In today’s blog post, we he covered the following:

    • How to implement the BAdI method SET_OUTPUT_DATA of BAdI EDOC_ADAPTOR to download and add an attachment to a standard XML (using Portugal eInvoice as example).
    • Prerequisites that must be fulfilled by your country/region solution for this procedure to work.
    • We provide the source code used to read the attachments from the attachment list of a source document, the XML tag that can be used by countries/regions using a UBL format to submit electronic invoices, and the complete source code.
    • How to display the attachment added to the XML file from the eDocument Cockpit (EDOC_COCKPIT).
3 Comments