Skip to Content

We had a requirement to convert IDOC’s in web service without PI (PO). We tried to find out whether SAP provides such solutions. SAP replied to our OSS message saying NO. So we developed our own solution that can convert any IDOC into a web service within minutes. Here I will explain the steps.

Once you set up the system then all programs are reusable to convert any IDOC into web service.

Step 1. Create WSDL for the IDOC basic type or extension type

Step 2. Create server proxy for the WSDL to host the IDOC

Step 1. Create WSDL for the IDOC basic type or extension type. You don’t need to transport step 1 to subsequent systems.

1) Copy class CL_PROXY_TEST_UTILS to ZCL_PROXY_UTILS

I) Edit method XSD2WSDL. Paste the source code attached below.

II) Create method GET_WSDL.  Paste the source code attached below.

2) Copy program SAPMSEDIDOCU to ZSAPMSEDIDOCU

I) Copy all include programs with prefix Z

II) Edit ZMSEDIDOCUF01 and paste source code below

3) Activate all programs

4) Assign a TCODE to program ZSAPMSEDIDOCU. In my case I have assigned ZIDOCWSDL

Run the transaction to download the WSDL of the IDOC. If you are using standard IDOC type then use parameter Basic Type or else if you have IDOC extension use Enhancement to download the WSDL.

Here I am downloading standard basic type ORDERS05

/wp-content/uploads/2014/09/1_545291.png

Save the file in your local drive. I have saved the file into my desktop.

/wp-content/uploads/2014/09/2_545292.png

/wp-content/uploads/2014/09/3_545293.png

Step 2. Create server proxy for the WSDL to host the IDOC

Create a class ZCL_CA_IDOC_SERVICE with 3 methods as below and copy paste the source code attached below and activate the class.

/wp-content/uploads/2014/09/4_545294.png

/wp-content/uploads/2014/09/5_545295.png

/wp-content/uploads/2014/09/6_545296.png

/wp-content/uploads/2014/09/7_545300.png

Now create the server proxy from the WSDL you downloaded in step 1. Go to SE80 and crate a service

/wp-content/uploads/2014/09/8_545301.png

/wp-content/uploads/2014/09/9_545302.png

/wp-content/uploads/2014/09/10_545306.png

/wp-content/uploads/2014/09/11_545307.png

/wp-content/uploads/2014/09/12_545312.png

/wp-content/uploads/2014/09/13_545313.png

I have used $tmp. Please use your package and transport here.

/wp-content/uploads/2014/09/14_545314.png

/wp-content/uploads/2014/09/15_545315.png

/wp-content/uploads/2014/09/16_545316.png

Activate the service

 

Go to the implementing class by double clicking, Insert this code and activate the class.

/wp-content/uploads/2014/09/17_545317.png

outputtid = zcl_ca_idoc_service=>trigger_idoc( input = input queueid = space ).

/wp-content/uploads/2014/09/18_545318.png

Go to SOAMANAGER and create an endpoint for the service.

/wp-content/uploads/2014/09/19_545319.png

Now test the service from SOAPUI to post an IDOC into the system

/wp-content/uploads/2014/09/20_545321.png

TID 0A6A381E48FE541C4FFF0304 create with IDOC 881704

/wp-content/uploads/2014/09/21_545322.png

IDOC posted in SAP

/wp-content/uploads/2014/09/22_545323.png

Similarly you can convert any IDOC into web service. With ABAP 7.40, SP05 you can further fine tune the code.

method XSD2WSDL.
  data:
    lr_ixml      type ref to if_ixml,
    lr_streamfac type ref to if_ixml_stream_factory,
    lr_istream   type ref to if_ixml_istream,
    lr_parser    type ref to if_ixml_parser,
    lr_document  type ref to if_ixml_document,
    lr_schema    type ref to if_ixml_element,
    lv_target_ns type string,
    lr_definitions    type ref to if_ixml_element,
    lr_types    type ref to if_ixml_element,
    lv_mess_name    type string,
    lr_message    type ref to if_ixml_element,
    lr_part    type ref to if_ixml_element,
    lv_part_name    type string,
    lr_porttype    type ref to if_ixml_element,
    lr_operation    type ref to if_ixml_element,
    lv_op_name    type string,
    lr_inout    type ref to if_ixml_element,
    lr_children type ref to if_ixml_node_list,
    lv_count type i,
    lv_index type i,
    lv_no type i,
    lr_child type ref to if_ixml_node,
    lr_element type ref to if_ixml_element,
    lv_name type string,
    lv_typename type string.



  lr_ixml      = cl_ixml=>create( ).
  lr_streamfac = lr_ixml->create_stream_factory( ).
  lr_istream   = lr_streamfac->create_istream_xstring( string = schema ).
  lr_document  = lr_ixml->create_document( ).
  lr_parser    = lr_ixml->create_parser( stream_factory = lr_streamfac
                                         istream        = lr_istream
                                         document       = lr_document ).
  call method lr_parser->set_namespace_mode( mode = if_ixml_parser=>co_namespace_aware ).

* whitespace Problem
  lr_parser->add_strip_space_element( name = '*' uri = '*' ).
  if lr_parser->parse( ) ne 0.
*   018(sprx): "The document description is syntactically incorrect."
    message e018(sprx).
  endif.
  lr_schema     = lr_document->get_root_element( ).

  cl_proxy_xsd_utils=>check_node( lr_schema ).


  lr_definitions = lr_document->create_element_ns(
    uri    = if_proxy_const_ns=>namespace_wsdl
    prefix = 'wsdl'                                         "#EC NOTEXT
    name   = 'definitions'                                  "#EC NOTEXT
  ).

  add_namespace_decl(
    document = lr_document
    element  = lr_definitions
    name     = 'wsdl'                                       "#EC NOTEXT
    uri      =  if_proxy_const_ns=>namespace_wsdl
  ).

  lv_target_ns = lr_schema->get_attribute( name = 'targetNamespace' )."#EC NOTEXT
  add_namespace_decl(
    document = lr_document
    element  = lr_definitions
    name     = 'tns'                                        "#EC NOTEXT
    uri      = lv_target_ns
  ).

  lr_definitions->set_attribute( name = 'targetNamespace' value = lv_target_ns )."#EC NOTEXT

  lr_document->replace_child( old_child = lr_schema  new_child = lr_definitions ).
  lr_definitions->append_child( lr_types ).

  lr_types = lr_document->create_element_ns(
    uri    = if_proxy_const_ns=>namespace_wsdl
    prefix = 'wsdl'
    name   = 'types'                                        "#EC NOTEXT
  ).
  lr_definitions->append_child( lr_types ).

  lr_types->append_child( lr_schema ).

  lr_porttype = lr_document->create_element_ns(
    uri    = if_proxy_const_ns=>namespace_wsdl
    prefix = 'wsdl'                                         "#EC NOTEXT
    name   = 'portType'                                     "#EC NOTEXT
  ).
  lr_definitions->append_child( lr_porttype ).
  lr_porttype->set_attribute(
    name = 'name'                                           "#EC NOTEXT
    value = short_name( lv_target_ns )
  ).

  lr_children = lr_schema->get_children( ).
  lv_index = 0.
  lv_no = 0.
  lv_count = lr_children->get_length( ).
  while lv_index < lv_count.
    lr_child = lr_children->get_item( lv_index ).
    lv_index = lv_index + 1.
    try.
        lr_element ?= lr_child.
        lv_name = lr_element->get_name( ).
        if lv_name = 'element'.                             "#EC NOTEXT
          lv_no = lv_no + 1.

          lv_mess_name = lv_no.
          concatenate 'message' lv_mess_name into lv_mess_name."#EC NOTEXT
          condense lv_mess_name no-gaps.

          lr_message = lr_document->create_element_ns(
            uri    = if_proxy_const_ns=>namespace_wsdl
            prefix = 'wsdl'                                 "#EC NOTEXT
            name   = 'message'                              "#EC NOTEXT
          ).

          lr_definitions->append_child( lr_message ).
          lr_message->set_attribute( name = 'name' value = lv_mess_name )."#EC NOTEXT

          lv_typename = lr_element->get_attribute( name = 'name' )."#EC NOTEXT
          concatenate 'tns:' lv_typename into lv_typename.  "#EC NOTEXT

          lv_part_name = lv_no.
          concatenate 'part' lv_part_name into lv_part_name."#EC NOTEXT
          condense lv_part_name no-gaps.

          lr_part = lr_document->create_element_ns(
            uri    = if_proxy_const_ns=>namespace_wsdl
            prefix = 'wsdl'                                 "#EC NOTEXT
            name   = 'part'                                 "#EC NOTEXT
          ).
          lr_message->append_child( lr_part ).
          lr_part->set_attribute( name = 'name' value = lv_part_name )."#EC NOTEXT
          lr_part->set_attribute( name = 'element' value =  lv_typename )."#EC NOTEXT

          lv_op_name = lv_no.
          concatenate 'op' lv_op_name into lv_op_name.
          condense lv_op_name no-gaps.

          lr_operation = lr_document->create_element_ns(
            uri    = if_proxy_const_ns=>namespace_wsdl
            prefix = 'wsdl'                                 "#EC NOTEXT
            name   = 'operation'                            "#EC NOTEXT
          ).
          lr_porttype->append_child( lr_operation ).
          lr_operation->set_attribute( name = 'name' value = lv_op_name )."#EC NOTEXT


          concatenate 'tns:' lv_mess_name into lv_mess_name."#EC NOTEXT
          lr_inout = lr_document->create_element_ns(
            uri    = if_proxy_const_ns=>namespace_wsdl
            prefix = 'wsdl'                                 "#EC NOTEXT
            name   = 'input'                                "#EC NOTEXT
          ).
          lr_operation->append_child( lr_inout ).
          lr_inout->set_attribute( name = 'message' value = lv_mess_name )."#EC NOTEXT

          lr_inout = lr_document->create_element_ns(
            uri    = if_proxy_const_ns=>namespace_wsdl
            prefix = 'wsdl'                                 "#EC NOTEXT
            name   = 'output'                               "#EC NOTEXT
          ).
          lr_operation->append_child( lr_inout ).
          lr_inout->set_attribute( name = 'message' value = lv_mess_name )."#EC NOTEXT

        endif.

      catch cx_sy_move_cast_error .                     "#EC NO_HANDLER
    endtry.
  endwhile.



  call function 'SDIXML_DOM_TO_XML'
    exporting
      document      = lr_document
      pretty_print  = 'X'
    importing
      xml_as_string = wsdl
    exceptions
      others        = 0.


endmethod.
METHOD GET_WSDL.
  DATA: xml_as_string TYPE  xstring,
      wsdl          TYPE  xstring,
      cwsdl2         TYPE  string.

  DATA: proxy	TYPE REF TO	cl_proxy.


  CALL FUNCTION 'SDIXML_DOM_TO_XML'
    EXPORTING
      document            = document
*   PRETTY_PRINT        = ' '
      IMPORTING
       xml_as_string       = xml_as_string
*   SIZE                =
* TABLES
*   XML_AS_TABLE        =
   EXCEPTIONS
     no_document         = 1
     OTHERS              = 2
            .
  IF sy-subrc <> 0.
* Implement suitable error handling here
  ENDIF.

  CALL METHOD cl_proxy_service=>xstring2cstring
    EXPORTING
      xstring = xml_as_string
    RECEIVING
      cstring = cwsdl.

  REPLACE FIRST OCCURRENCE OF '<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1.0">' IN cwsdl WITH
   '<xsd:schema targetNamespace="http://SAPIdocServices.com" xmlns="http://SAPIdocServices.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema">'.

  FIND '</xsd:schema>' IN cwsdl.
  IF sy-subrc = 0.
    DATA: lv_res TYPE string.
    CONCATENATE
     '<xsd:element name="TID.Response">'
            '<xsd:complexType>'
              '<xsd:all>'
                '<xsd:element name="TID" minOccurs="0">'
                  '<xsd:annotation>'
                    '<xsd:documentation>Transaction ID</xsd:documentation>'
                  '</xsd:annotation>'
                  '<xsd:simpleType>'
                    '<xsd:restriction base="xsd:string">'
                      '<xsd:maxLength value="24" />'
                    '</xsd:restriction>'
                  '</xsd:simpleType>'
                '</xsd:element>'
              '</xsd:all>'
            '</xsd:complexType>'
          '</xsd:element>' '</xsd:schema>' INTO lv_res.

  ENDIF.

  SPLIT cwsdl AT '</xsd:schema>' INTO cwsdl cwsdl2.
  IF sy-subrc = 0.
    CONCATENATE cwsdl lv_res INTO cwsdl.
  ENDIF.

  CALL METHOD cl_proxy_service=>cstring2xstring
    EXPORTING
      cstring = cwsdl
    RECEIVING
      xstring = wsdl.

  TRY.
      CALL METHOD zcl_proxy_utils=>xsd2wsdl
        EXPORTING
          schema = wsdl
        RECEIVING
          wsdl   = wsdl.
    CATCH cx_proxy_gen_error .
  ENDTRY.

  CALL METHOD cl_proxy_service=>xstring2cstring
    EXPORTING
      xstring = wsdl
    RECEIVING
      cstring = cwsdl.

*  IF idoctyp IS INITIAL.
*    idoctyp = mestyp.
*  ENDIF.

  CLEAR lv_res.
  CONCATENATE
  '<wsdl:definitions name="' idoctyp '" targetNamespace="http://SAPIdocServices.com" xmlns:tns="http://SAPIdocServices.com" '
   'xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" '
   'xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">'
    '<wsp:UsingPolicy wsdl:required="true" />'
    '<wsp:Policy wsu:Id="OP_' idoctyp '" />' INTO lv_res RESPECTING BLANKS.

  REPLACE FIRST OCCURRENCE OF
  '<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://SAPIdocServices.com" targetNamespace="http://SAPIdocServices.com">'
   IN cwsdl WITH lv_res.

  REPLACE FIRST OCCURRENCE OF '</wsdl:operation>' IN cwsdl WITH ''.
  REPLACE FIRST OCCURRENCE OF '</wsdl:portType>' IN cwsdl WITH ''.
  CLEAR lv_res.
  CONCATENATE '<wsdl:part name="part1" element="tns:' idoctyp '"/>' INTO lv_res.
  REPLACE FIRST OCCURRENCE OF lv_res IN cwsdl WITH ''.
  REPLACE FIRST OCCURRENCE OF '</wsdl:message>' IN cwsdl WITH ''.
  REPLACE FIRST OCCURRENCE OF '<wsdl:part name="part2" element="tns:TID.Response"/>' IN cwsdl WITH ''.
  REPLACE FIRST OCCURRENCE OF '</wsdl:message>' IN cwsdl WITH ''.
  REPLACE FIRST OCCURRENCE OF '<wsdl:output message="tns:message1"/>' IN cwsdl WITH ''.
  REPLACE FIRST OCCURRENCE OF '<wsdl:input message="tns:message2"/>' IN cwsdl WITH ''.
  REPLACE FIRST OCCURRENCE OF '<wsdl:portType name="Http">' IN cwsdl WITH ''.
  REPLACE FIRST OCCURRENCE OF '<wsdl:operation name="op1">' IN cwsdl WITH ''.
  REPLACE FIRST OCCURRENCE OF '<wsdl:operation name="op1">' IN cwsdl WITH ''.
  REPLACE FIRST OCCURRENCE OF '<wsdl:input message="tns:message1"/>' IN cwsdl WITH ''.
  REPLACE FIRST OCCURRENCE OF '<wsdl:output message="tns:message2"/>' IN cwsdl WITH ''.
  REPLACE FIRST OCCURRENCE OF '<wsdl:message name="message1">' IN cwsdl WITH ''.
  REPLACE FIRST OCCURRENCE OF '<wsdl:message name="message2">' IN cwsdl WITH ''.
  REPLACE FIRST OCCURRENCE OF '<wsdl:operation name="op2">' IN cwsdl WITH ''.
  REPLACE FIRST OCCURRENCE OF '<wsdl:input message="tns:message1"/>' IN cwsdl WITH ''.
  REPLACE FIRST OCCURRENCE OF '<wsdl:output message="tns:message2"/>' IN cwsdl WITH ''.
  REPLACE FIRST OCCURRENCE OF '</wsdl:operation>' IN cwsdl WITH ''.


  SPLIT cwsdl AT '</wsdl:definitions>' INTO cwsdl cwsdl2.
  CLEAR lv_res.
  CONCATENATE
  '<wsdl:message name="tns.message1">'
    '<wsdl:part name="part1" element="tns:' idoctyp '" />'
     '</wsdl:message>'
     '<wsdl:message name="tns.message2">'
    '<wsdl:part name="part2" element="tns:TID.Response" />'
  '</wsdl:message>'

  '<wsdl:portType name="' idoctyp '">'
    '<wsdl:operation name="' idoctyp '">'
      '<wsdl:input message="tns:tns.message1" />'
      '<wsdl:output message="tns:tns.message2" />'
    '</wsdl:operation>'
  '</wsdl:portType>'

  '<wsdl:binding name="' idoctyp 'Binding" type="tns:' idoctyp '">'
    '<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" />'
    '<wsdl:operation name="' idoctyp '">'
      '<soap:operation soapAction="http://sap.com/xi/WebService/soap1.1" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" />'
      '<wsdl:input>'
        '<soap:body use="literal" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" />'
      '</wsdl:input>'
      '<wsdl:output>'
        '<soap:body use="literal" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" />'
      '</wsdl:output>'
    '</wsdl:operation>'
  '</wsdl:binding> </wsdl:definitions>' INTO lv_res.

  CONCATENATE cwsdl lv_res INTO cwsdl.
ENDMETHOD.
*----------------------------------------------------------------------*
***INCLUDE MSEDIDOCUF01 .
*----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*&      Form  read_setget_param
*&---------------------------------------------------------------------*
FORM read_setget_param.
  DATA: l_type LIKE sed5struc-objecttype,
        l_object(30) TYPE c,
        l_recsel(3) TYPE c.

  GET PARAMETER ID 'SEG' FIELD seddocustr-segtyp.
  GET PARAMETER ID 'IDC' FIELD seddocustr-idoctyp.
  GET PARAMETER ID 'CIM' FIELD seddocustr-cimtyp.
  GET PARAMETER ID 'EDIDEF_OBJTYP' FIELD l_type. "settings from we30
  GET PARAMETER ID 'EDD' FIELD l_object.
  GET PARAMETER ID 'EDI_SELDOCU' FIELD l_recsel. "record selection

  IF sy-tcode EQ 'WE62'.               " segment documentation
    CLEAR seddocustr-bassel.
    CLEAR seddocustr-cimsel.
    seddocustr-segsel = 'X'.
  ELSEIF sy-tcode EQ 'WE61'.           "record types
    seddocustr-controlrec = 'X'.
    seddocustr-datarec = 'X'.
    seddocustr-statusrec = 'X'.
  ELSEIF sy-tcode EQ 'WE60' OR sy-tcode EQ 'WE63'.
    IF l_type EQ c_ext.
      CLEAR seddocustr-bassel.
      CLEAR seddocustr-segsel.
      seddocustr-cimsel = 'X'.
      IF NOT l_object IS INITIAL.
        seddocustr-cimtyp = l_object.
      ENDIF.
    ELSE.
      seddocustr-bassel = 'X'.
      CLEAR seddocustr-segsel.
      CLEAR seddocustr-cimsel.
      IF NOT l_object IS INITIAL.
        seddocustr-idoctyp = l_object.
      ENDIF.
    ENDIF.
  ENDIF.

* selection for record types suggested via SET/GET-parameter
* afterthat clear SET/GET-parameter, because the transaction itself
* does not support the SET/GET-parameter for selection of record types
  IF NOT l_recsel IS INITIAL.
    seddocustr-controlrec = l_recsel(1).
    seddocustr-datarec    = l_recsel+1(1).
    seddocustr-statusrec = l_recsel+2(1).
    SET PARAMETER ID 'EDI_SELDOCU' FIELD '   '.
  ENDIF.

ENDFORM.                               " read_setget_param
*&---------------------------------------------------------------------*
*&      Form  check_and_set_descrp
*&---------------------------------------------------------------------*
FORM check_and_set_descrp.
  DATA: l_attributes TYPE edi_iapi01,
        l_seghead    TYPE edisegmhd.

  CLEAR seddocustr-idoctdescr.
  CLEAR seddocustr-cimdescrp.
  CLEAR seddocustr-segdescrp.
  IF  seddocustr-idoctyp NE space.
* basic type selected
* existence check
    CALL FUNCTION 'IDOCTYPE_EXISTENCE_CHECK'
      EXPORTING
        pi_idoctyp    = seddocustr-idoctyp
        pi_read_devc  = ' '
      IMPORTING
        pe_attributes = l_attributes
      EXCEPTIONS
        OTHERS        = 1.
    IF sy-subrc <> 0      AND
       g_init_flag EQ 'X' AND
       okcode_100 NE 'TYPSEL' AND
       seddocustr-bassel NE space.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
* set description
    seddocustr-idoctdescr = l_attributes-descrp.
  ENDIF.
  IF seddocustr-cimtyp NE space.
* extension selected
* existence check
    CLEAR l_attributes.
    CALL FUNCTION 'EXTTYPE_EXISTENCE_CHECK'
      EXPORTING
        pi_cimtyp     = seddocustr-cimtyp
        pi_read_devc  = ' '
      IMPORTING
        pe_attributes = l_attributes
      EXCEPTIONS
        OTHERS        = 1.
    IF sy-subrc <> 0 AND g_init_flag EQ 'X'
       AND okcode_100 NE 'TYPSEL'
       AND seddocustr-cimsel NE space.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
* set description
    seddocustr-cimdescrp = l_attributes-descrp.
  ENDIF.
  IF seddocustr-segtyp NE space.
* segment is selected
    l_seghead-segtyp = seddocustr-segtyp.
    CALL FUNCTION 'SEGMENT_READ'
      EXPORTING
        segmenttyp    = l_seghead-segtyp
      IMPORTING
        segmentheader = l_seghead
      EXCEPTIONS
        OTHERS        = 1.
    IF sy-subrc <> 0 AND g_init_flag EQ 'X'
       AND okcode_100 NE 'TYPSEL'
       AND seddocustr-segsel NE space.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
* set description
    seddocustr-segdescrp = l_seghead-descrp.
  ENDIF.
ENDFORM.                               " check_and_set_descrp
*&---------------------------------------------------------------------*
*&      Form  read_version_descrp
*&---------------------------------------------------------------------*
FORM read_version_descrp.
  CALL FUNCTION 'DDIF_DOMA_GET'
    EXPORTING
      name      = 'EDI_VERSIO'
      langu     = sy-langu
    TABLES
      dd07v_tab = gt_version_descrp.
**       exceptions
**            illegal_input = 1
**            others        = 2.
* ignore exceptions
  LOOP AT gt_version_descrp WHERE domvalue_l EQ seddocustr-version.
    seddocustr-verdescrp = gt_version_descrp-ddtext.
    EXIT.
  ENDLOOP.
ENDFORM.                               " read_version_descrp
*&---------------------------------------------------------------------*
*&      Form  start_html_docu
*&---------------------------------------------------------------------*
FORM start_html_docu.
  DATA: l_type TYPE char1,
        l_segment TYPE edilsegtyp,
        l_object TYPE edi_docobj.


* basic type or extension
  IF NOT seddocustr-bassel IS INITIAL.
    l_type = 'B'.
    CONCATENATE text-100 seddocustr-idoctyp INTO g_titel
                SEPARATED BY space.
    l_object = seddocustr-idoctyp.
  ELSEIF NOT seddocustr-cimsel IS INITIAL.
    l_type = 'E'.
    CONCATENATE text-101 seddocustr-cimtyp INTO g_titel
                SEPARATED BY space.
    l_object = seddocustr-cimtyp.
  ELSEIF NOT seddocustr-segsel IS INITIAL.
    l_segment = seddocustr-segtyp.
    IF l_segment IS INITIAL.
      MESSAGE s653(e0). EXIT.
    ENDIF.
  ENDIF.

* check selection
  IF l_object              IS INITIAL AND
     seddocustr-segsel     IS INITIAL AND
     seddocustr-controlrec IS INITIAL AND
     seddocustr-datarec    IS INITIAL AND
     seddocustr-statusrec  IS INITIAL.
    MESSAGE s346.
    EXIT.
  ENDIF.


* fill global tables with html sources
  REFRESH gt_frameset. REFRESH gt_index. REFRESH gt_docu.
  REFRESH gt_formated_docu.
  g_basisurl = l_object.
  IF g_basisurl EQ space.
    g_basisurl = l_segment.
  ENDIF.
  WHILE g_basisurl CS '/'.
    REPLACE '/' WITH '' INTO g_basisurl.
  ENDWHILE.
  CONDENSE g_basisurl NO-GAPS.

  IF NOT seddocustr-bassel IS INITIAL OR
     NOT seddocustr-cimsel IS INITIAL.
    IF l_object IS INITIAL.   "only record types
      g_titel = text-103.
    ENDIF.
    CALL FUNCTION 'IDOC_TYPE_GENERATE_HTML'
      EXPORTING
        struct_type         = l_type
        idoctype            = l_object
        release             = g_released
        applrel             = gd_applrel
        version             = seddocustr-version
        basisurl            = g_basisurl
        with_control_record = seddocustr-controlrec
        with_data_record    = seddocustr-datarec
        with_status_record  = seddocustr-statusrec
      IMPORTING
        tab_frame           = gt_frameset
        tab_index           = gt_index
        tab_docu            = gt_docu
        htmlext             = g_htmlext
      EXCEPTIONS
        OTHERS              = 1.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
  ELSEIF NOT seddocustr-segsel IS INITIAL.
* segment type
    CONCATENATE text-102 l_segment INTO g_titel
                  SEPARATED BY space.
    CALL FUNCTION 'IDOC_SEGMENT_GENERATE_HTML'
      EXPORTING
        segment   = l_segment
        release   = g_released
        applrel   = gd_applrel
        version   = seddocustr-version
        basisurl  = g_basisurl
      IMPORTING
        tab_frame = gt_frameset
        tab_index = gt_index
        tab_docu  = gt_docu
        htmlext   = g_htmlext
      EXCEPTIONS
        OTHERS    = 1.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
  ENDIF.
* display docu
  CALL SCREEN 200.
ENDFORM.                               " start_html_docu
*&---------------------------------------------------------------------*
*&      Form  start_user_settings
*&---------------------------------------------------------------------*

FORM start_user_settings.
  CALL FUNCTION 'IDOC_MAINTAIN_USER'
    EXCEPTIONS
      OTHERS = 1.


  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
ENDFORM.                               " start_user_settings

*&---------------------------------------------------------------------*
*&      Form  check_unicode
*&---------------------------------------------------------------------*

FORM ask_unicode CHANGING unicode_flag.
  DATA l_answer TYPE char1.

  IF  seddocustr-version = '3'
      AND save_okcode100 = 'SCHEMA'.
    CLEAR unicode_flag.
    CALL FUNCTION 'POPUP_TO_CONFIRM_STEP'
      EXPORTING
        defaultoption  = 'Y'
        textline1      = text-106
        titel          = syst-title
        cancel_display = space
      IMPORTING
        answer         = l_answer.
    IF l_answer = 'J'.
      MOVE 'X' TO unicode_flag.
    ENDIF.
  ENDIF.
ENDFORM.                               " check_unicode

*&---------------------------------------------------------------------*
*&      Form  start_cheader_docu
*&---------------------------------------------------------------------*

FORM start_cheader_docu.
  DATA: l_type TYPE char1,
        l_object TYPE edi_docobj.


* basic type or extension
  IF NOT seddocustr-bassel IS INITIAL.
    l_type = 'B'.
    CONCATENATE text-100 seddocustr-idoctyp INTO g_titel
                SEPARATED BY space.
    l_object = seddocustr-idoctyp.
  ELSEIF NOT seddocustr-cimsel IS INITIAL.
    l_type = 'E'.
    CONCATENATE text-101 seddocustr-cimtyp INTO g_titel
                SEPARATED BY space.
    l_object = seddocustr-cimtyp.
  ELSEIF NOT seddocustr-segsel IS INITIAL.
    MESSAGE s345.
    EXIT.
  ENDIF.

* check selection
  IF l_object              IS INITIAL AND
     seddocustr-controlrec IS INITIAL AND
     seddocustr-datarec    IS INITIAL AND
     seddocustr-statusrec  IS INITIAL.
    MESSAGE s346.
    EXIT.
  ENDIF.

* generate c-header-declarations
  REFRESH gt_formated_docu.
  CALL FUNCTION 'IDOC_TYPE_GENERATE_C_HEADER'
    EXPORTING
      release               = g_released
      applrel               = gd_applrel
      struct_type           = l_type
      idoctype              = l_object
      with_control_record   = seddocustr-controlrec
      with_data_record      = seddocustr-datarec
      with_status_record    = seddocustr-statusrec
      version               = seddocustr-version
    TABLES
      text                  = gt_formated_docu
    EXCEPTIONS
      definition_read_error = 1
      format_error          = 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.

* output the table with C-Declarations
  PERFORM write_docu.


ENDFORM.                               " start_cheader_docu
*&---------------------------------------------------------------------*
*&      Form  write_docu
*&---------------------------------------------------------------------*
FORM write_docu.
  DATA: wa_docu TYPE LINE OF sedidoculine.
  LEAVE TO LIST-PROCESSING AND RETURN TO SCREEN 100.
  IF save_okcode100 EQ 'PARSER'.
    SET PF-STATUS 'DISPLAY_DOCU'.
  ELSE.
    SET PF-STATUS 'DISPLAY_DOCU' EXCLUDING 'PINFO'.
  ENDIF.
  SET TITLEBAR  'DISPLAY_DOCU' WITH g_titel.
  NEW-PAGE NO-TITLE LINE-SIZE 255.
  LOOP AT gt_formated_docu INTO wa_docu.
    IF wa_docu IS INITIAL.
      WRITE /.
    ELSE.
      WRITE wa_docu.
    ENDIF.
  ENDLOOP.
ENDFORM.                               " write_docu
*&---------------------------------------------------------------------*
*&      Form  start_dtd_docu
*&---------------------------------------------------------------------*
FORM start_dtd_docu USING conv_version TYPE edi_unicod.
  DATA:  l_idoctyp LIKE  edi_iapi00-idoctyp,
         l_cimtyp  LIKE  edi_iapi00-cimtyp,
         l_cimattr LIKE  edi_iapi01.


* check selection
  IF NOT seddocustr-segsel IS INITIAL.
    MESSAGE s345.
    EXIT.
  ELSEIF NOT seddocustr-bassel IS INITIAL AND
         seddocustr-idoctyp IS INITIAL .
    MESSAGE s653(e0).
    EXIT.
  ELSEIF NOT seddocustr-cimsel IS INITIAL AND
         seddocustr-cimtyp IS INITIAL.
    MESSAGE s653(e0).
    EXIT.
  ENDIF.

* basic type or extension
  IF NOT seddocustr-bassel IS INITIAL.
    l_idoctyp = seddocustr-idoctyp.
    CONCATENATE text-100 seddocustr-idoctyp INTO g_titel
                SEPARATED BY space.
  ELSEIF NOT seddocustr-cimsel IS INITIAL.
* read related basic type
    CALL FUNCTION 'EXTTYPE_READ'
      EXPORTING
        pi_cimtyp     = seddocustr-cimtyp
        pi_read_devc  = ' '
      IMPORTING
        pe_attributes = l_cimattr
      EXCEPTIONS
        OTHERS        = 1.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
    l_idoctyp = l_cimattr-idoctyp.
    l_cimtyp = seddocustr-cimtyp.
    CONCATENATE text-101 seddocustr-cimtyp INTO g_titel
                SEPARATED BY space.
  ENDIF.

* generate dtd-definition
  REFRESH gt_formated_docu.
  CALL FUNCTION 'IDOC_TYPE_DTD_TABLE'
    EXPORTING
      pi_idoctype    = l_idoctyp
      pi_cimtype     = l_cimtyp
      pi_dtd_type    = 'E'
      unicode_format = conv_version
    TABLES
      pt_dtd         = gt_formated_docu
    EXCEPTIONS
      OTHERS         = 1.
  IF sy-subrc NE 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

  IF seddocustr-docurel NE space OR seddocustr-version NE '3'.
    CALL FUNCTION 'POPUP_DISPLAY_TEXT'
      EXPORTING
        popup_title = text-105
        text_object = 'SED_DTD_INFO'
      EXCEPTIONS
        OTHERS      = 0.
  ENDIF.
* output the table with dtd-definition
  PERFORM write_docu.
ENDFORM.                               " start_dtd_docu
*&---------------------------------------------------------------------*
*&      Form  start_idoc
*&---------------------------------------------------------------------*
FORM start_idoc.
  DATA: l_type TYPE char1,
        l_docnum TYPE edi_docnum,
        l_object TYPE edi_docobj.
  RANGES lt_idocs FOR edidc-docnum OCCURS 2.


* basic type or extension
  IF NOT seddocustr-bassel IS INITIAL.
    l_type = 'B'.
    CONCATENATE text-100 seddocustr-idoctyp INTO g_titel
                SEPARATED BY space.
    l_object = seddocustr-idoctyp.
  ELSEIF NOT seddocustr-cimsel IS INITIAL.
    l_type = 'E'.
    CONCATENATE text-101 seddocustr-cimtyp INTO g_titel
                SEPARATED BY space.
    l_object = seddocustr-cimtyp.
  ELSEIF NOT seddocustr-segsel IS INITIAL.
    MESSAGE s345.
    EXIT.
  ENDIF.

* check selection
  IF l_object              IS INITIAL AND
     seddocustr-controlrec IS INITIAL AND
     seddocustr-datarec    IS INITIAL AND
     seddocustr-statusrec  IS INITIAL.
    MESSAGE s346.
    EXIT.
  ENDIF.


  IF NOT l_object IS INITIAL.
* basic type or extension selected ->
* create idoc for log. message SYIDOC
    CALL FUNCTION 'EDI_CREATE_SYIDOC01'
      EXPORTING
        object         = l_object
        object_type    = l_type
        object_release = g_released
        object_applrel = gd_applrel
        pi_rec_version = seddocustr-version
      IMPORTING
        docnum         = l_docnum
      EXCEPTIONS
        OTHERS         = 1.
    IF sy-subrc NE 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
    IF l_docnum NE 0.
      lt_idocs-sign = 'I'.
      lt_idocs-option = 'EQ'.
      lt_idocs-low = l_docnum.
      APPEND lt_idocs.
    ENDIF.
  ENDIF.
  IF NOT seddocustr-controlrec IS INITIAL OR
     NOT seddocustr-datarec    IS INITIAL OR
     NOT seddocustr-statusrec  IS INITIAL.
* create idoc for log.Message SYRECD
    CALL FUNCTION 'EDI_CREATE_SYRECD01'
      EXPORTING
        version             = seddocustr-version
        with_control_record = seddocustr-controlrec
        with_data_record    = seddocustr-datarec
        with_status_record  = seddocustr-statusrec
      IMPORTING
        docnum              = l_docnum
      EXCEPTIONS
        OTHERS              = 1.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
    IF l_docnum NE 0.
      lt_idocs-sign = 'I'.
      lt_idocs-option = 'EQ'.
      lt_idocs-low = l_docnum.
      APPEND lt_idocs.
    ENDIF.
  ENDIF.
* display idocs (if created)
  IF NOT lt_idocs[] IS INITIAL.
    SUBMIT rseidoc2 WITH docnum IN lt_idocs AND RETURN.
  ENDIF.
ENDFORM.                               " start_idoc
*&---------------------------------------------------------------------*
*&      Form  start_parser_docu
*&---------------------------------------------------------------------*
FORM start_parser_docu.
  DATA: l_type TYPE char1,
        l_object TYPE edi_docobj.


* basic type or extension
  IF NOT seddocustr-bassel IS INITIAL.
    l_type = 'B'.
    CONCATENATE text-100 seddocustr-idoctyp INTO g_titel
                SEPARATED BY space.
    l_object = seddocustr-idoctyp.
  ELSEIF NOT seddocustr-cimsel IS INITIAL.
    l_type = 'E'.
    CONCATENATE text-101 seddocustr-cimtyp INTO g_titel
                SEPARATED BY space.
    l_object = seddocustr-cimtyp.
  ELSEIF NOT seddocustr-segsel IS INITIAL.
    MESSAGE s345.
    EXIT.
  ENDIF.

* check selection
  IF l_object              IS INITIAL AND
     seddocustr-controlrec IS INITIAL AND
     seddocustr-datarec    IS INITIAL AND
     seddocustr-statusrec  IS INITIAL.
    MESSAGE s346.
    EXIT.
  ENDIF.



* generate c-header-declarations
  REFRESH gt_formated_docu.
  CALL FUNCTION 'EDI_IDOC_PARSER'
    EXPORTING
      object                = l_object
      object_type           = l_type
      object_release        = g_released
      object_applrel        = gd_applrel
      version               = seddocustr-version
      with_control_record   = seddocustr-controlrec
      with_data_record      = seddocustr-datarec
      with_status_record    = seddocustr-statusrec
    IMPORTING
      parser_docu           = gt_formated_docu
    EXCEPTIONS
      definition_read_error = 1
      OTHERS                = 2.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

* output the table with parser docu
  PERFORM write_docu.
ENDFORM.                               " start_parser_docu
*----------------------------------------------------------------------*
*       start_schema_docu                                              *
*----------------------------------------------------------------------*
FORM start_schema_docu USING unicode_flag TYPE char1.
* wenn unicode_flag = 'X', hat TABNAME den Wert 'EDI_DC40_U'
* hier muß seddocustr-bassel gefüllt sein
* in seddocustr-idoctyp steht Basis-IDoctyp
  DATA: document TYPE REF TO if_ixml_document,
        xml_schema TYPE REF TO if_ixml_element,             "#EC NEEDED
        schema_control TYPE dcxmlschcl,
        mestyp TYPE edi_mestyp ,
        idoctyp TYPE edi_idoctp,
        control TYPE dcxmlidscl,
        elements TYPE dcxmlelems,
        e TYPE REF TO if_ixml_element,
        i TYPE REF TO if_ixml_node_iterator,
        d TYPE REF TO if_ixml_node,
        m TYPE REF TO if_ixml_named_node_map,
        rc TYPE sy-subrc,
        idoctypdescr TYPE dcxmlidocd.

  DATA: xml(3) VALUE 'XML',
        xml_non_released.

  FIELD-SYMBOLS:
    <element> TYPE REF TO if_ixml_element.

  IF g_released IS INITIAL AND gd_applrel IS INITIAL.
    xml_non_released = 'X'.
  ENDIF.
  EXPORT xml_non_released TO MEMORY ID xml.

* namespace xsd for FUNCTION SDIXML_SCHEMA_CREATE:
  schema_control-xsdnsp = 'xsd'.

  CALL FUNCTION 'SDIXML_SCHEMA_CREATE'
    EXPORTING
      control        = schema_control
    IMPORTING
      schema         = xml_schema
    CHANGING
      document       = document
    EXCEPTIONS
      internal_error = 1
      OTHERS         = 2.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    EXIT.
  ENDIF.

  mestyp = ' '.
  control-idoc_text = 'X'.
  control-langu = sy-langu.
  control-atom_text = 'X'.
  control-stru_text = 'X'.
  control-ttyp_text = 'X'.
* namespace xsd for FUNCTION SDIXML_IDOC_TO_SCHEMA:
  control-xsdnsp    = 'xsd'.
  control-version = '02'.

  IF seddocustr-bassel = 'X'.
    IF NOT seddocustr-idoctyp IS INITIAL.
      idoctyp = seddocustr-idoctyp.
      control-is_cim = ' '.
      CALL FUNCTION 'SDIXML_IDOC_TO_SCHEMA'
        EXPORTING
          mestyp          = mestyp
          idoctyp         = idoctyp
          control         = control
        IMPORTING
          elements        = elements
        CHANGING
          idocdescr       = idoctypdescr
          document        = document
        EXCEPTIONS
          idoc_not_exists = 1
          OTHERS          = 2.
      IF sy-subrc <> 0.
        MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
             WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
        EXIT.
      ENDIF.
    ELSE.
      MESSAGE s346(ea).
      EXIT.
    ENDIF.
  ELSEIF seddocustr-cimsel = 'X'.
    IF NOT seddocustr-cimtyp IS INITIAL.
      idoctyp = seddocustr-cimtyp.
      control-is_cim = 'X'.
      CALL FUNCTION 'SDIXML_IDOC_TO_SCHEMA'
        EXPORTING
          mestyp          = mestyp
          idoctyp         = idoctyp
          control         = control
        IMPORTING
          elements        = elements
        CHANGING
          idocdescr       = idoctypdescr
          document        = document
        EXCEPTIONS
          idoc_not_exists = 1
          OTHERS          = 2.
      IF sy-subrc <> 0.
        MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
             WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
        EXIT.
      ENDIF.
    ELSE.
      MESSAGE s346(ea).
      EXIT.
    ENDIF.
  ELSE. " es muß eins der beiden ausgewählt worden sein
  ENDIF.

* creation of the document
* --> creation of the header
  CALL METHOD document->append_child
    EXPORTING
      new_child = xml_schema
    RECEIVING
      rval      = rc.
  CHECK rc = 0.
* --> creation of the body
  LOOP AT elements ASSIGNING <element>.
    IF NOT <element> IS INITIAL.
      CALL METHOD xml_schema->append_child
        EXPORTING
          new_child = <element>
        RECEIVING
          rval      = rc.
      IF rc NE 0.
        EXIT.
      ENDIF.
    ENDIF.
  ENDLOOP.

* Change the value of the field TABNAME, if unicode_flag = 'X'.
  IF NOT unicode_flag IS INITIAL.
    i = document->create_iterator( 10 ).
    d = i->get_next( ).
    WHILE NOT d IS INITIAL.
      IF d->get_name( ) = 'element'.                        "#EC NOTEXT
        m = d->get_attributes( ).
        IF NOT m IS INITIAL.
          d = m->get_named_item( 'name' ).                  "#EC NOTEXT
          IF NOT d IS INITIAL
              AND d->get_value( ) = 'TABNAM'.               "#EC NOTEXT
            d = m->get_named_item( 'fixed' ).               "#EC NOTEXT
            IF d->get_value( ) = 'EDI_DC40'.                "#EC NOTEXT
              d->set_value( value = 'EDI_DC40_U' ).         "#EC NOTEXT
              EXIT.
            ENDIF.
          ENDIF.
        ENDIF.
      ELSE.
        d = i->get_next( ).
      ENDIF.
    ENDWHILE.
  ENDIF.

  DATA: cwsdl TYPE string.
  DATA: xwsdl          TYPE  xstring.

  CALL METHOD zcl_proxy_utils=>get_wsdl
    EXPORTING
      document = document
      idoctyp  = idoctyp
    IMPORTING
      cwsdl    = cwsdl.

*  DATA: lr_proxy  TYPE REF TO cl_proxy.
*
*  DATA: dir(1024)       TYPE c,
*        tr_num          TYPE korrnum,
*        activate        TYPE c,
*        lr_fault     TYPE REF TO cx_root,
*        lv_text      TYPE string.
*
*  IF create IS NOT INITIAL.
*    TRY.
*
*        CALL METHOD cl_proxy_service=>cstring2xstring
*          EXPORTING
*            cstring = cwsdl
*          RECEIVING
*            xstring = xwsdl.
*
*        lr_proxy = zcl_proxy_utils=>wsdl2proxy(
*          wsdl    = xwsdl
*          package = ko007-l_devclass
*          praefix = prefix
*        ).
*
*        lr_proxy->activate(
*          EXPORTING
*            activate_all     = 'X'
*          CHANGING
*            transport_number = e070-trkorr
*        ).
*
*      CATCH cx_root INTO lr_fault.                       "#EC CATCH_ALL
*        lv_text = lr_fault->get_text( ).
*        MESSAGE lv_text TYPE 'E'.
*    ENDTRY.
*  ENDIF.

  PERFORM xml_download USING cwsdl idoctyp.
ENDFORM.                    "start_schema_docu
*&---------------------------------------------------------------------*
*&      Form  Xml_download
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->XML        text
*      -->SIZE       text
*----------------------------------------------------------------------*
FORM xml_download USING wsdl TYPE string
                        idoctyp type any.
  "SIZE TYPE I.

  DATA: t_wsdl TYPE TABLE OF string.

  DATA: filename TYPE string,
        rc TYPE sy-subrc.
  PERFORM get_filename USING 'S' CHANGING filename rc idoctyp.
  CHECK rc = 0.

  APPEND wsdl TO t_wsdl.
  CALL METHOD cl_gui_frontend_services=>gui_download
    EXPORTING
*      BIN_FILESIZE              =
      filename                  = filename
*      FILETYPE                  = 'wsdl'
*      APPEND                    = SPACE
*      WRITE_FIELD_SEPARATOR     = SPACE
*      HEADER                    = '00'
*      TRUNC_TRAILING_BLANKS     = SPACE
*      WRITE_LF                  = 'X'
*      COL_SELECT                = SPACE
*      COL_SELECT_MASK           = SPACE
*      DAT_MODE                  = SPACE
*      CONFIRM_OVERWRITE         = SPACE
*      NO_AUTH_CHECK             = SPACE
*      CODEPAGE                  = SPACE
*      IGNORE_CERR               = ABAP_TRUE
*      REPLACEMENT               = '#'
*      WRITE_BOM                 = SPACE
*      TRUNC_TRAILING_BLANKS_EOL = 'X'
*      WK1_N_FORMAT              = SPACE
*      WK1_N_SIZE                = SPACE
*      WK1_T_FORMAT              = SPACE
*      WK1_T_SIZE                = SPACE
*      SHOW_TRANSFER_STATUS      = 'X'
*      FIELDNAMES                =
*      WRITE_LF_AFTER_LAST_LINE  = 'X'
*      VIRUS_SCAN_PROFILE        = '/SCET/GUI_DOWNLOAD'
*    IMPORTING
*      FILELENGTH                =
    CHANGING
      data_tab                  = t_wsdl
    EXCEPTIONS
      file_write_error          = 1
      no_batch                  = 2
      gui_refuse_filetransfer   = 3
      invalid_type              = 4
      no_authority              = 5
      unknown_error             = 6
      header_not_allowed        = 7
      separator_not_allowed     = 8
      filesize_not_allowed      = 9
      header_too_long           = 10
      dp_error_create           = 11
      dp_error_send             = 12
      dp_error_write            = 13
      unknown_dp_error          = 14
      access_denied             = 15
      dp_out_of_memory          = 16
      disk_full                 = 17
      dp_timeout                = 18
      file_not_found            = 19
      dataprovider_exception    = 20
      control_flush_error       = 21
      not_supported_by_gui      = 22
      error_no_gui              = 23
      OTHERS                    = 24
          .
  IF sy-subrc <> 0.
*   Implement suitable error handling here
  ENDIF.


ENDFORM.                    " Xml_download

*&---------------------------------------------------------------------*
*&      Form  Get_filename
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->MODE       text
*      -->FILENAME   text
*      -->RC         text
*----------------------------------------------------------------------*
FORM get_filename USING mode TYPE c
                  CHANGING filename TYPE string
                           rc TYPE sy-subrc
                           idoctyp type any.

  DATA: fname TYPE string,
        path TYPE string,
        action TYPE i,
        filetable TYPE filetable,
        file_line TYPE file_table,
        rc_lok TYPE sy-subrc,
        file_name type string,
        file_filter TYPE string.

  CLASS cl_gui_frontend_services DEFINITION LOAD.
  CONCATENATE cl_gui_frontend_services=>filetype_xml
              cl_gui_frontend_services=>filetype_all
              INTO file_filter.
  file_name = idoctyp.
  IF mode = 'S'.

    CALL METHOD cl_gui_frontend_services=>file_save_dialog
      EXPORTING
        WINDOW_TITLE      = 'Download WSDL file'
        default_extension = 'wsdl'                           "#EC NOTEXT
        DEFAULT_FILE_NAME = file_name
        file_filter       = file_filter
*       INITIAL_DIRECTORY =
      CHANGING
        filename          = fname
        path              = path
        fullpath          = filename
        user_action       = action
      EXCEPTIONS
        OTHERS            = 3.
  ELSE.
    CALL METHOD cl_gui_frontend_services=>file_open_dialog
      EXPORTING
        WINDOW_TITLE            = 'Download WSDL file'
        default_extension       = 'wsdl'                     "#EC NOTEXT
        DEFAULT_FILENAME        = idoctyp
        file_filter             = file_filter
*       INITIAL_DIRECTORY       =
*       MULTISELECTION          =
      CHANGING
        file_table              = filetable
        rc                      = rc_lok
        user_action             = action
      EXCEPTIONS
        file_open_dialog_failed = 0
        OTHERS                  = 4.
  ENDIF.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
  IF action = cl_gui_frontend_services=>action_cancel.
    rc = 4.
    EXIT.
  ENDIF.
  IF mode = 'O'.
    READ TABLE filetable INDEX 1 INTO file_line.
    IF sy-subrc <> 0.
      rc = 4.
      EXIT.
    ENDIF.
    filename = file_line-filename.
  ENDIF.
ENDFORM.                    " Get_filename

 

METHOD trigger_idoc.
  DATA: ls_edidc_40 TYPE          edi_dc40,
        lt_edidc_40 TYPE TABLE OF edi_dc40,
        lt_edidd_40 TYPE TABLE OF edi_dd40.

  " Set a QUEUEID if Interface requires sync
  DATA: lv_logsys      TYPE tbdls-logsys,
        lv_rfc_dest    TYPE edi_logdes,
        lv_r3_trans_id TYPE arfctid.

  DATA: lcl_idoc TYPE REF TO zcl_ca_idoc_service.

  FIELD-SYMBOLS: <fs_dd03>  TYPE x031l,
                 <fs_input> TYPE any.

  CREATE OBJECT lcl_idoc.

  DATA: lt_dd03   TYPE dd_x031l_table,
        p_tabname TYPE tabname.

  CALL METHOD lcl_idoc->get_ddic_object
    EXPORTING
      input   = input
    IMPORTING
      tdd03   = lt_dd03
      refname = p_tabname.

  ASSIGN input TO <fs_input>.

  LOOP AT lt_dd03 ASSIGNING <fs_dd03>.
    IF <fs_dd03>-fieldname NE 'IDOC'.
      ASSIGN COMPONENT <fs_dd03>-fieldname OF STRUCTURE <fs_input> TO <fs_input>.
    ELSEIF <fs_dd03>-fieldname EQ 'IDOC'.
      EXIT.
    ENDIF.
  ENDLOOP.

  CALL METHOD lcl_idoc->get_idoc_data
    EXPORTING
      p_input  = <fs_input>
    IMPORTING
      edi_dc40 = ls_edidc_40
    CHANGING
      edi_dd40 = lt_edidd_40.

  " Set RFC_DEST from DB table EDIPOA by port or set RFC_DEST directly from
  "" HERE

  " If RFC_DEST is initial
  IF lv_rfc_dest IS INITIAL.
    CALL FUNCTION 'OWN_LOGICAL_SYSTEM_GET'
      IMPORTING
        own_logical_system             = lv_logsys
      EXCEPTIONS
        own_logical_system_not_defined = 1
        OTHERS                         = 2.
    IF sy-subrc <> 0 AND lv_rfc_dest IS INITIAL.
*     Implement suitable error handling here
      lv_rfc_dest = 'NONE'.
    ELSE.
      lv_rfc_dest = lv_logsys.
    ENDIF.
  ENDIF.

  IF queueid IS INITIAL.
    CALL FUNCTION 'IDOC_INBOUND_SINGLE'
      IN BACKGROUND TASK
      AS SEPARATE UNIT
      DESTINATION lv_rfc_dest
      EXPORTING
        pi_idoc_control_rec_40  = ls_edidc_40
        pi_do_commit            = 'X'
*     IMPORTING
*       PE_IDOC_NUMBER          =
*       PE_ERROR_PRIOR_TO_APPLICATION       =
      TABLES
        pt_idoc_data_records_40 = lt_edidd_40
      EXCEPTIONS
        idoc_not_saved          = 1
        OTHERS                  = 2.
    IF sy-subrc = 0.
      CALL FUNCTION 'ID_OF_BACKGROUNDTASK'
        IMPORTING
          tid    = lv_r3_trans_id
        EXCEPTIONS
          OTHERS = 0.
      tid = lv_r3_trans_id.
    ENDIF.

  ELSE.
    APPEND ls_edidc_40 TO lt_edidc_40.
* set outbound queue
    CALL FUNCTION 'TRFC_SET_QUEUE_NAME'
      EXPORTING
        qname = queueid.
* exceptions not possible because of asynchronous call
    CALL FUNCTION 'IDOC_INBOUND_IN_QUEUE'
      IN BACKGROUND TASK
      AS SEPARATE UNIT
      DESTINATION lv_rfc_dest
      EXPORTING
        qname                 = queueid
      TABLES
        idoc_control_rec_40   = lt_edidc_40
        idoc_data_queue       = lt_edidd_40
      EXCEPTIONS
        communication_failure = 1
        system_failure        = 2.
    IF sy-subrc <> 0.

    ENDIF.
    CALL FUNCTION 'ID_OF_BACKGROUNDTASK'
      IMPORTING
        tid    = lv_r3_trans_id
      EXCEPTIONS
        OTHERS = 0.

    tid = lv_r3_trans_id.

  ENDIF.
  COMMIT WORK.

ENDMETHOD.
METHOD get_ddic_object.
  DATA: l_desc  TYPE REF TO cl_abap_typedescr.
  DATA: l_line  TYPE LINE OF dd_x031l_table.
  DATA: x030l   TYPE x030l,
        lv_type TYPE  char10.

  l_desc = cl_abap_typedescr=>describe_by_data( input ).

  IF l_desc->kind = 'T'.
    x030l = l_desc->get_ddic_header( ).
    l_desc = cl_abap_typedescr=>describe_by_name( x030l-refname ).
    tdd03 = l_desc->get_ddic_object( ).
    refname = x030l-refname.
  ELSE.
    tdd03 = l_desc->get_ddic_object( ).
    SPLIT l_desc->absolute_name AT '=' INTO lv_type refname.
  ENDIF.

  DELETE tdd03 WHERE rollname EQ 'PRXCTRLTAB'.
  DELETE tdd03 WHERE ( dtyp NE 'TTAB' AND dtyp NE 'STR2' ).

ENDMETHOD.
METHOD get_idoc_data.
  DATA: ls_dd40   TYPE edi_dd40,
        ls_dd03   TYPE x031l,
        lt_dd03   TYPE dd_x031l_table,
        lt_dd03_1 TYPE dd_x031l_table,
        p_tabname TYPE tabname.

  FIELD-SYMBOLS: <fs_segnam>    TYPE                 any,
                 <fs_segnam_t>  TYPE                 any,
                 <fs_p_segnam>  TYPE                 any,
                 <fs_p_segnam1> TYPE                 any,
                 <fs_segnam1>   TYPE                 any,
                 <fs_segnam2>   TYPE                 any,
                 <fs_input>     TYPE                 any,
                 <fs_dc40>      TYPE                 any,
                 <fs_t_seg>     TYPE STANDARD TABLE,
                 <fs_s_seg>     TYPE                 any,
                 <fs_dd03>      TYPE                 x031l.

  DATA: lv_segnam   TYPE REF TO data,
        lv_data     TYPE        char50,
        lt_segnam_t TYPE REF TO data,
        ls_input    TYPE REF TO data.
*------------------------------------------------------------------------

  CALL METHOD me->get_ddic_object
    EXPORTING
      input   = p_input
    IMPORTING
      tdd03   = lt_dd03
      refname = p_tabname.

  CREATE DATA ls_input TYPE (p_tabname).
  ASSIGN ls_input->* TO <fs_input>.
  MOVE-CORRESPONDING p_input TO <fs_input>.

  LOOP AT lt_dd03 ASSIGNING <fs_dd03> WHERE depth LE '02'.
    READ TABLE lt_dd03 TRANSPORTING NO FIELDS WITH KEY fieldname = 'IDOC'.
    IF sy-subrc = 0.
      ASSIGN COMPONENT 'IDOC' OF STRUCTURE <fs_input> TO <fs_p_segnam>.
      ASSIGN COMPONENT 'IDOC' OF STRUCTURE <fs_input> TO <fs_p_segnam1>.
    ELSE.
      ASSIGN <fs_input> TO <fs_p_segnam>.
    ENDIF.

    IF <fs_dd03>-fieldname = 'IDOC'.
      ASSIGN COMPONENT 'IDOC' OF STRUCTURE <fs_input> TO <fs_p_segnam>.
    ELSEIF <fs_dd03>-fieldname = 'EDI_DC40'.
      ASSIGN COMPONENT 'EDI_DC40' OF STRUCTURE <fs_p_segnam> TO <fs_dc40>.
      MOVE-CORRESPONDING <fs_dc40> TO edi_dc40.
    ELSEIF <fs_dd03>-dtyp = 'STR2'.
      ls_dd40-segnam = <fs_dd03>-fieldname.

      lv_data = <fs_dd03>-fieldname.
      ASSIGN COMPONENT  lv_data OF STRUCTURE <fs_p_segnam> TO <fs_segnam>.
      IF sy-subrc = 0 AND <fs_segnam> IS ASSIGNED.
        ASSIGN  <fs_segnam> TO <fs_segnam2>.
        CREATE DATA lv_segnam TYPE (<fs_dd03>-fieldname).
        ASSIGN lv_segnam->* TO <fs_segnam1>.
        MOVE-CORRESPONDING <fs_segnam> TO <fs_segnam1>.
        IF <fs_segnam1> IS ASSIGNED AND <fs_segnam> IS NOT INITIAL.
          ls_dd40-sdata = <fs_segnam1>.
          APPEND ls_dd40 TO edi_dd40.
        ENDIF.
      ENDIF.

*     Nested loop is required to process all upto next depth level
      LOOP AT lt_dd03 INTO ls_dd03 WHERE depth = ( <fs_dd03>-depth + 1 ) .

        IF ls_dd03-dtyp = 'TTAB'.
          ls_dd40-segnam = ls_dd03-fieldname.
          ASSIGN COMPONENT ls_dd03-fieldname OF STRUCTURE <fs_segnam2> TO <fs_segnam_t>.
          IF sy-subrc = 0 AND <fs_segnam_t> IS ASSIGNED.
            CREATE DATA lt_segnam_t TYPE TABLE OF (ls_dd03-fieldname).
            CREATE DATA lv_segnam TYPE (ls_dd03-fieldname).
            ASSIGN lv_segnam->* TO <fs_segnam1>.

            ASSIGN <fs_segnam_t> TO <fs_t_seg>.
*           Nested loop is required to process all data
            LOOP AT <fs_t_seg> ASSIGNING <fs_s_seg>.
              MOVE-CORRESPONDING <fs_s_seg> TO <fs_segnam1>.
              IF <fs_segnam1> IS ASSIGNED AND <fs_s_seg> IS NOT INITIAL.
                ls_dd40-sdata = <fs_segnam1>.
                APPEND ls_dd40 TO edi_dd40.
              ENDIF.

              CALL METHOD me->get_ddic_object
                EXPORTING
                  input = <fs_s_seg>
                IMPORTING
                  tdd03 = lt_dd03_1.

              IF lt_dd03_1 IS NOT INITIAL.
                ASSIGN <fs_s_seg> TO <fs_p_segnam>.
                CALL METHOD me->get_idoc_data_2
                  EXPORTING
                    p_input  = <fs_s_seg>
                  CHANGING
                    edi_dd40 = edi_dd40.
              ENDIF.
            ENDLOOP.
          ENDIF.
        ELSEIF <fs_dd03>-dtyp = 'STR2'.
          ASSIGN COMPONENT  ls_dd03-fieldname OF STRUCTURE <fs_segnam2> TO <fs_segnam>.
          IF sy-subrc = 0 AND <fs_segnam> IS ASSIGNED.
            CREATE DATA lv_segnam TYPE (ls_dd03-fieldname).
            ASSIGN lv_segnam->* TO <fs_segnam1>.
            MOVE-CORRESPONDING <fs_segnam> TO <fs_segnam1>.
            IF <fs_segnam1> IS ASSIGNED AND <fs_segnam> IS NOT INITIAL.
              ls_dd40-segnam = ls_dd03-fieldname.
              ls_dd40-sdata = <fs_segnam1>.
              APPEND ls_dd40 TO edi_dd40.
            ENDIF.
          ENDIF.
          IF <fs_segnam> IS ASSIGNED.
            UNASSIGN <fs_segnam>.
          ENDIF.
          ASSIGN COMPONENT ls_dd03-fieldname OF STRUCTURE <fs_segnam2> TO <fs_segnam>.
          IF sy-subrc = 0 AND <fs_segnam> IS ASSIGNED.
            ASSIGN <fs_segnam> TO <fs_p_segnam>.
            CALL METHOD me->get_idoc_data_2
              EXPORTING
                p_input  = <fs_segnam>
              CHANGING
                edi_dd40 = edi_dd40.
          ENDIF.
        ENDIF.
      ENDLOOP.

    ELSEIF <fs_dd03>-dtyp = 'TTAB'.

      ls_dd40-segnam = <fs_dd03>-fieldname.
      ASSIGN COMPONENT <fs_dd03>-fieldname OF STRUCTURE <fs_p_segnam> TO <fs_segnam_t>.
      IF sy-subrc = 0 AND <fs_segnam_t> IS ASSIGNED.
        CREATE DATA lt_segnam_t TYPE TABLE OF (<fs_dd03>-fieldname).
        CREATE DATA lv_segnam TYPE (<fs_dd03>-fieldname).
        ASSIGN lv_segnam->* TO <fs_segnam1>.

        ASSIGN <fs_segnam_t> TO <fs_t_seg>.
*           Nested loop is required to process all data
        LOOP AT <fs_t_seg> ASSIGNING <fs_s_seg>.
          MOVE-CORRESPONDING <fs_s_seg> TO <fs_segnam1>.
          IF <fs_segnam1> IS ASSIGNED AND <fs_s_seg> IS NOT INITIAL.
            ls_dd40-sdata = <fs_segnam1>.
            APPEND ls_dd40 TO edi_dd40.
          ENDIF.

          CALL METHOD me->get_ddic_object
            EXPORTING
              input = <fs_segnam_t>
            IMPORTING
              tdd03 = lt_dd03_1.

          IF lt_dd03_1 IS NOT INITIAL.
            ASSIGN <fs_s_seg> TO <fs_p_segnam>.

            CALL METHOD me->get_idoc_data_2
              EXPORTING
                p_input  = <fs_p_segnam>
              CHANGING
                edi_dd40 = edi_dd40.
          ENDIF.
        ENDLOOP.
      ENDIF.
    ENDIF.
  ENDLOOP.

ENDMETHOD.
To report this post you need to login first.

17 Comments

You must be Logged on to comment or reply to a post.

  1. Jelena Perfiljeva

    Amaresh, thanks for sharing, quite interesting solution. It would never occur to me to use IDoc with a web service, but it’s nice to know nevertheless. I understand it’s been a year already, but could you by any chance elaborate more on what was behind this requirement? Why did you have to have web service with IDoc? Why not have web service call BAPI instead or why not RFC?

    Thank you!

    (0) 
    1. Amaresh Pani Post author

      Hi Jelena – IDOC and BAPI/RFC are used for different purposes, based on requirements. Here are 2 important points.

          IDOC vs BAPI/RFC

      1) Asynchronous vs Synchronous

      2) Out of the box error monitoring, editing & reprocessing tools vs none for BAPI/RFC

      With Regards

      Amaresh Pani

      (0) 
      1. Jelena Perfiljeva

        Yes, I understand the difference between IDoc and other things, but the question was – why did you have to do this with web service? Why didn’t you use a file or RFC connection to create the IDoc?

        Also – even though there are monitoring and reprocessing tools for IDocs with a web service we can build more flexible functionality. The standard one that comes with IDocs has certain limitations.

        (0) 
        1. Amaresh Pani Post author

          Jelena – We have a spring based homegrown private cloud middle-ware, it only uses file & web service adapter for collection & distribution of payloads. File wouldn’t have been a preferable way for single transaction message distribution; also middle-ware needed a real-time response (TID) as a confirmation of IDOC delivery & tracking. Web service makes these things much simpler than file.

          Initially our middle-ware was using a third party adapter that connects to SAP with JCo (RFC) to covert IDOC’s into web service as there was no out of the box solution. By developing this solution we were able to remove the third party adapter.

          We wanted to avoid any custom development around error handling & reprocessing of IDOC’s .

          (0) 
    1. Amaresh Pani Post author

      Hi Carmen – This is designed for single IDOC per transaction. You may need to modify the code for multiple IDOC’s per transaction.

      Amaresh Pani

      (0) 
  2. Frank Scory

    Hi Amaresh,
    good idea, gratulation!

    But i miss the coding of the method GET_DDIC_OBJECT.
    chance to add it to the blog?

    Thanks and BR,
    Frank

    (0) 
  3. John Giesen

    Dear Amaresh,

    Great solution. Exactly what I was looking for.
    Unfortunately you posted twice the coding for the “get_idoc_data” METHOD and there is no coding for  the “get_ddic_object” METHOD.

    Can you please share also the coding for the missing METHOD? That would be great.

    Thanks for sharing this great idea.

    John Giesen
     

    (0) 
  4. Stefan de Boer

    Hi Amaresh,

    Its really a good idea!
    I tried to implement this, but unfortunately the method “get_ddic_object” is missing.
    Can you please send me(email below) the missing code and add it to the blog?

    Thanks!

    Best regards,
    Stefan
    Steef_nh@hotmail.com

    (0) 

Leave a Reply