RAP Tutoriel End-to-End : Du modele de donnees a l

Catégorie
RAP
Publié
Auteur
Johannes

Ce tutoriel End-to-End vous guide a travers le processus de developpement complet d’une application RAP - de la table de base de donnees vide a l’application Fiori Elements fonctionnelle. Vous creez une gestion de projets avec une fonctionnalite CRUD complete.

Objectif

A la fin de ce tutoriel, vous aurez :

  • Une table de base de donnees pour les donnees de projet
  • Des CDS Views Interface et Projection
  • Une Behavior Definition avec CRUD et Actions personnalisees
  • Un service OData V4 pour l’API
  • Une UI Fiori Elements fonctionnelle

Prerequis

  • SAP BTP ABAP Environment ou S/4HANA 2022+
  • ABAP Development Tools (ADT) pour Eclipse
  • Connaissances de base en ABAP (SQL, types de donnees)

Pour la mise en place de l’environnement de developpement, voir Configurer l’environnement de developpement ABAP Cloud.

Apercu de l’architecture

┌─────────────────────────────────────────────────────────┐
│ SAP Fiori Elements UI │
│ (genere automatiquement a partir des Annotations)│
├─────────────────────────────────────────────────────────┤
│ Service OData V4 │
│ Service Binding (SRVB): ZUI_PROJECT_O4 │
├─────────────────────────────────────────────────────────┤
│ Service Definition (SRVD) │
│ ZUI_PROJECT_O4 │
├─────────────────────────────────────────────────────────┤
│ Projection Layer (C_*) │
│ CDS View: ZC_PROJECT Behavior: projection │
│ + Metadata Extension (UI Annotations) │
├─────────────────────────────────────────────────────────┤
│ Business Object Layer (I_*) │
│ CDS View: ZI_PROJECT Behavior Definition (BDEF) │
│ Behavior Implementation (BIL) │
├─────────────────────────────────────────────────────────┤
│ Table de base de donnees : ZPROJECT │
└─────────────────────────────────────────────────────────┘

Etape 1 : Creer la table de base de donnees

La table de base de donnees constitue la couche de persistance de notre Business Object.

Workflow ADT

  1. Clic droit sur votre package → NewOther ABAP Repository Object
  2. Recherche : Database Table → Next
  3. Nom : ZPROJECT | Description : Project Master Data
  4. Finish

Definition de la table

@EndUserText.label : 'Project Master Data"
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zproject {
key client : abap.clnt not null;
key project_id : abap.char(10) not null;
project_name : abap.char(100);
description : abap.string(1024);
responsible_person : abap.char(40);
start_date : abap.dats;
end_date : abap.dats;
@Semantics.amount.currencyCode : 'zproject.currency_code"
budget : abap.curr(15,2);
currency_code : abap.cuky;
status : abap.char(1);
priority : abap.char(1);
@Semantics.user.createdBy : true
created_by : abap.char(12);
@Semantics.systemDateTime.createdAt : true
created_at : timestampl;
@Semantics.user.lastChangedBy : true
last_changed_by : abap.char(12);
@Semantics.systemDateTime.lastChangedAt : true
last_changed_at : timestampl;
}

Activer : Ctrl+F3

Les annotations @Semantics permettent le remplissage automatique des champs d’audit par le framework RAP.


Etape 2 : CDS View Interface (I_*)

L’Interface View definit le modele de donnees semantique du Business Object. C’est l’API stable pour les autres consommateurs.

Workflow ADT

  1. Clic droit sur le package → NewOther ABAP Repository Object
  2. Recherche : Data Definition → Next
  3. Nom : ZI_PROJECT | Description : Project - Interface View
  4. Template : Define Root View Entity
  5. Finish

Definition de la CDS View

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Project - Interface View"
define root view entity ZI_PROJECT
as select from zproject
{
key project_id as ProjectId,
project_name as ProjectName,
description as Description,
responsible_person as ResponsiblePerson,
start_date as StartDate,
end_date as EndDate,
@Semantics.amount.currencyCode: 'CurrencyCode"
budget as Budget,
@Semantics.currencyCode: true
currency_code as CurrencyCode,
status as Status,
priority as Priority,
@Semantics.user.createdBy: true
created_by as CreatedBy,
@Semantics.systemDateTime.createdAt: true
created_at as CreatedAt,
@Semantics.user.lastChangedBy: true
last_changed_by as LastChangedBy,
@Semantics.systemDateTime.lastChangedAt: true
last_changed_at as LastChangedAt
}

Important : Le mot-cle root identifie l’entite racine du Business Object. Pour plus d’informations sur les CDS Views, voir ABAP CDS Views.


Etape 3 : Behavior Definition (BDEF)

La Behavior Definition declare ce qui peut etre fait avec le Business Object (CRUD, Actions, Validations, Determinations).

Workflow ADT

  1. Clic droit sur ZI_PROJECTNew Behavior Definition
  2. Implementation Type : Managed
  3. Finish

Code BDEF

managed implementation in class zbp_i_project unique;
strict ( 2 );
define behavior for ZI_PROJECT alias Project
persistent table zproject
lock master
authorization master ( instance )
etag master LastChangedAt
{
// Operations CRUD standard
create;
update;
delete;
// Controle des champs
field ( readonly ) ProjectId;
field ( readonly ) CreatedBy, CreatedAt, LastChangedBy, LastChangedAt;
field ( numbering : managed ) ProjectId;
// Validations
validation validateDates on save { field StartDate, EndDate; }
validation validateBudget on save { field Budget; }
// Determinations (valeurs automatiques)
determination setDefaultStatus on modify { create; }
// Actions personnalisees
action ( features : instance ) completeProject result [1] $self;
action ( features : instance ) cancelProject result [1] $self;
// Mapping vers la table de base de donnees
mapping for zproject
{
ProjectId = project_id;
ProjectName = project_name;
Description = description;
ResponsiblePerson = responsible_person;
StartDate = start_date;
EndDate = end_date;
Budget = budget;
CurrencyCode = currency_code;
Status = status;
Priority = priority;
CreatedBy = created_by;
CreatedAt = created_at;
LastChangedBy = last_changed_by;
LastChangedAt = last_changed_at;
}
}

Explication des mots-cles :

  • managed : Le framework RAP gere automatiquement le CRUD
  • strict ( 2 ) : Active les verifications de bonnes pratiques
  • numbering : managed : Attribution automatique des IDs
  • etag master : Verrouillage optimiste pour les acces paralleles

Pour plus de details sur Managed vs. Unmanaged, voir RAP Managed vs Unmanaged.


Etape 4 : Behavior Implementation (BIL)

La Behavior Implementation contient la logique ABAP pour les Validations, Determinations et Actions.

Classe generee automatiquement

Apres l’activation de la BDEF, ADT genere la classe ZBP_I_PROJECT. Ouvrez-la et implementez la Local Handler Class :

CLASS lhc_project DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS:
get_instance_features FOR INSTANCE FEATURES
IMPORTING keys REQUEST requested_features FOR Project RESULT result,
validateDates FOR VALIDATE ON SAVE
IMPORTING keys FOR Project~validateDates,
validateBudget FOR VALIDATE ON SAVE
IMPORTING keys FOR Project~validateBudget,
setDefaultStatus FOR DETERMINE ON MODIFY
IMPORTING keys FOR Project~setDefaultStatus,
completeProject FOR MODIFY
IMPORTING keys FOR ACTION Project~completeProject RESULT result,
cancelProject FOR MODIFY
IMPORTING keys FOR ACTION Project~cancelProject RESULT result.
ENDCLASS.
CLASS lhc_project IMPLEMENTATION.
METHOD get_instance_features.
READ ENTITIES OF zi_project IN LOCAL MODE
ENTITY Project
FIELDS ( Status )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_project)
FAILED failed.
result = VALUE #( FOR ls_project IN lt_project
( %tky = ls_project-%tky
%features-%action-completeProject = COND #(
WHEN ls_project-Status = 'A' THEN if_abap_behv=>fc-o-enabled
ELSE if_abap_behv=>fc-o-disabled )
%features-%action-cancelProject = COND #(
WHEN ls_project-Status = 'A' OR ls_project-Status = 'N"
THEN if_abap_behv=>fc-o-enabled
ELSE if_abap_behv=>fc-o-disabled )
) ).
ENDMETHOD.
METHOD validateDates.
READ ENTITIES OF zi_project IN LOCAL MODE
ENTITY Project
FIELDS ( StartDate EndDate )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_project).
LOOP AT lt_project INTO DATA(ls_project).
IF ls_project-EndDate IS NOT INITIAL
AND ls_project-EndDate < ls_project-StartDate.
APPEND VALUE #(
%tky = ls_project-%tky
%element-EndDate = if_abap_behv=>mk-on
) TO failed-project.
APPEND VALUE #(
%tky = ls_project-%tky
%element-EndDate = if_abap_behv=>mk-on
%msg = new_message_with_text(
severity = if_abap_behv_message=>severity-error
text = 'La date de fin doit etre apres la date de debut' )
) TO reported-project.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD validateBudget.
READ ENTITIES OF zi_project IN LOCAL MODE
ENTITY Project
FIELDS ( Budget )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_project).
LOOP AT lt_project INTO DATA(ls_project).
IF ls_project-Budget < 0.
APPEND VALUE #(
%tky = ls_project-%tky
%element-Budget = if_abap_behv=>mk-on
) TO failed-project.
APPEND VALUE #(
%tky = ls_project-%tky
%element-Budget = if_abap_behv=>mk-on
%msg = new_message_with_text(
severity = if_abap_behv_message=>severity-error
text = 'Le budget ne peut pas etre negatif' )
) TO reported-project.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD setDefaultStatus.
READ ENTITIES OF zi_project IN LOCAL MODE
ENTITY Project
FIELDS ( Status )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_project).
MODIFY ENTITIES OF zi_project IN LOCAL MODE
ENTITY Project
UPDATE FIELDS ( Status Priority )
WITH VALUE #( FOR ls_project IN lt_project
WHERE ( Status IS INITIAL )
( %tky = ls_project-%tky
Status = 'N"
Priority = 'M' ) )
REPORTED DATA(reported_modify).
ENDMETHOD.
METHOD completeProject.
MODIFY ENTITIES OF zi_project IN LOCAL MODE
ENTITY Project
UPDATE FIELDS ( Status )
WITH VALUE #( FOR key IN keys
( %tky = key-%tky
Status = 'C' ) )
FAILED failed
REPORTED reported.
READ ENTITIES OF zi_project IN LOCAL MODE
ENTITY Project
ALL FIELDS
WITH CORRESPONDING #( keys )
RESULT result.
ENDMETHOD.
METHOD cancelProject.
MODIFY ENTITIES OF zi_project IN LOCAL MODE
ENTITY Project
UPDATE FIELDS ( Status )
WITH VALUE #( FOR key IN keys
( %tky = key-%tky
Status = 'X' ) )
FAILED failed
REPORTED reported.
READ ENTITIES OF zi_project IN LOCAL MODE
ENTITY Project
ALL FIELDS
WITH CORRESPONDING #( keys )
RESULT result.
ENDMETHOD.
ENDCLASS.

Valeurs de statut : N = Nouveau, A = Actif, C = Termine, X = Annule

Pour plus de details sur les Validations et Determinations, voir RAP Determinations et Validations.


Etape 5 : Projection CDS View (C_*)

La Projection View est la vue specifique a l’UI sur le Business Object. Elle definit quels champs sont visibles pour une application donnee.

Workflow ADT

  1. Clic droit sur le package → NewData Definition
  2. Nom : ZC_PROJECT | Description : Project - Projection View
  3. Template : Define Projection View
  4. Finish

Code Projection View

@EndUserText.label: 'Project - Projection View"
@AccessControl.authorizationCheck: #NOT_REQUIRED
@Metadata.allowExtensions: true
@Search.searchable: true
define root view entity ZC_PROJECT
provider contract transactional_query
as projection on ZI_PROJECT
{
key ProjectId,
@Search.defaultSearchElement: true
@Search.fuzzinessThreshold: 0.8
ProjectName,
Description,
@Search.defaultSearchElement: true
ResponsiblePerson,
StartDate,
EndDate,
@Semantics.amount.currencyCode: 'CurrencyCode"
Budget,
@Semantics.currencyCode: true
CurrencyCode,
@ObjectModel.text.element: ['StatusText']
Status,
case Status
when 'N' then 'Nouveau"
when 'A' then 'Actif"
when 'C' then 'Termine"
when 'X' then 'Annule"
else 'Inconnu"
end as StatusText : localized,
@ObjectModel.text.element: ['PriorityText']
Priority,
case Priority
when 'H' then 'Haute"
when 'M' then 'Moyenne"
when 'L' then 'Basse"
else 'Inconnue"
end as PriorityText : localized,
CreatedBy,
CreatedAt,
LastChangedBy,
LastChangedAt
}

Note : provider contract transactional_query active le support transactionnel RAP. Les expressions case generent des textes lisibles pour le statut et la priorite.


Etape 6 : Projection Behavior Definition

La Projection BDEF determine quelles operations sont disponibles au niveau de la Projection.

Workflow ADT

  1. Clic droit sur ZC_PROJECTNew Behavior Definition
  2. Implementation Type : Projection
  3. Finish

Code Projection BDEF

projection;
strict ( 2 );
define behavior for ZC_PROJECT alias Project
{
use create;
use update;
use delete;
use action completeProject;
use action cancelProject;
}

Le mot-cle use delegue les operations au niveau Interface.


Etape 7 : Metadata Extension (UI Annotations)

La Metadata Extension definit le layout UI de l’application Fiori Elements.

Workflow ADT

  1. Clic droit sur ZC_PROJECTNew Metadata Extension
  2. Nom : ZC_PROJECT
  3. Finish

Code Metadata Extension

@Metadata.layer: #CORE
annotate entity ZC_PROJECT with
{
@UI.headerInfo: {
typeName: 'Projet',
typeNamePlural: 'Projets',
title: { value: 'ProjectName' },
description: { value: 'ProjectId' }
}
@UI.facet: [
{ id: 'GeneralInfo',
purpose: #STANDARD,
type: #IDENTIFICATION_REFERENCE,
label: 'Informations generales',
position: 10 },
{ id: 'Dates',
purpose: #STANDARD,
type: #FIELDGROUP_REFERENCE,
targetQualifier: 'Dates',
label: 'Periode',
position: 20 },
{ id: 'Financial',
purpose: #STANDARD,
type: #FIELDGROUP_REFERENCE,
targetQualifier: 'Financial',
label: 'Budget',
position: 30 }
]
@UI: { lineItem: [{ position: 10, importance: #HIGH }],
identification: [{ position: 10 }],
selectionField: [{ position: 10 }] }
ProjectId;
@UI: { lineItem: [{ position: 20, importance: #HIGH }],
identification: [{ position: 20 }],
selectionField: [{ position: 20 }] }
ProjectName;
@UI: { identification: [{ position: 30 }] }
Description;
@UI: { lineItem: [{ position: 30 }],
identification: [{ position: 40 }],
selectionField: [{ position: 30 }] }
ResponsiblePerson;
@UI: { lineItem: [{ position: 40 }],
fieldGroup: [{ qualifier: 'Dates', position: 10 }] }
StartDate;
@UI: { lineItem: [{ position: 50 }],
fieldGroup: [{ qualifier: 'Dates', position: 20 }] }
EndDate;
@UI: { lineItem: [{ position: 60 }],
fieldGroup: [{ qualifier: 'Financial', position: 10 }] }
Budget;
@UI.hidden: true
CurrencyCode;
@UI: { lineItem: [{ position: 70, importance: #HIGH,
criticality: 'StatusCriticality' }],
identification: [{ position: 50 }],
selectionField: [{ position: 40 }] }
@UI.textArrangement: #TEXT_ONLY
Status;
@UI: { lineItem: [{ position: 80 }],
identification: [{ position: 60 }] }
@UI.textArrangement: #TEXT_ONLY
Priority;
@UI: { lineItem: [{ position: 100, type: #FOR_ACTION, dataAction: 'completeProject',
label: 'Terminer' }] }
@UI: { identification: [{ position: 100, type: #FOR_ACTION,
dataAction: 'completeProject', label: 'Terminer le projet' }] }
@UI: { lineItem: [{ position: 110, type: #FOR_ACTION, dataAction: 'cancelProject',
label: 'Annuler' }] }
@UI: { identification: [{ position: 110, type: #FOR_ACTION,
dataAction: 'cancelProject', label: 'Annuler le projet' }] }
}

Pour plus d’informations sur les UI Annotations, voir CDS Annotations.


Etape 8 : Service Definition (SRVD)

La Service Definition determine quelles entites sont exposees via le service OData.

Workflow ADT

  1. Clic droit sur le package → NewOther ABAP Repository Object
  2. Recherche : Service Definition → Next
  3. Nom : ZUI_PROJECT_O4
  4. Finish

Code Service Definition

@EndUserText.label: 'Project Service Definition"
define service ZUI_PROJECT_O4 {
expose ZC_PROJECT as Project;
}

Etape 9 : Service Binding (SRVB)

Le Service Binding cree le point de terminaison OData reel.

Workflow ADT

  1. Clic droit sur le package → NewOther ABAP Repository Object
  2. Recherche : Service Binding → Next
  3. Nom : ZUI_PROJECT_O4
  4. Binding Type : OData V4 - UI
  5. Service Definition : ZUI_PROJECT_O4
  6. Finish

Activation et publication

  1. Activer : Ctrl+F3
  2. Dans l’editeur Service Binding : cliquer sur Publish
  3. Apres publication reussie : selectionner l’entite Project → cliquer sur Preview

Le navigateur ouvre l’application Fiori Elements.


Erreurs courantes et solutions

Erreur : “No behavior implementation found”

Cause : La classe Behavior Implementation n’existe pas ou n’est pas activee.

Solution :

  1. Ouvrez la BDEF
  2. Clic droit → NavigateBehavior Implementation
  3. Activez la classe avec Ctrl+F3

Erreur : “Field X is not mapped”

Cause : Un champ CDS n’a pas de mapping correspondant vers la table de base de donnees.

Solution : Completez le mapping dans la BDEF :

mapping for zproject
{
MissingField = missing_field;
}

Erreur : “Authorization check failed”

Cause : @AccessControl.authorizationCheck: #CHECK est defini, mais aucun Access Control n’existe.

Solution : Changez l’annotation en #NOT_REQUIRED ou creez un Access Control (DCL).

Erreur : “Draft table not found”

Cause : Le Draft est active dans la BDEF (with draft;), mais la table Draft n’existe pas.

Solution : Creez la table Draft ou supprimez with draft; de la BDEF.

Pour plus de solutions, voir Erreurs et solutions ABAP Cloud.


Prochaines etapes

Avec cette base, vous pouvez etendre l’application :

  • Fonctionnalite Draft : Sauvegarde intermediaire des saisies - voir RAP Draft Handling
  • Value Helps : Listes deroulantes pour Statut et Priorite - voir RAP Value Helps
  • Autorisations : Autorisation basee sur l’instance - voir RAP Authorization
  • Feature Control : Disponibilite dynamique des champs/boutons - voir RAP Feature Control
  • Associations : Entites subordonnees (ex. taches de projet) - voir RAP Basics

Pour un tutoriel interactif avec des captures d’ecran etape par etape, voir Tutoriel RAP Partie 1 : Votre premiere application Fiori.


Resume

Ce tutoriel a parcouru le cycle de developpement RAP complet :

CoucheArtefactObjectif
PersistanceZPROJECT (Table)Stockage des donnees
Modele de donneesZI_PROJECT (CDS)Modele semantique, API metier
ComportementBDEF + BILCRUD, Validations, Actions
ProjectionZC_PROJECT (CDS)Vue specifique a l’UI
UIMetadata ExtensionAnnotations de layout Fiori
ServiceSRVD + SRVBPoint de terminaison OData

Avec le scenario RAP Managed, le framework prend en charge toute la logique CRUD. Vous vous concentrez sur la logique metier dans les Validations, Determinations et Actions. Pour des exigences plus complexes avec integration Legacy, voir RAP Managed vs Unmanaged.