Como desarrolladores, a veces en nuestro trabajo, a menudo necesitamos actualizar listas de registros del mismo tipo sin abrir cada uno en la pantalla para actualizar. Este proceso se puede realizar con una pantalla de tratamiento. No hace mucho, tuve una solicitud de un cliente para actualizar los recibos de compra que aún no se habían publicado. Tienen un producto cuyo precio cambia casi a diario y trabajan con un margen pequeño por lo que es importante mantener el coste del producto en línea con los precios actuales.
Para ello, creé una pantalla de procesamiento que seleccionaría una lista de registros de recepción de pedidos y actualizaría el campo Coste unitario de las partidas y la programé para que se ejecutara una vez al día. A medida que se liberaban las partidas, se eliminaban de la lista de registros y dejaban de actualizarse.
Creación de pantallas de procesamiento personalizadas
Veamos cómo crear una pantalla de procesamiento personalizada. Cubriremos los elementos de la siguiente captura de pantalla y descubriremos cómo añadirlos a la pantalla. Luego veremos algunos errores básicos en el manejo de la pantalla de procesamiento. El código en el ayudante de procesamiento necesita implementar un bloque try catch entonces los errores fluirán hacia arriba.
La siguiente captura de pantalla muestra cómo se verá la salida de su procesamiento después de la ejecución - esperemos que sin errores.
El primer elemento que debe tener es la columna seleccionada en su pantalla como muestra la siguiente imagen.
Escribir el código
Para lograrlo, debe hacer dos cosas. En primer lugar, añada este campo al DAC que es la clase principal para los registros de procesamiento. Si utiliza un DAC incorporado, es posible que el campo ya esté presente. Aquí está el código para su DAC. En segundo lugar, asegúrese de que está desvinculado y añada la línea de código XML a su página aspx como se muestra a continuación.
#region Selected
public abstract class selected : IBqlField { }
[PXBool]
[PXUIField(DisplayName = “Selected”)]
public virtual bool? Selected { get; set; }
#endregion
Aquí está el código aspx que necesitamos:
En tercer lugar, tenemos que añadir un botón de cancelación como se muestra en la siguiente captura de pantalla.
El botón de cancelación se añadirá con una sola línea de código.
public PXCancel Cancelar;
El resto de elementos provendrán de las clases PXProcessing, PXProcessingJoin, PXFilterProcessing y se añadirán a la pantalla utilizando una de ellas.
El siguiente es un patrón que utilizo para procesar pantallas. Estas pantallas parecen sencillas, pero pueden ser muy complejas. Nuestro primer paso es obtener la lista de registros a procesar. He incluido un ejemplo de los registros de selección BQL a continuación.
public PXProcessing<POReceipt, Where<POReceipt.usrProcessed, NotEqual>> PagePrimaryView;
Se trata del processing select. Tiene otras variaciones: PXProcessingJoin, PXFilterProcessing, etc. y tiene que ser su vista primaria para la página y usando esta vista agregará sus botones Process, ProcessAll a la pantalla.
El segmento de código que muestro a continuación es lo que utilizo para recorrer los registros de uno en uno, hacer el procesamiento de un registro a la vez y, a continuación, si tiene éxito, escribir un mensaje de éxito. Si se produce un error, se inserta un mensaje de error en la línea y se establece la bandera de error global. El proceso llamará a un gráfico ayudante de proceso para el procesamiento o puedes extender un gráfico estándar para incluir el código del proceso. Este método le permitirá utilizar métodos incorporados de la pantalla y finalmente marcar el registro completo de alguna manera. Lo importante es que este método se marque como estático o no podrás verlo en el construtor para enlazarlo a la lista de registros. Por eso se usa un segundo gráfico para hacer los detalles del procesamiento y marcar el registro como completo. Debajo de esto está el código para establecer el método de proceso de la lista PXProcessing . Esto se hace en el constructor que es también el conjunto seleccionado que es parte de la magia para seleccionar todos los registros cuando se pulsa el botón ProcessAll .
Por último, añadimos una propiedad overridden para el gráfico IsDirty, evitando que la página intente guardar los cambios.
#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
Así que ahora todo lo que tienes que hacer es crear tu página aspx utilizando una plantilla Form Detail o ListView.
<%@ 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>
Sólo 48 líneas de código para crear la página, la mayoría de los botones se construyen en lo que no requiere mucho código más allá de eso.
Esperemos que todas tus páginas se vean así al final. El código difícil para estas páginas está en los métodos de proceso y está fuera del alcance de este post, ya que cada uno es diferente y tiene muchos requisitos.
Conclusión
Para proporcionar un breve resumen de lo que he demostrado aquí, hemos creado un poco de código C # para incluir un nuevo gráfico con un botón de cancelar, un PXProcessing BQL seleccionar, un bucle de plantilla para procesar nuestros registros, un constructor para vincular el método de proceso a la lista de registros, y un valor anulado a la caché de propiedad sucia.
Espero que esto le dará una buena ventaja para el uso de pantallas de procesamiento. ¡Feliz programación!