Connector für SAP Business Suite - API Beschreibung Teil 4 - Beispielcodings

Dieser Abschnitt enthält einige Beispielcodings, die die Implementierung eigener Verarbeitungsmodule erleichtern sollen. Grundsätzlich wird davon ausgegangen, dass ein neues Verarbeitungsmodul und eine zugehörige Transferstruktur – wie in der Checkliste für das Anlegen neuer Verarbeitungsmodule dargestellt – verwendet wird.

Beispiel interne Tabellen verfügbar machen

Funktionalität

Dieses einfache Beispiel demonstriert, wie eine beliebige interne Tabelle für einen externen Aufrufer zur Verfügung gestellt werden kann. Auf die Auswertung von eingehenden Parametern wird verzichtet.

Konzept

  • Neues Verarbeitungsmodul für den Datahandler GENERIC_VIEW vererbt vom Standardmodul für den GENERIC_VIEW Zugriff

  • Transferstruktur aus IV. 4.3.

  • Redefinition der API Methode GET_LIST

Screenshots

Coding

METHOD z_if_ia_ixa_intrexx_api~get_list.

				* -------------- local data  
				DATA: lt_data TYPE TABLE OF yixapi_demo.  
				DATA: ls_data TYPE yixapi_demo.

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

				* -------------- get inbound parameters
				* nothing to do

				* -------------- initial check routines
				* nothing to do

				* -------------- process
				* 1. fill demo table  
				ls_data-partner = '100000'.  
				ls_data-name = 'Meier'.  
				APPEND ls_data TO lt_data.

				ls_data-partner = '100001'.  
				ls_data-name = 'Müller'.  
				APPEND ls_data TO lt_data.

				ls_data-partner = '100002'.  
				ls_data-name = 'Schulze'.  
				APPEND ls_data TO lt_data.

				* -------------- fill outbound parameters
				* 1. sort internal table  
				SORT lt_data BY name.

				* 2. 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'
				iv_key_value    = ls_data-partner
				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.
				ADD 1 TO ev_count.
				ENDIF.
				ENDLOOP.

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

				ENDMETHOD.
		

Test

Suchhilfefunktion

Funktionalität

Dieses Beispiel demonstriert eine einfache Suchhilfe für den externen Verbraucher. Aufgrund einer externen Eingabe in ein Suchfeld (evtl. auch mit Wildcards) wird im SAP System eine Suche ausgeführt und die Ergebnisse mit Details angereichert. Als Beispiel dient der SAP Geschäftspartner (BOR Objekt BUS1006).

Konzept

  • Neues Verarbeitungsmodul für den Datahandler GENERIC_VIEW, vererbt vom Standardmodul für den GENERIC_VIEW Zugriff

  • Transferstruktur, erweitert um Suchfeld

  • Redefinition der API Methode GET_LIST

Screenshots

Coding

METHOD z_if_ia_ixa_intrexx_api~get_list.

				* -------------- local data
				DATA: lt_data TYPE TABLE OF yixapi_demo_f4.
				DATA: ls_data TYPE yixapi_demo_f4.
				DATA: ls_filter TYPE LINE OF zia_ixa_api_intrexx_filter_t.
				DATA: lv_search TYPE bu_mcname1.
				DATA: lt_result TYPE TABLE OF bus020_search_result.
				DATA: ls_result TYPE bus020_search_result.
				DATA: lv_name TYPE bu_descrip_long.
				DATA: lt_return TYPE TABLE OF bapiret2.

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

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

				* -------------- initial check routines
				IF lv_search IS INITIAL OR lv_search EQ '*'.
				ev_error     = ' '.
				EXIT.
				ENDIF.

				* -------------- process
				* 1. Search
				CALL FUNCTION 'BUPA_SEARCH'
				EXPORTING
				iv_mc_name1      = lv_search
				TABLES
				et_search_result = lt_result.

				* 2. build data table
				LOOP AT lt_result INTO ls_result.
				CLEAR lv_name.
				CALL FUNCTION 'BUPA_DESCRIPTION_GET'
				EXPORTING
				iv_partner          = ls_result-partner
				IMPORTING
				ev_description_long = lv_name
				TABLES
				et_return           = lt_return.

				IF lv_name NE space.
				CLEAR ls_data.
				ls_data-search  = lv_search.
				ls_data-partner = ls_result-partner.
				ls_data-name    = lv_name.
				APPEND ls_data TO lt_data.
				ENDIF.
				ENDLOOP.

				* -------------- fill outbound parameters
				* 1. sort internal table
				SORT lt_data BY name.

				* 2. 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_F4'
				iv_key_value    = ls_data-partner
				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.
				ADD 1 TO ev_count.
				ENDIF.
				ENDLOOP.

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

				ENDMETHOD.
		

Test

Funktionale Aufrufe

Funktionalität

Funktionale Aufrufe werden benötigt, wenn der externe Aufrufer das SAP mit Parametern aufruft, die dann dort ausgewertet und an den Aufrufer zurückgesendet werden. Dies entspricht im Wesentlichen dem Verhalten von Webservices oder den Aufruf von BAPI Funktionen (ohne die Rückgabe von Tabellen). Nebensächlich ist, ob und wo die Daten gesichert werden. Das Beispiel simuliert eine Preisabfrage in SAP. Dabei werden eine Materialnummer und eine Kundennummer zur Berechnung evtl. Rabatte an SAP übergeben und ein Preis ermittelt.

Konzept

  • Neues Verarbeitungsmodul für den Datahandler GENERIC_VIEW vererbt vom Standardmodul für den GENERIC_VIEW Zugriff

  • Transferstruktur mit Import- und Export-Parametern (optional; evtl. sinnvoll für den externen Aufrufer)

  • Redefinition der Methode MODIFY.

Screenshots

Coding

METHOD z_if_ia_ixa_intrexx_api~modify.

				* -------------- local data
				DATA: lv_kunnr TYPE kunnr.
				DATA: lv_matnr TYPE matnr.
				DATA: lv_price(20).

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

				* -------------- no saving within sap - external system is leading
				et_fields[] = it_fields[].
				ev_key = iv_key.

				* -------------- get inbound parameters
				* without convert because of external structure definition
				* -- get kunnr
				CALL METHOD me->get_field
				EXPORTING
				it_fields       = it_fields
				iv_record       = '1'
				iv_struc_name   = 'DEFAULT'
				iv_struc_record = '0'
				iv_fieldname    = 'IV_KUNNR'
				iv_convert      = ' '
				CHANGING
				cv_fieldvalue   = lv_kunnr
				EXCEPTIONS
				failed          = 1
				OTHERS          = 2.
				IF sy-subrc <> 0.
				EXIT.
				ENDIF.

				* -- get matnr
				CALL METHOD me->get_field
				EXPORTING
				it_fields       = it_fields
				iv_record       = '1'
				iv_struc_name   = 'DEFAULT'
				iv_struc_record = '0'
				iv_fieldname    = 'IV_MATNR'
				iv_convert      = ' '
				CHANGING
				cv_fieldvalue   = lv_matnr
				EXCEPTIONS
				failed          = 1
				OTHERS          = 2.
				IF sy-subrc <> 0.
				EXIT.
				ENDIF.

				* -------------- initial check routines
				CHECK NOT lv_kunnr IS INITIAL
				AND NOT lv_matnr IS INITIAL.

				* -------------- process
				* 1. call function module to get price (here simulated)
				* .....
				* 2. write price formatted to transfer structure
				lv_price = '1000,89'.

				* -------------- fill outbound parameters
				* -- modify ev_price
				CALL METHOD me->set_field
				EXPORTING
				*    IV_RECORD       = '1'
				*    IV_STRUC_NAME   = 'DEFAULT'
				*    IV_STRUC_RECORD = '0'
				iv_fieldname    = 'EV_PRICE'
				iv_convert      = ' '
				iv_fieldvalue   = lv_price
				CHANGING
				ct_fields       = et_fields
				EXCEPTIONS
				failed          = 1
				OTHERS          = 2
				.
				IF sy-subrc <> 0.
				EXIT.
				ENDIF.
				* -- modify ev_waers
				CALL METHOD me->set_field
				EXPORTING
				*    IV_RECORD       = '1'
				*    IV_STRUC_NAME   = 'DEFAULT'
				*    IV_STRUC_RECORD = '0'
				iv_fieldname    = 'EV_WAERS'
				iv_convert      = ' '
				iv_fieldvalue   = 'EUR'
				CHANGING
				ct_fields       = et_fields
				EXCEPTIONS
				failed          = 1
				OTHERS          = 2
				.
				IF sy-subrc <> 0.
				EXIT.
				ENDIF.

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

				ENDMETHOD.
		

Test

Spezifische Bemerkungen

Zur Umsetzung dieses Konzeptes wird eine Datengruppe im Intrexx-Portal erstellt, die alle Import- und Export-Parameter enthält. Vor dem ersten Sichern der Applikation sollten die Feldnamen angepasst werden, da sonst die automatisch generierten Feldnamen innerhalb des SAP-Verarbeitungsmoduls gemappt werden müssen.

Klicken Sie hier auf "Datenfeld bearbeiten".

Wechseln Sie auf den Reiter "Expert" und ändern Sie den Namen des Datenfeldes entsprechend ab. Danach wird eine Eingabeseite erzeugt, die die Importparameter als Eingabe und die Exportparameter als schreibgeschützte Eingabefelder definiert. Eine Schaltfläche löst die Aktion "Speichern" aus und bleibt auf der gleichen Eingabeseite. Dadurch werden später die während des Speicherns veränderten Exportparameter im Portal angezeigt. Die Applikation kann nun bereits ohne SAP-Integration getestet werden. Sie sollte bis auf ungefüllte Exportparameter normal reagieren, d.h. Datensätze werden beim Speichern angelegt. Die SAP-Integration wird über eine spezielle Exit-Businesslogik umgesetzt. Die gefüllte Eingabeseite wird vor dem Speichern im Portal erst an SAP gesendet. Dort können die Felder ausgewertet, geändert und evtl. sogar Fehler erzeugt werden. Danach wird der Speichervorgang im Portal fortgesetzt. Um diese Exit-Businesslogik zu aktivieren, müssen Parameter in den Expert-Attributen der Datengruppe geändert werden.

Dazu wird der "Datahandler" gegen eine alternative Klasse des SAP Connectors ersetzt. Der Parameter "bia-instance" muss die Datenquelle des aufgerufenen SAP Systems enthalten. Der als "name" angezeigte Parameter wird als Datengruppenname innerhalb der Findung der SAP Verarbeitungsmodule verwendet.

SAP Trigger mit externer Datenhaltung

Funktionalität

Dieses Beispiel zeigt, wie ein Prozess in SAP bei Datensatzänderungen ausgelöst werden kann. Dabei können auch die Daten des betreffenden Datensatzes ausgewertet werden.

Konzept

Das Konzept gleicht dem des funktionalen Aufrufs. Allerdings sollte SAP hier nicht prüfend aktiv werden, sondern nur die übergebenen Daten nutzen, um einen SAP-internen Folgeprozess anzustarten. Fehler sollte das Verarbeitungsmodul nicht erzeugen.

Coding

METHOD z_if_ia_ixa_intrexx_api~modify.

				* -------------- local data
				DATA: lv_kunnr TYPE kunnr.

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

				* -------------- no saving within sap - external system is leading
				et_fields[] = it_fields[].
				ev_key = iv_key.

				* -------------- get inbound parameters
				* -- get kunnr (example)
				CALL METHOD me->get_field
				EXPORTING
				it_fields       = it_fields
				iv_record       = '1'
				iv_struc_name   = 'DEFAULT'
				iv_struc_record = '0'
				iv_fieldname    = 'IV_KUNNR'
				CHANGING
				cv_fieldvalue   = lv_kunnr
				EXCEPTIONS
				failed          = 1
				OTHERS          = 2.
				IF sy-subrc <> 0.
				EXIT.
				ENDIF.

				* -------------- initial check routines
				CHECK NOT lv_kunnr IS INITIAL.

				* -------------- process
				* 1. call a trigger function module (e.g. SWE_EVENT_CREATE)

				ENDMETHOD.
		

Datenhaltung in SAP

Funktionalität

Dieses Beispiel zeigt eine einfache Methode der Datenhaltung in SAP. Es wird auf Konzepte wie Sperren, Berechtigungen oder Nummernkreise verzichtet. Die Daten werden in eine Tabelle im Kundennamensraum abgelegt. Innerhalb der API-Methoden könnte eine Weiterverarbeitung der Daten angestoßen werden. Durch die Verwendung von GUIDs als Tabellenschlüssel kann auf die Verwendung eines Nummernkreisobjektes verzichtet werden. Eine Erweiterung eines Sperrkonzeptes kann entweder über das SAP Standard-Sperrkonzept (mit evtl. Nachteilen durch statuslose Internetnutzung) oder die Musterimplementierung aus dem Kapitel Sperrkonzept nachgerüstet werden.

Konzept

  • Neues Verarbeitungsmodul für den Datahandler GENERIC_VIEW vererbt vom Standardmodul für den GENERIC_VIEW Zugriff

  • Tabelle im Kundennamensraum mit Primary Key in Form einer GUID

  • Tabelle wird als Transferstruktur verwendet

  • Die lesenden API Methoden (get_Metainfo; get_List; get_Detail) können aus dem Verarbeitungsmodul GENERIC_VIEW verwendet werden.

  • Redefinition der Methoden MODIFY und DELETE

Screenshots

Coding

METHOD z_if_ia_ixa_intrexx_api~modify.

				* -------------- local data
				DATA: ls_data TYPE yixapi_demodata.
				DATA: lv_guid TYPE sysuuid_x.

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

				* -------------- set export = import
				et_fields[] = it_fields.
				ev_key = iv_key.

				* -------------- get existing data
				CLEAR lv_guid.
				IF iv_key NE space AND iv_key NE '-1'.
				* ------- get existing
				lv_guid = iv_key.
				SELECT SINGLE * FROM yixapi_demodata
				INTO ls_data
				WHERE lid EQ iv_key.
				IF sy-subrc NE 0.
				CLEAR lv_guid.
				ENDIF.
				ENDIF.

				* -------- create a new guid if initial
				IF lv_guid IS INITIAL.
				CALL FUNCTION 'GUID_CREATE'
				IMPORTING
				ev_guid_16 = lv_guid.
				ENDIF.

				* -------------- get inbound parameters
				CALL METHOD me->get_fields_from_struc
				EXPORTING
				it_fields         = it_fields
				iv_record         = '1'
				iv_struc_name     = 'DEFAULT'
				iv_struc_record   = '0'
				iv_data_strucname = 'YIXAPI_DEMODATA'
				iv_convert        = 'X'
				CHANGING
				cs_data           = ls_data
				EXCEPTIONS
				failed            = 1
				OTHERS            = 2.
				IF sy-subrc <> 0.
				EXIT. "with error
				ENDIF.

				* -------------- process
				* 1. set key
				ls_data-lid = lv_guid.
				* 2. save to database
				SET UPDATE TASK LOCAL.
				MODIFY yixapi_demodata FROM ls_data.
				IF sy-subrc NE 0.
				ROLLBACK WORK.
				EXIT.
				ENDIF.

				* -------------- fill outbound parameters
				REFRESH et_fields.
				CALL METHOD me->set_results_from_struc
				EXPORTING 
				is_data         = ls_data
				*    IT_REQUESTED    =
				iv_data_struc   = 'YIXAPI_DEMODATA'
				*    IV_KEY_VALUE    =
				iv_record       = 1
				*    IV_STRUC_NAME   = 'DEFAULT'
				*    IV_STRUC_RECORD = 0
				CHANGING
				*      ct_keys         =
				ct_results      = et_fields
				EXCEPTIONS
				failed          = 1
				OTHERS          = 2
				.
				IF sy-subrc <> 0.
				ROLLBACK WORK.
				EXIT.
				ENDIF.

				* -------------- final commit
				COMMIT WORK.
				IF sy-subrc NE 0.
				ROLLBACK WORK.
				EXIT.
				ELSE.
				ev_key = lv_guid.
				ENDIF.

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

				ENDMETHOD.                    "Z_IF_IA_IXA_INTREXX_API~MODIFY

				METHOD z_if_ia_ixa_intrexx_api~delete.

				* -------- get existing data via API Func get_Detail
				CALL METHOD me->z_if_ia_ixa_intrexx_api~get_detail
				EXPORTING
				iv_key           = iv_key
				*      it_requested     =
				IMPORTING
				ev_error         = ev_error
				et_messages      = et_messages
				et_result_values = et_fields
				CHANGING
				cv_processed     = cv_processed
				EXCEPTIONS
				failed           = 1
				OTHERS           = 2.
				IF sy-subrc <> 0.
				RAISE failed.
				ENDIF.

				* -------- check processed and error
				IF cv_processed EQ 'X' AND ev_error NE 'X'.
				* -- DELETE Record
				SET UPDATE TASK LOCAL.
				DELETE FROM yixapi_demodata
				WHERE lid EQ iv_key.
				IF sy-subrc NE 0.
				ROLLBACK WORK.
				ev_error = 'X'.
				EXIT.
				ENDIF.
				COMMIT WORK.
				ELSE.
				* -- Record does not exist
				cv_processed = 'X'.
				ev_error     = 'X'.
				ENDIF.

				ENDMETHOD.
		

Test

SAP Trigger mit Datenhaltung im SAP

Funktionalität

Wie beim SAP Trigger mit externer Datenhaltung eignen sich Trigger besonders dazu, Prozesse miteinander zu verbinden. Dies kann asynchron bzw. synchron erfolgen. Dabei sind meistens vor allem die externe Performance (z.B. im Portal) und die Verhinderung von Datenverlust besonders wichtig bei der Konzeption. Dieses Beispiel setzt auf dem Demo Datenhaltung in SAP auf. Mit dem dort beschriebenen Ansatz können sogar wieder verwendbare Trigger programmiert werden. Die Transferstruktur würde dann natürlich nicht die Daten von SAP Geschäftspartnern enthalten, sondern zum Beispiel:

  • Triggertyp (Konstante)

  • Business Objekt Typ

  • Business Objekt ID

  • Parameter 1

  • Parameter n

Das folgende Coding enthält ein Beispiel, wie die Verarbeitung aus dem Demo Datenhaltung in SAP genutzt werden kann und – nach erfolgreicher Auführung – eine Triggerfunktion asynchron über qRFC angestartet wird.

Konzept

  • Neues Verarbeitungsmodul als Vererbung des Datahandler für SAP-interne Datenhaltung aus dem Demo Datenhaltung in SAP

  • Erweitern der Tabelle aus dem Demo Datenhaltung in SAP um Verarbeitunginformationen

  • Tabelle wird als Transferstruktur verwendet

  • Redefinition der Methode MODIFY

Screenshots

Coding

Funktionsbaustein für die Verarbeitung

FUNCTION y_ixapi_demo_trigger_process.
				*"----------------------------------------------------------------------
				*"*"Lokale Schnittstelle:
				*"  IMPORTING
				*"     VALUE(IV_GUID) TYPE  ZIA_IXA_FIELDVALUE
				*"  EXCEPTIONS
				*"      NOT_FOUND
				*"----------------------------------------------------------------------



				* -------- local data
				DATA: ls_data TYPE yixapi_demodata.



				* --------- get data
				SELECT SINGLE * FROM yixapi_demodata
				INTO ls_data
				WHERE lid EQ iv_guid.
				IF sy-subrc NE 0.
				RAISE not_found.
				ENDIF.



				* --------- prepare data
				ls_data-processed = 'X'.



				* --------- save to db
				SET UPDATE TASK LOCAL.
				MODIFY yixapi_demodata FROM ls_data.
				COMMIT WORK.

				ENDFUNCTION.
		

Methode MODIFY

METHOD z_if_ia_ixa_intrexx_api~modify.

				* --------- local data
				DATA: lv_queue TYPE trfcqnam VALUE 'YIXAPI-TRIGGER'.

				* --------- call super
				CALL METHOD super->z_if_ia_ixa_intrexx_api~modify
				EXPORTING
				iv_key       = iv_key
				it_fields    = it_fields
				IMPORTING
				ev_error     = ev_error
				et_messages  = et_messages
				et_fields    = et_fields
				ev_key       = ev_key
				CHANGING
				cv_processed = cv_processed
				EXCEPTIONS
				failed       = 1
				OTHERS       = 2.
				IF sy-subrc <> 0.
				RAISE failed.
				ENDIF.

				* ---------- start trigger
				IF ev_error NE 'X'
				AND cv_processed EQ 'X'
				AND NOT ev_key IS INITIAL.
				* ------ luw start
				SET UPDATE TASK LOCAL.
				* ------ set queue name
				CALL FUNCTION 'TRFC_SET_QUEUE_NAME'
				EXPORTING
				qname                    = lv_queue
				*     NOSEND                   = ' '
				*     TRFC_IF_SYSFAIL          = ' '
				*     CALL_EVENT               = ' '
				EXCEPTIONS
				invalid_queue_name       = 1
				OTHERS                   = 2
				.
				IF sy-subrc <> 0.
				ev_error = 'X'.
				ENDIF.
				* ------ call function module asynchron in qRFC
				CALL FUNCTION 'Y_IXAPI_DEMO_TRIGGER_PROCESS'
				IN BACKGROUND TASK AS SEPARATE UNIT
				DESTINATION 'NONE'
				EXPORTING
				iv_guid   = ev_key
				EXCEPTIONS
				not_found = 1
				OTHERS    = 2.
				IF sy-subrc <> 0.
				ev_error = 'X'.
				ENDIF.
				* ------- execute
				COMMIT WORK.
				ENDIF.

				ENDMETHOD.

		

Test

Intrexx spezifische Bemerkungen

Das Demo setzt auf die Kopierfunktionalität über den Prozess Manager auf. Die Dateneingabe erfolgt in einer eigenen Applikation mit Datenhaltung im Portal. Wird bei der Erfassung das Flag gesetzt, kopiert der Prozessmanager die Daten in die Datengruppe aus dem Beispiel Datenhaltung in SAP.

Die Daten werden dadurch an SAP übertragen und dort gebucht. Durch das veränderte Verarbeitungsmodul wird erst die Implementierung aus dem Demo Datenhaltung in SAP und danach das RFC-Verbundungsmodul asynchron innerhalb des qRFC aufgerufen. Erst hier erhält der Datensatz das Prozessed-Flag. QRFC Verarbeitungsprozesse lassen sich durch die Transaktionen SMQ1 und SMQ2 überwachen. Weitere Informationen zu diesem Thema finden Sie in der SAP Dokumentation zum QRFC.

Abbilden von SAP Business Objekten

Funktionalität

Dieses Beispiel beschreibt den Zugriff auf SAP Standardobjekte (mit Datenhaltung im SAP). Im Gegensatz zum Beispiel Datenhaltung in SAP wird dabei nicht direkt lesend und schreibend auf die SAP-Tabellen zugegriffen. Der SAP Standard stellt hierfür meistens Zugriffsroutinen in Form von Funktionsbausteinen (evtl. sogar als BAPI Funktion) zur Verfügung. Falls solche BAPI Funktionen für das gewünschte Objekt existieren, sollten diese auch für den externen Aufrufer verwendet werden. Zur Demonstration wird hier das Beispiel "Ansprechpartner zu einem Kunden im Portal ändern" verwendet. Das SAP Business Objekt ist "BUS1006002" (Transaktion SWO1). Diese bildet z.B. im SAP CRM-Umfeld oder in einigen Branchenlösungen die Beziehung zwischen einer Organisation (Kunde) und einer Person (Ansprechpartner beim Kunden) ab.

Für dieses Objekt sind BAPI-Funktionen (z.B. CREATE, CHANGE usw.; zu erkennen am grünen Icon) vorhanden. Der externe Aufrufer übergibt in diesem Beispiel immer die ID der Organisation (z.B. als Benutzerparameter am Login hinterlegt) und kann dann auf die Ansprechpartnerdaten zugreifen. Die Ansprechpartner werden zusätzlich um Detailinformationen des SAP Business Objektes "BUS1006" des Ansprechpartners ergänzt.

Konzept

  • Neues Verarbeitungsmodul als Vererbung des Datahandlers für GENERIC_VIEW

  • Transferstruktur mit inkludierten BAPI-Strukturen angereichert um Schlüsselinformationen und aufbereitete Customizing-Texte

  • Hilfsstruktur mit X-Feldern für BAPI-Change-Methoden

  • Redefinition der Methoden GET_LIST, GET_DETAIL und MODIFY

  • Unterstützung von Offset-Zugriff und Sortierung

  • GET_LIST verwendet GET_DETAIL-Implementierung über eine Austausch-Variable

Screenshots

Coding

GET_DETAIL

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.
		

GET_LIST

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.
		

MODIFY

METHOD z_if_ia_ixa_intrexx_api~modify.

				* ------ local data
				DATA: lv_org  TYPE bu_partner. 
				DATA: lv_per  TYPE bu_partner. 
				DATA: ls_data TYPE yixapi_demo_bapi_conr. 
				DATA: ls_datax TYPE yixapi_demo_bapi_conrx.
				DATA: ls_relation TYPE bapibus1006002_central. 
				DATA: ls_relation_x TYPE bapibus1006002_central_x. 
				DATA: ls_central TYPE bapibus1006_central.
				DATA: ls_central_x TYPE bapibus1006_central_x. 
				DATA: ls_person TYPE bapibus1006_central_person. 
				DATA: ls_person_x TYPE bapibus1006_central_person_x. 
				DATA: lt_return TYPE TABLE OF bapiret2. 
				DATA: ls_return TYPE bapiret2.
				DATA: lv_error.

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

				* ------ get fields 
				CALL METHOD me->get_fields_from_struc 
				EXPORTING   
				it_fields         = it_fields
				*    IV_RECORD         = '1'
				*    IV_STRUC_NAME     = 'DEFAULT'
				*    IV_STRUC_RECORD   = '0'   
				iv_data_strucname = 'YIXAPI_DEMO_BAPI_CONR'
				iv_convert        = 'X' 
				CHANGING    
				cs_data           = ls_data  
				cs_data_x         = ls_datax
				EXCEPTIONS     
				failed            = 1  
				OTHERS            = 2 
				. 
				IF sy-subrc <> 0.  
				EXIT. 
				ENDIF.

				* ------ split key 
				IF iv_key CS '~'.
				* ############################################### MODIFY
				* existing record 
				SPLIT iv_key AT '~' INTO lv_org lv_per. 
				CHECK lv_org NE space AND lv_per NE space.

				* prepare BAPI access   
				MOVE-CORRESPONDING ls_data TO ls_central.   
				MOVE-CORRESPONDING ls_datax TO ls_central_x.

				MOVE-CORRESPONDING ls_data TO ls_person. 
				MOVE-CORRESPONDING ls_datax TO ls_person_x.

				MOVE-CORRESPONDING ls_data TO ls_relation.  
				MOVE-CORRESPONDING ls_datax TO ls_relation_x.

				* Change BAPI BP 
				IF NOT ls_central_x IS INITIAL   
				OR NOT ls_person_x IS INITIAL.    
				CALL FUNCTION 'BAPI_BUPA_CENTRAL_CHANGE' 
				EXPORTING        
				businesspartner     = lv_per   
				centraldata         = ls_central  
				centraldataperson   = ls_person      
				centraldata_x       = ls_central_x    
				centraldataperson_x = ls_person_x    
				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'. 
				ENDIF.

				* Change BAPI Relation   
				IF NOT ls_relation_x IS INITIAL.   
				CALL FUNCTION 'BAPI_BUPR_CONTP_CHANGE'   
				EXPORTING     
				businesspartner             = lv_org  
				contactperson               = lv_per
				*     VALIDFROMDATE               =
				*     VALIDUNTILDATE              =
				*     DEFAULTRELATIONSHIP         =
				*     DEFAULTRELATIONSHIP_X       = 
				centraldata                 = ls_relation 
				centraldata_x               = ls_relation_x 
				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'.

				ev_key = iv_key.

				ENDIF.
				ELSE.
				* ############################################### INSERT
				*  check given business partner for org  
				lv_org = ls_data-org_id. 
				CHECK lv_org NE space.

				*  prepare bapi data  
				MOVE-CORRESPONDING ls_data TO ls_central.
				MOVE-CORRESPONDING ls_data TO ls_person.  
				MOVE-CORRESPONDING ls_data TO ls_relation.

				*  create business partner   
				CALL FUNCTION 'BAPI_BUPA_CREATE_FROM_DATA' 
				EXPORTING
				*   BUSINESSPARTNEREXTERN              = 
				partnercategory                    = '1'
				*   PARTNERGROUP                       = 
				centraldata                        = ls_central  
				centraldataperson                  = ls_person
				*   CENTRALDATAORGANIZATION            =
				*   CENTRALDATAGROUP                   =
				*   ADDRESSDATA                        =
				*   DUPLICATE_MESSAGE_TYPE             =
				*   ACCEPT_ERROR                       = ' '  
				IMPORTING
				businesspartner           				= lv_per    
				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'.

				CHECK lv_per NE space.

				*   create relation  
				CALL FUNCTION 'BAPI_BUPR_CONTP_CREATE'  
				EXPORTING     
				businesspartner              = lv_org      
				contactperson                = lv_per
				*   VALIDFROMDATE                = '00010101'
				*   VALIDUNTILDATE               = '99991231'
				*   DEFAULTRELATIONSHIP          =
				*   ADDRESSGUID                  = 
				centraldata                  = ls_relation
				*   ADDRESSDATA                  =
				*   DUPLICATE_MESSAGE_TYPE       =  
				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 key  
				CONCATENATE lv_org lv_per   
				INTO ev_key           
				SEPARATED BY '~'.

				ENDIF.

				* ------------ final BAPI Commit 
				CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'  
				EXPORTING   
				wait   = 'X'  
				IMPORTING  
				return = ls_return.
				IF ls_return-type CA 'EAX'.  
				EXIT. 
				ENDIF.

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

				ENDMETHOD.
		

Test

SAP Dokumente extern zur Verfügung stellen

Oft besteht der Wunsch, SAP Dokumente extern zur Verfügung zu stellen. Das betrifft beispielsweise gescannte Eingangsrechnungen oder Rechnungen an Kunden, die vom Kunden angefordert und elektronisch z.B. als PDF zur Verfügung stehen. Eine technische Umsetzungsempfehlung ist davon abhängig, wie die Binärdaten der gewünschten Dokumente physisch im SAP gespeichert sind. Hier gibt es beispielsweise folgende Möglichkeiten:

  • Als Anlage an einem SAPOffice-Objekt (z.B. ausgehende Mail)

  • Als binäre Daten für ältere WebRFC Funktionen

  • Als Dokument zu einem SAP Business Objekt

  • Kundenindividuelle Funktionalität zum Speichern und Lesen von Dokumenten

Für den externen Aufrufer müssen mindestens die Binärdaten, der Dokumententyp und die physische Länge verfügbar sein. D.h. die Dokumente müssen als interne Tabelle extrahiert werden können, bevor sie, für einen externen Aufrufer aufbereitet, das SAP System verlassen können. In den meisten Fällen handelt es sich um Dokumente, die physisch nicht im SAP System sondern in einem Content Server (auch Knowledge Provider), also in einem speziellen Dokumentenmanagement System vorgehalten werden (z.B. Docuware, ixOS). Eine SAP Applikation, die ein gescanntes Dokument zum SAP Business Objekt anzeigt (z.B. Eingangsrechnung) würde in solchen Fällen nur die Verknüpfungen zwischen SAP Business Objekt und binärem Dokument kennen. Für die Anzeige wird das meist externe Dokumenten Management System angewiesen werden. In den neueren SAP Versionen wird dies über einen http-Request organisiert. Dies könnte theoretisch für einen externen Aufrufer ausgenutzt werden, indem zum eigentlichen Ausliefern des Dokumentes dieser DMS-Server verwendet wird.

Dokumente aus DMS extern zur Verfügung stellen

Für den Fall, dass die gewünschten Dokumente in einem Dokumentenmanagement-System verfügbar sind, könnte das Dokument via generierter URL direkt aus dem DMS bezogen werden. Dazu muss der DMS-Server dort erreichbar sein, wo das Dokument verfügbar sein soll. Oft sind Szenarien gefordert, in dem Externe Benutzer auf das firmeninterne DMS zugreifen sollen. Es muss klar sein, dass damit der vielleicht wichtigste Server eines Unternehmens (in einem DMS liegen manchmal auch Verträge oder Technische Dokumentation) im Internet freigegeben werden muss, was eine nicht unerhebliche Sicherheitslücke bedeuten kann. Externe könnten so auch Zugang zu Dokumenten bekommen, die eigentlich für den externen Zugriff tabu sind. Zumindest ist ein gewisser Aufwand für organisatorische Aktivitäten und Sicherheitsmaßnahmen (z.B. Firewalleinrichtung) einzuplanen. Für dieses Szenario müsste ein Handler entwickelt werden, der die extern gewünschten Recherchemerkmale auswertet (z.B. Kundennummer, Datum, Stichworte), die Verknüpfung zu möglichen Dokumenten ermittelt und schließlich URLs generiert, wo die Dokumente extern verfügbar sind. Die Verknüpfungen findet man im SAP System typischerweise in den TOA*-Tabellen.

Dokumente extern replizieren

Dieses Szenario geht davon aus, dass die Dokumente als interne Tabelle im ABAP zur Verfügung stehen. Sie wären dann auch kopierbar. Ein gängiges Szenario wäre das Kopieren des Dokumentes auf das Dateisystem des externen Aufrufers. Über die Pfadinformationen wäre das Dokument dann extern verfügbar (z.B. als HTTP-Request, wenn das Dokument im Webspace eines Webservers repliziert wurde). Bei diesem Szenario werden Kopien der eigentlichen Dokumente erzeugt. Je nach Größe der Dokumente, Netzverbindung und sonstigen technischen Rahmenbedingungen können synchrone Szenarien (Anforderung / Dokument extrahieren / Dokument replizieren) praktisch unmöglich werden. Das Szenario mit Replikation von Dokumenten kann aus ABAP-Sicht recht einfach umgesetzt werden, wenn die Dokumente als interne Tabelle vorhanden sind. Die Zielpfade lassen sich meistens an den SAP Applikationsserver mounten oder via Netzwerknamen (z.B. "\\webspace\outdocs") ansprechen (z.B. über Transaktion AL11). Dann können direkt aus dem SAP mit dem Befehl OPEN DATASET …TRANSFER Daten in dieses externe Verzeichnis geschrieben werden. Soll zusätzlich der Missbrauch solcher extern abgelegter Dokumente verhindert werden, können die Dateinamen verfremdet werden. Hier eignet sich die Verwendung von Global Unique ID (GUID), da diese kaum zu merken sind. GUIDs können durch den Funktionsbaustein GUID_CREATE erzeugt werden (z.B. als 32-stellige Strings). Die nächste Stufe können die Dokumente unter Verwendung von Passworten eingepackt (z.B. ZIP) werden. Auf Windows basierenden SAP Systemen lässt sich dazu das bekannte Programm WINZIP über die Kommandozeile starten (Anregung Transaktionen SM49, SM69; Funktionsbaustein SAPXPG_START_XPG. Konsequenterweise sollte man auch dafür sorgen, dass solche Replikate auch wieder gelöscht werden. Dies kann beispielsweise über einen SAP Batch-Job oder durch periodische Skripte beim externen Aufrufer umgesetzt werden (z.B. Alle Dateien um 24:00 Uhr löschen).

Asynchrone Auslieferung der Dokumente

Die o.a. Szenarien zeigen, dass synchrone Szenarien zwar wünschenswert, machmal aber aus organisatorischer oder technischer Sicht nicht machbar sind. Hier sollte man darüber nachdenken, ob es den gewünschten Prozess wirklich sehr stört, wenn Dokumente nicht sofort zur Verfügung stehen. In vielen Fällen reicht es, wenn der Prozess von "Dokument anzeigen" in "Dokument anfordern" geändert wird. Das gewünschte Dokument wird angefordert und aysnchron ausgeliefert. Dies kann als Replikat in einem externen Webspace oder auch als Email erfolgen. Beide Szenarien sind durchaus üblich. Der Email Versand kann z.B. aus dem SAP in einem Hintergrundprozess angestoßen werden. Hier eignet sich der Funktionsbaustein SO_NEW_DOCUMENT_ATT_SEND_API1.

Dokumente aus dem Archivsystem über URL verfügbarmachen

Das folgende Beispiel stellt über den Link des Archivsystems Dokumente SAP Auftragsbestätigungen o.ä. extern zur Verfügung. Die hier generierte URL muss auch für externe erreichbar sein. Es besteht aber die Möglichkeit die SAP-typische URL durch einen anderen Präfix zu verstecken und den extern sichtbaren Präfix über Reverse Proxying (siehe Apache Dokumentation) an das SAP durchzustellen. Das Coding ermittelt erst aus dem extern mitgegebenen User-Code (z.B. SAP Geschäftspartnernummer) die relevanten Datensätze (kundeneigene Tabelle) und liest dann die entsprechenden Aufträge aus der Tabelle VBAK nach. Dann wird durch eine SAP Funktion die URL zum Dokument (falls existent) ermittelt. Voraussetzung für diese Funktion ist natürlich, dass die Archivfunktionen für die entsprechenden Business Objekte (hier Auftrag VBAK) im SAP Standard eingerichtet wurden und Dokumente (z.B. Auftragsbestätigungen) im Archiv existieren (Auftragsbestätigung drucken und ablegen). Diese Methodik kann auch für andere Dokumenttypen verwendet werden (z.B. Lieferscheine, Rechnungen). Dazu müssen die entsprechenden archivtypischen Einrichtungen im SAP erfolgt sein.

METHOD z_if_ia_ixa_intrexx_api~get_list.

				"* ---------- local data"
				DATA: ls_filter LIKE LINE OF it_filter.
				DATA: lv_user TYPE bu_partner.
				DATA: lt_f4 TYPE /tsii/fr_f4_value_t.
				DATA: ls_f4 LIKE LINE OF lt_f4.
				DATA: lr_handler TYPE REF TO /tsii/cl_bl_bp_user.
				DATA: ls_data TYPE /tsii/exix_ixa_tr_dc_vbak.
				DATA: lt_data LIKE TABLE OF ls_data.
				DATA: lv_guid TYPE /tsii/fr_id_internal.
				DATA: lt_par TYPE /tsii/fr_parameter_t.
				DATA: ls_par LIKE LINE OF lt_par.
				DATA: ls_customizing TYPE /tsii/df_cust_scenario.
				DATA: lv_url TYPE string.

				"* --------- macros"
				DEFINE append_par.
				clear ls_par.
				ls_par-param = &1. 
				ls_par-value = &2.
				append ls_par to lt_par.
				END-OF-DEFINITION.

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

				"* --------- check inbound parameter – get external user"
				READ TABLE it_filter INTO ls_filter
				WITH KEY fieldname = 'USER'
				operand   = 'EQ'.
				IF sy-subrc NE 0.
				EXIT.
				ELSE.
				* --------- add leading 0
				lv_user = ls_filter-value_low.
				CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
				EXPORTING
				input  = lv_user
				IMPORTING
				output = lv_user.
				ENDIF.

				"* ---------- get all orders (from table VBAK depending of another table)"
				DATA: lt_iba TYPE TABLE OF /tsii/m_enpriba.
				DATA: lt_vbak TYPE TABLE OF vbak.
				DATA: ls_vbak TYPE vbak.

				* ---------- get orders orderes by given user
				SELECT * FROM /tsii/m_enpriba
				INTO TABLE lt_iba
				WHERE basket_user EQ lv_user.
				CHECK NOT lt_iba[] IS INITIAL.

				"* ---------- get depending vbak record"
				SELECT * FROM vbak
				INTO TABLE lt_vbak
				FOR ALL ENTRIES IN lt_iba
				WHERE vbeln = lt_iba-basket_id.
				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-user = lv_user.

				*   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   = '/TSII/EXIX_IXA_TR_DC_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.
		

Weitere Informationen

Allgemeines

Installation

Verbindung erstellen

Integration in Applikationen

SAP Skript Generator

SAP Trust Manager SSO configuration

API Beschreibung Teil 1 - Übersicht

API Beschreibung Teil 2 - SAP Portal Plugin

API Beschreibung Teil 3 - Implementierung eigener Verarbeitungsmodule

Entwicklerhandbuch Teil 1

Entwicklerhandbuch Teil 2 - Integrationsszenario SAP-Fremddatengruppe

Entwicklerhandbuch Teil 3 - Integrationsszenario Skripting

Entwicklerhandbuch Teil 4 - Personalisierter SAP Zugriff / Single Sign On (SSO)

Entwicklerhandbuch Teil 5 - Addons

Entwicklerhandbuch Anhang

Entwicklerhandbuch - Mustercodings