Introduction
Application des techniques et concepts de base
Utilisation des classes locales
Lecture des données de la base de données
Utilisation d'objets de données structurés
Utilisation de tables internes complexes
Implémentation de mises à jour de base de données à l'aide d'objets de gestion
Description du modèle de programmation d'applications ABAP RESTful

Ajout de la logique ABAP

Objective

After completing this lesson, you will be able to implémentez le comportement d'un objet de gestion.

Validations

Vérification de la clé sémantique

Dans le modèle de programmation d'applications ABAP RESTful, la clé d'une table de base de données est souvent constituée de la zone mandant et d'une zone UUID, dont la valeur est affectée automatiquement par l'exécution lorsque vous créez une nouvelle instance de l'objet de gestion. Cette combinaison de zones est suffisante pour que le système puisse identifier chaque enregistrement dans la table de manière univoque. Cependant, en plus de cette clé technique, notre objet possède également une clé sémantique - dans ce cas, la combinaison de compagnie aérienne et de numéro de vol, qui doit également être unique selon la logique de gestion. Pour garantir l'unicité de cette combinaison de zones, vous devez implémenter votre propre contrôle sous la forme d'une validation.

Vous déclarez les validations dans la définition de comportement de l'entité de vue CDS et vous les implémentez dans la classe d'implémentation de comportement.

Contrôles de saisie dans l'application

Outre le contrôle de la clé sémantique, il existe d'autres contrôles que vous devez effectuer. Par exemple, bien que l'application générée vous permette de créer, lire, mettre à jour et supprimer des données, elle ne contient pas encore de contrôles de cohérence. Par conséquent, vous pouvez créer des liaisons aériennes pour les compagnies aériennes qui n'existent pas ou pour lesquelles les aéroports de départ et de destination sont identiques.

Pour éviter cela, vous définissez d'autres validations dans la définition de comportement et vous les implémentez dans la classe d'implémentation de comportement.

Création de textes de message

Avant de créer la validation, vous devez créer les textes que vous voulez afficher. Pour ce faire, utilisez une classe de messages. Une classe de messages est une collection de 1 000 messages au maximum appartenant à un domaine d'application particulier. Comme le montre la figure, chaque texte a un numéro qui identifie le message de manière unique dans la classe de messages.

Pour créer une nouvelle classe de messages, procédez comme suit :

  1. Sélectionnez FichierNouveauAutre… et saisissez le message dans la zone de filtre.

  2. Double-cliquez sur l'entrée Classe de messages dans la liste des occurrences, puis saisissez un package, un nom et une description pour la nouvelle classe de messages. Cliquez sur Next.

  3. Affectez la classe de messages à un ordre de transport et sélectionnez Terminer.

Les messages peuvent également contenir des caractères génériques qui sont remplacés par des valeurs concrètes lors de l'affichage du message. Les espaces réservés sont signalés par une esperluette suivie d'un nombre. Vous pouvez utiliser jusqu'à quatre caractères génériques dans chaque message.

Définition de la validation

Pour définir une validation, vous ajoutez une déclaration de validation à la définition de comportement de votre objet de gestion. Dans cet exemple, la validation doit être effectuée chaque fois que l'utilisateur sauvegarde un enregistrement de données, ce qui peut être le cas lors de la création de l'enregistrement ou s'il le modifie ultérieurement.

Lorsque vous définissez la validation dans la définition du comportement, un avertissement vous indique que la méthode correspondante n'existe pas. Utilisez un correctif rapide (combinaison de touches CTRL + 1) pour ajouter la méthode à l'implémentation de comportement. L'implémentation de comportement est une classe locale dans votre pool de comportements. La définition de méthode contient l'option FOR VALIDATE ON SAVE, qui l'identifie comme implémentation de la validation. Il a un paramètre d'import KEYS. Il s'agit d'une table interne contenant les clés des objets créés ou modifiés. Vous les utilisez pour lire les données réelles que l'utilisateur a saisies.

L'option FOR Connection~CheckSemanticKey relie la méthode à la validation CheckSemanticKey à partir de la définition de comportement. Ici, Connexion est le nom d'alias de l'entité de vue Z_R_CONNECTION.

Lorsque vous définissez une validation, vous devez également créer son implémentation. Il s'agit d'une méthode dans le pool de comportements. La manière la plus simple de le faire est d'utiliser un correctif rapide. Positionnez le curseur sur le nom de la validation et appuyez sur CTRL + 1. ADT propose de créer la méthode. Double-cliquez sur la proposition pour créer la méthode.

Processus de validation

Remarque

Certains exemples de code dans cette section utilisent des instructions SELECT à l'intérieur de boucles. Cela a été fait pour garder les exemples simples. Notez que les SELECT dans les boucles peuvent entraîner des problèmes de performance et doivent être évités.

Lorsque le système déclenche une validation, il appelle l'implémentation correspondante. Le paramètre d'import KEYS contient les clés des enregistrements de données modifiés. Vous utilisez les clés pour lire les zones des enregistrements dont vous avez besoin à l'aide de Entity Manipulation Language (EML). EML est un ensemble spécial d'instructions dans ABAP qui vous permet d'adresser des objets de gestion.

Une fois que vous avez lu les données, vous pouvez effectuer les contrôles dont vous avez besoin. Si le contrôle échoue, vous devez éditer un message d'erreur approprié et, surtout, indiquer au framework de ne pas écrire les modifications dans la base de données.

La première tâche d'une validation consiste à lire l'entrée utilisateur. Pour ce faire, utilisez l'instruction Entity Manipulation Language (EML) READ ENTITIES. Les clés des enregistrements de données correspondants sont transmises à la validation à l'aide des clés de paramètre d'importation.

Les zones dont vous avez besoin pour valider la clé sémantique sont CarrierID pour la compagnie aérienne et ConnectionID pour le numéro de vol.

L'extrait de code utilise le mot-clé CORRESPONDING et une déclaration en ligne pour l'ensemble de résultats. Ci-dessous, vous voyez le code équivalent à l'aide de variables définies explicitement, ce qui facilite la compréhension des types utilisés.

Code Snippet
12345678910111213
DATA read_keys TYPE TABLE FOR READ IMPORT zs4d400_r_connection. DATA connections TYPE TABLE FOR READ RESULT zs4d400_r_connection. read_keys = CORRESPONDING #( keys ). READ ENTITIES OF zs4d400_r_connection IN LOCAL MODE ENTITY Connection FIELDS ( CarrierID ConnectionID ) WITH read_keys RESULT connections.

Une fois que vous avez lu l'entrée utilisateur, vous pouvez utiliser les valeurs de CarrierID et ConnectionID pour voir si cette clé sémantique a déjà été utilisée dans un autre ensemble de données que celui que vous êtes en train de traiter. Étant donné que la combinaison-clé peut se trouver dans la table active ou la table en version préliminaire, vous devez rechercher les deux et la manière la plus efficace de le faire est avec une union.

L'ensemble de résultats de cette requête doit toujours être vide. Si ce n'est pas le cas, il existe d'autres enregistrements avec la même combinaison d'ID de transporteur et d'ID de connexion, ce qui signifie que l'enregistrement que l'utilisateur tente actuellement de créer est un doublon et doit être refusé.

Si la combinaison d'ID de transporteur et d'ID de connexion existe déjà, il y aura une entrée dans la table check_result. Dans ce cas, vous devez éditer un message.

La première étape consiste à créer un objet de message. Pour ce faire, utilisez l'auto-référence me et appelez la méthode new_message( ). Les paramètres ID, nombre et degré de gravité sont obligatoires. ID est le nom de la classe de messages qui contient le message ; le numéro est le numéro du message. Le degré de gravité classifie le message comme message de réussite, d'information, d'avertissement ou d'erreur. La classe d'implémentation de comportement contient une constante structurée ms dont les composantes représentent les différents degrés de gravité. Dans ce cas, vous avez besoin du degré de gravité ms-erreur.

La méthode a également des paramètres d'importation facultatifs v1, v2, v3 et v4. Vous les utilisez pour remplacer les caractères génériques par des valeurs concrètes. Dans cet exemple, le caractère générique &1 est remplacé par le code de compagnie aérienne, le caractère générique &2 est remplacé par le numéro de vol.

Le résultat de l'appel de méthode est une référence d'objet. Au cours de l'étape suivante, vous allez transmettre l'objet à l'exécution afin que le message d'erreur soit renvoyé au service OData et affiché dans l'aperçu de l'application.

Pour que la durée d'exécution affiche un message, vous devez le signaler à l'aide de la structure du reporting financier. Il s'agit d'un paramètre de modification implicite de toutes les méthodes de validation et il s'agit d'une structure arborescente. Il contient un composant avec le nom d'alias de l'entité. Cette composante est une table interne.

Pour signaler le message, vous devez effectuer trois actions :

  1. Ajoutez la clé de l'enregistrement concerné à la table interne. Pour ce faire, utilisez le groupe de zones %tky. Lorsque vous regroupez des champs comme celui-ci, vous pouvez adresser le nom du groupe au lieu de devoir adresser chaque champ individuellement.
  2. Joignez l'objet de message à la table. Pour ce faire, affectez la référence d'objet de l'objet de message à la composante %msg de la table interne.
  3. Liez le message à la zone concernée. Cela garantit que la zone est mise en évidence dans l'application. Cela aide à son tour l'utilisateur à mieux naviguer dans l'application. Pour ce faire, utilisez le composant %element de la table interne.

Dans cet exemple, rapport_enregistrement est une structure avec le type de ligne de la connexion de rapport de table interne. Vous renseignez la composante %tky avec le contenu du groupe de zones %tky dans la connexion de structure. Cette structure de connexion est utilisée comme espace de travail pour la table interne contenant les données saisies par l'utilisateur. Ensuite, vous affectez l'objet de message que vous avez créé à l'aide de la méthode new_message( ) au composant %msg. Enfin, pour lier le message aux zones CarrierID et ConnectionID, vous utilisez la structure %element. %element contient un composant pour chaque champ de l'entité. Si vous définissez un composant sur Vrai, la zone de saisie correspondante sera mise en surbrillance dans l'application. Pour ce faire, utilisez la constante structurée if_abap_behv=>mk. Composant activé pour coché/vrai et désactivé pour décoché/faux.

Vous ne pouvez pas utiliser les constantes globales abap_true et abap_false à ce stade car leurs types de données ne sont pas compatibles.

En plus d'éditer le message, vous devez également indiquer à la durée d'exécution de ne pas sauvegarder les données incorrectes. Pour ce faire, vous utilisez la structure ayant échoué de la méthode de validation. Échec est un paramètre de modification implicite présent dans toutes les méthodes de validation.

Pour signaler un enregistrement comme ayant échoué, ajoutez son groupe de champs %tky au groupe de champs %tky de la table interne en échec - Connexion.

La validation suivante vérifie que la compagnie aérienne que l'utilisateur a saisie existe réellement. La première étape consiste à lire l'entrée utilisateur à l'aide de l'instruction EML READ ENTITIES. Cette fois-ci, il vous suffit de lire la zone ID du transporteur.

L'instruction SELECT SINGLE lit les données à l'aide de l'entité de vue CDS /dmo/i_Carrier et vérifie si la compagnie aérienne indiquée existe. Si c'est le cas, la valeur de la constante globale abap_true ("X") est placée dans la zone. S'il existe une valeur initiale suite à l'instruction SELECT, vous devez éditer un message, le signaler et ajouter l'enregistrement à la structure ayant échoué comme vous l'avez fait dans l'exemple précédent.

La validation finale vérifie que les aéroports d'origine et de destination sont différents. La première étape consiste à lire l'entrée utilisateur à l'aide d'une instruction READ ENTITIES. Cette fois, les zones AirportFromID et AirportToID sont pertinentes.

Si les aéroports de départ et d'arrivée sont identiques, vous devez éditer le message correspondant et renseigner les structures signalées et ayant échoué. L'extrait de code affiche le codage pertinent pour créer le message. Le codage permettant de renseigner les structures signalées et ayant échoué est le même que dans les exemples précédents.

Validation de la clé sémantique

Déterminations

Déterminer les villes en fonction des codes d'aéroport

Dans l'exemple d'application, l'entité de liaison aérienne contient un aéroport de départ, une ville et un pays, ainsi qu'un aéroport d'arrivée, une ville et un pays. Bien qu’il soit possible de forcer l’utilisateur à saisir toutes ces informations, il est préférable en termes d’expérience utilisateur et de cohérence des données que l’utilisateur saisisse uniquement les codes d’aéroport et que l’application lise les informations correspondantes sur la ville et le pays à partir de la base de données. Dans le modèle de programmation d'applications ABAP RESTful, vous pouvez exécuter ce type de tâche à l'aide d'une détermination.

Vous allez d'abord implémenter la détermination. Vous apprendrez ensuite à désactiver la saisie pour les zones qui seront renseignées automatiquement.

Définition de la détermination

Vous définissez une détermination dans la définition du comportement d'un objet de gestion. La détermination s'appelle ici getCities, elle est appelée chaque fois que l'objet de gestion est sauvegardé et qu'au moins l'une des zones AirportFromID et AirportToID a été modifiée. Vous pouvez utiliser un correctif rapide dans la définition de comportement pour créer la méthode correspondante dans l'implémentation de comportement.

Processus de détermination

Voyons chaque étape du processus de détermination.

Lorsque le système déclenche une détermination, il appelle l'implémentation correspondante. Le paramètre d'import KEYS contient les clés des enregistrements de données modifiés. Dans la méthode de détermination, vous utilisez EML pour lire les données sur la base des clés exactement de la même manière que dans les validations. Cependant, dans une détermination, vous manipulez également les données dans la méthode et vous devez par conséquent mettre à jour les données détenues par la structure à l'aide de l'instruction EML UPDATE.

Remarque

Certains exemples de code dans cette section utilisent des instructions SELECT à l'intérieur de boucles. Cela a été fait pour garder les exemples simples. Notez que les SELECT dans les boucles peuvent entraîner des problèmes de performance et doivent être évités.

Au début de la détermination, vous lisez l'entrée utilisateur à l'aide d'EML. Vous avez besoin des champs AirportFromID et AirportToID et les utiliserez pour renseigner les informations sur la ville et le pays.

Le modèle de données de démonstration fournit une entité de vue CDS /dmo/i_airport que vous pouvez utiliser pour lire la ville et le pays dans lesquels se trouve un aéroport particulier. L'exemple utilise la variante de la clause INTO dans laquelle vous indiquez explicitement les zones de la structure que vous voulez renseigner. N'oubliez pas que les modifications apportées aux données se trouvent dans l'espace de travail de la table interne et que vous devez les retourner à la table elle-même à l'aide de l'instruction MODIFY.

L'instruction READ ENTITIES renvoie une table interne avec le type dérivé FOR READ RESULT. Pour modifier les données dans la mémoire tampon transactionnelle, vous avez besoin d'une instruction MODIFY ENTITIES. Vous transférez les données que vous voulez modifier à cette instruction à l'aide d'une table interne avec le type dérivé FOR UPDATE. Les zones de données sont identiques dans les deux types, mais la table FOR UPDATE a une structure supplémentaire appelée %control qui contient des informations de gestion.

Vous ne pouvez pas transmettre la table de connexions à l'instruction MODIFY ENTITIES. Vous devez donc copier vos données dans une table interne de type approprié (connections_upd) avant d'effectuer la modification réelle.

Pour mettre à jour les données avec les zones que vous avez renseignées dans la détermination, vous utilisez l'instruction MODIFY ENTITIES. Vous y indiquez les zones qui doivent être mises à jour dans la clause FIELDS et transférez les données dans une table interne à l'aide de l'option WITH. Cette table doit avoir le type de données dérivé correct, qui dans ce cas serait TYPE TABLE FOR UPDATE zsd4d400_r_connection.

L'instruction MODIFY ENTITIES peut renvoyer des messages que vous recevez à l'aide de la clause REPORTED. Vous propagez ensuite ces messages à votre propre objet de gestion en copiant le contenu de la table interne dans la structure REPORTED de la méthode de détermination.

Comment déterminer les villes et les pays

Valider le prix du vol

Dans cet exercice, vous définissez et implémentez une validation pour le prix du vol.

Modèle :

  • Aucune

Solution :

  • /LRN/S4D400_R_FLIGHT (définition de comportement)
  • /LRN/BP_S4D400_R_FLIGHT (classe globale)

Conditions requises

Vous avez terminé les exercices précédents. Vous avez créé et renseigné la table de base de données Z##FLIGHT (où ## est votre numéro de groupe) et généré les objets de développement pour un service IU OData.

Tâche 1: Valider le prix

Définissez et implémentez une validation pour vérifier que la zone Price a une valeur positive (nom suggéré : validatePrice). Si la valeur est négative ou égale à zéro, refusez la modification et signalez un message d'erreur approprié de la classe de messages /LRN/S4D400.

Étapes

  1. Dans la définition de comportement ZR_##FLIGHT, définissez une nouvelle validation validatePrice. Assurez-vous que la validation est toujours exécutée lors de l'opération standard Créer, mais uniquement si la valeur du Prix a été modifiée pour toutes les autres opérations.

    Astuce

    Dans la mesure du possible, utilisez la saisie semi-automatique du code.
    1. Ouvrez la définition de comportement ZR_##FLIGHT.

    2. Adaptez le code comme suit :

      Code Snippet
      12345
      create; update; delete; validation validatePrice on save { create; field Price; }
  2. Activez la définition de comportement.

    1. Appuyez sur Ctrl + F3 pour activer la définition de comportement.

  3. Utilisez un correctif rapide pour créer la méthode d'implémentation de validation dans la classe Handler de comportement.

    1. Positionnez le curseur sur le nom de la validation et sélectionnez Ctrl + 1.

    2. Double-cliquez sur l'entrée Ajouter méthode pour validation....

  4. Au début de la méthode validatePrice, déclarez un objet de données structuré que vous saisissez avec le type de ligne de vol en échec (nom suggéré : failed_record). De même, déclarez un objet de données structuré que vous tapez avec le type de ligne de vol signalé (nom suggéré : rapport_enregistrement).

    Remarque

    Ces structures seront utilisées pour ajouter des lignes au vol en échec et au vol signalé, au cas où la validation détecterait une erreur.
    1. Ajoutez le code suivant :

      Code Snippet
      12
      DATA failed_record LIKE LINE OF failed-flight. DATA reported_record LIKE LINE OF reported-flight.
  5. Utilisez une instruction READ ENTITIES pour lire l'entrée utilisateur à partir de la mémoire tampon transactionnelle. Utilisez l'option EN MODE LOCAL et assurez-vous que seules les zones clés et la zone Prix sont lues. Utilisez une déclaration en ligne pour l'ensemble de résultats (nom suggéré : vols).

    Remarque

    Il n'est pas nécessaire de répertorier les zones clés après l'option FIELDS. READ ENTITIES lit toujours les zones clés.
    1. Après les déclarations, ajoutez le code suivant en remplaçant ## par votre numéro de groupe :

      Code Snippet
      12345
      READ ENTITIES OF ZR_##Flight IN LOCAL MODE ENTITY Flight FIELDS ( Price ) WITH CORRESPONDING #( keys ) RESULT DATA(flights).
  6. Implémentez une boucle sur les données que vous venez de lire. Utilisez une déclaration en ligne pour l'espace de travail (nom suggéré : vol).

    1. Après l'instruction EML, ajoutez le code suivant :

      Code Snippet
      123
      LOOP AT flights INTO DATA(flight). ENDLOOP.
  7. Dans la boucle, vérifiez si le composant Prix est supérieur à zéro. Si ce n'est pas le cas, renseignez la structure failed_record avec la clé du vol actuel et ajoutez-la comme nouvelle ligne dans la table failed-flight. De même, remplissez la structure prétend_record avec la clé du vol en cours et ajoutez-la comme nouvelle ligne au tableau de bord.

    Astuce

    Dans les objets de gestion compatibles avec les versions préliminaires, il est recommandé d'utiliser le composant %tky pour affecter la clé.
    1. Dans la boucle, ajoutez le code suivant :

      Code Snippet
      12345678
      IF flight-price <= 0. failed_record-%tky = flight-%tky. APPEND failed_record TO failed-flight. reported_record-%tky = flight-%tky. APPEND reported_record TO reported-flight. ENDIF.
  8. Avant l'instruction APPEND, renseignez le composant %msg de la structure Notid_record avec une référence à un objet de message. Pour créer l'objet message, appelez la méthode new_message avec l'entrée suivante :

    Nom du paramètreValeur
    ID"/LRN/S4D400"
    numéro"101"
    degré de gravitéms-erreur
    1. Adaptez le code comme suit :

      Code Snippet
      123456789101112131415
      LOOP AT flights INTO DATA(flight). IF flight-price <= 0. failed_record-%tky = flight-%tky. APPEND failed_record TO failed-flight. reported_record-%tky = flight-%tky. reported_record-%msg = new_message( id = '/LRN/S4D400' number = '101' severity = ms-error ). APPEND reported_record TO reported-flight. ENDIF. ENDLOOP.
  9. Activez la classe.

    1. Appuyez sur Ctrl + F3 pour activer la classe.

Tâche 2: Test et débogage

Définissez un point d'arrêt dans l'implémentation de validation. Relancez l'aperçu du service IU OData et modifiez le prix d'un vol existant. Effectuez des entrées valides et non valides et déboguez la validation.

Étapes

  1. Définissez un point d'arrêt au niveau de l'instruction READ ENTITIES de la méthode validatePrice.

    1. Dans l'implémentation de la méthode validatePrice, recherchez l'instruction READ ENTITIES et double-cliquez sur la zone à gauche du numéro de ligne pour définir un point d'arrêt.

  2. Relancez l'aperçu du service IU OData.

    1. Fermez la fenêtre ou l'onglet du navigateur qui contient l'aperçu.

    2. Ouvrez la liaison de service ZUI_##FLIGHT_O4. Dans la liste Ensemble d'entités et association à droite, sélectionnez d'abord l'entrée Vol, puis Aperçu....

  3. Dans l'application, affichez la liste des vols, ouvrez les détails de l'un des vols et passez en mode de modification.

    1. Procédez comme vous l'avez fait dans les exercices précédents.

  4. Apportez des modifications au prix, puis sélectionnez Sauvegarder. Analysez la validation dans le débogueur.

    1. Procédez comme vous l'avez fait dans les exercices précédents.