Accueil Blog Comprendre l'attribut PXProjection d'Acumatica

Comprendre l'attribut PXProjection d'Acumatica

L'attribut PXProjection est utilisé pour définir une nouvelle classe de CAD dérivée de l'interface IBqlTable ou de tout autre CAD existant, avec des colonnes/champs/propriétés spécifiques provenant de CAD inclus dans une instruction de sélection qui définit les données gérées par cette nouvelle classe.
Dioris Aguilar | 26 juillet 2022

Comprendre l'attribut PXProjection d'Acumatica

Introduction

D'un certain point de vue, un ERP (Enterprise Resource Planning) est essentiellement un système de stockage et de manipulation des données saisies par les utilisateurs. Il s'agit d'un point de vue très général qui souligne l'importance de la gestion des données à l'intérieur du système.

Dans Acumatica, les données stockées dans la base de données sont gérées par une couche qui permet aux développeurs de manipuler les données sans interroger directement la base de données. Pour les développeurs Acumatica, il s'agit d'une couche d'abstraction bien connue - Business Query Language ou simplement BQL. Cette couche fournit de multiples façons de manipuler les données et l'une d'entre elles est l'attribut PXProjection.

Dans ce billet, nous allons nous pencher un peu plus sur cet attribut, nous passerons en revue certaines de ses propriétés, comment il peut être utilisé, et nous montrerons des scénarios courants où il s'applique.

Attribut PXProjection

Cet attribut est utilisé pour définir une nouvelle classe de CAD dérivée de l'interface IBqlTable ou de tout autre CAD existant, avec des colonnes/champs/propriétés spécifiques provenant des CAD inclus dans une instruction select qui définit les données gérées par cette nouvelle classe. D'un certain point de vue, nous pouvons considérer cette nouvelle classe de DAC comme l'équivalent d'une vue SQL, les deux définissant un ensemble de données à partir d'une instruction et les deux étant une table virtuelle, c'est-à-dire qu'il n'y a pas de table réelle dans la base de données avec leurs noms.

Voici un exemple de cette projection DAC utilisant INTranSplit comme DAC principal dans l'instruction select :

GIST : https://gist.github.com/Dioris/26e2bf16c5634fa550d6bd11482fd7fa

Le CAD de projection ci-dessus sélectionne les derniers documents d'entrée validés pour les articles sérialisés dans le système et nous pouvons l'utiliser dans une déclaration de vue pour afficher les enregistrements résultants dans l'interface utilisateur d'un écran comme ci-dessous :

GIST: https://gist.github.com/Dioris/2ef5dde25d6e9c361637834a8b60284c

ou nous pouvons l'utiliser directement dans une autre instruction BQL :

GIST: https://gist.github.com/Dioris/2149a44aab505a6c63c541423d6d85ba

Il ne fait aucun doute que l'exemple ci-dessus est un peu complexe, mais il montre à quel point un CAD de projection peut être utile pour traiter des ensembles de données complexes, en permettant de réduire la complexité de la BQL finale et en rendant possibles des requêtes difficiles.

Commençons par le début :

Il existe fondamentalement deux façons de déclarer un CAD de projection en ce qui concerne l'objet de base. Nous pouvons le définir en utilisant l'interface IBqlTable comme dans l'exemple ci-dessus, ou nous pouvons dériver la nouvelle classe à partir d'un CAD existant :

GIST: https://gist.github.com/Dioris/b3f322e3db560f8be6fac8caf7a62c36

Dans ce cas, les deux déclarations permettront de récupérer toutes les commandes clients approuvées. Cependant, la principale différence entre ces deux définitions est que la première vous oblige à déclarer les propriétés et les champs nécessaires, y compris au moins les champs clés. Pour la seconde définition, la nouvelle projection DAC hérite de tous les champs et propriétés de la classe de base(SOOrder).

Comme tout autre CAD, nous devons définir les champs clés pour fixer les conditions d'unicité de ses enregistrements en attribuant la propriété IsKey = true à l'attribut base. En reprenant le même exemple, nous devons déclarer les champs OrderType et OrderNbr pour la première déclaration :

GIST : https://gist.github.com/Dioris/37ecc07072c32f73aa1f4a0d29a6cb71

Remarquez que les propriétés ajoutées sont explicitement mappées à une propriété existante du DAC de l'instruction select en attribuant le type approprié à la propriété BqlField. Cependant, cela n'est pas nécessaire lorsque l'on dérive d'un DAC existant et que ce DAC est le même que celui utilisé dans l'instruction select, comme dans la deuxième définition.

Au cas où nous aurions besoin de modifier une propriété de base dérivée de la classe de base, nous devrions la surcharger comme suit :

GIST: https://gist.github.com/Dioris/dfdb49060df1f07a80e493864d0d91a4

Remarquez que la classe abstraite orderNbr est définie avec le nouveau modificateur pour masquer la définition de la classe de base. Cette nouvelle classe abstraite est normalement utilisée si cette propriété est utilisée dans une autre instruction Bql. La propriété OrderNbr doit avoir le modificateur override afin de définir les nouveaux attributs.

Comme indiqué initialement, l'instruction Select peut impliquer plus d'une table, ce qui signifie que nous devons mapper les champs nécessaires à partir des DAC supplémentaires au cas où un champ de ces derniers serait requis, sinon les DAC supplémentaires ne seront utilisés que pour filtrer les données que nous voulons.

Voici un exemple de projection d'un CAD pour récupérer des enregistrements de commandes clients avec un comportement différent de celui de RM :

GIST : https://gist.github.com/Dioris/d61f6b13ef068e3dd997d7be79a122e0

Dans ce cas, le DAC supplémentaire(SOOrderType) n'est utilisé qu'à des fins de filtrage puisque le nouveau DAC de projection ne mappe aucun champ de ce DAC supplémentaire(SOOrderType). Cependant, nous pourrions avoir un besoin particulier de mapper un champ de cette table. Dans ce cas, nous devons procéder comme suit :

GIST : https://gist.github.com/Dioris/a0620755584c73fb8e00ac96aea97bfd

Propriété persistante

Par défaut, le DAC de projection est en lecture seule, c'est-à-dire qu'il ne permet pas de persister les changements dans la base de données. Cependant, il existe une propriété Persistent qui permet de le faire en la définissant comme true, comme vous pouvez le voir ici :

GIST: https://gist.github.com/Dioris/403d482003d6b1f4979965ca0f1ea49f

Cette propriété vous permet de conserver les modifications apportées à la base de données, qu'elles soient insérées, supprimées ou mises à jour.

Bien entendu, les modifications peuvent être persistées dans toutes les tables/CAD impliquées dans l'instruction de sélection. Si les modifications apportées à la table principale sont persistantes et si plusieurs tables doivent être mises à jour dans le CAD de projection, la documentation indique que les champs mettant en œuvre la relation entre la table principale et les tables jointes doivent avoir l'attribut PXExtraKey pour permettre la mise à jour correcte appelée par la projection. Vous pouvez le voir clairement ci-dessous :

GIST: https://gist.github.com/Dioris/78c378c17ab91824bd0f38a6b0e986fc

Dans ce cas, la propriété OrderType est la seule impliquée dans la relation entre les deux tables et c'est là que l'attribut doit être placé.

Cet attribut comporte également une option permettant de définir une liste des tables qui doivent être persistantes. Dans ce cas, les tables qui n'en ont pas besoin peuvent être exclues :

GIST: https://gist.github.com/Dioris/9f41d1f189a129a3f789987a812298d9

Lorsque l'on utilise la propriétépersistante (sans majuscule) pour définir la liste des DAC à persister, la propriété Persistent est automatiquement fixée à true.

Important !

Lors de la mise à jour des modifications apportées à la base de données, tous les champs de tous les CED impliqués dans l'instruction de sélection ne sont pas mis à jour : seuls les champs mappés sont mis à jour..

Nous espérons que ces informations vous aideront à mieux comprendre cet attribut et à améliorer vos requêtes BQL.

Bon codage !

Auteur du blog

Dioris est entré dans le monde de l'informatique en tant qu'ingénieur en électronique en 2005 et a trouvé la carrière de programmeur très stimulante et attrayante. Il a fait partie de l'équipe qui a créé le module Field Service, acquis plus tard par Acumatica. Aujourd'hui, il conçoit et fournit des solutions personnalisées et des intégrations à la demande. Il a passé une partie de sa carrière à fournir un support technique à des personnes ne connaissant pas la technologie, ce qui l'a aidé à concevoir des solutions centrées sur le client et visant à fournir une expérience utilisateur fluide sur le produit final. En tant qu'ancien employé d'Acumatica, il connaît la puissance qui se cache derrière le framework et aime rester impliqué dans l'écosystème.

Recevez les mises à jour du blog dans votre boîte de réception.