Product Lifecycle Management Blogs by Members
Get insider knowledge about product lifecycle management software from SAP. Tap into insights and real-world experiences with community member blog posts.
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

Document Archiving SAP and IXOS (DMS) Server

SATISH G. KAREMORE

Cognizant Technology Solutions Pvt.Ltd

There is continuous effort being done by various areas in SAP development to reduce the load over application server. This brought in concept of using external server to store the images of document. This approach solves two purposes, one for reducing load on SAP application server and other to maintain documentation consistency.

Present document provides step-by-step process to store and retrieve document from external DMS (IXOS) server in this particular case.

Business Requirement

An online application to developed for online invoice approval. Approver should be able to see the invoice from frontend. There is button on the approver portal to see the invoice printout which must be retrieved from IXOS server and display as PDF. There were multiple activities should be done to complete the storage and retrieve the document printout at the time of invoice approval.  

This code gives the step-by-step approach to Archive Documents to DMS (Example IXOS) server. This particular code was built to load invoice data into smart form and send it to external DMS (IXOS) server. It generates archive link which can be use further to identify and pull the document back to SAP from DMS server. This is helpful to the customer to save space on SAP application server to store documents and improve database performance.


Following code can be reused to generate PDF format of the invoice data in expected format.  You can retrieve desired data as per requirement.

*******************************************************************************************************************

* Get device type for Smart forms. 

CALL FUNCTION 'SSF_GET_DEVICE_TYPE'
    EXPORTING
      i_language             = v_language
      i_application          = 'SAPDEFAULT'
    IMPORTING
      e_devtype              = v_e_devtype
    EXCEPTIONS
      no_language            = 1
      language_not_installed = 2
      no_devtype_found       = 3
      system_error           = 4
      OTHERS                 = 5.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

* Pass output options and control parameters to smartform.
  wa_output_options-tdprinter     = v_e_devtype.
  wa_control_parameters-no_dialog = k_x.
  wa_control_parameters-getotf    = k_x.

*.................GET SMARTFORM FUNCTION MODULE NAME.................* 

CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
    EXPORTING
      formname           = k_formname
    IMPORTING
      fm_name            = v_fm_name
    EXCEPTIONS
      no_form            = 1
      no_function_module = 2
      OTHERS             = 3.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
*...........................CALL SMARTFORM............................*
  CALL FUNCTION v_fm_name
    EXPORTING
      control_parameters   = wa_control_parameters
      output_options       = wa_output_options
    IMPORTING
      document_output_info = wa_document_output_info
      job_output_info      = wa_job_output_info
      job_output_options   = wa_job_output_options
    TABLES
      i_vbrk               = i_vbrk[]
      i_vbrp               = i_vbrp[]
    EXCEPTIONS
      formatting_error     = 1
      internal_error       = 2
      send_error           = 3
      user_canceled        = 4
      OTHERS               = 5.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
*.........................CONVERT TO OTF TO PDF.......................*

Following function module converts the OTF output format of the smart forms in to PDF format.

Probably you can download and check the output at this point before proceeding further.

  CALL FUNCTION 'CONVERT_OTF_2_PDF'
    IMPORTING
      bin_filesize           = v_bin_filesize
    TABLES
      otf                    = wa_job_output_info-otfdata
      doctab_archive         = it_docs
      lines                  = it_lines
    EXCEPTIONS
      err_conv_not_possible  = 1
      err_otf_mc_noendmarker = 2
      OTHERS                 = 3.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
* ..............Download PDF temporarily on Application server.......*  OPEN DATASET vg_file FOR OUTPUT IN BINARY MODE.
  IF sy-subrc = 0.
    LOOP AT it_lines INTO wa_lines.
      TRANSFER wa_lines TO vg_file.
      CLEAR wa_lines.
    ENDLOOP.
  ENDIF.
  CLOSE DATASET vg_file.
ENDFORM.                    " generate_PDF

We have PDF format of the document on application server now. Next process is to upload the PDF output of the document to IXOS server and generate unique archive key, so that document can be retrieved in SAP at any point of time for different purposes. Archive link generation process starts from this point of time.

Get Archive ID is the first step in the process:

Following code can be reused to generate the archive 

  CLEAR : v_archiv_id.
* Get the logical archive id,that is customized for this project

  CALL FUNCTION 'ARCHIV_CONNECTDEFINITION_GET'      "Get logical archive
       EXPORTING
            objecttype    = k_ledger_sap_obj
            documenttype  = k_ledger_ar_obj
            client        = sy-mandt
       IMPORTING
            archivid      =  v_archiv_id
       EXCEPTIONS
            nothing_found = 1
            OTHERS        = 2.

  IF sy-subrc NE 0.
    MESSAGE e401(oa).                  "Archive Link customizing is wrong
    EXIT.
  ENDIF.

Now the PDF document should be archived to IXOS server.

* Get or check the document class
  PERFORM get_document_class_from_type(saplalink_display_document)
                                       USING k_ledger_ar_obj
                                             v_document_class.
  IF v_document_class IS INITIAL.
    MESSAGE e286(oa).
  ENDIF.
* Get the communication type to find the way to make the communication
  PERFORM get_created_communication_type(saplalink_display_document)
                      USING v_archiv_id v_document_class v_communication_type.

* Pass to IXOS
  PERFORM archive_file TABLES it_outdoctab
                       USING  wa_infiletab
                              v_archiv_id
                              v_document_class
                              v_arc_link
                              vg_file
                              v_communication_type
                              v_docty.
 

TOP include must be defined with the following important constants. SAP OBJECT name and AR_OBJECT names are very important and must be provided by basis to developer to identify the object in the landscape.

************************************************************************
***                         CONSTANTS                                ***
************************************************************************

CONSTANTS: k_ledger_sap_obj LIKE toav0-sap_object VALUE 'ZIXPURLDGR',
           k_ledger_ar_obj  LIKE toav0-ar_object  VALUE 'ZIXIILLDGR',
           k_ledger_num_obj LIKE inri-object      VALUE 'ZIXPURNR',
           k_x              TYPE c VALUE 'X'.

Subroutines:

*&---------------------------------------------------------------------*
*&      Form  archive_file
*----------------------------------------------------------------------*
*       Archive file to IXOS
*&---------------------------------------------------------------------*
FORM archive_file  TABLES   i_outdoctab             STRUCTURE toadt
                   USING    ip_infiletab            TYPE      filetable
                            l_archiv_id             TYPE      saearchivi
                            l_document_class        TYPE      saedoktyp
                            l_archiv_doc_id         TYPE      saeardoid
                            l_filenamewithpath      TYPE      char255
                            l_communication_type    TYPE      p
                            l_return_document_class TYPE      saedoktyp.
*
  DATA:
*        countfiletab TYPE i,
        l_filename   TYPE file_table,
        l_onlypathname TYPE file_table,
        l_onlyfilename TYPE file_table,
        l_new_document_class TYPE saedoktyp.

  IF l_filenamewithpath <> space.
    APPEND l_filenamewithpath TO ip_infiletab.
  ENDIF.

* Archive the files
  CLEAR i_outdoctab. REFRESH i_outdoctab.
  LOOP AT ip_infiletab INTO l_filename.
    PERFORM give_me_the_real_documentclass(saplalink_display_document)
                                     USING l_filename-filename
                                           l_document_class
                                           l_new_document_class.
    PERFORM split_filename(saplalink_display_document)
             USING l_filename-filename l_onlypathname l_onlyfilename.
    PERFORM send_file
             USING l_new_document_class
                   l_onlypathname
                   l_onlyfilename
                   l_archiv_id
                   l_archiv_doc_id.

* Build outtab.
    i_outdoctab-contrep_id  = l_archiv_id.
    i_outdoctab-arc_doc_id  = l_archiv_doc_id.
    i_outdoctab-doc_class   = l_new_document_class.
    APPEND i_outdoctab.
    l_return_document_class = l_new_document_class.

  ENDLOOP.

ENDFORM.                    " archive_file
*&---------------------------------------------------------------------*
*&      Form  send_file
*&---------------------------------------------------------------------*
*       Send File to IXOS
*----------------------------------------------------------------------*
FORM send_file     USING  la_document_class TYPE saedoktyp
                          la_onlypathname   TYPE any
                          la_onlyfilename   TYPE any
                          la_archiv_id      TYPE saearchivi
                          la_archiv_doc_id  TYPE saeardoid.


  DATA: la_components    TYPE STANDARD TABLE OF scms_comps,
        wa_components    TYPE scms_comps,
        la_components_nr TYPE i,
        la_opn(255)      TYPE c,
        il_comps         TYPE STANDARD TABLE OF scms_comp,
        wa_comps         TYPE scms_comp,
        la_mimetype      TYPE bdn_con-mimetype.

  la_components_nr = 1.
**
* conversion variable
  la_opn = la_onlypathname.
* archive the local file
  PERFORM get_mimetype(saplalink_display_document) TABLES la_components
                       USING  la_document_class
                              la_mimetype
                              la_components_nr.

  wa_comps-name     = la_onlyfilename.
  wa_comps-mimetype = la_mimetype.
  CLEAR wa_comps-fsize.
  wa_comps-compid   = 'data'.
  APPEND wa_comps TO il_comps.

  CALL FUNCTION 'SCMS_HTTP_CREATE_FILES'
    EXPORTING
      crep_id    = la_archiv_id
      path       = la_opn
      frontend   = ''
      get_size   = k_x
      doc_prot   = 'rcud'
    IMPORTING
      doc_id_out = la_archiv_doc_id
    TABLES
      comps      = il_comps
    EXCEPTIONS
      OTHERS     = 10.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
            RAISING error_contentrepository.
  ENDIF.
ENDFORM.                    " send_file

Now get the object ID of the archived document. Here number/reference number is the SAP document number of the scanned image/PDF. Following function module provides next number against the SAP document number.

* Get new record number for IIL
  CALL FUNCTION 'NUMBER_GET_NEXT'      "Get new record number
       EXPORTING
            nr_range_nr             = '01'
            object                  = k_ledger_num_obj
       IMPORTING
            number                  = v_refnr
       EXCEPTIONS
            interval_not_found      = 1
            number_range_not_intern = 2
            object_not_found        = 3
            quantity_is_0           = 4
            quantity_is_not_1       = 5
            interval_overflow       = 6
            OTHERS                  = 7.
  IF sy-subrc NE 0.
    MESSAGE e870(nr).          "Number range object not available
  ELSE.
    v_object_id  = v_refnr.
  ENDIF.

  READ TABLE it_outdoctab INTO wa_outdoctab INDEX 1.
  IF sy-subrc EQ 0.
    v_arc_doc_id = wa_outdoctab-arc_doc_id.
  ENDIF.
  v_arc_doc_id = v_arc_link.

Following functional module updated the table entry in the archive key tables. This is insertion of the link between the SAP document number and archive key is very important to read back the image into SAP. 

  CALL FUNCTION 'ARCHIV_CONNECTION_INSERT'
    EXPORTING
      archiv_id             = v_archiv_id
      arc_doc_id            = v_arc_doc_id
      ar_object             = k_ledger_ar_obj
      object_id             = v_object_id
      sap_object            = k_ledger_sap_obj
      doc_type              = 'PDF'
    EXCEPTIONS
      error_connectiontable = 1
      OTHERS                = 2.

  IF sy-subrc NE 0.
    MESSAGE e402(oa) WITH k_ledger_sap_obj k_ledger_ar_obj.
    LEAVE TO SCREEN 0.
  ELSE.
    COMMIT WORK.
  ENDIF.

You have option to delete the PDF document stored on the SAP application server after successful update of the archive key relations in the tables. You can reuse code below for the same.

  CALL FUNCTION 'SCMS_FILE_DELETE'
    EXPORTING
      filename      = vg_file
      frontend      = ''
    EXCEPTIONS
      not_found     = 1
      name_too_long = 2
      OTHERS        = 3.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

Now we have everything ready in place. Document is stored on the IXOS server and its archive key is generated and relation available in archiving tables. Following function modules can be used to retrieve the document image in any SAP application using reference of the document number.

  CALL FUNCTION 'ARCHIVOBJECT_GET_URI'
    EXPORTING
      objecttype               = 'ZIXPURLDGR'
      object_id                = v_refnr
      location                 = 'F'
      http_url_only            = ' '
    TABLES
      uri_table                = it_url
    EXCEPTIONS
      error_archiv             = 1
      error_communicationtable = 2
      error_kernel             = 3
      error_http               = 4
      error_dp                 = 5
      OTHERS                   = 6.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

12 Comments