Connector for SAP Business Suite - Developer's Manual - Example codings

1. Exchange solutions - The community idea

Anyone involved with IT solutions is grateful for information, example solutions or ready-to-use applications. This giving and taking of information is not a matter of course for everyone, as a lot of their knowhow often becomes public in the process. However, this was no obstacle to publishing this documentation. For us the exchange of ideas is in the foreground. Everyday challenges do not have to be challenges if solutions to recurring problems are well documented. This frees up time for innovative IT solutions. The exchange of ideas and solutions in the Intrexx environment is very simple. By exporting and importing applications, complex portal developments can be exchanged very easily. Visit our Application Store! Here you will find a large selection of ready-made applications and layouts for your portal. In the Intrexx Forum you will also find, among other things, the category "Connectors", where you can exchange ideas about SAP Business Suite with others.

In the SAP environment, it is unfortunately not quite as easy to exchange applications with others. Here there are more organizational hurdles (e.g. authorizations, internal company restrictions) that hinder the community idea. Efforts are being made to change this. For example, the Software Developer Network http://sdn.sap.com is a very good address to find like-minded people. The SAP world has also become more complex. It is no longer just SAP reports that can be passed on with simple text files. For current technologies such as ABAP objects, WebDynpro, and so on, an SAP transport must usually be used to transfer implementations to other SAP systems. For this reason, the open source project SAPlink has been organized. The main objective of the project is to exchange complex SAP applications via an alternative mechanism. SAP objects are not passed on via SAP transports. SAPLink packages the most important SAP objects in XML structures, the so-called "nuggets". This allows an early inspection of the contents of a package before it is imported into an SAP system. You can also use cross-system versioning, as is usual in the non-SAP area using versioning tools such as CVS and Subversion.

In most cases, Intrexx extensions are extensions using ABAP objects classes (data group handlers), function groups or simple reports. Technically speaking, it would be possible to exchange such enhancements using SAPlink tools. However, we are dependent on your cooperation and look forward to every new "nugget" on the internet.

2. Handlers for SAP external data groups

Handlers for SAP external data groups are based on the expansion concept of the SAP Portal Plugin SAPPOPI. The foundational principle of this expansion concept is the passing on of an ABAP object class from a template or another handler. Afterwards, the API methods of the handler are redefined, depending on the requirement. The handlers need to be registered as a class in the SAP Portal Plugin. Afterwards, a mapping from the data group ID used in Intrexx to the actual ABAP object handler is registered. For bespoke modifications it is normal to define an ABAP structure that contains every externally available field, this does not necessarily need to be available as a physical table. This structure (e.g. "Z_INTREXX_F4_KNA1") is then used externally as the table name in the data group. The correct handler is identified via the mapping in SAP. More information about this can be found API Developer's Manual.

2.1. Example coding: F4 help for SAP customer base

For this coding, a structure ("ZITIX_IXA_F4_KNA1" in this case) is required that contains the desired fields for the search aid and a specific search field ("SEARCH" in this case). This structure was used and registered as the transfer structure for the handler. Access to the portal is made using the name of the transfer structure.
METHOD z_if_ia_ixa_intrexx_api~get_list.

* ---- local data
  DATA: ls_data TYPE zitix_ixa_f4_kna1.
  DATA: lt_data LIKE TABLE OF ls_data.
  DATA: ls_filter LIKE LINE OF it_filter.
  DATA: lv_search TYPE string.
  DATA: lt_kna1 TYPE TABLE OF kna1.
  DATA: ls_kna1 LIKE LINE OF lt_kna1.
  DATA: lv_tabix TYPE sytabix.

* ---- init
  cv_processed = 'X'.


* ---- get search
  READ TABLE it_filter INTO ls_filter
    WITH KEY fieldname = 'SEARCH'.
  IF sy-subrc NE 0.
    EXIT.
  ENDIF.

  lv_search = ls_filter-value_low.

  IF lv_search EQ '' OR lv_search EQ '*'.
    EXIT.
  ENDIF.

  REPLACE ALL OCCURRENCES OF '*' IN lv_search WITH '%'.

* ----- search postcode
  SELECT * FROM kna1 APPENDING TABLE lt_kna1
    WHERE pstlz LIKE lv_search.

* ----- search name1
  SELECT * FROM kna1 APPENDING TABLE lt_kna1
    WHERE name1 LIKE lv_search.

* ----- search name2
  SELECT * FROM kna1 APPENDING TABLE lt_kna1
    WHERE name2 LIKE lv_search.

* ----- search ort01
  SELECT * FROM kna1 APPENDING TABLE lt_kna1
    WHERE ort01 LIKE lv_search.

* ----- search kunnr
  SELECT * FROM kna1 APPENDING TABLE lt_kna1
    WHERE kunnr LIKE lv_search.

* ----- sort and delete duplicates
  SORT lt_kna1.
  DELETE ADJACENT DUPLICATES FROM lt_kna1.


* ----- build transfer table
  LOOP AT lt_kna1 INTO ls_kna1.
    MOVE-CORRESPONDING ls_kna1 TO ls_data.
    ls_data-search = lv_search.
    APPEND ls_data TO lt_data.
  ENDLOOP.

* ------ sort

* ------ final build export
  LOOP AT lt_data INTO ls_data.
    lv_tabix = sy-tabix.
    CALL METHOD me->set_results_from_struc
      EXPORTING
        is_data         = ls_data
*    IT_REQUESTED    =
        iv_data_struc   = 'ZITIX_IXA_F4_KNA1'
        iv_key_value    = ls_data-kunnr
        iv_record       = lv_tabix
        iv_struc_name   = 'DEFAULT'
        iv_struc_record = 0
        iv_convert      = 'X'
      CHANGING
        ct_keys         = et_result_keys
        ct_results      = et_result_values
      EXCEPTIONS
        failed          = 1
        OTHERS          = 2
            .
    IF sy-subrc EQ 0.
      ADD 1 TO ev_count.
    ENDIF.

  ENDLOOP.

ENDMETHOD.

2.2. Example coding: Transfer internal table

The complete documentation for this example can be found here. The contact persons for an SAP business partner are identified and returned sorted. The API method "GET_DETAIL" is used to process the details.
METHOD z_if_ia_ixa_intrexx_api~get_list.

* -------------- local data
  DATA: lt_data TYPE TABLE OF yixapi_demo_bapi_conr.
  DATA: lt_data_int TYPE TABLE OF yixapi_demo_bapi_conr.
  DATA: ls_data TYPE yixapi_demo_bapi_conr.
  DATA: lt_return TYPE TABLE OF bapiret2.
  DATA: ls_filter TYPE LINE OF zia_ixa_api_intrexx_filter_t.
  DATA: lv_org TYPE bu_partner.
  DATA: lv_key TYPE zia_ixa_fieldvalue.
  DATA: lv_error.
  DATA: lv_processed TYPE xfeld.
  DATA: lv_lin TYPE i.
  DATA: lt_rel TYPE TABLE OF bapibus1006_relations.
  DATA: ls_rel TYPE bapibus1006_relations.
  DATA: ls_orderby TYPE LINE OF zia_ixa_api_intrexx_orderby_t.
  DATA: lv_rows TYPE i.


* -------------- init
  cv_processed = 'X'.
  ev_error     = 'X'.


* -------------- get inbound parameters
  READ TABLE it_filter INTO ls_filter
    WITH KEY fieldname = 'ORG_ID'.
  IF sy-subrc NE 0.
    ev_error     = ' '.
    EXIT.
  ENDIF.
  lv_org = ls_filter-value_low.


* -------------- initial check routines
  IF lv_org IS INITIAL.
    ev_error     = ' '.
    EXIT.
  ENDIF.


* -------------- process
* 1. Search
  CALL FUNCTION 'BAPI_BUPA_RELATIONSHIPS_GET'
    EXPORTING
      businesspartner = lv_org
    TABLES
      relationships   = lt_rel
      return          = lt_return.
  LOOP AT lt_return TRANSPORTING NO FIELDS
    WHERE type CA 'EAX'.
    lv_error = 'X'.
    EXIT.
  ENDLOOP.
  CHECK lv_error NE 'X'.

* 2. check relations
  DESCRIBE TABLE lt_rel LINES lv_lin.
  CHECK lv_lin GT 0.

* 3. build data table
  LOOP AT lt_rel INTO ls_rel
    WHERE relationshipcategory  = 'BUR001'
      AND validfromdate         LE sy-datum
      AND validuntildate        GE sy-datum.
*   build key
    CONCATENATE ls_rel-partner1
                ls_rel-partner2
                INTO lv_key
                SEPARATED BY '~'.
*   clear working var
    CLEAR me->current_data.

*   build detail information; transfer via working var
    CALL METHOD me->z_if_ia_ixa_intrexx_api~get_detail
      EXPORTING
        iv_key           = lv_key
*    IT_REQUESTED     =
*  IMPORTING
*    EV_ERROR         =
*    ET_MESSAGES      =
*    ET_RESULT_VALUES =
      CHANGING
        cv_processed     = lv_processed
      EXCEPTIONS
        failed           = 1
        OTHERS           = 2
            .
    IF sy-subrc EQ 0
      AND lv_processed EQ 'X'
      AND NOT me->current_data IS INITIAL.
*     append working var to table
      APPEND me->current_data TO lt_data.
    ENDIF.
  ENDLOOP.


* -------------- fill outbound parameters
* 1. ev_count
  DESCRIBE TABLE lt_data LINES ev_count.
* 2. sort internal table
  DESCRIBE TABLE it_orderby LINES lv_lin.
  IF lv_lin EQ 1.
    READ TABLE it_orderby INTO ls_orderby INDEX 1.
    IF ls_orderby-ordertype EQ 'A'.
      SORT lt_data BY (ls_orderby-fieldname) ASCENDING.
    ELSE.
      SORT lt_data BY (ls_orderby-fieldname) DESCENDING.
    ENDIF.
  ELSE.
    SORT lt_data BY per_id.
  ENDIF.

* 3. check offset access
  IF iv_max_rows GT 0 OR iv_start_row GT 0.
*   move to a working tab
    lt_data_int[] = lt_data.
    REFRESH lt_data.

*   loop working tab
    LOOP AT lt_data_int INTO ls_data.

*     check offset access
      IF iv_start_row GT 0
        AND sy-tabix LE iv_start_row.
        CONTINUE.
      ENDIF.

*     append to exporting tab
      APPEND ls_data TO lt_data.

*     check max rows
      IF iv_max_rows GT 0.
        ADD 1 TO lv_rows.
        IF lv_rows GE iv_max_rows.
          EXIT.
        ENDIF.
      ENDIF.

    ENDLOOP.
  ENDIF.

* 4. loop and fill export
  LOOP AT lt_data INTO ls_data.
    CALL METHOD me->set_results_from_struc
      EXPORTING
        is_data         = ls_data
        it_requested    = it_requested
        iv_data_struc   = 'YIXAPI_DEMO_BAPI_CONR'
        iv_key_value    = ls_data-lid
        iv_record       = sy-tabix
        iv_struc_name   = 'DEFAULT'
        iv_struc_record = 0
      CHANGING
        ct_keys         = et_result_keys
        ct_results      = et_result_values
      EXCEPTIONS
        failed          = 1
        OTHERS          = 2.
    IF sy-subrc EQ 0.
*     ignore
    ENDIF.
  ENDLOOP.


* -------------- finally set no error
  ev_error    = ' '.


ENDMETHOD.
METHOD z_if_ia_ixa_intrexx_api~get_detail.

* ------ local data
  DATA: lv_org  TYPE bu_partner.
  DATA: lv_per  TYPE bu_partner.
  DATA: ls_data TYPE yixapi_demo_bapi_conr.
  DATA: ls_relation TYPE bapibus1006002_central.
  DATA: ls_central TYPE bapibus1006_central.
  DATA: ls_person TYPE bapibus1006_central_person.
  DATA: lt_return TYPE TABLE OF bapiret2.
  DATA: lv_error.
  DATA: lv_language TYPE spras.


* ------ set default
  ev_error = 'X'.
  cv_processed = 'X'.


* ------ check for new record
  IF iv_key EQ space OR iv_key EQ '-1'.
* ------ optional: set a default data structure and leave without errors
    EXIT.
  ELSE.
* ------ split key
    SPLIT iv_key AT '~' INTO lv_org lv_per.
* ------ check key
    CHECK lv_org NE space AND lv_per NE space.
  ENDIF.

* ------ get data relation
  CALL FUNCTION 'BAPI_BUPR_CONTP_GETDETAIL'
    EXPORTING
      businesspartner           = lv_org
      contactperson             = lv_per
   IMPORTING
*     VALIDFROMDATE             =
*     VALIDUNTILDATE            =
*     DEFAULTRELATIONSHIP       =
      centraldata               = ls_relation
   TABLES
     return                    = lt_return
            .
  LOOP AT lt_return TRANSPORTING NO FIELDS
    WHERE type CA 'EAX'.
    lv_error = 'X'.
    EXIT.
  ENDLOOP.
  CHECK lv_error NE 'X'.


* ------- get data BP
  CALL FUNCTION 'BAPI_BUPA_CENTRAL_GETDETAIL'
    EXPORTING
      businesspartner   = lv_per
      valid_date        = sy-datum
    IMPORTING
      centraldata       = ls_central
      centraldataperson = ls_person
    TABLES
      return            = lt_return.
  LOOP AT lt_return TRANSPORTING NO FIELDS
    WHERE type CA 'EAX'.
    lv_error = 'X'.
    EXIT.
  ENDLOOP.
  CHECK lv_error NE 'X'.



* -------- build transfer record
* 1. BAPI Info
  MOVE-CORRESPONDING ls_relation TO ls_data.
  MOVE-CORRESPONDING ls_central  TO ls_data.
  MOVE-CORRESPONDING ls_person   TO ls_data.

* 2. ID Info
  ls_data-org_id  = lv_org.
  ls_data-per_id  = lv_per.

* 3. Key Info
  CONCATENATE lv_org lv_per
    INTO ls_data-lid
    SEPARATED BY '~'.

* 4. generate additional text fields with type converting
*    get portal language
  CALL METHOD me->map_intrexx_language_to_sap
    EXPORTING
      iv_language = me->ix_control-ix_language
    IMPORTING
      ev_language = lv_language
    EXCEPTIONS
      not_found   = 1
      OTHERS      = 2.
  IF sy-subrc <> 0.
    lv_language = sy-langu.
  ENDIF.
*  get department
  IF ls_data-department NE space.
    SELECT SINGLE bez20 FROM tb911 INTO ls_data-text_abtnr
      WHERE spras EQ lv_language
        AND abtnr EQ ls_data-department.
  ENDIF.

*  get function
  IF ls_data-function NE space.
    SELECT SINGLE bez30 FROM tb913 INTO ls_data-text_pafkt
      WHERE spras EQ lv_language
        AND pafkt EQ ls_data-function.
  ENDIF.


* -------- save for other API Methods
  me->current_data = ls_data.


* -------- build export
  CALL METHOD me->set_results_from_struc
    EXPORTING
      is_data         = ls_data
*    IT_REQUESTED    =
      iv_data_struc   = 'YIXAPI_DEMO_BAPI_CONR'
      iv_key_value    = ls_data-lid
      iv_record       = 1
      iv_struc_name   = 'DEFAULT'
      iv_struc_record = 0
    CHANGING
*    CT_KEYS         =
      ct_results      = et_result_values
    EXCEPTIONS
      failed          = 1
      OTHERS          = 2
          .
  IF sy-subrc <> 0.
    EXIT.
  ENDIF.


* ------- finally OK result
  ev_error = ' '.

ENDMETHOD.

2.3 Example coding: Documents from the archive system via URL

This example coding identifies all of the available sales documents from the archive (e.g. order confirmations) for a customer number (from the customer context). The URL to the external documents is returned to the portal. This can then be modified if required.
METHOD z_if_ia_ixa_intrexx_api~get_list.

* ---------- local data
  DATA: ls_filter LIKE LINE OF it_filter.
  DATA: lv_kunnr TYPE kunnr.
  DATA: ls_data TYPE Z_IXAPI_ARCHIV_DOC_VBAK.
  DATA: lt_data LIKE TABLE OF ls_data.
  DATA: lv_url TYPE string.

* --------- init
  ev_error = ' '.
  cv_processed = 'X'.

* --------- check inbound parameter - get kunnr from context
  READ TABLE it_filter INTO ls_filter
    WITH KEY fieldname = 'KUNNR'
             operand   = 'EQ'.
  IF sy-subrc NE 0.
    EXIT.
  ELSE.
* --------- add leading 0
    lv_kunnr = ls_filter-value_low.
    CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
      EXPORTING
        input  = lv_kunnr
      IMPORTING
        output = lv_kunnr
  ENDIF.

* ---------- get all orders (from table VBAK)
  DATA: lt_vbak TYPE TABLE OF vbak.
  DATA: ls_vbak TYPE vbak.


* ---------- get depending vbak record
  SELECT * FROM vbak
      INTO TABLE lt_vbak
      WHERE kunnr = lv_kunnr.
  CHECK NOT lt_vbak[] IS INITIAL.


* ---------- loop VBAK and fill export table with archive URL 
  DATA: lv_objid TYPE saeobjid.
  DATA: lt_url TYPE TABLE OF toauri.
  DATA: ls_url LIKE LINE OF lt_url.
  DATA: lv_lin TYPE i.
  DATA: lv_tabix TYPE sytabix.

  LOOP AT lt_vbak INTO ls_vbak.
    lv_tabix = sy-tabix.

*   prepare export table
    CLEAR ls_data.
    MOVE-CORRESPONDING ls_vbak TO ls_data.
    ls_data-kunnr = lv_kunnr.

*   get archive info
    lv_objid = ls_vbak-vbeln.
    REFRESH lt_url.
    CALL FUNCTION 'ARCHIVOBJECT_GET_URI'
      EXPORTING
        objecttype               = 'VBAK'
        object_id                = lv_objid
        location                 = 'B'
        http_url_only            = 'X'
      TABLES
        uri_table                = lt_url
      EXCEPTIONS
        error_archiv             = 1
        error_communicationtable = 2
        error_kernel             = 3
        error_http               = 4
        error_dp                 = 5
        OTHERS                   = 6.
    IF sy-subrc EQ 0.
      DESCRIBE TABLE lt_url LINES lv_lin.
      IF lv_lin GE 1.
        READ TABLE lt_url INTO ls_url INDEX lv_lin.
        IF sy-subrc EQ 0.
          ls_data-url = ls_url-uri.
        ENDIF.
      ENDIF.
    ENDIF.

*   optional replace the sap like URL with a extern available prefix
*   …

*   append record to export
    APPEND ls_data TO lt_data.

    sy-tabix = lv_tabix.
  ENDLOOP.


* ----------- sort
  DELETE lt_data WHERE url EQ space.
  SORT lt_data BY vbeln DESCENDING.


* ----------- loop and fill to final export parameter
  LOOP AT lt_data INTO ls_data.
    CALL METHOD me->set_results_from_struc
      EXPORTING
        is_data         = ls_data
*    it_requested    =
        iv_data_struc   = 'Z_IXAPI_ARCHIV_DOC_VBAK'
        iv_key_value    = ls_data-vbeln
        iv_record       = sy-tabix
        iv_struc_name   = 'DEFAULT'
        iv_struc_record = 0
        iv_convert      = 'X'
      CHANGING
        ct_keys         = et_result_keys
        ct_results      = et_result_values
      EXCEPTIONS
        failed          = 1
        OTHERS          = 2
            .
    IF sy-subrc EQ 0.
      ADD 1 TO ev_count.
    ENDIF.
  ENDLOOP.

* ----------- set final
  ev_error     = ' '.

ENDMETHOD.

2.4 Example coding: Generic handler Read & Write

The description for using this data handler can be found here.
METHOD z_if_ia_ixa_intrexx_api~initialize.
  CALL METHOD super->z_if_ia_ixa_intrexx_api~initialize
    EXPORTING
      is_control = is_control
    EXCEPTIONS
      failed     = 1
      OTHERS     = 2.
  IF sy-subrc <> 0.
    RAISE failed.
  ENDIF.
  me->cfgtag = 'ixapida'.
ENDMETHOD. 

METHOD z_if_ia_ixa_intrexx_api~prepare_usage_after_creation.

* --------- check object type GENERIC_WRITE
  IF me->cust_mapping-ix_objecttype EQ 'GENERIC_WRITE'.
* ---- set defaults to object customzing
    IF me->cust_object-struc_transfer IS INITIAL.
      me->cust_object-struc_transfer = me->ix_control-ix_datagroup.
    ENDIF.
    IF me->cust_object-struc_data IS INITIAL.
      me->cust_object-struc_data = me->ix_control-ix_datagroup.
    ENDIF.
    IF me->cust_object-master_tab IS INITIAL.
      me->cust_object-master_tab = me->ix_control-ix_datagroup.
    ENDIF.
    IF me->cust_object-field_key IS INITIAL.
      me->cust_object-field_key = 'GUID'.
    ENDIF.
* ---- create transfer
    CALL METHOD z_cl_ia_ixa_object=>create_data_and_build_ddic
      EXPORTING
        iv_tabname = me->cust_object-struc_transfer
      IMPORTING
        er_data    = me->transfer
        et_ddic    = me->ddic_transfer[]
      EXCEPTIONS
        failed     = 1
        OTHERS     = 2.
    IF sy-subrc <> 0.
      RAISE failed.
    ENDIF.

* ---- create data
    CALL METHOD z_cl_ia_ixa_object=>create_data_and_build_ddic
      EXPORTING
        iv_tabname = me->cust_object-struc_data
      IMPORTING
        er_data    = me->data
        et_ddic    = me->ddic_data[]
      EXCEPTIONS
        failed     = 1
        OTHERS     = 2.
    IF sy-subrc <> 0.
      RAISE failed.
    ENDIF.

  ENDIF.

* --------- call super
CALL METHOD super->z_if_ia_ixa_intrexx_api~prepare_usage_after_creation
    EXCEPTIONS
      failed = 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.


ENDMETHOD. 

METHOD z_if_ia_ixa_intrexx_api~modify.

* --------- local data
  DATA: lv_new.
  FIELD-SYMBOLS: <data> TYPE data.
  FIELD-SYMBOLS: <transfer> TYPE data.
  FIELD-SYMBOLS: <key> TYPE data.
  DATA: lv_guid TYPE zia_ixa_guid.
  DATA: lv_fkey(40) VALUE '<data>-guid'.
  DATA: lv_key TYPE zia_ixa_fieldvalue.
  DATA: lt_sql TYPE zia_ixa_api_intrexx_sql_t.
  DATA: ls_sql TYPE LINE OF zia_ixa_api_intrexx_sql_t.



* ---------- prepare data
  ASSIGN me->data->* TO <data>.
  ASSIGN me->transfer->* TO <transfer>.
  CHECK <data> IS ASSIGNED.
  CHECK <transfer> IS ASSIGNED.

* ---------- prepare key access
  ASSIGN (lv_fkey) TO <key>.
  CHECK <key> IS ASSIGNED.


* ---------- check given key
  lv_new = 'X'.
  IF NOT iv_key IS INITIAL.
    lv_key = iv_key.

* ---------- prepare sql
    CHECK me->cust_object-field_key NE space.
    CONCATENATE ''''
                lv_key
                ''''
                INTO ls_sql-line.
    CONCATENATE me->cust_object-field_key
                'EQ'
                ls_sql-line
                INTO ls_sql-line
                SEPARATED BY ' '.
    APPEND ls_sql TO lt_sql.


    SELECT SINGLE * FROM (me->cust_object-master_tab) INTO <data>
      WHERE (lt_sql).
    IF sy-subrc EQ 0.
      CLEAR lv_new.
    ENDIF.
  ENDIF.

* ---------- create key
  IF lv_new EQ 'X'.
    IF iv_key IS INITIAL.
      CALL FUNCTION 'GUID_CREATE'
        IMPORTING
          ev_guid_16 = lv_guid.
      lv_key = lv_guid.
    ELSE.
      lv_key = iv_key.
    ENDIF.
  ENDIF.


* ---------- get inbound
  MOVE-CORRESPONDING <data> TO <transfer>.
  CALL METHOD me->map_inbound_fields
    EXPORTING
      iv_delete = ' '
      it_fields = it_fields.

* ---------- set key
  <key> = lv_key.


* ---------- modify database
  SET UPDATE TASK LOCAL.
  MODIFY (me->cust_object-master_tab) FROM <data>.
  IF sy-subrc NE 0.
    ROLLBACK WORK.
    EXIT.
  ELSE.
    COMMIT WORK.
  ENDIF.

* ----------- map modified data to outbound
  CALL METHOD me->map_outbound_fields
    EXPORTING
      iv_index        = 1
      iv_struc_name   = 'DEFAULT'
      iv_struc_record = 0
    CHANGING
      ct_fields       = et_fields
*    ct_keys         =
    EXCEPTIONS
      failed          = 1
      OTHERS          = 2
          .
  IF sy-subrc <> 0.
    RAISE failed.
  ENDIF.

* ---------- finally set processed flag
  ev_key = lv_key.
  cv_processed = 'X'.


ENDMETHOD. 

METHOD z_if_ia_ixa_intrexx_api~delete.
* --------- local data
  DATA: lv_new.
  FIELD-SYMBOLS: <data> TYPE data.
  FIELD-SYMBOLS: <transfer> TYPE data.
  FIELD-SYMBOLS: <key> TYPE data.
  DATA: lv_guid TYPE zia_ixa_guid.
  DATA: lv_fkey(40) VALUE '<data>-guid'.
  DATA: lv_key TYPE zia_ixa_fieldvalue.
  DATA: lt_sql TYPE zia_ixa_api_intrexx_sql_t.
  DATA: ls_sql TYPE LINE OF zia_ixa_api_intrexx_sql_t.
  DATA: lv_field_key TYPE string.


* ---------- check key
  CHECK iv_key NE space.

* ---------- prepare data
  ASSIGN me->data->* TO <data>.
  ASSIGN me->transfer->* TO <transfer>.
  CHECK <data> IS ASSIGNED.
  CHECK <transfer> IS ASSIGNED.

* ---------- prepare key access
  lv_field_key = me->cust_object-field_key.
  IF lv_field_key IS INITIAL.
    lv_field_key = 'guid'.
  ENDIF.
  CONCATENATE '<data>-' lv_field_key INTO lv_fkey.
  ASSIGN (lv_fkey) TO <key>.
  CHECK <key> IS ASSIGNED.


* ---------- check given key
  lv_key = iv_key.

* ---------- prepare sql
  CONCATENATE ''''
              lv_key
              ''''
              INTO ls_sql-line.
  CONCATENATE lv_field_key
              'EQ'
              ls_sql-line
              INTO ls_sql-line
              SEPARATED BY ' '.
  APPEND ls_sql TO lt_sql.


  SELECT SINGLE * FROM (me->cust_object-master_tab) INTO <data>
    WHERE (lt_sql).
  IF sy-subrc NE 0.
    EXIT.
  ENDIF.

* ---------- get inbound
  MOVE-CORRESPONDING <data> TO <transfer>.


* ---------- modify database
  SET UPDATE TASK LOCAL.
  DELETE FROM (me->cust_object-master_tab) WHERE (lt_sql).
  IF sy-subrc NE 0.
    ROLLBACK WORK.
    EXIT.
  ELSE.
    COMMIT WORK.
  ENDIF.

* ----------- map modified data to outbound
  CALL METHOD me->map_outbound_fields
    EXPORTING
      iv_index        = 1
      iv_struc_name   = 'DEFAULT'
      iv_struc_record = 0
    CHANGING
      ct_fields       = et_fields
*    ct_keys         =
    EXCEPTIONS
      failed          = 1
      OTHERS          = 2
          .
  IF sy-subrc <> 0.
    RAISE failed.
  ENDIF.

* ---------- finally set processed flag
  cv_processed = 'X'.

ENDMETHOD.

2.5. Example coding: Data handler Generic Report

The following handler takes on the role of starting simple reports and transferring the results to Intrexx. This handler can be created manually on older systems. The class must be passed on by a generic view class (e.g. "Z_CL_IA_IXA_GENERIC_VIEW") and registered as a data handler for "GENERIC_REPORT". In addition, the following methods should be created or redefined.
method z_if_ia_ixa_intrexx_api~get_data_objects.

* ------- local data
  data: ls_do type line of zia_ixa_api_intrexx_dataobj_t.
  data: lv_wildcard type zia_ixa_fieldvalue.
  data: lv_max_rows type i.
  data: begin of ls_prog,
          progname type progname,
        end of ls_prog.
  data: lt_prog like table of ls_prog.
  data: ls_report type rstionamex.
  data: lv_text type rsti_title.
  data: lv_langu type sylangu.

* ------- init
  refresh et_data_objects.
  cv_processed = 'X'.
  lv_wildcard  = iv_wildcard.
  while sy-subrc eq 0.
    replace '*' with '%' into lv_wildcard.
  endwhile.
  lv_max_rows = iv_max_rows.
  if lv_max_rows le 0.
    lv_max_rows = 200.
  endif.

* ------- check
  check not lv_wildcard is initial.


* ------- GENERIC REPORT
  select progname from reposrc
    into table lt_prog
    up to lv_max_rows rows
    where progname like lv_wildcard
      and r3state eq 'A'
      and subc    eq '1'.


* -------- map external language
  call method z_cl_ia_ixa_generic_report=>map_intrexx_language_to_sap
    exporting
      iv_language = me->ix_control-ix_language
    importing
      ev_language = lv_langu
    exceptions
      not_found   = 1
      others      = 2.
  if sy-subrc <> 0.
    lv_langu = sy-langu.
  endif.



* -------- map selected reports
  loop at lt_prog into ls_prog.
    ls_do-dataobject  = ls_prog-progname.
    ls_report-onam = ls_prog-progname.

    call function 'RRI_RT_REPORT_TEXT'
      exporting
        e_s_onamext = ls_report
        e_langu     = lv_langu
      importing
        i_text      = lv_text
      exceptions
        not_found   = 1
        others      = 2.
    if sy-subrc <> 0.
      ls_do-description = ls_prog-progname.
    else.
      ls_do-description = lv_text.
    endif.

    append ls_do to et_data_objects.
  endloop.

endmethod.
method z_if_ia_ixa_intrexx_api~get_list.

  data: ls_filter type line of zia_ixa_api_intrexx_filter_t.
  data: ls_par type rsparams.
  data: lt_par type table of rsparams.
  data: lt_requested type zia_ixa_api_intrexx_rq_flds_t.
  data: ls_requested type line of zia_ixa_api_intrexx_rq_flds_t.

  data: lv_report type progname.
  data: lt_list  type tedrtext.
  data: ls_list  type line of tedrtext.
  data: lv_text type string.
  data: ls_ddic type dfies.

  data: lt_html  type w3htmltab.
  data: ls_html  type line of w3htmltab.
  data: lv_html      type string.

  field-symbols: <transfer> type data.
  field-symbols: <data> type data.
  field-symbols: <lid> type data.
  field-symbols: <line> type data.
  data: lv_error type xfeld.

  data: begin of ls_line,
          line(255),
        end of ls_line.
  data: lt_line like table of ls_line.
  data: lv_tabix type sytabix.
  data: lv_value type zia_ixa_fieldvalue.

  data: lt_scr type table of rsscr.
  data: ls_scr type rsscr.
  data: lv_subrc type sysubrc.
  data: lv_rows type i.


* --------------------- MACRO
  define map_ix_to_sap.
    lv_value = &1.
    if lv_value ne space.

      call method me->map_fieldvalue_ix_to_sap
        exporting
          is_control  = me->ix_control
          iv_function = me->current_api_function
          is_ddic     = ls_ddic
        changing
          cv_value    = lv_value.
      &1 = lv_value.
    endif.
  end-of-definition.


* ------------ prepare
  assign me->transfer->* to <transfer>.
  assign me->data->* to <data>.
  check <transfer> is assigned.

  assign ('<transfer>-lid') to <lid>.
  assign ('<transfer>-line') to <line>.
  check <line> is assigned and <lid> is assigned.

* ----------- build requested
  ls_requested-fieldname = 'LID'.
  append ls_requested to lt_requested.
  ls_requested-fieldname = 'LINE'.
  append ls_requested to lt_requested.


* ---------- prepare report
  lv_report = me->ix_control-ix_datagroup.


* --------- get infos from sel screen
  perform load_sscr in program rsdbrunt
    tables    lt_scr
    using     lv_report
    changing  lv_subrc.

  call method me->map_filter_to_report_params
    exporting
      it_filter          = it_filter
      it_ddic            = me->ddic_transfer
      iv_flag_map_to_sap = 'X'
      it_selscreen       = lt_scr
    importing
      et_params          = lt_par
    exceptions
      failed             = 1
      others             = 2.
  if sy-subrc <> 0.
    raise failed.
  endif.

* ------------ call report in background
  call method z_cl_ia_ixa_generic_report=>start_report_in_background
    exporting
      iv_progname   = lv_report
      it_parameters = lt_par
    importing
      et_list       = lt_list
      et_html       = lt_html.

  if me->cust_mapping-parameter_1 eq 'hmtl'
    or me->cust_mapping-parameter_1 eq 'HTML'.

*----------------------------------------- TEXT MAPPING
* ----------- map list to lines
    loop at lt_html into ls_html.
      concatenate lv_html ls_html-line
        into lv_html.
    endloop.

* ----------- split
    split lv_html at '<br>' into table lt_line.

* ----------- build export
    lv_rows = 0.
    describe table lt_line lines ev_count.
    loop at lt_line into ls_line.

      lv_tabix = sy-tabix.

      if iv_start_row gt 0 and lv_tabix lt iv_start_row.
        continue.
      endif.

      if lv_rows ge iv_max_rows.
        exit.
      endif.

      <lid>   = lv_tabix.
      "concatenate ls_line-line '>' into <line>.
      <line> = ls_line-line.

      move-corresponding <transfer> to <data>.

      call method me->map_outbound_fields
        exporting
          iv_index           = lv_tabix
          iv_struc_name      = 'DEFAULT'
          iv_struc_record    = 0
          it_requested       = lt_requested
*        IV_IGNORE_LANGUAGE = ' '
        changing
          ct_fields          = et_result_values
          ct_keys            = et_result_keys
        exceptions
          failed             = 1
          others             = 2
              .
      if sy-subrc <> 0.
        lv_error = 'X'.
        exit.
      endif.

      add 1 to lv_rows.

      sy-tabix = lv_tabix.
    endloop.

    if lv_error ne 'X'.
      cv_processed = 'X'.
    endif.

  else.
* ------------------------------------- HTML Mapping
* ----------- map list to lines
    loop at lt_list into ls_list.
      concatenate lv_text ls_list-tdline
        into lv_text.
    endloop.

* ----------- split
    split lv_text at cl_abap_char_utilities=>newline into table lt_line.

* ----------- build export
    lv_rows = 0.
    describe table lt_line lines ev_count.
    loop at lt_line into ls_line.

      lv_tabix = sy-tabix.

      if iv_start_row gt 0 and lv_tabix lt iv_start_row.
        continue.
      endif.

      if lv_rows ge iv_max_rows.
        exit.
      endif.

      <lid>   = lv_tabix.
      <line>  = ls_line-line.

      move-corresponding <transfer> to <data>.

      call method me->map_outbound_fields
        exporting
          iv_index           = lv_tabix
          iv_struc_name      = 'DEFAULT'
          iv_struc_record    = 0
          it_requested       = lt_requested
*        IV_IGNORE_LANGUAGE = ' '
        changing
          ct_fields          = et_result_values
          ct_keys            = et_result_keys
        exceptions
          failed             = 1
          others             = 2
              .
      if sy-subrc <> 0.
        lv_error = 'X'.
        exit.
      endif.

      add 1 to lv_rows.

      sy-tabix = lv_tabix.
    endloop.

    if lv_error ne 'X'.
      cv_processed = 'X'.
    endif.
  endif.

endmethod.
method z_if_ia_ixa_intrexx_api~prepare_usage_after_creation.

* --------- local data
  data: ls_ddic type dfies.
  data: lv_lin type i.
  data: lv_report type progname.
*  DATA: lv_report TYPE raldb_repo.
  data: lt_selpar type table of rsparams.
  data: ls_selpar type rsparams.
  data: c_type(40) value 'ZIA_IXA_API_GR_REPORT_DDIC_TMP'.
  data: lt_ddic type ddfields.

* ---------- get fields from selection screen
  lv_report = me->ix_control-ix_datagroup.
  call method z_cl_ia_ixa_generic_report=>get_ddic_for_report
    exporting
      iv_report = lv_report
    importing
      et_ddic   = lt_ddic
    exceptions
      failed    = 1
      others    = 2.
  if sy-subrc <> 0.
    raise failed.
  endif.

*---------- get template
  call function 'DDIF_NAMETAB_GET'
    exporting
      tabname           = 'ZIA_IXA_API_GR_REPORT_DDIC_TMP'
*   ALL_TYPES         = ' '
*   LFIELDNAME        = ' '
*   GROUP_NAMES       = ' '
*   UCLEN             =
* IMPORTING
*   X030L_WA          =
*   DTELINFO_WA       =
*   TTYPINFO_WA       =
*   DDOBJTYPE         =
*   DFIES_WA          =
*   LINES_DESCR       =
   tables
*   X031L_TAB         =
      dfies_tab         = me->ddic_transfer
   exceptions
     not_found         = 1
     others            = 2
            .
  if sy-subrc <> 0.
    raise failed.
  endif.

* ---------- set lid to key field
  read table me->ddic_transfer into ls_ddic index 1.
  ls_ddic-keyflag = 'X'.
  modify me->ddic_transfer from ls_ddic index 1.

* ---------- get parameter dummy
  describe table me->ddic_transfer lines lv_lin.
  read table me->ddic_transfer into ls_ddic index lv_lin.
  if sy-subrc ne 0.
    raise failed.
  endif.

* ---------- delete dummy
  delete me->ddic_transfer where fieldname = ls_ddic-fieldname.

  loop at lt_ddic into ls_ddic.
    add 1 to ls_ddic-position.
    append ls_ddic to me->ddic_transfer.
  endloop.

* ------------ set the same to ddic
  me->ddic_data[] = me->ddic_transfer[].

  create data me->data type (c_type).
  create data me->transfer type (c_type).

endmethod.
method get_ddic_for_report.

* ------- local data
  data: lt_scr type table of rsscr.
  data: ls_scr type rsscr.
  data: lv_subrc type sysubrc.
  data: ls_ddic type dfies.

* --------- get infos from sel screen
  perform load_sscr in program rsdbrunt
    tables    lt_scr
    using     iv_report
    changing  lv_subrc.

  if lv_subrc ne 0.
    raise failed.
  endif.

* --------- mapping
  loop at lt_scr into ls_scr.

    clear ls_ddic.

    ls_ddic-tabname       = iv_report.
    ls_ddic-fieldname     = ls_scr-name.
    ls_ddic-position      = sy-tabix + 1.
    ls_ddic-leng          = ls_scr-length.
    ls_ddic-offset        = ls_scr-offset.
    ls_ddic-intlen        = ls_scr-length.
    ls_ddic-outputlen     = ls_scr-olength.
    ls_ddic-datatype      = ls_scr-dtyp.
    ls_ddic-inttype       = ls_scr-type.

    append ls_ddic to et_ddic.

  endloop.

endmethod.
method start_report_in_background.

* ------- local data
  data: lt_list type table of abaplist.
  data: lt_text type table of rtfline.
  data: ls_text type rtfline.
  data: lv_text type string.
  data: ls_par type rsparams.
  data: lv_url(132) type c.
  data: lt_html type table of w3html.
  field-symbols: <fs> type swww_t_merge_item.

* --------- start programm
  submit (iv_progname)
      with selection-table it_parameters
      exporting list to memory
      and return.

* -------- get list from memory
  call function 'LIST_FROM_MEMORY'
    tables
      listobject = lt_list
    exceptions
      not_found  = 1
      others     = 2.
  if sy-subrc <> 0.
    exit.
  endif.

* ------- convert list 0: Textedit
  call function 'LIST_TO_TXT'
* EXPORTING
*   LIST_INDEX               = -1
    tables
      listtxt                  = lt_text
      listobject               = lt_list
   exceptions
     empty_list               = 1
     list_index_invalid       = 2
     others                   = 3
            .
  if sy-subrc <> 0.
    exit.
  endif.

* ---------- convert list: html
  call function 'GET_REPORT_LISTS'
    exporting
      callback_form    = 'LIST_TO_HTML'
      callback_program = 'SAPLSURL'
    tables
      listobject       = lt_list
    exceptions
      empty_list       = 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.

  assign ('(SAPLSURL)G_MERGE_ITEM') to <fs>.
  if <fs> is assigned.
    lt_html[] = <fs>-html[].
  endif.

* ------------ fill export
  et_list[] = lt_text[].
  et_html[] = lt_html[].

endmethod.

2.6. Examples for Generic Report integration

2.6.1. Purchase information about material

*&---------------------------------------------------------------------*
*& Report  ZZ_DEMO_IXAPI_REPORT
*&
*&---------------------------------------------------------------------*
*& The report searches using the material number, supplier + Preis.
*& The appearance of the results is influenced by the Intrexx html
*& classes.
*&---------------------------------------------------------------------*

report  zz_demo_ixapi_report no standard page heading line-size 256.


* ------- interface
parameters matnr type matnr.


start-of-selection.
* ------- local data + constants
  data: ls_mara like mara,
        lv_matnr type matnr,
        ls_eina like eina,
        ls_eine like eine.

  constants:
    c_h1_open type string
      value '<h1 style="margin:0px;" class="SCUP_Text_H1_normal">',
    c_h1_close type string
      value '</h1>',
    c_h2_open type string
      value '<h2 style="margin:0px;" class="SCUP_Text_H2_normal">',
    c_h2_close type string
      value '</h2>',
    c_skip type string
      value '<br>'.


* ------- convert to internal
  call function 'CONVERSION_EXIT_ALPHA_INPUT'
    exporting
      input  = matnr
    importing
      output = lv_matnr.


* ------ get data
  clear ls_mara.
* ------ select materialdata
  select single * from mara
    into corresponding fields of ls_mara
    where matnr = lv_matnr.
* ------ select vendor (recordinfo)
  select single * from eina
    into corresponding fields of ls_eina
    where matnr = ls_mara-matnr.
* ------ select priceinfo
  select single * from eine
    into corresponding fields of ls_eine
    where infnr = ls_eina-infnr.


* ------- check input
  if ls_mara is initial.
* ------ error message
    write: / c_h1_open, 'Error! Material not found.', c_h1_close.
  else.
* ------ display data
    write: / c_h1_open, 'Materialdata', c_h1_close.
    write: / c_skip.
    write: / c_h2_open, 'Materialnumber',c_h2_close.
    write:  ls_mara-matnr.
    write: / c_h2_open, 'Materialtype',c_h2_close.
    write:  ls_mara-mtart.
    write: / c_skip.
    write: / c_h2_open, 'Supplier',c_h2_close.
    write: ls_eina-lifnr.
    write: / c_h2_open, 'Price',c_h2_close.
    write: ls_eine-netpr.
  endif.

3. Groovy script

3.1 Example script: Convert SAP fields

# SAP Datum
def l_sdfDatum = new java.text.SimpleDateFormat("yyyyMMdd")
l_sdfDatum.setTimeZone(g_session.user.timeZone)

String l_sap_date = l_sdfDatum.format(g_record["15853B4A180BB11A1B55AC1668AA065764C3A537"].value);

# SAP Time
def l_sdfZeit = new java.text.SimpleDateFormat("HHmmss")
l_sdfZeit.setTimeZone(g_session.user.timeZone)
String l_sap_time = l_sdfZeit.format(g_record["F11324BB5A892F1BC5DB68E0521E27BC02F7227E"].value);


# SAP ID with leading zeroes
String zeroes = '0000000000000000000000000000000000000000'
def l_strNumber = g_record["731ED21599DB3C90B2103202F6834F1FBD12A3B8"].value
if (l_strNumber.length() < 10)
{
	l_strNumber = zeroes.substring(0,10-l_strNumber.length()) + l_strNumber
}

3.2. Example script: SAP sales order

/****************************************************************************************************
 * Groovy Integration for SAP Business Suite Connector
 * Use this coding with Intrexx >= 7.0 and JCo >= 3.0.10
 * minimum requirement is a valid business adapter for SAP module "View & Write"
 * 
 * 
 *  Some hints for using API:
 *  Convert datetime to SAP date:				g_sap.convertToSapDate(Date p_datetime)
 *  Convert datetime to SAP time:				g_sap.convertToSapTime(Date p_datetime)
 *  Convert SAP date and time time to String:	g_sap.convertSapToIXDateTime(String p_sapdate, String p_saptime)
 *  Convert SAP date and time time to java.util.Date:	convertSapToTimestamp(String p_sapdate, String p_saptime, String p_timezone)
 *  Convert string to numeric:					g_sap.convertToLeadingZero(String p_in, int p_size)
 *  Convert SAP numeric to string:				g_sap.convertFromLeadingZero(String p_in)
 ****************************************************************************************************/

// ---------- imported packages
import net.initall.ixapi.groovy.*

// ---------- definitions
def l_datasource   = "saperp"			// name of the SAP datasource within Intrexx Integration
def l_logintype    = "system"			// login mode to SAP: valid = ||
def l_trace        = true				// trace on/off
def l_stateful     = false    			// use stateful connection (true|false)
def l_logprefix    = "SAP Access: " 	// prefix for log messages
def l_text_noapi   = "Groovy SAP API not available."
def l_text_nocon   = "Connection to SAP is not available."
def l_text_nofunc  = "SAP function module not available."
def l_text_error   = "SAP function module called with errors."
def l_text_except  = "SAP Error: "
def l_saperror     = true      			// helper var for error handling; default error
def l_rows_to_add  = 0         			// number of rows for Table Parameters; set at the appropriate imports

// ---------- variables
def g_sap          = null      // Groovy SAP API Instance
def l_client       = null      // connection to an SAP system
def l_function     = null      // proxy to an SAP function module
def l_funcmod      = null      // name of the function module
def l_table        = null      // sap table object
def l_value        = ""        // dummy var for value mapping

// ---------- get fields from ix application
def l_auart = g_record["B2E580EB9A14390F897CD06FE33E536EB9D67229"].getValue() //datafield Auftragsart
def l_vkorg = g_record["8A3F82307B9D1173FE1B9BE4EF90EC27C6A88731"].getValue() //datafield Verkaufsorganisation
def l_vtweg = g_record["36C6B21F7C8C54F5761CDA117A2D3C799295F2BC"].getValue() //datafield Vertriebsweg
def l_spart = g_record["9C65868FAB1B8F7FF317954FE05A03A2F0A0FBA5"].getValue() //datafield Sparte
def l_kunnr = g_record["BF43DAD1B151C08D751B2221176C57F0CA588525"].getValue() //datafield Kundennummer
def l_bstnk = g_record["5B16C6BA37377218C685E23271D740736B2F8AEC"].getValue() //datafield Bestellnummer
def l_bstdt = g_record["406930D3BE19D5CE79E3E84DF438EC424E58CBF0"].getValue() //datafield Bestelldatum
def l_matnr = g_record["CBC25B6B716AC1F50DC5C2D40359AFA2BA365C6D"].getValue() //datafield Artikel Nr.
def l_qunty = g_record["55CE9B34ED4BC0C017DA43052C00F2A526BF5F1F"].getValue() //datafield Menge

// ---------- Connect to sap and execute
try {
// initialize Groovy SAP API
	if(l_trace) g_log.info("Get access to SAP API")

	g_sap = IxSapGroovyAPI.getInstance()
	
	if(g_sap == null) throw new Exception(l_text_noapi)
//==========> INITIALIZE SAP CONNECTION
// get sap connection
	l_client = g_sap.getSapConnection(l_datasource, l_logintype)
	if(l_client == null)
		return null
	  
	l_function = g_sap.getSapFunction("BAPI_SALESORDER_CREATEFROMDAT2")
	if(l_function == null)
		return null

//==========> IMPORTING PARAMETERS
// ORDER_HEADER_IN (ABAP Structure: BAPISDHD1) - Auftragskopf
	g_sap.setImpStrucParField(l_function, "ORDER_HEADER_IN","DOC_TYPE", l_auart) //ABAP Type C: 4,0
	g_sap.setImpStrucParField(l_function, "ORDER_HEADER_IN","SALES_ORG", l_vkorg) //ABAP Type C: 4,0
	g_sap.setImpStrucParField(l_function, "ORDER_HEADER_IN","DISTR_CHAN", l_vtweg) //ABAP Type C: 2,0
	g_sap.setImpStrucParField(l_function, "ORDER_HEADER_IN","DIVISION", l_spart) //ABAP Type C: 2,0
	g_sap.setImpStrucParField(l_function, "ORDER_HEADER_IN","PURCH_DATE", "20080820") // ABAP Type D: 8,0
	g_sap.setImpStrucParField(l_function, "ORDER_HEADER_IN","PURCH_NO_C", l_bstnk) //ABAP Type C: 35,0
	//==========> IMPORTING TABLES
	// Imported Table ORDER_ITEMS_IN (ABAP Structure: BAPISDITM) - Positionsdaten
	def l_posnr = "1"
	l_table = g_sap.getTable(l_function,"ORDER_ITEMS_IN")
	for(int i = 0; i < 1; i++){
		l_table.appendRow()
		g_sap.setTableField(l_table, "ITM_NUMBER", l_posnr) // ABAP Type N: 6,0
		g_sap.setTableField(l_table, "MATERIAL", l_matnr) // ABAP Type C: 18,0
	} // Table ORDER_ITEMS_IN end
	// Imported Table ORDER_SCHEDULES_IN (ABAP Structure: BAPISCHDL) - Einteilungsdaten
	l_table = g_sap.getTable(l_function,"ORDER_SCHEDULES_IN")
	for(int i = 0; i < 1; i++){
		l_table.appendRow()
		g_sap.setTableField(l_table, "ITM_NUMBER", l_posnr) // ABAP Type N: 6,0
		g_sap.setTableField(l_table, "REQ_QTY", l_qunty) // ABAP Type P: 7,3
	} // Table ORDER_SCHEDULES_IN end
	// Imported Table ORDER_PARTNERS (ABAP Structure: BAPIPARNR) - Belegpartner
	l_table = g_sap.getTable(l_function,"ORDER_PARTNERS")
	for(int i = 0; i < 1; i++){
		l_table.appendRow()
		g_sap.setTableField(l_table, "PARTN_ROLE", "AG") // ABAP Type C: 2,0
		g_sap.setTableField(l_table, "PARTN_NUMB", l_kunnr) // ABAP Type C: 10,0
	} // Table ORDER_PARTNERS end
	//==========> EXECUTE SAP FUNCTION
	if(g_sap.executeSapFunction(l_client, l_function)){
	
		// SALESDOCUMENT (ABAP Type: C 10,0) - Nummer des erzeugten Beleges
		def l_vbeln = g_sap.getExpPar(l_function,"SALESDOCUMENT")
		if(l_vbeln.equals("")){
			g_sap.BapiRollback(l_client)
			return null
		}

		// save vbeln to datagroup
		l_conn = g_dbConnections.systemConnection
		l_lid = g_record["66B1F38BA125C4C22444D27AC9108B91A208EE16"].getValue() //	datafield (PK) (S) ID
		l_stmtOrderUpdate = g_dbQuery.prepare(l_conn, "UPDATE XTABLE9EB02DDB SET SAP_VBELN = ? WHERE LID = ?")
		l_stmtOrderUpdate.setString(1, l_vbeln)
		l_stmtOrderUpdate.setInt(2, l_lid)
		l_stmtOrderUpdate.executeUpdate()
		// final commit
		g_sap.BapiCommit(l_client, false) // set to true if commit should wait
	}else{
		g_sap.BapiRollback(l_client)
	}
}
catch(e) {
  g_log.error(l_logprefix + l_text_except + " - " + e.getMessage())
}
finally{
  if(l_trace) g_log.info(l_logprefix + "Destroy SAP connection")

  // End Stateful (if configured)
  if(l_stateful && g_sap != null && l_client != null) g_sap.setContextEnd(l_client)

  // Destroy SAP API
  if(g_sap != null) g_sap.destroy()
}

3.3 Example script: Stock transfer

The following Groovy script should be used as a template and contains constants from a customer scenario.
/****************************************************************************************************
 * Groovy Integration for SAP Business Suite Connector
 * Use this coding with Intrexx >= 7.0 and JCo >= 3.0.10
 * minimum requirement is a valid business adapter for SAP module "View & Write"
 * 
 * 
 *  Some hints for using API:
 *  Convert datetime to SAP date:				g_sap.convertToSapDate(Date p_datetime)
 *  Convert datetime to SAP time:				g_sap.convertToSapTime(Date p_datetime)
 *  Convert SAP date and time time to String:	g_sap.convertSapToIXDateTime(String p_sapdate, String p_saptime)
 *  Convert SAP date and time time to java.util.Date:	convertSapToTimestamp(String p_sapdate, String p_saptime, String p_timezone)
 *  Convert string to numeric:					g_sap.convertToLeadingZero(String p_in, int p_size)
 *  Convert SAP numeric to string:				g_sap.convertFromLeadingZero(String p_in)
 ****************************************************************************************************/

// ---------- imported packages
import net.initall.ixapi.groovy.*

// ---------- definitions
def l_datasource   = "saperp"			// name of the SAP datasource within Intrexx Integration
def l_logintype    = "system"			// login mode to SAP: valid = ||
def l_trace        = true				// trace on/off
def l_stateful     = false    			// use stateful connection (true|false)
def l_logprefix    = "SAP Access: " 	// prefix for log messages
def l_text_noapi   = "Groovy SAP API not available."
def l_text_nocon   = "Connection to SAP is not available."
def l_text_nofunc  = "SAP function module not available."
def l_text_error   = "SAP function module called with errors."
def l_text_except  = "SAP Error: "
def l_saperror     = true      			// helper var for error handling; default error
def l_rows_to_add  = 0         			// number of rows for Table Parameters; set at the appropriate imports

// ---------- variables
def g_sap          = null      // Groovy SAP API Instance
def l_client       = null      // connection to an SAP system
def l_function     = null      // proxy to an SAP function module
def l_funcmod      = null      // name of the function module
def l_table        = null      // sap table object
def l_value        = ""        // dummy var for value mapping

// ---------- Connect to sap and execute
try {
// initialize Groovy SAP API
	if(l_trace) g_log.info("Get access to SAP API")

	g_sap = IxSapGroovyAPI.getInstance()
	
	if(g_sap == null) throw new Exception(l_text_noapi)
//==========> INITIALIZE SAP CONNECTION
// get sap connection
	l_client = g_sap.getSapConnection(l_datasource, l_logintype)
	if(l_client == null)
		return null
	  
	l_function = g_sap.getSapFunction("BAPI_GOODSMVT_CREATE")
	if(l_function == null)
		return null

//==========> INITIALIZE SAP CONNECTION
// get sap connection
	l_client = g_sap.getSapConnection("system") // valid: <system|mixed|user>
	if(l_client == null){
		g_log.error("no connection to sap")
		return null
	}
	l_function = g_sap.getSapFunction("BAPI_GOODSMVT_CREATE")
	if(l_function == null){
		g_log.error("function not available")
		return null
	}
//==========> IMPORTING PARAMETERS
// GOODSMVT_CODE (ABAP Structure: BAPI2017_GM_CODE) - Assign code to transaction for stock transfer
	g_sap.setImpStrucParField(l_function, "GOODSMVT_CODE","GM_CODE", "05") // ABAP TypeC: 2,0
// GOODSMVT_HEADER (ABAP Structure: BAPI2017_GM_HEAD_01) - Header data for material document
	g_sap.setImpStrucParField(l_function, "GOODSMVT_HEADER","PSTNG_DATE", "20080807") // ABAP Type D: 8,0
	g_sap.setImpStrucParField(l_function, "GOODSMVT_HEADER","DOC_DATE", "20080807") //ABAP Type D: 8,0
	g_sap.setImpStrucParField(l_function, "GOODSMVT_HEADER","HEADER_TXT", "BAPICRR") //ABAP Type C: 25,0
	g_sap.setImpStrucParField(l_function, "GOODSMVT_HEADER","VER_GR_GI_SLIP", "1") //ABAP Type C: 1,0
//==========> IMPORTING TABLES
// Imported Table GOODSMVT_ITEM (ABAP Structure: BAPI2017_GM_ITEM_CREATE) - Material document items
	l_table = g_sap.getTable(l_function,"GOODSMVT_ITEM")
	for(int i = 0; i < 1; i++){
		l_table.appendRow()
		g_sap.setTableField(l_table, "MATERIAL", "BM00009") // ABAP Type C: 18,0
		g_sap.setTableField(l_table, "PLANT", "0001") // ABAP Type C: 4,0
		g_sap.setTableField(l_table, "STGE_LOC", "0001") // ABAP Type C: 4,0
		g_sap.setTableField(l_table, "MOVE_TYPE", "501") // ABAP Type C: 3,0
		g_sap.setTableField(l_table, "ENTRY_QNT", "1") // ABAP Type P: 7,3
		g_sap.setTableField(l_table,"ENTRY_UOM", "ST") // ABAP Type C: 3,0
		g_sap.setTableField(l_table,"ENTRY_UOM_ISO", "PCE") // ABAP Type C: 3,0
		g_sap.setTableField(l_table,"ITEM_TEXT", "CRRBAPI") // ABAP Type C: 50,0
		g_sap.setTableField(l_table,"LINE_ID", "000001") // ABAP Type N: 6,0
	} // Table GOODSMVT_ITEM end
// Imported Table GOODSMVT_SERIALNUMBER (ABAP Structure: BAPI2017_GM_SERIALNUMBER) - Serial number
	l_table = g_sap.getTable(l_function,"GOODSMVT_SERIALNUMBER")
	for(int i = 0; i < 1; i++){
		l_table.appendRow()
		g_sap.setTableField(l_table, "MATDOC_ITM", "0001") // ABAP Type N: 4,0
		g_sap.setTableField(l_table, "SERIALNO", "100006000000000501") // ABAP TypeC: 18,0
	} // Table GOODSMVT_SERIALNUMBER end
//==========> EXECUTE SAP FUNCTION
	if(g_sap.executeSapFunction(l_client, l_function)){
		// ----> INSERT FURTHER CHECKS HERE
//==========> EXPORTED PARAMETERS
		// GOODSMVT_HEADRET (ABAP Structure: BAPI2017_GM_HEAD_RET) - Material document no./year
		/*
		l_value = g_sap.getExpStrucParField(l_function, "GOODSMVT_HEADRET","MAT_DOC") // ABAP Type C: 10,0
		l_value = g_sap.getExpStrucParField(l_function, "GOODSMVT_HEADRET","DOC_YEAR") //ABAP Type N: 4,0
		// MATDOCUMENTYEAR (ABAP Type: N 4,0) - Materialbelegjahr
		l_value = g_sap.getExpPar(l_function,"MATDOCUMENTYEAR")
		*/
// Exported Table RETURN (ABAP Structure: BAPIRET2) - Returns
		l_table = g_sap.getTable(l_function,"RETURN")
		for(int i = 0; i < l_table.getNumRows(); i++){
			l_value = g_sap.getTableField(l_table, "TYPE") // ABAP Type C: 1,0
			l_value = g_sap.getTableField(l_table, "ID") // ABAP Type C: 20,0
			l_value = g_sap.getTableField(l_table, "NUMBER") // ABAP Type N: 3,0
			l_value = g_sap.getTableField(l_table, "MESSAGE") // ABAP Type C: 220,0
			g_log.info("SAPRETURN: " + l_value)
			l_value = g_sap.getTableField(l_table, "LOG_NO") // ABAP Type C: 20,0
			l_value = g_sap.getTableField(l_table, "LOG_MSG_NO") // ABAP Type N: 6,0
			l_value = g_sap.getTableField(l_table, "MESSAGE_V1") // ABAP Type C: 50,0
			l_value = g_sap.getTableField(l_table, "MESSAGE_V2") // ABAP Type C: 50,0
			l_value = g_sap.getTableField(l_table, "MESSAGE_V3") // ABAP Type C: 50,0
			l_value = g_sap.getTableField(l_table, "MESSAGE_V4") // ABAP Type C: 50,0
			l_value = g_sap.getTableField(l_table, "PARAMETER") // ABAP Type C: 32,0
			l_value = g_sap.getTableField(l_table, "ROW") // ABAP Type I: 4,0
			l_value = g_sap.getTableField(l_table, "FIELD") // ABAP Type C: 30,0
			l_value = g_sap.getTableField(l_table, "SYSTEM") // ABAP Type C: 10,0
			l_table.nextRow()
		} // Table RETURN end
// MATERIALDOCUMENT (ABAP Type: C 10,0) - Material document number
		l_value = g_sap.getExpPar(l_function,"MATERIALDOCUMENT")
		g_log.info("Materialbeleg: " + l_value
		// ...
		g_sap.BapiCommit(l_client, false) // set to true if commit should wait
		// ----> INSERT YOUR CODE HERE
		// ...
	}else{
		g_log.error("error executing sap function")
		g_sap.BapiRollback(l_client)
	}
}
catch(e) {
  g_log.error(l_logprefix + l_text_except + " - " + e.getMessage())
}
finally{
  if(l_trace) g_log.info(l_logprefix + "Destroy SAP connection")

  // End Stateful (if configured)
  if(l_stateful && g_sap != null && l_client != null) g_sap.setContextEnd(l_client)

  // Destroy SAP API
  if(g_sap != null) g_sap.destroy()
}

3.4. Example script: Use the simpleRFC API in Velocity

The complete description of this script can be found here.
## ============================================================
## Velocity Integration for SAP Business Suite Connectorto SAP
## Use this coding with Intrexx >=7.0 and and JCo >=3.0.10
## minimum requirement is a valid business adapter for SAP module "View & Write"  
## 
## 
##  Some hints for using API:
##  Simple RFC with Parameter INPUT and RESULT:		$GSAP.simpleRfcTrigger(String p_instance, String p_loginmode, String p_function, String p_parameter)
## ============================================================

## define variables
#set( $strInstance  = "saperp" )
#set( $strLoginType = "system" )
#set( $strFunction  = "/IATL/MESSE_IPHONE_GET_STOCK" )
#set( $bTrace		= true )
#set( $bCommit		= false )
#set( $strError		= "" )
#set( $strValue		= "" )
#set( $strLogCon	= "No connection to SAP" )
#set( $strLogFun	= "Unable to get access to SAP function module" )
#set( $strLogExec	= "Errors occured while calling SAP" )
#set( $bStateful    = true)

## ============= connect to SAP
#set( $bOkConnect   = $GSAP.simpleRfcConnect($strInstance,$strLoginType) )
#if(  $bOkConnect ==  true)
	#if( $bStateful == true ) $GSAP.simpleRfcSetContextBegin() #end
## ============= get function
	#set( $bOkFunction = $GSAP.simpleRfcFunctionLoad( $strFunction ) )
	#if(  $bOkFunction == true )

## ============= fill parameter	
	<br>Execute: $GSAP.simpleRfcFunctionExecute(false)

	## loop export table
	<br>Set Focus Table: $GSAP.simpleRfcSetFocusTable("ET_STOCK")
	<br>Records found: $GSAP.simpleRfcTableGetCount()
	#set($strOutput = "<table>")
	#foreach($line in $GSAP.simpleRfcTableGetEntries())
		<br> List Item: $line
		Set Table Line: $GSAP.simpleRfcTableSetLine($line)
		#if($GSAP.simpleRfcSetFocusTableField("MATNR"))
			#set($strMatnr = $GSAP.simpleRfcGetParameterValue())
		#end
		#if($GSAP.simpleRfcSetFocusTableField("MAKTX"))
			#set($strText = $GSAP.simpleRfcGetParameterValue())
		#end
		#if($GSAP.simpleRfcSetFocusTableField("COUNT"))
			#set($strCount = $GSAP.simpleRfcGetParameterValue())
		#end
		#set($strOutput = $strOutput + "<tr><td>" + $strMatnr + "</td><td>" + $strText + "</td><td>" + $strCount + "</td></tr>")
	#end
	#set($strOutput = $strOutput + "</table>")

## ============= close connection
  #if( $bStateful == true ) $GSAP.simpleRfcSetContextEnd() #end	
	#set( $bRC = $GSAP.simpleRfcClose() )
#else
	#set( $strError = $strLogCon )
#end

## ============= Output
#if( $strError == "" )
## -- success
#else
## -- error
	#if( $bTrace )
		$strError
	#end
#end

4. Remote Services ABAP Programme

4.1. Replicate SAP data

REPORT  /iatl/udc_replicate NO STANDARD PAGE HEADING LINE-SIZE 1023.

* link to external database
PARAMETERS: p_inst LIKE /iatl/c_udcins-udc_instance OBLIGATORY.
PARAMETERS: p_obj  TYPE /iatl/udc_object_id.
SELECTION-SCREEN: SKIP.
* fields in external database
PARAMETERS: p_extkey  TYPE /iatl/udc_fieldname_key DEFAULT 'LID' OBLIGATORY.
PARAMETERS: p_erpkey  TYPE /iatl/udc_fieldname_key DEFAULT 'ERPID' OBLIGATORY.
PARAMETERS: p_erptxt  TYPE /iatl/udc_fieldname_key DEFAULT 'ERPTEXT' OBLIGATORY.
SELECTION-SCREEN: SKIP.
* fields in sap
PARAMETERS: p_saptab LIKE dd03l-tabname DEFAULT 'BUT000' OBLIGATORY.
PARAMETERS: p_sapkey LIKE dd03l-fieldname DEFAULT 'PARTNER' OBLIGATORY.
PARAMETERS: p_saptxt LIKE dd03l-fieldname DEFAULT 'NAME_ORG1' OBLIGATORY.
SELECTION-SCREEN: SKIP.
* where clause
PARAMETERS: p_where TYPE char255 DEFAULT 'type = 2'.

* ================= Include UDC Macros
INCLUDE /iatl/udc_include_report. "some tools for UDC Reports


* ================= Reaction for F4 requests
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_extkey.

  CALL METHOD /iatl/cl_udc_handler=>util_popup_f4_metainfo
    EXPORTING
      iv_instance      = p_inst
      iv_object        = p_obj
      iv_dynpro_field  = 'P_EXTKEY'
      iv_display_popup = 'X'
    CHANGING
      cv_fieldname     = p_extkey
    EXCEPTIONS
      technical_error  = 1
      cancelled        = 2
      OTHERS           = 3.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_erpkey.

  CALL METHOD /iatl/cl_udc_handler=>util_popup_f4_metainfo
    EXPORTING
      iv_instance      = p_inst
      iv_object        = p_obj
      iv_dynpro_field  = 'P_ERPKEY'
      iv_display_popup = 'X'
    CHANGING
      cv_fieldname     = p_erpkey
    EXCEPTIONS
      technical_error  = 1
      cancelled        = 2
      OTHERS           = 3.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_erptxt.

  CALL METHOD /iatl/cl_udc_handler=>util_popup_f4_metainfo
    EXPORTING
      iv_instance      = p_inst
      iv_object        = p_obj
      iv_dynpro_field  = 'P_ERPTXT'
      iv_display_popup = 'X'
    CHANGING
      cv_fieldname     = p_erptxt
    EXCEPTIONS
      technical_error  = 1
      cancelled        = 2
      OTHERS           = 3.


AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_obj.

  CALL METHOD /iatl/cl_udc_handler=>util_popup_f4_table
    EXPORTING
      iv_instance      = p_inst
      iv_dynpro_field  = 'P_OBJ'
      iv_display_popup = 'X'
    CHANGING
      cv_object_id     = p_obj
    EXCEPTIONS
      technical_error  = 1
      cancelled        = 2
      OTHERS           = 3.


* ================= START OF PROGRAM
START-OF-SELECTION.

* ------------ local data
  DATA: lc_dataobject TYPE /iatl/udc_object_id VALUE 'public.xia_replica_demo'.
  DATA: lt_return TYPE TABLE OF bapiret2.
  DATA: lo_connector TYPE REF TO /iatl/cl_udc_handler.
  DATA: lv_count_selected TYPE i.
  DATA: lv_count_insert TYPE i.
  DATA: lv_count_update TYPE i.
  DATA: lv_count_error TYPE i.
  DATA: ls_config	TYPE /iatl/udc_request_config.
  DATA: lt_requested   TYPE /iatl/udc_requested_fields_t.
  DATA: lt_existing TYPE /iatl/udc_result_t.
  DATA: ls_existing LIKE LINE OF lt_existing.
  DATA: lv_count TYPE i.
  DATA: lt_filter TYPE /iatl/udc_filter_t.
  DATA: ls_filter LIKE LINE OF lt_filter.
  DATA: lt_values TYPE /iatl/udc_result_t.
  DATA: ls_values LIKE LINE OF lt_values.
  DATA: lv_fname(80).
  DATA: lv_status(80).

  DATA: lr_erp_t TYPE REF TO data.
  DATA: lr_erp_s TYPE REF TO data.

  FIELD-SYMBOLS: <erpid> TYPE data.
  FIELD-SYMBOLS: <erptxt> TYPE data.
  FIELD-SYMBOLS: <lt_erp> TYPE table.
  FIELD-SYMBOLS: <ls_erp> TYPE data.



* =============================== create udc handler : Connect
  CALL METHOD /iatl/cl_udc_handler=>object_factory_by_instance
    EXPORTING
      iv_instance       = p_inst
      iv_connect        = 'X'
*    IV_CLASS          =
    IMPORTING
      eo_udc_connection = lo_connector
    EXCEPTIONS
      not_customized    = 1
      wrong_customizing = 2
      connection_error  = 3
      OTHERS            = 4
          .
  IF sy-subrc <> 0 OR lo_connector IS INITIAL.
    WRITE: / 'Fehler'.
    EXIT.
  ENDIF.

* =============================== get existing data from external table
  APPEND p_extkey TO lt_requested.
  APPEND p_erpkey TO lt_requested.


  CALL METHOD lo_connector->api_get_data
    EXPORTING
      i_ds_id             = p_obj
      is_config           = ls_config
      it_requested_fields = lt_requested
    IMPORTING
      e_count             = lv_count
      et_results          = lt_existing
    CHANGING
      ct_return           = lt_return
    EXCEPTIONS
      connection_error    = 1
      errors_occured      = 2
      not_connected       = 3
      OTHERS              = 4.
  IF sy-subrc <> 0.
    WRITE: / 'Fehler get_data.'.
  ENDIF.


* =============================== create mapping between external and internal record
  DATA: BEGIN OF ls_map,
          id_portal TYPE i,
          id_sap TYPE string,
        END OF ls_map.
  DATA: lt_map LIKE TABLE OF ls_map.
  DATA: lv_tabix TYPE sytabix.
  DATA: lv_max_lid TYPE i.

  LOOP AT lt_existing INTO ls_existing.

    AT NEW record.
      IF NOT ls_map IS INITIAL.
        APPEND ls_map TO lt_map.
        CLEAR ls_map.
      ENDIF.
    ENDAT.

    IF ls_existing-fieldname = p_extkey.
      ls_map-id_portal = ls_existing-value.
      IF lv_max_lid LE ls_map-id_portal.
        lv_max_lid = ls_map-id_portal.
      ENDIF.
    ENDIF.
    IF ls_existing-fieldname = p_erpkey.
      ls_map-id_sap = ls_existing-value.
    ENDIF.

  ENDLOOP.
  IF NOT ls_map IS INITIAL.
    APPEND ls_map TO lt_map.
  ENDIF.


* =============================== select sap data
  CREATE DATA lr_erp_t TYPE TABLE OF (p_saptab).
  CREATE DATA lr_erp_s TYPE (p_saptab).

  ASSIGN lr_erp_t->* TO <lt_erp>.
  ASSIGN lr_erp_s->* TO <ls_erp>.

  CONCATENATE '<ls_erp>-' p_sapkey INTO lv_fname.
  ASSIGN (lv_fname) TO <erpid>.

  CONCATENATE '<ls_erp>-' p_saptxt INTO lv_fname.
  ASSIGN (lv_fname) TO <erptxt>.

  SELECT * FROM (p_saptab)
    INTO TABLE <lt_erp>
    WHERE (p_where).


* =============================== make current time
* 2008-08-08 07:20:24.

  DATA: lv_date(20).
  DATA: lv_time(20).
  DATA: lv_current(20).

  CONCATENATE sy-datum(4)
              '-'
              sy-datum+4(2)
              '-'
              sy-datum+6(2)
              INTO lv_date.

  CONCATENATE sy-uzeit(2)
              ':'
              sy-uzeit+2(2)
              ':'
              sy-uzeit+4(2)
              INTO lv_time.

  CONCATENATE lv_date lv_time INTO lv_current SEPARATED BY ' '.



* =============================== loop at sap data : transfer to portal
  LOOP AT <lt_erp> INTO <ls_erp>.
    lv_tabix = sy-tabix.

* ----- sapgui status
    lv_status = lv_tabix.
    CONDENSE lv_status.
    CONCATENATE 'Processing...' lv_status INTO lv_status SEPARATED BY ' '.
    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        text = lv_status.

* ----- prepare values insert/update
    REFRESH lt_values.

    ls_values-record = 1.

    ls_values-fieldname = 'LUSERID'.  ls_values-value = '1'.                 APPEND ls_values TO lt_values.
    ls_values-fieldname = 'DTEDIT'.   ls_values-value = lv_current.          APPEND ls_values TO lt_values.

    ls_values-fieldname = p_erptxt.   ls_values-value = <erptxt>.            APPEND ls_values TO lt_values.
    ls_values-fieldname = p_erpkey.   ls_values-value = <erpid>.             APPEND ls_values TO lt_values.


* ----  get existing id
    READ TABLE lt_map INTO ls_map
      WITH KEY id_sap = <erpid>.
    IF sy-subrc EQ 0.
* -----------------> exists
*     build where clause
      REFRESH lt_filter.
      ls_filter-selpos        = 1.
      ls_filter-combine       = 'AND'.
      ls_filter-lparenthesis  = 0.
      ls_filter-fieldname     = p_extkey.
      ls_filter-operand       = 'EQ'.
      ls_filter-value_low     = ls_map-id_portal.
      ls_filter-value_high    = space.
      ls_filter-rparenthesis  = 0.
      CONDENSE ls_filter-value_low.
      APPEND ls_filter TO lt_filter.

*     update
      DATA: lv_sql TYPE /iatl/udc_sql.
      CALL METHOD lo_connector->api_update
        EXPORTING
          i_ds_id          = p_obj
          is_config        = ls_config
          it_filters       = lt_filter
          it_values        = lt_values
        IMPORTING
          e_count          = lv_count
          e_sql            = lv_sql
        CHANGING
          ct_return        = lt_return
        EXCEPTIONS
          connection_error = 1
          errors_occured   = 2
          not_connected    = 3
          OTHERS           = 4.
      IF sy-subrc <> 0.
        WRITE: / 'Error Update : ', <erpid>.
        ADD 1 TO lv_count_error.
      ELSE.
        WRITE: / 'Success Update: ', <erpid>.
        ADD 1 TO lv_count_update.
      ENDIF.

    ELSE.
* -----------------> new
*     prepare additional insert fields
      ls_values-fieldname = 'LUSERIDINSERT'. ls_values-value = 1.          APPEND ls_values TO lt_values.
      ls_values-fieldname = 'DTINSERT'.      ls_values-value = lv_current. APPEND ls_values TO lt_values.

      ADD 1 TO lv_max_lid.
      ls_values-fieldname = p_extkey.        ls_values-value = lv_max_lid. APPEND ls_values TO lt_values.

*     insert
      CALL METHOD lo_connector->api_insert
        EXPORTING
          i_ds_id          = p_obj
          is_config        = ls_config
          it_values        = lt_values
        IMPORTING
          e_count          = lv_count
        CHANGING
          ct_return        = lt_return
        EXCEPTIONS
          connection_error = 1
          errors_occured   = 2
          not_connected    = 3
          OTHERS           = 4.

      IF sy-subrc <> 0.
        WRITE: / 'Error Insert : ', <erpid>.
        ADD 1 TO lv_count_error.
      ELSE.
        WRITE: / 'Success Insert: ', <erpid>.
        ADD 1 TO lv_count_insert.
      ENDIF.

    ENDIF.

    sy-tabix = lv_tabix.
  ENDLOOP.


* ================= final status
  ULINE.
  WRITE: / 'SAP Table               : ', p_saptab.
  WRITE: / 'External DB Instance    : ', p_inst.
  WRITE: / 'External Table          : ', p_obj.
  WRITE: / 'Where Clause            : ', p_where.
  WRITE: / 'Selected SAP record     : ', lv_count_selected.
  WRITE: / 'New external records    : ', lv_count_insert.
  WRITE: / 'Updated external records: ', lv_count_update.
  WRITE: / 'Record with errors      : ', lv_count_error.

4.2. External system to SAP: Groovy script for replication API

/****************************************************************************************************
 * Groovy Integration for SAP Business Suite Connector
 * Use this coding with Intrexx >= 7.0 and JCo >= 3.0.10
 * minimum requirement is a valid business adapter for SAP module "View & Write"
 * 
 * 
 *  Some hints for using API:
 *  Convert datetime to SAP date:				g_sap.convertToSapDate(Date p_datetime)
 *  Convert datetime to SAP time:				g_sap.convertToSapTime(Date p_datetime)
 *  Convert SAP date and time time to String:	g_sap.convertSapToIXDateTime(String p_sapdate, String p_saptime)
 *  Convert SAP date and time time to java.util.Date:	convertSapToTimestamp(String p_sapdate, String p_saptime, String p_timezone)
 *  Convert string to numeric:					g_sap.convertToLeadingZero(String p_in, int p_size)
 *  Convert SAP numeric to string:				g_sap.convertFromLeadingZero(String p_in)
 ****************************************************************************************************/

// ---------- imported packages
import net.initall.ixapi.groovy.*

// ---------- definitions
def l_datasource   = "saperp"				// name of the SAP datasource within Intrexx Integration
def l_logintype    = "system"			// login mode to SAP: valid = ||
def l_trace        = true				// trace on/off
def l_stateful     = false    			// use stateful connection (true|false)
def l_logprefix    = "SAP Access: " 	// prefix for log messages
def l_text_noapi   = "Groovy SAP API not available."
def l_text_nocon   = "Connection to SAP is not available."
def l_text_nofunc  = "SAP function module not available."
def l_text_error   = "SAP function module called with errors."
def l_text_except  = "SAP Error: "
def l_saperror     = true      			// helper var for error handling; default error
def l_rows_to_add  = 0         			// number of rows for Table Parameters; set at the appropriate imports

// ---------- variables
def g_sap          = null      // Groovy SAP API Instance
def l_client       = null      // connection to an SAP system
def l_function     = null      // proxy to an SAP function module
def l_funcmod      = null      // name of the function module
def l_table        = null      // sap table object
def l_value        = ""        // dummy var for value mapping

// ---------- Connect to sap and execute
try {
// initialize Groovy SAP API
	if(l_trace) g_log.info("Get access to SAP API")

	g_sap = IxSapGroovyAPI.getInstance()
	
	if(g_sap == null) throw new Exception(l_text_noapi)
//==========> INITIALIZE SAP CONNECTION
// get sap connection
	l_client = g_sap.getSapConnection(l_datasource, l_logintype)
	if(l_client == null)
		return null
	  
	l_function = g_sap.getSapFunction("/IATL/UDC_REPL_API_INB_TRIGGER")
	if(l_function == null)
		return null

//===========> get ix values
	def l_lid = g_record["1C914F1AB6E1A38661FDC0BA93789BD1A87C175A"].value // datafield (PK) (S) ID
	def l_str_lid = g_record["1C914F1AB6E1A38661FDC0BA93789BD1A87C175A"].value // datafield (PK) (S) ID
	def l_name = g_record["25B3880A8B1679C413C6BC3504957E1151401F58"].value // datafield Firma
	def l_kunnr = g_record["072D6FF8B9E0BB5AA0A1BEA8A84ABC55E58C0D48"].value // datafield Kundennummer
	def l_ort = g_record["E741B7475651E57DC649D0C66BD9D4AB8D58157D"].value // datafield Ort
	def l_plz = g_record["ECFC786378FD342C602B420C500BE96EA64D2839"].value // datafield PLZ
	def l_strasse = g_record["B9A1D5F80F511D550E8335715F7F4AE94CE21C10"].value // datafield Straße

//==========> IMPORTING PARAMETERS
	// IV_EXTERN_ID (ABAP Type: C 70,0) - UDC: External key
	g_sap.setImpPar(l_function,"IV_EXTERN_ID", l_str_lid)
	// IV_FLAG_MERGE_MODE (ABAP Type: C 1,0) - Merge data
	g_sap.setImpPar(l_function,"IV_FLAG_MERGE_MODE"," ")
	// IV_FLAG_NO_EXCEPTION (ABAP Type: C 1,0) - No exception for errors in flag/table
	g_sap.setImpPar(l_function,"IV_FLAG_NO_EXCEPTION","X")
	// IV_FLAG_ONLY_CHECK (ABAP Type: C 1,0) - Check only, do not write
	g_sap.setImpPar(l_function,"IV_FLAG_ONLY_CHECK"," ")
	// IV_FLAG_PROTOCOL (ABAP Type: C 1,0) - UDC: Show flag protocol
	g_sap.setImpPar(l_function,"IV_FLAG_PROTOCOL"," ")
	// IV_FLAG_READ_EXTERN (ABAP Type: C 1,0) - Read data
	g_sap.setImpPar(l_function,"IV_FLAG_READ_EXTERN"," ")
	// IV_FLAG_SAVE_TS (ABAP Type: C 1,0) - Save time stamp for delta
	g_sap.setImpPar(l_function,"IV_FLAG_SAVE_TS"," ")
	// IV_REPL_OBJECT (ABAP Type: C 30,0) - UDC: Replication object
	g_sap.setImpPar(l_function,"IV_REPL_OBJECT","/IATL/UDCIXCRM_KNA1")
	// IV_SAP_ID (ABAP Type: C 70,0) - UDC: Internal key
	g_sap.setImpPar(l_function,"IV_SAP_ID",l_kunnr)
//==========> IMPORTING TABLES

	// Imported Table IT_DATA (ABAP Structure: /IATL/UDC_RESULT) - ESB: Results of a selection (Raw Information)
	l_table = g_sap.getTable(l_function,"IT_DATA") 
	// STR_COMPANY
	l_table.appendRow()
	g_sap.setTableField(l_table, "RECORD", "1") // ABAP Type I: 4,0
	g_sap.setTableField(l_table, "FIELDNAME", "STR_COMPANY") // ABAP Type C: 40,0
	g_sap.setTableField(l_table, "VALUE", l_name) // ABAP Type C: 70,0
	// STR_ORT
	l_table.appendRow()
	g_sap.setTableField(l_table, "RECORD", "1") // ABAP Type I: 4,0
	g_sap.setTableField(l_table, "FIELDNAME", "STR_ORT") // ABAP Type C: 40,0
	g_sap.setTableField(l_table, "VALUE", l_ort) // ABAP Type C: 70,0
	// STR_PLZ
	l_table.appendRow()
	g_sap.setTableField(l_table, "RECORD", "1") // ABAP Type I: 4,0
	g_sap.setTableField(l_table, "FIELDNAME", "STR_PLZ") // ABAP Type C: 40,0
	g_sap.setTableField(l_table, "VALUE", l_plz) // ABAP Type C: 70,0
	// STR_STRASSE
	l_table.appendRow()
	g_sap.setTableField(l_table, "RECORD", "1") // ABAP Type I: 4,0
	g_sap.setTableField(l_table, "FIELDNAME", "STR_STRASSE") // ABAP Type C: 40,0
	g_sap.setTableField(l_table, "VALUE", l_strasse) // ABAP Type C: 70,0
//==========> EXECUTE SAP FUNCTION
	if(g_sap.executeSapFunction(l_client, l_function)){
//==========> EXPORTED PARAMETERS
		// EV_ERROR (ABAP Type: C 1,0) - Field to be checked off
		def l_error = g_sap.getExpPar(l_function,"EV_ERROR")
		g_log.info("SAP Function executed. Error = " + l_error)
		// Exported Table ET_MESSAGES (ABAP Structure: /IATL/UDC_MESSAGES_T) - UDC: Messages
		def l_message = ""
		l_table = g_sap.getTable(l_function,"ET_MESSAGES")
		for(int i = 0 i < l_table.getNumRows() i++){
			def l_type = g_sap.getTableField(l_table, "TYPE") // ABAP Type C: 1,0
			def l_msg = g_sap.getTableField(l_table, "MESSAGE") // ABAP Type C: 220,0
			if(l_type.equals("E") || l_type.equals("A") || l_type.equals("X")){
				if(l_message.equals("")){
					l_message = l_msg
				}else{
					l_message = l_message + "\n" + l_msg
				}
			}
			l_table.nextRow()
		} // Table ET_MESSAGES end
	
		// check error without error message
		if(l_error.equals("X") && l_message.equals("")){
			l_message = "An unknown error has occurred."
		}
		g_log.info("Message created = " + l_message)
		// save info to db
		l_conn = g_dbConnections.systemConnection
		def l_stmtOrderUpdate = g_dbQuery.prepare(l_conn, "UPDATE XCRM_CUSTOMER SET ERROR_MESSAGE = ? WHERE LID = ?")
		l_stmtOrderUpdate.setString(1, l_message)
		l_stmtOrderUpdate.setInt(2, l_lid)
		l_stmtOrderUpdate.executeUpdate()
		if(l_error.equals("X")){
			g_sap.destroy()
			g_log.error("Failed to update SAP customer")
			return false
		}
	}else{
		g_sap.destroy()
		return true
	}
//==========> FINISH SAP CONNECTION
}
catch(e) {
  g_log.error(l_logprefix + l_text_except + " - " + e.getMessage())
}
finally{
  if(l_trace) g_log.info(l_logprefix + "Destroy SAP connection")

  // End Stateful (if configured)
  if(l_stateful && g_sap != null && l_client != null) g_sap.setContextEnd(l_client)

  // Destroy SAP API
  if(g_sap != null) g_sap.destroy()
}

4.3. External system to SAP: Modify batch input for sold-to party

FUNCTION /IATL/UDC_IXCRM_BTCI_XD02.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  IMPORTING
*"     VALUE(CTU) LIKE  APQI-PUTACTIVE DEFAULT 'X'
*"     VALUE(MODE) LIKE  APQI-PUTACTIVE DEFAULT 'N'
*"     VALUE(UPDATE) LIKE  APQI-PUTACTIVE DEFAULT 'L'
*"     VALUE(GROUP) LIKE  APQI-GROUPID OPTIONAL
*"     VALUE(USER) LIKE  APQI-USERID OPTIONAL
*"     VALUE(KEEP) LIKE  APQI-QERASE OPTIONAL
*"     VALUE(HOLDDATE) LIKE  APQI-STARTDATE OPTIONAL
*"     VALUE(NODATA) LIKE  APQI-PUTACTIVE DEFAULT '/'
*"     VALUE(IV_KUNNR) LIKE  BDCDATA-FVAL
*"     VALUE(D0110_002) LIKE  BDCDATA-FVAL DEFAULT 'X'
*"     VALUE(USE_ZAV_003) LIKE  BDCDATA-FVAL DEFAULT 'X'
*"     VALUE(IV_NAME1) LIKE  BDCDATA-FVAL DEFAULT '/'
*"     VALUE(IV_NAME2) LIKE  BDCDATA-FVAL DEFAULT '/'
*"     VALUE(IV_SORT1) LIKE  BDCDATA-FVAL DEFAULT '/'
*"     VALUE(IV_STREET) LIKE  BDCDATA-FVAL DEFAULT '/'
*"     VALUE(IV_HOUSE_NUM1) LIKE  BDCDATA-FVAL DEFAULT '/'
*"     VALUE(IV_POST_CODE1) LIKE  BDCDATA-FVAL DEFAULT '/'
*"     VALUE(IV_CITY1) LIKE  BDCDATA-FVAL DEFAULT '/'
*"     VALUE(IV_COUNTRY) LIKE  BDCDATA-FVAL DEFAULT '/'
*"     VALUE(IV_LANGU) LIKE  BDCDATA-FVAL DEFAULT '/'
*"  EXPORTING
*"     VALUE(SUBRC) LIKE  SYST-SUBRC
*"  TABLES
*"      MESSTAB STRUCTURE  BDCMSGCOLL OPTIONAL
*"----------------------------------------------------------------------

  subrc = 0.

  PERFORM bdc_nodata      USING nodata.

  PERFORM open_group      USING group user keep holddate ctu.

  PERFORM bdc_dynpro      USING 'SAPMF02D' '0101'.
  PERFORM bdc_field       USING 'BDC_CURSOR'
                                'USE_ZAV'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '/00'.
  PERFORM bdc_field       USING 'RF02D-KUNNR'
                                iv_kunnr.
  PERFORM bdc_field       USING 'RF02D-D0110'
                                d0110_002.
  PERFORM bdc_field       USING 'USE_ZAV'
                                use_zav_003.
  PERFORM bdc_dynpro      USING 'SAPMF02D' '0111'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '/00'.
  PERFORM bdc_field       USING 'BDC_CURSOR'
                                'ADDR1_DATA-CITY1'.
  PERFORM bdc_field       USING 'ADDR1_DATA-NAME1'
                                iv_name1.
  PERFORM bdc_field       USING 'ADDR1_DATA-NAME2'
                                iv_name2.
  PERFORM bdc_field       USING 'ADDR1_DATA-SORT1'
                                iv_sort1.
  PERFORM bdc_field       USING 'ADDR1_DATA-STREET'
                                iv_street.
  PERFORM bdc_field       USING 'ADDR1_DATA-HOUSE_NUM1'
                                iv_house_num1.
  PERFORM bdc_field       USING 'ADDR1_DATA-POST_CODE1'
                                iv_post_code1.
  PERFORM bdc_field       USING 'ADDR1_DATA-CITY1'
                                iv_city1.
  PERFORM bdc_field       USING 'ADDR1_DATA-COUNTRY'
                                iv_country.
  PERFORM bdc_field       USING 'ADDR1_DATA-LANGU'
                                iv_langu.
  PERFORM bdc_dynpro      USING 'SAPMF02D' '0900'.
  PERFORM bdc_field       USING 'BDC_CURSOR'
                                'KNA1-J_3GETYP'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '=UPDA'.
  PERFORM bdc_transaction TABLES messtab
  USING                         'XD02'
                                ctu
                                mode
                                update.
  IF sy-subrc <> 0.
    subrc = sy-subrc.
    EXIT.
  ENDIF.

  PERFORM close_group USING     ctu.

ENDFUNCTION.
INCLUDE bdcrecxy .

4.4. External system to SAP: Method SAP_RECORD_UPDATE

method sap_record_update.

* ----- local data
  data: ls_kna1 type kna1.
  data: lt_messtab type table of bdcmsgcoll.
  data: lv_subrc type sysubrc.

  data: lv_ort      type bdc_fval.
  data: lv_plz      type bdc_fval.
  data: lv_name     type bdc_fval.
  data: lv_strasse  type bdc_fval.
  data: lv_hnr      type bdc_fval.
  data: lv_kunnr    type bdc_fval.

  data: begin of ls_split,
          value(40),
        end of ls_split.
  data: lt_split like table of ls_split.
  data: lv_lin type i.



* ----- no new record
  if iv_sap_id eq space.
    raise failed.
  endif.
* ----- move data
  move-corresponding cs_data to ls_kna1.
  lv_name = ls_kna1-name1.
  lv_ort  = ls_kna1-ort01.
  lv_plz  = ls_kna1-pstlz.
  lv_kunnr = ls_kna1-kunnr.

* ----- split strasse --> strasse - hnr
* set to default
  lv_strasse = ls_kna1-stras.
  lv_hnr     = space.
* split to get the last part
  split ls_kna1-stras at ' ' into table lt_split.
  describe table lt_split lines lv_lin.
* check if text contains spaces
  if lv_lin gt 1.
*   get last part
    read table lt_split into ls_split index lv_lin.
    lv_hnr = ls_split-value.
*   check last part contains any numbers
    if lv_hnr ca '0123456789'.
      subtract 1 from lv_lin.
      clear lv_strasse.
      do lv_lin times.
        read table lt_split into ls_split index sy-index.
        if sy-index = 1.
          lv_strasse = ls_split-value.
        else.
          concatenate lv_strasse ls_split-value
           into lv_strasse separated by ' '.
        endif.
      enddo.
    else.
*   last part has no number -> back to default
      clear lv_hnr.
    endif.
  endif.


* ----- call btci module
  call function '/IATL/UDC_IXCRM_BTCI_XD02'
    exporting
*     CTU                 = 'X'
*     MODE                = 'N'
*     UPDATE              = 'L'
*     GROUP               = GROUP
*     USER                = USER
*     KEEP                = KEEP
*     HOLDDATE            = HOLDDATE
*     NODATA              = '/'
      iv_kunnr            = lv_kunnr
*     D0110_002           = 'X'
*     USE_ZAV_003         = 'X'
      iv_name1            = lv_name
*     IV_NAME2            = '/'
*     IV_SORT1            = '/'
      iv_street           = lv_strasse
      iv_house_num1       = lv_hnr
      iv_post_code1       = lv_plz
      iv_city1            = lv_ort
*     IV_COUNTRY          = '/'
*     IV_LANGU            = '/'
   importing
     subrc               = lv_subrc
   tables
     messtab             = lt_messtab
            .

* ------ map bdc messages
  call method /iatl/cl_udc_hndl_replica=>util_convert_bdcmsgcoll
    exporting
      it_bdcmsgcoll = lt_messtab[]
    receiving
      et_messages   = ct_messages.


* ------ check errors in bdc messages
  loop at ct_messages transporting no fields
      where type ca 'EAX'.
    lv_subrc = 1.
    exit.
  endloop.


* ------ check for errors
  if lv_subrc ne 0.
    raise failed.
  endif.

endmethod.

5. SAPGUI integration

5.1. Integrate portal pages in the SAPGUI

*&---------------------------------------------------------------------*
*& Report  /IATL/IXA_DEMO_IX_FROM_SAPGUI
*&
*&---------------------------------------------------------------------*
*& Demo: Using Intrexx Portal pages within SAPGUI
*& (c) 2008 www.initall.de
*&---------------------------------------------------------------------*

REPORT  /IATL/IXA_DEMO_IX_FROM_SAPGUI no standard page heading.


* ------- interface
PARAMETERS: p_url TYPE char255 lower case.
PARAMETERS: P_URLPOR TYPE CHAR255 lower case default 'http://localhost:8080/bugfix45/?'.
PARAMETERS: p_dock AS CHECKBOX DEFAULT 'X'.

* ------- local data
TABLES: kna1.
DATA: lo_container_sc TYPE REF TO cl_gui_custom_container.
DATA: lo_container_dc TYPE REF TO cl_gui_docking_container.
DATA: lo_container_dg TYPE REF TO cl_gui_dialogbox_container.
DATA: lo_html1 TYPE REF TO cl_gui_html_viewer.
DATA: lo_html2 TYPE REF TO cl_gui_html_viewer.
DATA: lv_url_kunnr TYPE char255.

START-OF-SELECTION.

* ------- set default url if empty
  IF p_url EQ space.
    p_url = 'http://www.unitedplanet.de'.
  ENDIF.

* ------- build url for filtered customer info
  CONCATENATE
    p_urlpor
    'rq_AppId=31313035&rq_TargetId=31303131&rq_RecId=2D31'
    '&rq_Template=696E7465726E616C2F6C61796F75742F766D2F68746D6C2F6C61796F7574342F667261'
    '6D65732F6170706D61696E2E766D'
    INTO lv_url_kunnr.


* ------- call screen
  CALL SCREEN 2000.


*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_2000  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE user_command_2000 INPUT.
  CASE sy-ucomm.
    WHEN 'CANC' OR 'EXIT' OR 'BACK'.
      LEAVE TO SCREEN 0.
  ENDCASE.
  IF sy-ucomm EQ space AND kna1-kunnr NE space.
    PERFORM refresh_kunnr USING kna1-kunnr.
  ENDIF.
ENDMODULE.                 " USER_COMMAND_2000  INPUT
*&---------------------------------------------------------------------*
*&      Module  STATUS_2000  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE status_2000 OUTPUT.
  SET PF-STATUS '2000'.
  SET TITLEBAR '2000'.
  PERFORM init_controls.
ENDMODULE.                 " STATUS_2000  OUTPUT
*&---------------------------------------------------------------------*
*&      Form  init_controls
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM init_controls .
  CHECK lo_container_sc IS INITIAL.


* ------------ DYNPRO
  CREATE OBJECT lo_container_sc
    EXPORTING
      container_name = 'CONTAINER_PORTAL'.

  CREATE OBJECT lo_html1
    EXPORTING
      parent = lo_container_sc.


* ------------ DOCKING OR DIALOG
  IF p_dock EQ 'X'.
    CREATE OBJECT lo_container_dc
      EXPORTING
        repid     = sy-repid
        dynnr     = sy-dynnr
        side      = cl_gui_docking_container=>dock_at_right
        extension = 400.

    CREATE OBJECT lo_html2
      EXPORTING
        parent = lo_container_dc.

  ELSE.
    CREATE OBJECT lo_container_dg
      EXPORTING
        width   = 400
        height  = 200
        top     = 0
        left    = 0
        caption = 'Zusatzinformationen'.

    CREATE OBJECT lo_html2
      EXPORTING
        parent = lo_container_dg.

  ENDIF.

* ------------ SHOW URL
  CALL METHOD lo_html1->show_url
    EXPORTING
      url = lv_url_kunnr.

  CALL METHOD lo_html2->show_url
    EXPORTING
      url = p_url.

ENDFORM.                    " init_controls
*&---------------------------------------------------------------------*
*&      Form  refresh_kunnr
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_KNA1_KUNNR  text
*----------------------------------------------------------------------*
FORM refresh_kunnr  USING    p_kunnr.

  DATA: lv_url TYPE char255.
  DATA: lv_kunnr TYPE string.

  lv_url = lv_url_kunnr.


  lv_kunnr = p_kunnr.

*  clear kna1.
  select single * from kna1 into kna1
    where kunnr = p_kunnr.

  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
    EXPORTING
      input  = lv_kunnr
    IMPORTING
      output = lv_kunnr.


  CONCATENATE lv_url
              '&rq_kunnr='
              INTO lv_url.


  WHILE lv_kunnr NE space.

    CONCATENATE lv_url
                '3'
                lv_kunnr(1)
                INTO lv_url.

    lv_kunnr = lv_kunnr+1.

  ENDWHILE.


  CALL METHOD lo_html1->show_url
    EXPORTING
      url = lv_url.


ENDFORM.                    " refresh_kunnr
The Dynpro 2000 as well as the GUI status need to be implemented additionally. The fields from the structure KNA1 are expected (at least KNA1-KUNNR) are expected on the Dynpro. To include the website later, a custom container with the name "CONTAINER_PORTAL" is expected.

5.2. Start SAP BusinessObjects

A call of SAP interfaces via functions of the corresponding business object from the transaction "SWO1". To transfer parameters, this report must also be called in a transaction.
*&---------------------------------------------------------------------*
*& Report  /IATL/SSO_START_BOR
*&
*&---------------------------------------------------------------------*
*& Starting SAP documents via BOR (transaction SWO1) remote
*& 
*&---------------------------------------------------------------------*

report  /iatl/sso_start_bor.

* --------- interface
parameters: object type swo_objtyp obligatory.
parameters: key    type swo_typeid obligatory.
parameters: method type swo_method obligatory default 'DISPLAY'.
parameters: numlen type i default 0.


start-of-selection.

* ------------ local data
  data: lv_len type i.

* ------------ append zeros
  if numlen gt 0.
    do.
      lv_len = strlen( key ).
      if lv_len ge numlen.
        exit. "from do
      else.
        concatenate '0' key into key.
      endif.
    enddo.
  endif.


* ------------ call sap
  call function 'EWC_OBJ_METHOD_CALL'
    exporting
      x_objtype              = object
      x_objkey               = key
      x_method               = method
*   X_FREE                 = X_FREE
* TABLES
*   X_CONT                 = X_CONT
   exceptions
     object_not_found       = 1
     method_failed          = 2
     others                 = 3
            .
  if sy-subrc <> 0.
    write: 'An error has occurred.'.
  endif.

6. JavaScript examples

6.1. Start an SAP shortcut via a button

/**
 * BIASAP: start a sapgui shortcut with type transaction
 */
function biasap_start_transaction(p_instance, p_loginmode, p_transaction, p_extra, p_skip){
	oShortcut = new upActionControl();
	oShortcut.oHtml = new Object();
	oShortcut.oTarget = new upTarget();
	oShortcut.oTarget.rq_Template = "internal/system/vm/custom/biasap_shortcut.vm";
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_filename", "link.sap", oShortcut.oTarget.addParam);
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_instance", p_instance, oShortcut.oTarget.addParam);
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_loginmode", p_loginmode, oShortcut.oTarget.addParam);
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_transaction", p_transaction, oShortcut.oTarget.addParam);
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_extra", p_extra, oShortcut.oTarget.addParam);
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_skipscreen", p_skip, oShortcut.oTarget.addParam);
	oShortcut.processRequest();
	return true;
}

/**
 * BIASAP: start a sapgui shortcut with type report
 */
function biasap_start_report(p_instance, p_loginmode, p_report, p_variant){
	oShortcut = new upActionControl();
	oShortcut.oHtml = new Object();
	oShortcut.oTarget = new upTarget();
	oShortcut.oTarget.rq_Template = "internal/system/vm/custom/biasap_shortcut.vm";
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_filename", "link.sap", oShortcut.oTarget.addParam);
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_instance", p_instance, oShortcut.oTarget.addParam);
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_loginmode", p_loginmode, oShortcut.oTarget.addParam);
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_report", p_report, oShortcut.oTarget.addParam);
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_variant", p_variant, oShortcut.oTarget.addParam);
	oShortcut.processRequest();
	return true;
}

6.2. Save field values in the context as a request value

This function can be implemented universally and can be called used the onclick of a button as follows:
"setRequestValue('<Text area GUID>', this, 'rq_<id des request parameters>')"
function setRequestValue(p_fieldguid, p_button, p_param){
 var oButton = null;	
 var oTextcontrol = getElement(p_fieldguid); 
 var sValue = "";

 // get access to button	
 if (p_button && p_button.oUp && p_button.oUp.upType == "upButtonControl")
 {
   oButton = p_button;
 }else{
   oButton = getElement(p_button); // try this parameter is GUID
 }
 if (!checkButtonReference(oButton)) return false;

 // get value from field	
 if (oTextcontrol && oTextcontrol.oUp && oTextcontrol.oUp.oHtml && (oTextcontrol.oUp.upType == "upTextControl" || oTextcontrol.oUp.upType == "upDateTimeControl"))
 {
	sValue = oTextcontrol.oUp.oHtml.value;
 } else {
	sValue = getTextValue(oTextcontrol);
 }

 // set request parameter
 if (sValue.length == 0 || sValue == false) {
	return false;
 }else{
	oButton.oUp.oTarget.addParam = Helper.setQsValueByParam(p_param, sValue, oButton.oUp.oTarget.addParam);
	return true;
 }
}

7. VTL example codings

7.1. Support for SAP shortcuts

##########################################################################
## Creating SAP Shortcuts from Intrexx Requests				 #
## 				 					 #
##                                                                       #
## last changed 2008/10/08						 #
##                                                                       #
## Place this file as internal/system/vm/custom/biasap_shortcut.vm       #
## Intrexx >=4.5 required                                         	 #
## Use this Vm with Buttons, see documentation for sap adapter		 #
##########################################################################
##
## ================ get parameters for all moded
#set($instance 		= $Request.get("rq_sc_instance",""))
#set($loginmode 	= $Request.get("rq_sc_loginmode","user"))
##
## ================ get parameters for transaction mode
#set($transaction 	= $Request.get("rq_sc_transaction",""))
#set($extra	 	= $Request.get("rq_sc_extra",""))
#set($skipscreen	= $Request.get("rq_sc_skipscreen","false"))
##
## ================ get parameters for report mode
#set($report 	= $Request.get("rq_sc_report",""))
#set($variant	= $Request.get("rq_sc_variant",""))
##
## ================ create the shortcut
#if( $report == "" )
	#set($guid = $GSAP.shortcutNewTransaction($instance, $loginmode, $transaction, $extra, $skipscreen))
#else
	#set($guid = $GSAP.shortcutNewReport($instance, $loginmode, $report, $variant))	
#end	
##
##
## ================ set html header info
$Response.setIgnoreWrite(true)
$Response.setHeader("Content-Type","application/octet-stream")  
$Response.setHeader("Content-Transfer-Encoding:", "$Request.get('rq_MimeCharset','$charset')")
$Response.setHeader("Content-Disposition","attachment;filename=$Request.get('rq_sc_filename','sap.sap')")
$Response.setIgnoreWrite(false)
##
## ================ output shortcut as text
$Response.setIgnoreWrite(false)
$GSAP.shortcutGetAsText($guid)
$Response.setIgnoreWrite(true)
##
## ================ remove from cache
#$GSAP.shortcut.remove($guid)

7.2. Transfer request values to the server via AJAX

$Response.setIgnoreWrite(true)
## Identify CostCenter from a request value and create session parameters

#set( $costCenterId = $Request.get('rq_customCostCenterId') )
#set( $costCenterName = $Request.get('rq_customCostCenterName') )
$Session.put('costCenterId', $!costCenterId)
$Session.put('costCenterName', $!costCenterName)

## Write header
$Response.setHeader("Cache-Control","no-cache")
$Response.setHeader("Content-Type","text/json; charset=UTF-8")
$Response.setIgnoreWrite(false)
## Generation of JSON objects
#if( 1 == 1 )
{"myobject":{"result":"true"}
#else
{"error":{"title":"ERROR","message":"Session parameter not created"}}
#end

8. More information

Developer's Manual Appendix
API Developer's Manual