Les annotations CDS enrichissent les vues CDS avec des métadonnées pour le rendu UI, la génération OData, la recherche et l’analytique. Elles sont centrales pour Fiori Elements et le modèle de programmation RAP.
Catégories d’annotations
| Catégorie | Préfixe | Description |
|---|---|---|
| UI | @UI | Conception de l’interface |
| OData | @OData | Propriétés OData |
| Semantics | @Semantics | Signification sémantique |
| Search | @Search | Comportement de recherche |
| Analytics | @Analytics | Propriétés analytiques |
| ObjectModel | @ObjectModel | Métadonnées du modèle objet |
Annotations UI
Configuration UI de base
@EndUserText.label: 'Commandes"@Metadata.allowExtensions: truedefine view entity ZC_Order as projection on ZI_Order{ @UI.facet: [{ id: 'OrderHeader', purpose: #STANDARD, type: #IDENTIFICATION_REFERENCE, label: 'En-tête de commande', position: 10 }, { id: 'OrderItems', purpose: #STANDARD, type: #LINEITEM_REFERENCE, label: 'Positions', position: 20, targetElement: '_Items" }]
@UI: { lineItem: [{ position: 10, importance: #HIGH }], identification: [{ position: 10 }], selectionField: [{ position: 10 }] } key OrderId,
@UI: { lineItem: [{ position: 20, importance: #HIGH }], identification: [{ position: 20 }], selectionField: [{ position: 20 }] } CustomerId,
@UI: { lineItem: [{ position: 30, importance: #MEDIUM }], identification: [{ position: 30 }] } OrderDate,
@UI: { lineItem: [{ position: 40, importance: #HIGH, criticality: 'StatusCriticality' }], identification: [{ position: 40 }], selectionField: [{ position: 30 }] } Status,
@UI: { lineItem: [{ position: 50, importance: #HIGH }], identification: [{ position: 50 }] } @Semantics.amount.currencyCode: 'Currency" TotalAmount,
Currency,
@UI.hidden: true StatusCriticality,
_Items}Informations d’en-tête
@UI.headerInfo: { typeName: 'Commande', typeNamePlural: 'Commandes', title: { type: #STANDARD, value: 'OrderId' }, description: { type: #STANDARD, value: 'CustomerName' }, imageUrl: 'ImageUrl"}define view entity ZC_OrderFacettes et sections
@UI.facet: [ { id: 'GeneralInfo', purpose: #STANDARD, type: #COLLECTION, label: 'Informations générales', position: 10 }, { id: 'HeaderData', parentId: 'GeneralInfo', type: #FIELDGROUP_REFERENCE, targetQualifier: 'HeaderData', position: 10 }, { id: 'AddressData', parentId: 'GeneralInfo', type: #FIELDGROUP_REFERENCE, targetQualifier: 'Address', position: 20 }, { id: 'ItemsTable', purpose: #STANDARD, type: #LINEITEM_REFERENCE, label: 'Positions', position: 20, targetElement: '_Items" }, { id: 'Notes', purpose: #STANDARD, type: #FIELDGROUP_REFERENCE, targetQualifier: 'Notes', label: 'Notes', position: 30 }]Groupes de champs
@UI.fieldGroup: [{ qualifier: 'HeaderData', position: 10, label: 'Numéro de commande' }]OrderId,
@UI.fieldGroup: [{ qualifier: 'HeaderData', position: 20, label: 'Date de commande' }]OrderDate,
@UI.fieldGroup: [{ qualifier: 'Address', position: 10, label: 'Rue' }]Street,
@UI.fieldGroup: [{ qualifier: 'Address', position: 20, label: 'Ville' }]City,
@UI.fieldGroup: [{ qualifier: 'Notes', position: 10, label: 'Remarques' }]@UI.multiLineText: trueNotesActions et boutons
@UI: { lineItem: [{ position: 10, type: #FOR_ACTION, dataAction: 'confirmOrder', label: 'Confirmer" }, { position: 20, type: #FOR_ACTION, dataAction: 'cancelOrder', label: 'Annuler', criticality: #NEGATIVE }], identification: [{ position: 100, type: #FOR_ACTION, dataAction: 'confirmOrder', label: 'Confirmer la commande" }]}OrderId,Types de DataField
" Champ standard@UI.lineItem: [{ position: 10, type: #STANDARD }]OrderId,
" Avec navigation@UI.lineItem: [{ position: 20, type: #WITH_NAVIGATION_PATH, targetElement: '_Customer"}]CustomerId,
" Comme URL@UI.lineItem: [{ position: 30, type: #WITH_URL, url: 'WebLink"}]DocumentLink,
" Notation@UI.lineItem: [{ position: 40, type: #AS_DATAPOINT}]@UI.dataPoint: { visualization: #RATING, targetValue: 5}Rating,
" Progression@UI.lineItem: [{ position: 50, type: #AS_DATAPOINT}]@UI.dataPoint: { visualization: #PROGRESS, targetValue: 100, criticality: 'ProgressCriticality"}CompletionPercentAnnotations Semantics
" Montants et devises@Semantics.amount.currencyCode: 'Currency"TotalAmount,
@Semantics.currencyCode: trueCurrency,
" Quantités et unités@Semantics.quantity.unitOfMeasure: 'Unit"Quantity,
@Semantics.unitOfMeasure: trueUnit,
" Champs système@Semantics.user.createdBy: trueCreatedBy,
@Semantics.user.lastChangedBy: trueChangedBy,
@Semantics.systemDateTime.createdAt: trueCreatedAt,
@Semantics.systemDateTime.lastChangedAt: trueChangedAt,
" E-mail et téléphone@Semantics.eMail.address: trueEmail,
@Semantics.telephone.type: [#WORK]PhoneNumber,
" Nom@Semantics.name.fullName: trueCustomerName,
" Adresse@Semantics.address.street: trueStreet,
@Semantics.address.city: trueCity,
@Semantics.address.country: trueCountryAnnotations Search
@Search.searchable: truedefine view entity ZC_Order{ @Search.defaultSearchElement: true @Search.fuzzinessThreshold: 0.8 @Search.ranking: #HIGH key OrderId,
@Search.defaultSearchElement: true @Search.ranking: #MEDIUM CustomerName,
@Search.defaultSearchElement: true @Search.ranking: #LOW Description}Annotations OData
@OData.publish: true@OData.entityType.name: 'Order"@OData.entitySet.name: 'Orders"define view entity ZC_Order
" Navigations@OData.navigable: true_Customer,
" Actions@OData.operation.name: 'confirmOrder"Annotations Analytics
@Analytics.dataCategory: #CUBEdefine view entity ZI_SalesAnalytics{ @Analytics.dimension: true @ObjectModel.text.element: ['CustomerName'] CustomerId,
CustomerName,
@Analytics.dimension: true SalesOrg,
@Analytics.dimension: true @Semantics.calendar.yearMonth: true CalendarYearMonth,
@Analytics.measure: true @Aggregation.default: #SUM @Semantics.amount.currencyCode: 'Currency" Revenue,
@Analytics.measure: true @Aggregation.default: #SUM Quantity,
@Analytics.measure: true @Aggregation.default: #AVG AveragePrice,
Currency}Annotations ObjectModel
@ObjectModel: { modelCategory: #BUSINESS_OBJECT, compositionRoot: true, transactionalProcessingEnabled: true, writeActivePersistence: 'ZORDERS', semanticKey: ['OrderId'], representativeKey: 'OrderId"}define view entity ZI_Order
" Relation de texte@ObjectModel.text.element: ['StatusText']Status,
@ObjectModel.text.association: '_StatusText"_StatusText
" Clé étrangère@ObjectModel.foreignKey.association: '_Customer"CustomerId,
" Transitoire (non persistant)@ObjectModel.virtualElement: true@ObjectModel.virtualElementCalculatedBy: 'ABAP:ZCL_ORDER_VIRTUAL"CalculatedFieldExtensions de métadonnées
" Fichier d'annotation séparé@Metadata.layer: #CUSTOMERannotate view ZC_Order with{ @UI.lineItem: [{ position: 10, importance: #HIGH }] @UI.identification: [{ position: 10 }] OrderId;
@UI.lineItem: [{ position: 20 }] @UI.hidden: true InternalField;
@UI.facet: [{ id: 'CustomSection', purpose: #STANDARD, type: #FIELDGROUP_REFERENCE, targetQualifier: 'Custom', label: 'Spécifique client', position: 100 }] _root;}Criticité (couleurs feu tricolore)
" Statut avec criticité@UI.lineItem: [{ criticality: 'StatusCriticality' }]Status,
" Champ de criticité calculécase Status when 'O' then 2 -- Jaune (Open) when 'C' then 3 -- Vert (Confirmed) when 'X' then 1 -- Rouge (Cancelled) else 0 -- Neutreend as StatusCriticality,
" Valeurs de criticité :" 0 = Neutre (Gris)" 1 = Négatif (Rouge)" 2 = Critique (Jaune/Orange)" 3 = Positif (Vert)" 5 = Nouvel élément (Bleu) - seulement pour certains contextesAides de valeurs
@Consumption.valueHelpDefinition: [{ entity: { name: 'ZI_Customer', element: 'CustomerId" }, additionalBinding: [{ element: 'CustomerName', localElement: 'CustomerName', usage: #RESULT }]}]CustomerId,
" Avec filtre@Consumption.valueHelpDefinition: [{ entity: { name: 'ZI_Status' }, qualifier: 'StatusVH', useForValidation: true}]@Consumption.filter: { selectionType: #SINGLE, multipleSelections: false}StatusContrôle d’accès
@AccessControl.authorizationCheck: #CHECK@AccessControl.privilegedAssociations: ['_Admin']define view entity ZI_Order
" DCL (Data Control Language)@EndUserText.label: 'Order Access Control"@MappingRole: truedefine role ZI_ORDER_DCL { grant select on ZI_Order where ( SalesOrg ) = aspect pfcg_auth( V_VBAK_VKO, VKORG, ACTVT = '03' ) and ( CustomerId ) = aspect pfcg_auth( Z_CUSTOMER, KUNNR, ACTVT = '03' );}Référence des annotations
| Annotation | Valeurs | Description |
|---|---|---|
| @UI.importance | #HIGH, #MEDIUM, #LOW | Priorité des colonnes |
| @UI.hidden | true/false | Masquer le champ |
| @Aggregation.default | #SUM, #AVG, #MIN, #MAX, #COUNT | Agrégation par défaut |
| @Analytics.dataCategory | #DIMENSION, #CUBE, #FACT | Catégorie analytique |
| @Search.ranking | #HIGH, #MEDIUM, #LOW | Priorité de recherche |
Bonnes pratiques
- Extensions de métadonnées : Garder les annotations UI séparées
- Utiliser Semantics : Pour les devises, quantités, champs système
- Labels cohérents : Utiliser EndUserText.label
- Criticité : Pour la mise en évidence visuelle
- Recherche : Rendre les champs importants recherchables
- Aides de valeurs : Aide à la saisie conviviale
Sujets connexes
- Vues CDS - Fondamentaux des Core Data Services
- Services OData - Services Web RESTful
- AMDP - Procédures de base de données
- Vérifications d’autorisation - Contrôle d’accès