En tant que développeurs, nous avons parfois besoin, dans notre travail, de mettre à jour des listes d'enregistrements du même type sans ouvrir chacun d'entre eux dans l'écran à mettre à jour. Ce processus peut être réalisé à l'aide d'un écran de traitement. Il n'y a pas longtemps, un client m'a demandé de mettre à jour les reçus d'achat qui n'avaient pas encore été publiés. Ils ont un produit dont le prix change presque quotidiennement et ils travaillent avec une petite marge, il est donc important de garder le coût du produit en ligne avec les prix actuels.
Pour ce faire, j'ai créé un écran de traitement qui sélectionnerait une liste d'enregistrements de bons de commande et mettrait à jour le champ Coût unitaire des postes, et je l'ai programmé pour qu'il s'exécute une fois par jour. Au fur et à mesure que les articles étaient libérés, ils disparaissaient de la liste des enregistrements et n'étaient plus mis à jour.
Création d'écrans de traitement personnalisés
Voyons donc comment créer un écran de traitement personnalisé. Nous aborderons les éléments de la capture d'écran ci-dessous et découvrirons comment les ajouter à votre écran. Nous verrons ensuite comment gérer les erreurs de base dans l'écran de traitement. Le code de l'assistant de traitement doit mettre en œuvre un bloc try catch pour que les erreurs remontent.
La capture d'écran ci-dessous montre à quoi ressemblera la sortie de votre traitement après exécution - en espérant qu'il n'y ait pas d'erreur.
Le premier élément dont vous avez besoin est la colonne sélectionnée dans votre écran, comme le montre l'image suivante.
Rédiger le code
Pour ce faire, vous devez procéder de deux manières. Premièrement, ajoutez ce champ au CED, qui est la classe primaire des enregistrements de traitement. Si vous utilisez un CED intégré, il se peut que le champ soit déjà présent. Voici le code de votre CAD. Deuxièmement, assurez-vous qu'il n'est pas lié et ajoutez la ligne de code XML à votre page aspx comme indiqué ci-dessous.
#region Selected
public abstract class selected : IBqlField { }
[PXBool]
[PXUIField(DisplayName = “Selected”)]
public virtual bool? Selected { get; set; }
#endregion
Voici le code aspx dont nous avons besoin :
Troisièmement, nous devons ajouter un bouton d'annulation, comme le montre la capture d'écran suivante.
Le bouton d'annulation sera ajouté avec une seule ligne de code.
public PXCancel Cancel ;
Les autres éléments proviennent des classes PXProcessing, PXProcessingJoin, PXFilterProcessing et sont ajoutés à l'écran en utilisant l'une d'entre elles.
Voici un modèle que j'utilise pour traiter les écrans. Ces écrans semblent simples, mais ils peuvent être très complexes. La première étape consiste à obtenir la liste des enregistrements à traiter. J'ai inclus un exemple de sélection d'enregistrements BQL ci-dessous.
public PXProcessing<POReceipt, Where<POReceipt.usrProcessed, NotEqual>> PagePrimaryView;
Il s'agit de la sélection de traitement. Il existe d'autres variantes : PXProcessingJoin, PXFilterProcessing, etc. Elle doit être la vue principale de la page et son utilisation ajoutera les boutons Process, ProcessAll à l'écran.
Le segment de code que je montre ci-dessous est celui que j'utilise pour parcourir les enregistrements un par un, effectuer le traitement un enregistrement à la fois, puis, en cas de succès, écrire un message de réussite. En cas d'erreur, un message d'erreur est inséré dans la ligne et le drapeau d'erreur global est activé. Le processus appellera un graphique d'aide au traitement ou vous pouvez étendre un graphique standard pour inclure le code du processus. Cette méthode vous permettra d'utiliser les méthodes intégrées de l'écran et, enfin, de marquer l'enregistrement d'une manière ou d'une autre. Ce qui est important, c'est que cette méthode soit marquée comme statique, sinon vous ne pourrez pas la voir dans le constructeur pour établir un lien avec la liste des enregistrements. C'est pourquoi vous utilisez un second graphique pour traiter les détails et marquer votre enregistrement comme complet. Ci-dessous se trouve le code permettant de définir la méthode de traitement de la liste PXProcessing . Ceci est fait dans le constructeur qui est aussi le set selected qui est une partie de la magie pour sélectionner tous les enregistrements lorsque le bouton ProcessAll est pressé.
Enfin, nous ajoutons une propriété surchargée pour le graphique IsDirty, ce qui empêche la page d'essayer d'enregistrer les modifications.
#region Process Receipts List
//method is static, list of records from pxprocessing select
private static void ProcessReceiptList(IList records)
{
//here set variable for global error message.
var globalError = false;
//here I have a variable for the po receipt nbr to tie to the lines
var receiptNbr = string.Empty;
//here I create the graph that will do the processing, can be custom graph also
var graph = CreateInstance();
//here I get a handle to graph extension to be able to use the added methods.
var graphExt = graph.GetExtension();
//now cycle through the list of records and process each.
foreach (var record in records)
{
//here I have a local variable for each line
var lineError = false;
//it is also possible to add transaction support here if only needed for the line item
try
{
//clear the receipt graph of the last record
graph.Clear();
//assign the new receipt nbr for messages
receiptNbr = record.ReceiptNbr;
//set the next record to be processed to the current of the graph
graph.Document.Current = record;
//call the process method that I added to the po receipt entry graph
graphExt.ProcessPrice();
//then save the results, including the processed flag or condition
graph.Save.Press();
}
//catch any errors that happen in the receipt graph and format the message here, you can
also write code to a log or record extension to fix the error
catch (Exception e)
{
//set line error to true so will skip the process correct below
lineError = true;
//set globaError flag to true to get the global message
globalError = true;
//create a custom error message to post on the grid
var message = “Error Processing PO Receipt Transaction: “ + receiptNbr + “: “ +
e.Message;
//add the custom error message to the grid line PXProcessing.SetError(records.IndexOf(record), message);
}
//create a process complete message and assign to the grid line
var messageTwo = “PO Receipt Transaction: “ + receiptNbr + ” Was Processed.”;
if (!lineError) PXProcessing.SetInfo(records.IndexOf(record), messageTwo);
}
//add last create the global error message that displays at the top of the screen
if (globalError) throw new PXException(“At Least One PO Receipt Transaction Was Not
Processed.”);
}
#endregion
#region Constructor
public ProcessPOReceipts()
{
PagePrimaryView.SetProcessDelegate(ProcessReceiptList);
PagePrimaryView.SetSelected();
}
#endregion
#region Overridden Properties
public override bool IsDirty => false;
#endregion
Il ne vous reste donc plus qu'à créer votre page aspx en utilisant un modèle de formulaire détaillé ou de liste.
<%@ Page Language=”C#” MasterPageFile=”~/MasterPages/ListView.master” AutoEventWireup=”true” ValidateRequest=”false” CodeFile=”AM501060.aspx.cs” Inherits=”Page_AM501060″ Title=”Untitled Page” %>
<%@ MasterType VirtualPath=”~/MasterPages/ListView.master” %>
<asp:Content ID=”cont1″ ContentPlaceHolderID=”phDS” runat=”Server”>
<px:PXDataSource ID=”ds” runat=”server” Visible=”True” Width=”100%” TypeName=”AM.Objects.ProcessPOReceipts” PrimaryView=”PagePrimaryView”>
<CallbackCommands/>
</px:PXDataSource>
</asp:Content>
<asp:Content ID=”cont2″ ContentPlaceHolderID=”phL” runat=”Server”>
<px:PXGrid ID=”grid” runat=”server” Height=”400px” Width=”100%” Style=”z-index: 100″ ActionsPosition=”Top” FilesIndicator=”False” NoteIndicator=”False”
AllowSearch=”True” DataSourceID=”ds” SkinID=”PrimaryInquire” FastFilterFields=”PlantTransNbr”>
<Levels>
<px:PXGridLevel DataMember=”PagePrimaryView”>
<RowTemplate>
<px:PXSelector ID=”edReceiptNbr” runat=”server” DataField=”ReceiptNbr” AllowEdit=”True”/>
<px:PXSelector ID=”edUsrPurContractID” runat=”server” DataField=”UsrPurContractID” AllowEdit=”True”/>
<px:PXSelector ID=”edUsrSpecID” runat=”server” DataField=”UsrSpecID” AllowEdit=”True”/>
<px:PXSegmentMask ID=”edUsrStockItemID” runat=”server” DataField=”UsrStockItemID” AllowEdit=”True” />
<px:PXSegmentMask ID=”edVendorID” runat=”server” DataField=”VendorID” AllowEdit=”True” DisplayMode=”Text”/>
</RowTemplate>
<Columns>
<px:PXGridColumn DataField=”Selected” TextAlign=”Center” Type=”CheckBox” Width=”30″ AllowCheckAll=”True” AllowSort=”False” AllowMove=”False”/>
<px:PXGridColumn DataField=”ReceiptNbr” Width=”90″/>
<px:PXGridColumn DataField=”ReceiptDate” Width=”90″/>
<px:PXGridColumn DataField=”Status” Width=”80″/>
<px:PXGridColumn DataField=”UsrTransStatus” Type=”DropDownList” Width=”110″/>
<px:PXGridColumn DataField=”UsrPurContractID” Width=”100″/>
<px:PXGridColumn DataField=”UsrCalculateDaily” TextAlign=”Center” Type=”CheckBox” Width=”80″/>
<px:PXGridColumn DataField=”UsrPricingComplete” TextAlign=”Center” Type=”CheckBox” Width=”80″/>
<px:PXGridColumn DataField=”UsrInvTransfered” TextAlign=”Center” Type=”CheckBox” Width=”90″/>
<px:PXGridColumn DataField=”UsrInvAdjusted” TextAlign=”Center” Type=”CheckBox” Width=”90″/>
<px:PXGridColumn DataField=”UsrIsComplete” TextAlign=”Center” Type=”CheckBox” Width=”90″/>
<px:PXGridColumn DataField=”UsrSpecID” Width=”90″/>
<px:PXGridColumn DataField=”UsrStockItemID” Width=”100″/>
<px:PXGridColumn DataField=”InvoiceNbr” Width=”110″/>
<px:PXGridColumn DataField=”UsrShippedDate” Width=”90″/>
<px:PXGridColumn DataField=”UsrDeliveredDate” Width=”90″/>
<px:PXGridColumn DataField=”VendorID” AllowUpdate=”False” Width=”340px” DisplayMode=”Text”/>
</Columns>
</px:PXGridLevel>
</Levels>
<ActionBar PagerVisible=”Bottom”>
<PagerSettings Mode=”NumericCompact”/>
</ActionBar>
<AutoSize Container=”Window” Enabled=”True” MinHeight=”200″ />
</px:PXGrid>
</asp:Content>
Seulement 48 lignes de code pour créer la page, la plupart des boutons sont intégrés et ne nécessiteront donc pas beaucoup de codage au-delà.
Nous espérons que toutes vos pages ressembleront à cela à la fin. Le code difficile de ces pages se trouve dans les méthodes de traitement et n'entre pas dans le cadre de cet article, car chaque page est différente et a de nombreuses exigences.
Conclusion
Pour récapituler brièvement ce que j'ai démontré ici, nous avons créé du code C# pour inclure un nouveau graphique avec un bouton d'annulation, une sélection BQL PXProcessing, une boucle modèle pour traiter nos enregistrements, un constructeur pour lier la méthode de traitement à la liste d'enregistrements et une valeur surchargée pour la propriété cache dirty.
J'espère que cela vous donnera une bonne longueur d'avance dans l'utilisation des écrans de traitement. Bon codage !