Stratégie Clean Core pour S/4HANA : Le guide complet

Catégorie
General
Publié
Auteur
Johannes

Clean Core est la réponse stratégique de SAP au problème vieux de plusieurs décennies des modifications SAP chaotiques et menaçant les mises à niveau. L’idée centrale : gardez le code SAP standard propre (clean) et réalisez les extensions uniquement via des interfaces définies et stables.

Le problème : les personnalisations SAP traditionnelles

Modifications classiques (avant Clean Core)

" ❌ MAUVAIS : Intervention directe dans le standard SAP
ENHANCEMENT-POINT ep_vbap_check IN PROGRAM sapmv45a.
" Logique personnalisée directement dans le programme SAP standard
IF vbap-matnr = 'SPECIAL'.
vbap-kwmeng = vbap-kwmeng * 2.
ENDIF.
END-ENHANCEMENT-POINT.
" ❌ MAUVAIS : Utilisation de tables/champs non libérés
SELECT SINGLE * FROM but000 WHERE partner = lv_partner.
" but000 n'est pas libéré → peut changer à tout moment !
" ❌ MAUVAIS : User-Exits/BADIs avec accès non propre
METHOD if_ex_badi_name~execute.
" Accès direct aux structures internes SAP
DATA(lv_internal) = cl_sap_internal_class=>get_data( ).
ENDMETHOD.

Les conséquences :

  • 🔴 Les mises à niveau sont bloquées ou cassent les personnalisations
  • 🔴 Coûts de maintenance élevés (en moyenne 30-40% du budget IT)
  • 🔴 Innovation lente (peur des breaking changes)
  • 🔴 La dette technique croît de manière exponentielle

Clean Core : La solution

Clean Core signifie une séparation stricte entre :

  1. Code standard SAP (Core) – intouché
  2. Extensions (Extensions) – uniquement via des APIs libérées
┌──────────────────────────────────────────────────────┐
│ SAP Standard │
│ (SAP S/4HANA Core) │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ Released APIs & Extension Points │ │
│ │ (Garanties stables par SAP) │ │
│ └──────────────┬──────────────────────────┘ │
└─────────────────┼───────────────────────────────────┘
│ Uniquement via des interfaces libérées
┌──────────▼──────────────────────────┐
│ Extensions Clean Core │
│ │
│ • Tier-3 : In-Stack (ABAP Cloud) │
│ • Key User Extensibility │
│ • Side-by-Side (BTP) │
│ • Intégration API │
└─────────────────────────────────────┘

Les 3 Tiers : Modèle d’extensibilité

SAP définit un modèle d’extension à 3 niveaux :

Tier 1 : Developer Extensibility (Side-by-Side)

Principe : Les extensions s’exécutent sur SAP BTP (en dehors de S/4HANA)

" Développé sur BTP ABAP Environment
CLASS zcl_btp_sales_extension DEFINITION PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS zcl_btp_sales_extension IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
" Accès à S/4HANA via OData/APIs
DATA(lo_http) = cl_web_http_client_manager=>create_by_http_destination(
i_destination = cl_http_destination_provider=>create_by_url(
i_url = 'https://my-s4hana.com/sap/opu/odata4/sap/api_salesorder_v1' )
).
DATA(lo_request) = lo_http->get_http_request( ).
lo_request->set_header_field( i_name = 'Accept' i_value = 'application/json' ).
DATA(lo_response) = lo_http->execute( if_web_http_client=>get ).
DATA(lv_json) = lo_response->get_text( ).
" Logique métier propre
" → Pas d'accès aux éléments internes S/4HANA
" → Complètement isolé
ENDMETHOD.
ENDCLASS.

Avantages :

  • ✅ Découplage complet
  • ✅ Cycle de release propre
  • ✅ Mise à l’échelle indépendante de S/4HANA
  • ✅ Tous les langages de programmation (ABAP, Java, Node.js…)

Inconvénients :

  • ⚠️ Latence réseau (appels API)
  • ⚠️ Complexité accrue (deux systèmes)
  • ⚠️ Coûts de licence supplémentaires (BTP)

Tier 2 : Key User Extensibility (No-Code/Low-Code)

Principe : Les utilisateurs métier étendent S/4HANA sans code via des outils

Custom Fields (Champs personnalisés) :

SAP GUI → Paramètres → Custom Fields and Logic
1. Sélectionner l'objet (ex. Sales Order)
2. "Créer un nouveau champ"
3. Nom du champ : ZZ_PRIORITY
4. Type de données : String(10)
5. Ajouter à l'UI
→ Terminé ! Le champ est disponible dans la table, les CDS Views et l'UI

Custom Logic (Règles métier) :

1. Sélectionner le déclencheur : "Before Save - Sales Order"
2. Condition : IF NetAmount > 10000
3. Action : SET ZZ_PRIORITY = 'HIGH"
→ Aucune connaissance ABAP requise !

Avantages :

  • ✅ Rapide (minutes au lieu de jours)
  • ✅ Pas de compétences développeur requises
  • ✅ Intégré dans S/4HANA (pas de latence)
  • ✅ Automatiquement sécurisé pour les mises à niveau

Inconvénients :

  • ⚠️ Complexité limitée
  • ⚠️ Uniquement pour les Business Objects libérés

Tier 3 : Developer Extensibility (In-Stack)

Principe : Développement ABAP à l’intérieur de S/4HANA avec ABAP Cloud

C’est le sweet spot pour les développeurs ABAP classiques :

" ✅ BON : Extension ABAP Cloud dans S/4HANA
" Utiliser uniquement des APIs libérées
CLASS zcl_sales_validator DEFINITION PUBLIC.
PUBLIC SECTION.
INTERFACES if_badi_interface.
ENDCLASS.
CLASS zcl_sales_validator IMPLEMENTATION.
METHOD if_badi_interface~validate.
" Accès UNIQUEMENT via des APIs libérées
SELECT SINGLE *
FROM i_salesorder " ← CDS View libérée (libérée par SAP)
WHERE salesorder = @iv_order_id
INTO @DATA(ls_order).
" Logique métier
IF ls_order-TotalNetAmount > 50000.
" Message via API libérée
DATA(lo_msg) = cl_message_helper=>get_instance( ). " ← Libérée
lo_msg->add_message(
id = 'ZMSG"
number = '001"
v1 = 'Approbation requise"
).
ENDIF.
ENDMETHOD.
ENDCLASS.

Comment reconnaître les APIs libérées ?

" Dans Eclipse ADT :
" 1. Ouvrir l'API (ex. CDS View, Classe)
" 2. Afficher les propriétés → "API State"
" 3. Chercher "Released" ou "C1" (Cloud-Ready)
" Exemple : I_SalesOrder
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Sales Order"
@Metadata.allowExtensions: true
@ObjectModel.usageType.serviceQuality: #A
@VDM.viewType: #BASIC
" → Si @VDM.viewType est présent : fait partie du Virtual Data Model (VDM)
" = Libéré pour la consommation !
define view I_SalesOrder
as select from vbak " ← vbak n'est PAS libéré, mais I_SalesOrder l'est !
{
key vbeln as SalesOrder,
erdat as CreationDate,
netwr as TotalNetAmount,
waerk as TransactionCurrency
}

Trouver les APIs libérées :

SAP API Business Hub : api.sap.com

Filtre : "API Type" → "ABAP Cloud"
"Product" → "SAP S/4HANA"
Exemples :
- I_SalesOrder, I_Customer, I_Product (CDS Views)
- CL_BALI_LOG (Application Logging)
- CL_NUMBERRANGE_RUNTIME (Number Ranges)
- CL_WEB_HTTP_* (HTTP Client)

Stratégie d’implémentation Clean Core

Phase 1 : Assessment (Analyse de l’existant)

Utiliser le Custom Code Analyzer :

" Transaction : ATC (ABAP Test Cockpit)
" Ou dans Eclipse ADT :
" Projet → Properties → ABAP Development → Code Inspector
" Check Variant : S4HANA_READINESS_REMOTE
" → Affiche toutes les utilisations d'APIs non libérées

Résultats typiques :

CatégorieExempleRisqueEffort
Tables non libéréesSELECT FROM but000ÉlevéMoyen
Implicit EnhancementsENHANCEMENT-POINTÉlevéÉlevé
APIs non libéréesCALL FUNCTION 'RFC_READ_TABLE'MoyenFaible
Accès DB directOPEN CURSOR FOR SELECT * FROM (lv_tabname)Très élevéÉlevé

Phase 2 : Remédiation

Stratégie 1 : Remplacer les APIs

" ❌ Avant : Non libérée
SELECT SINGLE * FROM but000 WHERE partner = @lv_partner.
" ✅ Après : API libérée
SELECT SINGLE * FROM i_businesspartner
WHERE businesspartner = @lv_partner
INTO @DATA(ls_bp).

Stratégie 2 : Couche Wrapper

" Wrapper central pour les accès critiques
CLASS zcl_bp_access DEFINITION PUBLIC CREATE PRIVATE.
PUBLIC SECTION.
CLASS-METHODS:
get_instance RETURNING VALUE(ro_instance) TYPE REF TO zcl_bp_access,
get_business_partner
IMPORTING iv_partner TYPE bu_partner
RETURNING VALUE(rs_partner) TYPE i_businesspartner.
PRIVATE SECTION.
CLASS-DATA go_instance TYPE REF TO zcl_bp_access.
ENDCLASS.
CLASS zcl_bp_access IMPLEMENTATION.
METHOD get_instance.
IF go_instance IS NOT BOUND.
CREATE OBJECT go_instance.
ENDIF.
ro_instance = go_instance.
ENDMETHOD.
METHOD get_business_partner.
" Aujourd'hui : API libérée
SELECT SINGLE * FROM i_businesspartner
WHERE businesspartner = @iv_partner
INTO @rs_partner.
" Si l'API ne suffit pas :
" TODO : Demander une extension d'API à SAP (via Influence Request)
ENDMETHOD.
ENDCLASS.
" Partout dans le code personnalisé :
DATA(ls_bp) = zcl_bp_access=>get_instance( )->get_business_partner( lv_partner ).
" → Si SAP modifie l'API : modifier uniquement zcl_bp_access, pas 100 endroits

Stratégie 3 : Refactoring vers RAP

" ❌ Avant : Programme Dynpro avec accès DB direct
REPORT zsales_order_maintain.
PARAMETERS: p_order TYPE vbeln.
START-OF-SELECTION.
" Accès directs aux tables
UPDATE vbak SET status = 'CLOSED' WHERE vbeln = p_order.
COMMIT WORK.
" ✅ Après : RAP Business Object
" → voir /rap-basics/ pour les détails
MODIFY ENTITIES OF i_salesordertp
ENTITY SalesOrder
UPDATE FIELDS ( OverallSDProcessStatus )
WITH VALUE #( ( SalesOrder = lv_order
OverallSDProcessStatus = 'C' ) )
FAILED DATA(failed)
REPORTED DATA(reported).
COMMIT ENTITIES.

Phase 3 : Gouvernance (Rester Clean durablement)

1. ATC Checks dans le pipeline CI/CD

# Pipeline Azure DevOps / Jenkins
- task: ABAP_ATC_Check
inputs:
checkVariant: 'CUSTOM_CLOUD_READINESS"
failOnErrors: true
excludePackages: '$TMP' # Exclure les développements de test

2. Documenter les directives de développement

# Standards de développement ABAP (Exemple)
## Règles obligatoires
1. ✅ Uniquement les APIs libérées (Vérifier : API Business Hub)
2. ✅ Syntaxe ABAP Cloud (pas de CALL TRANSACTION, etc.)
3. ✅ RAP pour les apps transactionnelles (pas de Dynpro)
4. ✅ CDS Views au lieu de SELECT sur les tables DB
5. ✅ Pas d'Implicit Enhancement Framework
## Recommandations
- Classes wrapper pour les APIs fréquemment utilisées
- Tests unitaires avec Test Doubles (voir /test-doubles-mocking/)
- EML pour l'accès aux BO (voir /eml-guide/)

3. Revues de code avec checklist

Checklist Pull Request :
□ ATC-Check vert (Clean Core Variant) ?
□ Uniquement des APIs libérées utilisées ?
□ Tests unitaires présents (Couverture ≥ 80%) ?
□ CDS Views documentées (Labels/Descriptions) ?
□ Pas d'Implicit Enhancements ?

Clean Core & ABAP Cloud

ABAP Cloud = implémentation technique de Clean Core

" ABAP Cloud Language Version : Le compilateur impose Clean Core !
CLASS zcl_order_processor DEFINITION PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS zcl_order_processor IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
" ✅ Autorisé : API libérée
SELECT * FROM i_salesorder
INTO TABLE @DATA(lt_orders).
" ❌ Erreur de compilation : vbak n'est pas libérée !
" SELECT * FROM vbak INTO TABLE @DATA(lt_vbak).
" → "vbak is not released for ABAP Cloud"
" ❌ Erreur de compilation : CALL TRANSACTION non autorisé
" CALL TRANSACTION 'VA03'.
" → "CALL TRANSACTION is not allowed in ABAP Cloud"
ENDMETHOD.
ENDCLASS.

Activer ABAP Cloud dans S/4HANA :

Eclipse ADT :
1. Créer/Ouvrir le package
2. Properties → ABAP Language Version
3. Sélectionner : "ABAP for Cloud Development"
→ Tous les objets dans ce package sont conformes Clean Core !

Migration : Étape par étape

Exemple : Sales Order Enhancement

Situation initiale (Classic ABAP) :

" ❌ User-Exit intégré dans le standard SAP
ENHANCEMENT-SECTION zenhancement_vbap IN sapmv45a.
ENHANCEMENT 1 zorder_validation.
" Accès aux variables globales du programme SAP
IF vbap-matnr CO '0123456789'.
MESSAGE 'Numéro de matériel invalide' TYPE 'E'.
ENDIF.
ENDENHANCEMENT.
END-ENHANCEMENT-SECTION.

Migration vers Clean Core (ABAP Cloud + RAP) :

" ✅ Étape 1 : Utiliser le BAdI (si disponible)
CLASS zcl_order_badi DEFINITION PUBLIC.
PUBLIC SECTION.
INTERFACES if_ex_sd_sales_item_check. " ← BAdI SAP
ENDCLASS.
CLASS zcl_order_badi IMPLEMENTATION.
METHOD if_ex_sd_sales_item_check~validate_item.
" Accès uniquement via les paramètres de l'interface (pas d'accès global)
IF is_item-material CO '0123456789'.
" API libérée pour les messages
DATA(lo_msg) = cl_bali_message_setter=>create(
severity = if_bali_constants=>c_severity_error
id = 'ZMSG"
number = '001"
).
APPEND lo_msg TO ct_messages.
ENDIF.
ENDMETHOD.
ENDCLASS.
" ✅ Étape 2 : Si pas de BAdI → Wrapper Event
" Voir RAP Business Events : /events-raise-handler/
" ✅ Étape 3 : À long terme → RAP Validation
" Dans la Behavior Definition :
validation validateMaterialNumber on save
{ field Material; }
" Behavior Implementation :
METHOD validateMaterialNumber.
READ ENTITIES OF zi_salesorder IN LOCAL MODE
ENTITY SalesOrderItem
FIELDS ( Material )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_items).
LOOP AT lt_items INTO DATA(ls_item) WHERE Material CO '0123456789'.
APPEND VALUE #(
%tky = ls_item-%tky
%element-Material = if_abap_behv=>mk-on
) TO failed-salesorderitem.
APPEND VALUE #(
%tky = ls_item-%tky
%msg = new_message_with_text(
severity = if_abap_behv_message=>severity-error
text = 'Numéro de matériel invalide"
)
) TO reported-salesorderitem.
ENDLOOP.
ENDMETHOD.

Outils pour Clean Core

OutilObjectifTransaction/Lien
Custom Code Migration AppAnalyse + SuiviFiori Launchpad : F2802
ATC (ABAP Test Cockpit)Analyse statique du codeSE80/ADT
SAP API Business HubTrouver les APIs libéréesapi.sap.com
ABAP Cloud Flight CheckerViolations Clean CoreEclipse ADT
Code InspectorVérifications legacySCI/ATC
Transport Dependency AnalyzerAnalyse d’impactSE03

Notes importantes / Bonnes pratiques

  • Clean Core n’est pas une option : À partir de S/4HANA 2025+, ce sera obligatoire pour les éditions Cloud
  • Commencez tôt : La migration prend 2-5 ans selon le volume de code personnalisé
  • Règle 80/20 : 20% du code cause 80% des problèmes – priorisez !
  • Utilisez SAP Influence : Une API libérée manque ? → influence.sap.com
  • Ne pas tout migrer : Les anciens programmes peu utilisés peuvent être désactivés
  • Pattern Wrapper : Encapsulez le code de transition dans des classes centrales
  • ABAP Cloud = Support du compilateur : Utilisez la Language Version pour les nouveaux développements
  • Test Doubles : Voir Test Doubles & Mocking pour des tests propres
  • RAP-First : Nouvelles apps transactionnelles toujours avec RAP (voir RAP Basics)
  • Documentation : Justifiez chaque écart (ex. “SAP livrera l’API dans la release XY”)
  • Établir la gouvernance : Pull Requests + ATC-Checks = Clean Core durable
  • Formation : Formez l’équipe – Clean Core est un changement de mentalité, pas seulement de syntaxe

Ressources supplémentaires