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: 
MichelleLuft
Product and Topic Expert
Product and Topic Expert

SAP ArchiveLink is a powerful tool for storing and managing documents, including those related to compliance reporting. In SAP Document and Reporting Compliance(SAP DRC), adding attachments to your eDocuments can be made even easier with the integration to SAP ArchiveLink. In this blog post, we will explore how to include supporting documents stored in SAP ArchiveLink in your XML file. We will cover the steps involved in retrieving the archived documents, converting them to the required format, and adding them to the electronic invoice. The code snippets can be used for UBL (Universal Business Language) and CII (Cross-Industry Invoice) messages. Both UBL and CII are designed to make electronic invoicing more efficient. They allow for the exchange of electronic invoices in a standardized format, which helps to reduce errors and inconsistencies in invoicing. 

Please note that the following code example is for illustrative purposes only and might need to be reworked before being used in a production environment. It is important to thoroughly test and review the code to ensure it meets your specific requirements, coding-, or other standards. Additionally, some code snippets may omit error handling for brevity.

Prerequisites

  • The documents to be embedded were archived with SAP ArchiveLink
  • The country supports UBL or CII

Procedure

BAdI EDOC_ADAPTOR

This blog post illustrates how to use the SET_OUTPUT_DATA method of the Business Add-In (BAdI) Enhancements for eDocument (EDOC_ADAPTOR) to retrieve and embed archived PDF documents into the XML file. If you haven't created the enhancement implementation yet, search for the EDOC_ADAPTOR BAdI using the SE18 transaction. In my example, I have created the implementation ZEI_EDOC_ADAPTOR_EU for Germany, which is defined using the Filter Values. If you want to use the implementation for other countries, check the country/region-specific SAP Notes for the Filter Values.

MichelleLuft_0-1709117630573.png

Method "SET_OUTPUT_DATA"

To implement the method SET_OUTPUT_DATA, switch to "Implementing Class" inside the enhancement implementation and double-click on the name. This method distinguishes between the eDocument type and calls the LOAD_ARCHIVELINK_DOCUMENTS method, which retrieves the documents from SAP ArchiveLink for the corresponding source document and attaches the files to the respective XML segment.

ℹ️  If you are implementing the E-Mail Process in Germany: This code snipped works for Cross-Industry Invoices too, as the CII document is generated based on the UBL document.

 

 

 

 

 

  METHOD if_edoc_adaptor~set_output_data.

    DATA: lo_data      TYPE REF TO edoc_src_data_sd_invoice,
          lv_object_id TYPE toav0-object_id.

    FIELD-SYMBOLS:
      <ls_invoice>    TYPE edo_ubl_standard_business_doc2,
      <ls_creditnote> TYPE edo_ubl_standard_business_doc5.

    lv_object_id = io_source->mv_source_key. "the source key will be later used to retrieve the corresponding documents e.g. for the SD or FI document. Check whether you may be using a different ID and adjust it

    CASE iv_edoc_type. " If you want to use this code snippet for a country other than Germany, replace the country code, e.g. NO_INV or AT_CRE.
      WHEN 'DE_INV'. " This distinction is necessary because the structures differ depending on the eDocument type
        ASSIGN cs_output_data TO <ls_invoice>.

        load_archivelink_documents( "with this method, the documents are retrieved from ArchiveLink and added to <ls_invoice>
          EXPORTING
            iv_object_id   = lv_object_id
            iv_edoc_type   = iv_edoc_type
          CHANGING
            cs_output_data = <ls_invoice>
        ).

      WHEN 'DE_CRE'.
        ASSIGN cs_output_data TO  <ls_creditnote>.

        load_archivelink_documents( "with this method, the documents are retrieved from ArchiveLink and added to <ls_creditnote>
          EXPORTING
            iv_object_id   = lv_object_id
            iv_edoc_type   = iv_edoc_type
          CHANGING
            cs_output_data = <ls_creditnote>
        ).

    ENDCASE.
  ENDMETHOD.

 

 

 

 

 

Method "LOAD_ARCHIVELINK_DOCUMENTS"

Let’s have a deeper look into the LOAD_ARCHIVELINK_DOCUMENTS method. You need to create the method inside the implementing class of the EDOC_ADAPTOR

MichelleLuft_1-1709126328288.png

The method uses two Importing and one Changing Parameters:

  • IV_OBJECT_ID is the source document key, e.g. the SD billing document number
  • IV_EDOC_TYPE is the eDocument type of the document, e.g. invoice or credit note
  • CS_OUTPUT_DATA includes the eDocument data after the Standard Mapping

MichelleLuft_2-1709126861180.png

In addition, create a new customizing table ZEDOCARCHIVELINK to define which documents should be considered for embedding. 

MichelleLuft_3-1709127545553.png

Within the LOAD_ARCHIVELINK_DOCUMENTS method, the entries of ZEDOCARCHIVELINK are first selected, for which several ArchiveLink function modules are called to retrieve the connection details and the stored documents. These documents will be converted into an XSTRING and finally added to the XML file. For more details, check the comments inside the code snippet:

 

 

 

 

 

METHOD load_archivelink_documents.

    DATA:
      lv_archiv_id       TYPE saearchivi,
      lt_connections     TYPE TABLE OF toav0,
      lv_index           TYPE c,
      lv_archive_doc_id  TYPE sapb-sapadokid,
      lv_archiv_id_tooar TYPE toaar-archiv_id,
      lt_bitstream       TYPE TABLE OF tbl1024,
      lt_fileattributes  TYPE TABLE OF toaat,
      lv_filename        TYPE string,
      ls_inv_additional  TYPE LINE OF edo_ubl_additional_documen_tab,
      ls_cre_additional  TYPE LINE OF edo_ubl_additional_docume_tab1,
      lv_xstring         TYPE xstring.

    FIELD-SYMBOLS: <ls_connections>        TYPE toav0,
                   <ls_edo_archivelinkdoc> TYPE zedocarchivelink,
                   <ls_invoice>            TYPE edo_ubl_standard_business_doc2,
                   <ls_creditnote>         TYPE edo_ubl_standard_business_doc5.

    SELECT * FROM zedocarchivelink INTO TABLE (lt_edo_archivelinkdoc). "This table contains information on the document and object types used in SAP ArchiveLink which should be considered

    LOOP AT lt_edo_archivelinkdoc ASSIGNING <ls_edo_archivelinkdoc>.
      CALL FUNCTION 'ARCHIV_CONNECTDEFINITION_GET'
        EXPORTING
          objecttype    = <ls_edo_archivelinkdoc>-sap_object "represents the SAP application that the document is associated with, such as FI or SD. Examples: VBRK (billing document) or BKPF (accounting document).
          documenttype  = <ls_edo_archivelinkdoc>-ar_object "represents the type of document that is being archived, such as an PDF document. TCODE OAC2
          client        = sy-mandt
        IMPORTING
          archivid      = lv_archiv_id "get the content repository id for above combination, TCODE OAC3
        EXCEPTIONS
          nothing_found = 1
          OTHERS        = 2.
      IF sy-subrc <> 0.
*              Implement suitable error handling here
      ENDIF.

      CALL FUNCTION 'ARCHIV_GET_CONNECTIONS_INT' "retrieve the list of documents that are stored in the content repository for the specific eDocument
        EXPORTING
          objecttype       = <ls_edo_archivelinkdoc>-sap_object
          object_id        = iv_object_id "eDocument source key, e.g. SD or FI document number
          client           = sy-mandt
          archiv_id        = lv_archiv_id "content repository
          documenttype     = <ls_edo_archivelinkdoc>-ar_object
        TABLES
          connections      = lt_connections
          file_attributes  = lt_fileattributes
        EXCEPTIONS
          nothing_found    = 1
          error_authorithy = 2
          error_parameter  = 3
          OTHERS           = 4.
      IF sy-subrc <> 0.
*              Implement suitable error handling here
      ENDIF.

      LOOP AT lt_connections ASSIGNING <ls_connections>. "list of documents to be embedded

        lv_index = sy-tabix.
        lv_archive_doc_id = <ls_connections>-arc_doc_id.
        lv_archiv_id_tooar = <ls_connections>-archiv_id.

        CALL FUNCTION 'ARCHIVOBJECT_GET_BYTES' "returns the binary data for the document in a table of 1024-byte blocks.
          EXPORTING
            archiv_id                = lv_archiv_id_tooar
            archiv_doc_id            = lv_archive_doc_id
            document_type            = 'PDF' "change if required
            length                   = 999999999
            offset                   = 0
            mode                     = ' '
            signature                = 'X'
            shift_flag               = ' '
            compid                   = 'data'
          TABLES
            binarchivobject          = lt_bitstream
          EXCEPTIONS
            error_archiv             = 1
            error_communicationtable = 2
            error_kernel             = 3
            OTHERS                   = 4.
        IF sy-subrc <> 0.
*              Implement suitable error handling here
        ENDIF.

        CALL FUNCTION 'SCMS_BINARY_TO_XSTRING' "convert the binary data for the document into an XSTRING
          EXPORTING
            input_length = lines( lt_bitstream ) * 1024
          IMPORTING
            buffer       = lv_xstring
          TABLES
            binary_tab   = lt_bitstream
          EXCEPTIONS
            failed       = 1
            OTHERS       = 2.
        IF sy-subrc <> 0.
*              Implement suitable error handling here
        ENDIF.

        "Define Filename
        IF lt_fileattributes IS NOT INITIAL.  "if file attributes are available, generate a filename based on the date, time, and filename
          LOOP AT lt_fileattributes ASSIGNING FIELD-SYMBOL(<ls_fileattributes>) WHERE arc_doc_id = <ls_connections>-arc_doc_id.
            CONCATENATE <ls_connections>-ar_date '_' <ls_fileattributes>-creatime '_' <ls_fileattributes>-filename INTO lv_filename.
          ENDLOOP.
        ELSE. "file attributes not availabe, generate a fixed string including the index and date.
          CONCATENATE 'Attachment_' lv_index '_' <ls_connections>-ar_date '.' <ls_connections>-reserve INTO lv_filename.
        ENDIF.

        IF iv_edoc_type EQ 'DE_INV'. "This distinction is necessary because the structures differ depending on the eDocument type
          ASSIGN cs_output_data TO <ls_invoice>.

          ls_inv_additional-id-base-base-content =  <ls_invoice>-invoice-id-base-base-content. "Identifier for object, change according to your needs
          ls_inv_additional-attachment-embedded_document_binary_objec-base-content = lv_xstring.
          ls_inv_additional-attachment-embedded_document_binary_objec-base-mime_code ='application/pdf'. "for other mime codes check code list 'Mime code (subset of IANA code list)'
          ls_inv_additional-attachment-embedded_document_binary_objec-base-filename = lv_filename.

          APPEND ls_inv_additional TO  <ls_invoice>-invoice-additional_document_reference.

        ELSE.
          ASSIGN cs_output_data TO <ls_creditnote>.
          ls_cre_additional-id-base-base-content = <ls_creditnote>-credit_note-id-base-base-content.
          ls_cre_additional-attachment-embedded_document_binary_objec-base-content = lv_xstring.
          ls_cre_additional-attachment-embedded_document_binary_objec-base-mime_code ='application/pdf'.
          ls_cre_additional-attachment-embedded_document_binary_objec-base-filename = lv_filename.

          APPEND ls_cre_additional TO <ls_creditnote>-credit_note-additional_document_reference.

        ENDIF.
      ENDLOOP.
    ENDLOOP.
  ENDMETHOD.

 

 

 

 

 

Let's test!

Two business documents were archived with regard to my SD billing document:

MichelleLuft_5-1709128124797.png

I have maintained the corresponding object and document type in the ZEDOCARCHIVELINK table.

MichelleLuft_4-1709128049642.png

Once the eDocument is displayed in the eDocument Cockpit, the above BAdI implementation will be called and the coding will be run through

MichelleLuft_0-1709215322010.png

Scrolling down to the "AdditionalDocumentReference" element, I see that both files are embedded:

MichelleLuft_6-1709128231033.png

Additional Use Case

If you are implementing the ZUGFeRD scenario in Germany, you can use a similar approach for uploading the PDF to the XML. I'll be writing a new blog post soon!

Summary

In conclusion, SAP ArchiveLink is a powerful tool for document storage and management, and its integration with SAP DRC can greatly enhance the electronic invoicing process. The use of the SET_OUTPUT_DATA method through the EDOC_ADAPTOR BAdI allows for easy attachment of necessary supporting documents in both UBL and CII formats.