ABAP Cloud in S/4HANA Public Cloud ermöglicht Unternehmen, das SAP-Standardsystem um eigene Geschäftslogik zu erweitern - ohne den Clean Core zu gefährden. Dieser Artikel erklärt die Besonderheiten, verfügbaren APIs und praktischen Einsatzszenarien.
S/4HANA Public Cloud vs. BTP ABAP Environment
SAP bietet zwei Umgebungen für ABAP Cloud-Entwicklung:
| Aspekt | S/4HANA Public Cloud | BTP ABAP Environment |
|---|---|---|
| Bezeichnung | Embedded Steampunk | Steampunk |
| Zweck | Standard erweitern | Neue Apps entwickeln |
| Datenhaltung | Im S/4HANA-System | Eigene Datenbank |
| APIs | S/4HANA Released APIs | BTP Released APIs |
| Extensibility | On-Stack | Side-by-Side |
| Deployment | Teil von S/4HANA | Eigene BTP-Instanz |
| Updates | Quartalsweise durch SAP | Selbst gesteuert |
| Lizenzierung | S/4HANA Cloud Lizenz | Separate BTP-Lizenz |
Wann S/4HANA Public Cloud wählen?
S/4HANA Public Cloud Extensibility ist ideal für:
- Erweiterungen des Standards ohne separate Infrastruktur
- Zugriff auf S/4HANA-Daten ohne Integration
- Schnelle Time-to-Value durch direkten Zugang zu Geschäftsdaten
- Konsistente User Experience innerhalb einer Systemlandschaft
Wann BTP ABAP Environment?
BTP ABAP Environment passt besser für:
- Komplett neue Anwendungen ohne S/4HANA-Abhängigkeit
- Side-by-Side-Extensions mit eigener Datenbank
- Multi-Cloud-Szenarien (AWS, Azure, GCP)
- Unabhängige Release-Zyklen vom S/4HANA-Kernsystem
Architektur in S/4HANA Public Cloud
3-System-Landschaft
S/4HANA Public Cloud nutzt eine feste 3-System-Landschaft:
┌─────────────────────────────────────────────────────────┐│ SAP-verwaltete Landschaft │├─────────────────┬─────────────────┬─────────────────────┤│ Development │ Test │ Production ││ (DEV) │ (TST/QAS) │ (PRD) │├─────────────────┼─────────────────┼─────────────────────┤│ Entwicklung │ Integrations- │ Produktiver ││ & Unit Tests │ tests │ Betrieb │├─────────────────┼─────────────────┼─────────────────────┤│ ABAP Cloud │ Transportierte │ Transportierte ││ Entwickler │ Objekte testen │ Objekte aktiv │└─────────────────┴─────────────────┴─────────────────────┘ │ │ │ └───── Transport ─────► Transport ──┘ (automatisiert über SAP-Prozesse)Transportwesen
Der Transport in S/4HANA Public Cloud unterscheidet sich vom On-Premise-Modell:
| Aspekt | S/4HANA Public Cloud | On-Premise |
|---|---|---|
| Transportsteuerung | SAP-verwaltet | Eigenverantwortlich |
| Transportroute | DEV → TST → PRD (fest) | Frei konfigurierbar |
| Release-Zyklus | Mit SAP-Updates | Individuell |
| Konfliktprüfung | Automatisiert | Manuell |
| Zurücksetzen | Eingeschränkt | Flexibel |
Software Component Konzept
Entwicklungsobjekte werden in Software Components organisiert:
" Software Component Struktur" /NAMESPACE/COMPONENT_NAME
" Beispiel-Struktur:" ZEXT_SALES" ├── ZEXT_SALES_CDS " CDS Views" ├── ZEXT_SALES_BP " Behavior Pools" ├── ZEXT_SALES_IF " Interfaces" └── ZEXT_SALES_CL " KlassenSoftware Components werden über Adaptation Transport Organizer (ATO) verwaltet:
- Clone Repository: Software Component aus Git klonen
- Pull: Änderungen vom Remote-Repository holen
- Checkout: Branch für Entwicklung auschecken
- Release: Änderungen freigeben und transportieren
Verfügbare APIs und Einschränkungen
Released APIs in S/4HANA Public Cloud
S/4HANA Public Cloud stellt eine kuratierte Menge an APIs bereit:
" Prüfen, ob eine API released ist:" In ADT: Rechtsklick → Properties → API State
" Released APIs haben:" - Stability Contract: Released" - Visibility: Public" - Cloud-Kompatibilität: JaKategorien von Released APIs
| Kategorie | Beispiele | Verwendung |
|---|---|---|
| RAP BOs | I_BusinessPartner, I_SalesOrder | Geschäftsobjekte lesen/ändern |
| CDS Views | I_Product, I_CostCenter | Daten abfragen |
| BAPI-Wrapper | CL_BAPI_* Klassen | Legacy-Funktionen nutzen |
| XCO Library | XCO_CP_*, XCO_CDS | Metadaten & Generierung |
| ABAP Cloud APIs | CL_ABAP_, CL_HTTP_ | Basis-Funktionen |
Wichtige Einschränkungen
" ❌ Nicht erlaubt in S/4HANA Public Cloud:
" Direkte Tabellenzugriffe auf SAP-TabellenSELECT * FROM mara INTO TABLE @lt_mara. " Verboten!
" Nicht freigegebene FunktionsbausteineCALL FUNCTION 'BAPI_MATERIAL_GET_DETAIL'. " Verboten!
" Klassische ALV-ReportsCALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'. " Verboten!
" SAP GUI-TransaktionenCALL TRANSACTION 'MM03'. " Verboten!" ✅ Stattdessen Released APIs nutzen:
" CDS Views für DatenabfrageSELECT * FROM I_Product WHERE Product = @lv_product INTO TABLE @DATA(lt_products).
" RAP für GeschäftslogikDATA(lo_product) = cl_product_api=>create_instance( ).lo_product->get_details( EXPORTING iv_product = lv_product IMPORTING es_details = ls_details ).
" OData Services für Integration" → Fiori Elements Apps nutzenAPI-Verfügbarkeit prüfen
CLASS zcl_api_checker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. INTERFACES if_oo_adt_classrun.ENDCLASS.
CLASS zcl_api_checker IMPLEMENTATION. METHOD if_oo_adt_classrun~main. " XCO nutzen, um API-Status zu prüfen DATA(lo_class) = xco_cp_abap_repository=>object->clas->for( 'CL_ABAP_RANDOM' ).
IF lo_class->exists( ). DATA(lv_api_state) = lo_class->content( )->get_api_state( )->get_release_state( ).
out->write( |API State: { lv_api_state }| ). ENDIF.
" CDS View prüfen DATA(lo_view) = xco_cp_cds=>view( 'I_PRODUCT' ). IF lo_view->exists( ). out->write( 'I_PRODUCT ist verfügbar' ). ENDIF. ENDMETHOD.ENDCLASS.Developer Extensibility in Public Cloud
Extensibility-Optionen
S/4HANA Public Cloud bietet mehrere Extensibility-Ebenen:
┌─────────────────────────────────────────────────┐│ Extensibility-Pyramide │├─────────────────────────────────────────────────┤│ ▲ Custom Applications (RAP Business Objects) ││ │ ───────────────────────────────────────── ││ │ Behavior Extensions (RAP Erweiterungen) ││ │ ───────────────────────────────────────── ││ │ CDS View Extensions (Felderweiterungen) ││ │ ───────────────────────────────────────── ││ │ BAdI Implementations (Geschäftslogik) ││ │ ───────────────────────────────────────── ││ ▼ Key User Extensibility (No-Code) │└─────────────────────────────────────────────────┘ Komplexität ▲ ▼ EinfachheitBAdI-Implementierungen
Released BAdIs ermöglichen Erweiterungen der Standardlogik:
CLASS zcl_badi_salesorder DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. " BAdI für Sales Order Erweiterung INTERFACES if_sd_sales_order_create.ENDCLASS.
CLASS zcl_badi_salesorder IMPLEMENTATION. METHOD if_sd_sales_order_create~validate. " Eigene Validierung bei Auftragsanlage LOOP AT it_sales_order_item ASSIGNING FIELD-SYMBOL(<ls_item>). " Prüfe Mindestbestellmenge für bestimmte Kunden IF <ls_item>-sold_to_party IN lr_vip_customers AND <ls_item>-order_quantity < 100.
APPEND VALUE #( item_number = <ls_item>-item_number message = 'VIP-Kunden: Mindestbestellmenge 100 Stück' severity = 'E' ) TO ct_messages. ENDIF. ENDLOOP. ENDMETHOD.ENDCLASS.RAP Behavior Extensions
Standard-RAP-Business-Objects können erweitert werden:
" Behavior Extension für I_SalesOrderTP" (wenn von SAP für Erweiterung freigegeben)
extension using interface /sap/bc/i_salesordertp_extimplementation in class zbp_ext_salesorder unique;
extend behavior for SalesOrder{ " Zusätzliche Validierung validation validateCustomPriority on save { field CustomerPriority; }
" Zusätzliche Determination determination setDefaultPriority on modify { field SoldToParty; }
" Zusätzliche Action action ( features : instance ) escalatePriority result [1] $self;}CLASS zbp_ext_salesorder DEFINITION PUBLIC ABSTRACT FINAL FOR BEHAVIOR OF i_salesordertp_ext.ENDCLASS.
CLASS zbp_ext_salesorder IMPLEMENTATION. METHOD validateCustomPriority. " Eigene Validierungslogik READ ENTITIES OF i_salesordertp_ext IN LOCAL MODE ENTITY SalesOrder FIELDS ( CustomerPriority SoldToParty ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_orders).
LOOP AT lt_orders ASSIGNING FIELD-SYMBOL(<ls_order>). IF <ls_order>-CustomerPriority IS INITIAL. APPEND VALUE #( %tky = <ls_order>-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = 'Kundenpriorität muss gepflegt werden' ) ) TO reported-salesorder.
APPEND VALUE #( %tky = <ls_order>-%tky ) TO failed-salesorder. ENDIF. ENDLOOP. ENDMETHOD.
METHOD setDefaultPriority. " Standardpriorität basierend auf Kunde setzen READ ENTITIES OF i_salesordertp_ext IN LOCAL MODE ENTITY SalesOrder FIELDS ( SoldToParty CustomerPriority ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_orders).
LOOP AT lt_orders ASSIGNING FIELD-SYMBOL(<ls_order>) WHERE CustomerPriority IS INITIAL.
" Prüfe Kundenkategorie SELECT SINGLE CustomerClassification FROM I_Customer WHERE Customer = @<ls_order>-SoldToParty INTO @DATA(lv_classification).
DATA(lv_priority) = SWITCH #( lv_classification WHEN 'A' THEN 'HIGH' WHEN 'B' THEN 'MEDIUM' ELSE 'LOW' ).
MODIFY ENTITIES OF i_salesordertp_ext IN LOCAL MODE ENTITY SalesOrder UPDATE FIELDS ( CustomerPriority ) WITH VALUE #( ( %tky = <ls_order>-%tky CustomerPriority = lv_priority ) ). ENDLOOP. ENDMETHOD.ENDCLASS.Custom RAP Business Objects
In S/4HANA Public Cloud können eigene RAP Business Objects erstellt werden:
Beispiel: Kundenanfragen-Management
Schritt 1: Datenbanktabelle definieren
@EndUserText.label : 'Customer Inquiries'@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE@AbapCatalog.tableCategory : #TRANSPARENT@AbapCatalog.deliveryClass : #Adefine table zinquiry { key client : abap.clnt not null; key inquiry_id : sysuuid_x16 not null; customer : kunnr; inquiry_type : abap.char(4); subject : abap.char(100); description : abap.string(0); priority : abap.char(1); status : abap.char(2); created_by : abap.uname; created_at : timestampl; changed_by : abap.uname; changed_at : timestampl;}Schritt 2: CDS View mit Annotationen
@AccessControl.authorizationCheck: #CHECK@Metadata.allowExtensions: true@EndUserText.label: 'Customer Inquiry'define root view entity ZI_Inquiry as select from zinquiry association [0..1] to I_Customer as _Customer on $projection.Customer = _Customer.Customer{ key inquiry_id as InquiryId, customer as Customer, inquiry_type as InquiryType, subject as Subject, description as Description, priority as Priority, status as Status,
@Semantics.user.createdBy: true created_by as CreatedBy, @Semantics.systemDateTime.createdAt: true created_at as CreatedAt, @Semantics.user.lastChangedBy: true changed_by as ChangedBy, @Semantics.systemDateTime.lastChangedAt: true changed_at as ChangedAt,
_Customer}Schritt 3: Behavior Definition
managed implementation in class zbp_i_inquiry unique;strict ( 2 );with draft;
define behavior for ZI_Inquiry alias Inquirypersistent table zinquirydraft table zinquiry_dlock master total etag ChangedAtauthorization master ( instance )etag master ChangedAt{ create; update; delete;
field ( readonly ) InquiryId, CreatedBy, CreatedAt, ChangedBy, ChangedAt; field ( mandatory ) Customer, InquiryType, Subject;
determination setInquiryId on save { create; } determination setDefaultStatus on modify { create; }
validation validateCustomer on save { field Customer; } validation validatePriority on save { field Priority; }
action ( features : instance ) escalate result [1] $self; action ( features : instance ) close result [1] $self;
draft action Edit; draft action Activate optimized; draft action Discard; draft action Resume; draft determine action Prepare;
mapping for zinquiry corresponding { InquiryId = inquiry_id; Customer = customer; InquiryType = inquiry_type; Subject = subject; Description = description; Priority = priority; Status = status; CreatedBy = created_by; CreatedAt = created_at; ChangedBy = changed_by; ChangedAt = changed_at; }}Schritt 4: Behavior Implementation
CLASS zbp_i_inquiry DEFINITION PUBLIC ABSTRACT FINAL FOR BEHAVIOR OF zi_inquiry.
PRIVATE SECTION. CONSTANTS: BEGIN OF gc_status, open TYPE c LENGTH 2 VALUE '01', in_process TYPE c LENGTH 2 VALUE '02', escalated TYPE c LENGTH 2 VALUE '03', closed TYPE c LENGTH 2 VALUE '04', END OF gc_status.ENDCLASS.
CLASS zbp_i_inquiry IMPLEMENTATION. METHOD setInquiryId. READ ENTITIES OF zi_inquiry IN LOCAL MODE ENTITY Inquiry FIELDS ( InquiryId ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_inquiries).
DATA lt_inquiries_update TYPE TABLE FOR UPDATE zi_inquiry.
LOOP AT lt_inquiries ASSIGNING FIELD-SYMBOL(<ls_inquiry>) WHERE InquiryId IS INITIAL.
TRY. DATA(lv_uuid) = cl_system_uuid=>create_uuid_x16_static( ). CATCH cx_uuid_error. CONTINUE. ENDTRY.
APPEND VALUE #( %tky = <ls_inquiry>-%tky InquiryId = lv_uuid %control-InquiryId = if_abap_behv=>mk-on ) TO lt_inquiries_update. ENDLOOP.
MODIFY ENTITIES OF zi_inquiry IN LOCAL MODE ENTITY Inquiry UPDATE FIELDS ( InquiryId ) WITH lt_inquiries_update. ENDMETHOD.
METHOD setDefaultStatus. READ ENTITIES OF zi_inquiry IN LOCAL MODE ENTITY Inquiry FIELDS ( Status ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_inquiries).
DATA lt_inquiries_update TYPE TABLE FOR UPDATE zi_inquiry.
LOOP AT lt_inquiries ASSIGNING FIELD-SYMBOL(<ls_inquiry>) WHERE Status IS INITIAL.
APPEND VALUE #( %tky = <ls_inquiry>-%tky Status = gc_status-open %control-Status = if_abap_behv=>mk-on ) TO lt_inquiries_update. ENDLOOP.
MODIFY ENTITIES OF zi_inquiry IN LOCAL MODE ENTITY Inquiry UPDATE FIELDS ( Status ) WITH lt_inquiries_update. ENDMETHOD.
METHOD validateCustomer. READ ENTITIES OF zi_inquiry IN LOCAL MODE ENTITY Inquiry FIELDS ( Customer ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_inquiries).
" Sammle alle Kunden für Massenprüfung DATA lt_customers TYPE SORTED TABLE OF kunnr WITH UNIQUE KEY table_line. LOOP AT lt_inquiries ASSIGNING FIELD-SYMBOL(<ls_inquiry>). INSERT <ls_inquiry>-Customer INTO TABLE lt_customers. ENDLOOP.
" Prüfe Existenz über Released CDS View SELECT Customer FROM I_Customer WHERE Customer IN @lt_customers INTO TABLE @DATA(lt_valid_customers).
" Validiere LOOP AT lt_inquiries ASSIGNING <ls_inquiry>. IF NOT line_exists( lt_valid_customers[ Customer = <ls_inquiry>-Customer ] ). APPEND VALUE #( %tky = <ls_inquiry>-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = |Kunde { <ls_inquiry>-Customer } existiert nicht| ) ) TO reported-inquiry.
APPEND VALUE #( %tky = <ls_inquiry>-%tky ) TO failed-inquiry. ENDIF. ENDLOOP. ENDMETHOD.
METHOD validatePriority. READ ENTITIES OF zi_inquiry IN LOCAL MODE ENTITY Inquiry FIELDS ( Priority ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_inquiries).
LOOP AT lt_inquiries ASSIGNING FIELD-SYMBOL(<ls_inquiry>). IF <ls_inquiry>-Priority NOT IN VALUE #( ( 'H' ) ( 'M' ) ( 'L' ) ). APPEND VALUE #( %tky = <ls_inquiry>-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = 'Priorität muss H (Hoch), M (Mittel) oder L (Niedrig) sein' ) ) TO reported-inquiry.
APPEND VALUE #( %tky = <ls_inquiry>-%tky ) TO failed-inquiry. ENDIF. ENDLOOP. ENDMETHOD.
METHOD escalate. " Status auf Eskaliert setzen MODIFY ENTITIES OF zi_inquiry IN LOCAL MODE ENTITY Inquiry UPDATE FIELDS ( Status Priority ) WITH VALUE #( FOR key IN keys ( %tky = key-%tky Status = gc_status-escalated Priority = 'H' " Automatisch hohe Priorität %control-Status = if_abap_behv=>mk-on %control-Priority = if_abap_behv=>mk-on ) ).
" Ergebnis zurückgeben READ ENTITIES OF zi_inquiry IN LOCAL MODE ENTITY Inquiry ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(lt_inquiries).
result = VALUE #( FOR inquiry IN lt_inquiries ( %tky = inquiry-%tky %param = inquiry ) ). ENDMETHOD.
METHOD close. MODIFY ENTITIES OF zi_inquiry IN LOCAL MODE ENTITY Inquiry UPDATE FIELDS ( Status ) WITH VALUE #( FOR key IN keys ( %tky = key-%tky Status = gc_status-closed %control-Status = if_abap_behv=>mk-on ) ).
READ ENTITIES OF zi_inquiry IN LOCAL MODE ENTITY Inquiry ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(lt_inquiries).
result = VALUE #( FOR inquiry IN lt_inquiries ( %tky = inquiry-%tky %param = inquiry ) ). ENDMETHOD.
METHOD get_instance_features. READ ENTITIES OF zi_inquiry IN LOCAL MODE ENTITY Inquiry FIELDS ( Status ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_inquiries).
result = VALUE #( FOR inquiry IN lt_inquiries ( %tky = inquiry-%tky " Escalate nur möglich wenn nicht schon eskaliert oder geschlossen %action-escalate = COND #( WHEN inquiry-Status = gc_status-escalated OR inquiry-Status = gc_status-closed THEN if_abap_behv=>fc-o-disabled ELSE if_abap_behv=>fc-o-enabled ) " Close nur möglich wenn nicht schon geschlossen %action-close = COND #( WHEN inquiry-Status = gc_status-closed THEN if_abap_behv=>fc-o-disabled ELSE if_abap_behv=>fc-o-enabled ) ) ). ENDMETHOD.ENDCLASS.Praktisches Beispiel: Integration mit Standard
Ein häufiges Szenario ist die Integration eigener Objekte mit S/4HANA-Standard:
Kundenanfragen mit Kundenstamm verknüpfen
CLASS zcl_inquiry_customer_integration DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. INTERFACES if_oo_adt_classrun.
TYPES: BEGIN OF ty_customer_inquiries, customer_id TYPE kunnr, customer_name TYPE bu_name1st, open_inquiries TYPE i, avg_resolution TYPE i, END OF ty_customer_inquiries.
METHODS get_customer_inquiry_stats RETURNING VALUE(rt_stats) TYPE STANDARD TABLE OF ty_customer_inquiries.ENDCLASS.
CLASS zcl_inquiry_customer_integration IMPLEMENTATION. METHOD if_oo_adt_classrun~main. DATA(lt_stats) = get_customer_inquiry_stats( ).
out->write( 'Kundenanfragen-Statistik:' ). out->write( '─────────────────────────────────────────────' ).
LOOP AT lt_stats ASSIGNING FIELD-SYMBOL(<ls_stat>). out->write( |Kunde: { <ls_stat>-customer_name }| ). out->write( | Offene Anfragen: { <ls_stat>-open_inquiries }| ). out->write( | Ø Bearbeitungszeit: { <ls_stat>-avg_resolution } Tage| ). out->write( '' ). ENDLOOP. ENDMETHOD.
METHOD get_customer_inquiry_stats. " Kombiniere eigene Tabelle mit S/4HANA Kundenstamm SELECT i~customer AS customer_id, c~CustomerName AS customer_name, COUNT( CASE WHEN i~status <> '04' THEN 1 END ) AS open_inquiries, AVG( DATS_DAYS_BETWEEN( i~created_at, CASE WHEN i~status = '04' THEN i~changed_at ELSE @sy-datum END ) ) AS avg_resolution FROM zinquiry AS i INNER JOIN I_Customer AS c ON i~customer = c~Customer GROUP BY i~customer, c~CustomerName INTO TABLE @rt_stats. ENDMETHOD.ENDCLASS.OData Service für Fiori App
" Service Definition@EndUserText.label: 'Inquiry Service'define service ZUI_INQUIRY_O4 { expose ZC_Inquiry as Inquiry;}
" Consumption View mit UI-Annotationen@AccessControl.authorizationCheck: #CHECK@Metadata.allowExtensions: true@UI.headerInfo: { typeName: 'Kundenanfrage', typeNamePlural: 'Kundenanfragen', title: { value: 'Subject' }, description: { value: 'Customer' }}define view entity ZC_Inquiry as projection on ZI_Inquiry{ @UI.facet: [{ id: 'GeneralInfo', type: #IDENTIFICATION_REFERENCE, label: 'Allgemeine Informationen', position: 10 }]
@UI.lineItem: [{ position: 10 }] @UI.identification: [{ position: 10 }] key InquiryId,
@UI.lineItem: [{ position: 20 }] @UI.identification: [{ position: 20 }] @UI.selectionField: [{ position: 10 }] @Consumption.valueHelpDefinition: [{ entity: { name: 'I_Customer', element: 'Customer' } }] Customer,
@UI.lineItem: [{ position: 30 }] @UI.identification: [{ position: 30 }] @UI.selectionField: [{ position: 20 }] InquiryType,
@UI.lineItem: [{ position: 40 }] @UI.identification: [{ position: 40 }] Subject,
@UI.identification: [{ position: 50 }] Description,
@UI.lineItem: [{ position: 50, criticality: 'PriorityCriticality' }] @UI.identification: [{ position: 60 }] @UI.selectionField: [{ position: 30 }] Priority,
@UI.lineItem: [{ position: 60, criticality: 'StatusCriticality' }] @UI.identification: [{ position: 70 }] @UI.selectionField: [{ position: 40 }] Status,
@UI.lineItem: [{ position: 70 }] CreatedAt,
CreatedBy, ChangedAt, ChangedBy,
" Criticality für Semantic Coloring case Priority when 'H' then 1 " Rot when 'M' then 2 " Gelb else 3 " Grün end as PriorityCriticality,
case Status when '03' then 1 " Eskaliert = Rot when '01' then 2 " Offen = Gelb when '02' then 2 " In Bearbeitung = Gelb else 3 " Geschlossen = Grün end as StatusCriticality,
_Customer}Best Practices für S/4HANA Public Cloud
DO: Empfohlene Praktiken
✅ Nur Released APIs verwenden✅ Software Components für Modularität nutzen✅ Unit Tests schreiben (ABAP Unit)✅ Clean ABAP Guidelines befolgen✅ Dokumentation in ABAP Doc pflegen✅ Feature Control für Actions nutzen✅ Authorization Checks implementierenDON’T: Zu vermeidende Praktiken
❌ Direkte Zugriffe auf SAP-Tabellen❌ Nicht freigegebene APIs verwenden❌ Hardcoded System-IDs oder Mandanten❌ Synchrone HTTP-Aufrufe in Transaktionen❌ Lange laufende Prozesse ohne Background Processing❌ Komplexe Logik ohne ModularisierungCheckliste vor dem Transport
| Prüfpunkt | Erledigt |
|---|---|
| ATC-Prüfung bestanden (ABAP Cloud Variante) | ☐ |
| Unit Tests vorhanden und erfolgreich | ☐ |
| Authorization Checks implementiert | ☐ |
| Keine nicht-freigegebenen APIs | ☐ |
| Dokumentation aktuell | ☐ |
| Performance-Tests durchgeführt | ☐ |
Weiterführende Themen
- Steampunk vs. Embedded Steampunk - Detailvergleich der Architekturen
- Developer Extensibility - Erweiterungsmechanismen im Detail
- RAP Basics - Grundlagen des RESTful Application Programming Model
- Clean ABAP - Coding Guidelines für wartbaren Code
- Key User Extensibility - Erweiterungen ohne Entwicklerzugriff