ABAP Cloud dans S/4HANA Public Cloud : Developpement & Extensibilite

Catégorie
ABAP Cloud
Publié
Auteur
Johannes

ABAP Cloud dans S/4HANA Public Cloud permet aux entreprises d’etendre le systeme standard SAP avec leur propre logique metier - sans compromettre le Clean Core. Cet article explique les particularites, les APIs disponibles et les scenarios d’utilisation pratiques.

S/4HANA Public Cloud vs. BTP ABAP Environment

SAP propose deux environnements pour le developpement ABAP Cloud :

AspectS/4HANA Public CloudBTP ABAP Environment
DesignationEmbedded SteampunkSteampunk
ObjectifEtendre le standardDevelopper de nouvelles apps
Stockage des donneesDans le systeme S/4HANABase de donnees propre
APIsAPIs Released S/4HANAAPIs Released BTP
ExtensibiliteOn-StackSide-by-Side
DeploiementPartie de S/4HANAInstance BTP separee
Mises a jourTrimestrielles par SAPAuto-gerees
LicenceLicence S/4HANA CloudLicence BTP separee

Quand choisir S/4HANA Public Cloud ?

L’extensibilite S/4HANA Public Cloud est ideale pour :

  • Extensions du standard sans infrastructure separee
  • Acces aux donnees S/4HANA sans integration
  • Time-to-Value rapide grace a l’acces direct aux donnees metier
  • Experience utilisateur coherente au sein d’un meme paysage systeme

Quand BTP ABAP Environment ?

BTP ABAP Environment convient mieux pour :

  • Applications entierement nouvelles sans dependance S/4HANA
  • Extensions Side-by-Side avec leur propre base de donnees
  • Scenarios Multi-Cloud (AWS, Azure, GCP)
  • Cycles de release independants du systeme S/4HANA central

Architecture dans S/4HANA Public Cloud

Paysage 3 systemes

S/4HANA Public Cloud utilise un paysage fixe a 3 systemes :

┌─────────────────────────────────────────────────────────┐
│ Paysage gere par SAP │
├─────────────────┬─────────────────┬─────────────────────┤
│ Developpement │ Test │ Production │
│ (DEV) │ (TST/QAS) │ (PRD) │
├─────────────────┼─────────────────┼─────────────────────┤
│ Developpement │ Tests d' │ Exploitation │
│ & tests unit. │ integration │ productive │
├─────────────────┼─────────────────┼─────────────────────┤
│ Developpeurs │ Objets │ Objets │
│ ABAP Cloud │ transportes │ transportes │
│ │ testes │ actifs │
└─────────────────┴─────────────────┴─────────────────────┘
│ │ │
└───── Transport ─────► Transport ──┘
(automatise via processus SAP)

Systeme de transport

Le transport dans S/4HANA Public Cloud differe du modele On-Premise :

AspectS/4HANA Public CloudOn-Premise
Gestion transportGeree par SAPResponsabilite propre
Route de transportDEV → TST → PRD (fixe)Configurable librement
Cycle de releaseAvec mises a jour SAPIndividuel
Verification conflitsAutomatiseeManuelle
Retour arriereLimiteFlexible

Concept Software Component

Les objets de developpement sont organises en Software Components :

" Structure Software Component
" /NAMESPACE/COMPONENT_NAME
" Exemple de structure:
" ZEXT_SALES
" ├── ZEXT_SALES_CDS " CDS Views
" ├── ZEXT_SALES_BP " Behavior Pools
" ├── ZEXT_SALES_IF " Interfaces
" └── ZEXT_SALES_CL " Classes

Les Software Components sont geres via Adaptation Transport Organizer (ATO) :

  1. Clone Repository : Cloner le Software Component depuis Git
  2. Pull : Recuperer les modifications du repository distant
  3. Checkout : Checkout de la branche pour developpement
  4. Release : Liberer les modifications et transporter

APIs disponibles et restrictions

APIs Released dans S/4HANA Public Cloud

S/4HANA Public Cloud fournit un ensemble curate d’APIs :

" Verifier si une API est released:
" Dans ADT: Clic droit → Properties → API State
" Les APIs Released ont:
" - Stability Contract: Released
" - Visibility: Public
" - Compatibilite Cloud: Oui

Categories d’APIs Released

CategorieExemplesUtilisation
RAP BOsI_BusinessPartner, I_SalesOrderLire/modifier objets metier
CDS ViewsI_Product, I_CostCenterInterroger les donnees
BAPI-WrapperClasses CL_BAPI_*Utiliser les fonctions legacy
Librairie XCOXCO_CP_*, XCO_CDSMetadonnees & generation
APIs ABAP CloudCL_ABAP_, CL_HTTP_Fonctions de base

Restrictions importantes

" ❌ Non autorise dans S/4HANA Public Cloud:
" Acces directs aux tables SAP
SELECT * FROM mara INTO TABLE @lt_mara. " Interdit!
" Modules de fonction non liberes
CALL FUNCTION 'BAPI_MATERIAL_GET_DETAIL'. " Interdit!
" Reports ALV classiques
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'. " Interdit!
" Transactions SAP GUI
CALL TRANSACTION 'MM03'. " Interdit!
" ✅ Utiliser les APIs Released a la place:
" CDS Views pour l'interrogation des donnees
SELECT * FROM I_Product
WHERE Product = @lv_product
INTO TABLE @DATA(lt_products).
" RAP pour la logique metier
DATA(lo_product) = cl_product_api=>create_instance( ).
lo_product->get_details( EXPORTING iv_product = lv_product
IMPORTING es_details = ls_details ).
" Services OData pour l'integration
" → Utiliser les Apps Fiori Elements

Verifier la disponibilite des APIs

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.
" Utiliser XCO pour verifier le statut API
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.
" Verifier une CDS View
DATA(lo_view) = xco_cp_cds=>view( 'I_PRODUCT' ).
IF lo_view->exists( ).
out->write( 'I_PRODUCT est disponible' ).
ENDIF.
ENDMETHOD.
ENDCLASS.

Developer Extensibility dans Public Cloud

Options d’extensibilite

S/4HANA Public Cloud offre plusieurs niveaux d’extensibilite :

┌─────────────────────────────────────────────────┐
│ Pyramide d'extensibilite │
├─────────────────────────────────────────────────┤
│ ▲ Custom Applications (RAP Business Objects) │
│ │ ───────────────────────────────────────── │
│ │ Behavior Extensions (Extensions RAP) │
│ │ ───────────────────────────────────────── │
│ │ CDS View Extensions (Extensions de champs) │
│ │ ───────────────────────────────────────── │
│ │ BAdI Implementations (Logique metier) │
│ │ ───────────────────────────────────────── │
│ ▼ Key User Extensibility (No-Code) │
└─────────────────────────────────────────────────┘
Complexite ▲ ▼ Simplicite

Implementations BAdI

Les BAdIs Released permettent des extensions de la logique standard :

CLASS zcl_badi_salesorder DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
" BAdI pour extension Sales Order
INTERFACES if_sd_sales_order_create.
ENDCLASS.
CLASS zcl_badi_salesorder IMPLEMENTATION.
METHOD if_sd_sales_order_create~validate.
" Propre validation a la creation de commande
LOOP AT it_sales_order_item ASSIGNING FIELD-SYMBOL(<ls_item>).
" Verifier quantite minimum pour certains clients
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 = 'Clients VIP: Quantite minimum 100 pieces"
severity = 'E"
) TO ct_messages.
ENDIF.
ENDLOOP.
ENDMETHOD.
ENDCLASS.

RAP Behavior Extensions

Les RAP Business Objects standard peuvent etre etendus :

" Behavior Extension pour I_SalesOrderTP
" (si libere par SAP pour extension)
extension using interface /sap/bc/i_salesordertp_ext
implementation in class zbp_ext_salesorder unique;
extend behavior for SalesOrder
{
" Validation supplementaire
validation validateCustomPriority on save
{ field CustomerPriority; }
" Determination supplementaire
determination setDefaultPriority on modify
{ field SoldToParty; }
" Action supplementaire
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.
" Propre logique de validation
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 = 'La priorite client doit etre renseignee"
)
) TO reported-salesorder.
APPEND VALUE #( %tky = <ls_order>-%tky ) TO failed-salesorder.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD setDefaultPriority.
" Definir la priorite par defaut selon le client
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.
" Verifier la categorie client
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

Dans S/4HANA Public Cloud, des RAP Business Objects propres peuvent etre crees :

Exemple : Gestion des demandes clients

Etape 1 : Definir la table de base de donnees

@EndUserText.label : 'Customer Inquiries"
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
define 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;
}

Etape 2 : CDS View avec annotations

@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
}

Etape 3 : Behavior Definition

managed implementation in class zbp_i_inquiry unique;
strict ( 2 );
with draft;
define behavior for ZI_Inquiry alias Inquiry
persistent table zinquiry
draft table zinquiry_d
lock master total etag ChangedAt
authorization 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;
}
}

Etape 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).
" Collecter tous les clients pour verification en masse
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.
" Verifier l'existence via CDS View Released
SELECT Customer
FROM I_Customer
WHERE Customer IN @lt_customers
INTO TABLE @DATA(lt_valid_customers).
" Valider
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 = |Client { <ls_inquiry>-Customer } n'existe pas|
)
) 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 = 'La priorite doit etre H (Haute), M (Moyenne) ou L (Basse)"
)
) TO reported-inquiry.
APPEND VALUE #( %tky = <ls_inquiry>-%tky ) TO failed-inquiry.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD escalate.
" Mettre le statut a Escalade
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' " Automatiquement haute priorite
%control-Status = if_abap_behv=>mk-on
%control-Priority = if_abap_behv=>mk-on
) ).
" Retourner le resultat
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 uniquement possible si pas deja escalade ou ferme
%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 uniquement possible si pas deja ferme
%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.

Exemple pratique : Integration avec le standard

Un scenario frequent est l’integration d’objets propres avec le standard S/4HANA :

Lier les demandes clients avec la fiche client

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( 'Statistiques demandes clients:' ).
out->write( '─────────────────────────────────────────────' ).
LOOP AT lt_stats ASSIGNING FIELD-SYMBOL(<ls_stat>).
out->write( |Client: { <ls_stat>-customer_name }| ).
out->write( | Demandes ouvertes: { <ls_stat>-open_inquiries }| ).
out->write( | Temps moyen traitement: { <ls_stat>-avg_resolution } jours| ).
out->write( '' ).
ENDLOOP.
ENDMETHOD.
METHOD get_customer_inquiry_stats.
" Combiner sa propre table avec la fiche client S/4HANA
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.

Service OData pour App Fiori

" Service Definition
@EndUserText.label: 'Inquiry Service"
define service ZUI_INQUIRY_O4 {
expose ZC_Inquiry as Inquiry;
}
" Consumption View avec annotations UI
@AccessControl.authorizationCheck: #CHECK
@Metadata.allowExtensions: true
@UI.headerInfo: {
typeName: 'Demande client',
typeNamePlural: 'Demandes clients',
title: { value: 'Subject' },
description: { value: 'Customer' }
}
define view entity ZC_Inquiry
as projection on ZI_Inquiry
{
@UI.facet: [{
id: 'GeneralInfo',
type: #IDENTIFICATION_REFERENCE,
label: 'Informations generales',
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 pour coloration semantique
case Priority
when 'H' then 1 " Rouge
when 'M' then 2 " Jaune
else 3 " Vert
end as PriorityCriticality,
case Status
when '03' then 1 " Escalade = Rouge
when '01' then 2 " Ouvert = Jaune
when '02' then 2 " En cours = Jaune
else 3 " Ferme = Vert
end as StatusCriticality,
_Customer
}

Bonnes pratiques pour S/4HANA Public Cloud

DO : Pratiques recommandees

✅ Utiliser uniquement les APIs Released
✅ Utiliser les Software Components pour la modularite
✅ Ecrire des tests unitaires (ABAP Unit)
✅ Suivre les directives Clean ABAP
✅ Maintenir la documentation dans ABAP Doc
✅ Utiliser le Feature Control pour les Actions
✅ Implementer les Authorization Checks

DON’T : Pratiques a eviter

❌ Acces directs aux tables SAP
❌ Utiliser des APIs non liberees
❌ IDs systeme ou mandants codes en dur
❌ Appels HTTP synchrones dans les transactions
❌ Processus longs sans Background Processing
❌ Logique complexe sans modularisation

Checklist avant transport

Point de verificationFait
Verification ATC reussie (variante ABAP Cloud)
Tests unitaires presents et reussis
Authorization Checks implementes
Pas d’APIs non liberees
Documentation a jour
Tests de performance effectues

Sujets connexes