我具有到自定义屏幕的文档/事务(FormGrid)结构。当标题中的“保留”框未选中时,我需要验证“事务”级别中的值。从根本上讲,我的挑战似乎来自事件处理程序的操作顺序。 (FieldVerifying-> FieldUpdating-> Field Updated-> RowUpdating-> RowUpdated)与已处理视图的顺序结合在一起(似乎是其他视图之前的主要视图)。
我现在完全感到困惑的是,如果我将该字段留在表单的事务(网格)部分中,则CommitChanges将触发,并且一切正常。但是,如果我将字段(OrderQty)设置为0,然后立即取消选中标题中的Hold而没有先“保留” OrderQty字段,则直到处理Hold复选框后才提交OrderQty值。这意味着我无法验证OrderQty大于0。从字面上看,我无法在缓存或任何形式的视图中看到我的OrderQty值,因为在表格中的OrderQty之前处理标题中的保留框。
我已经尝试了简单的方法来进行测试,这是一小段尝试获取数据的摘要。 Caches []。Updated在处理保留复选框之后(而不是在此之后)保留新值。 AddWithoutDuplicates是一种简单地确保列表中没有记录的方法(允许查看更新的缓存值,而不是尚未提交的旧值)
List<SSRQLine> list = new List<SSRQLine>();
foreach (SSRQLine line in Caches[typeof(SSRQLine)].Updated)
{
AddWithoutDuplicates(list, line);
}
foreach (SSRQLine line in Caches[typeof(SSRQLine)].Inserted)
{
AddWithoutDuplicates(list, line);
}
foreach (SSRQLine line in Lines.Select())
{
AddWithoutDuplicates(list, line);
}
foreach (SSRQLine line in list)
...
是否有方法在输入期间可靠地从保留复选框验证网格数据?还是必须稍后在RowPersisting事件中处理验证?或关于其他如何通过Hold_FieldVerifying验证网格中用户输入的建议?
父DAC为SSRQRequisition,子DAC为SSRQLine。
由于目标是监视取消保留的请求,因此最初的工作将附加到标头DAC的保留字段。问题在于,它需要在子DAC未处理其现场事件的一对多关系中验证子DAC值。要警告用户但不阻止保存请求,请创建以下事件处理程序:
#region SSRQLine_OrderQty_FieldVerifying
protected virtual void _(Events.FieldVerifying<SSRQLine.orderQty> e)
{
SSRQLine row = (SSRQLine) e.Row;
if((decimal?)e.NewValue == 0)
{
e.Cache.RaiseExceptionHandling<SSRQLine.orderQty>(e.Row, row.OrderQty, new PXSetPropertyException(Messages.InvalidQuantity, PXErrorLevel.Warning));
}
}
#endregion
要重新验证整个请求,然后允许用户在取消请求后将其保存,请在标头DAC的RowPersisting事件处理程序中执行验证。请注意,如果要删除请求,则不应执行验证,因此也要对操作进行测试。此外,仅当用户取消保留请求时才需要进行测试,因此在放回保留状态时无需进行验证。
#region SSRQRequisition_RowPersisting
protected void _(Events.RowPersisting<SSRQRequisition> e)
{
SSRQRequisition row = e.Row;
if (e.Operation != PXDBOperation.Delete && row?.Hold == false)
{
ValidateConsignment();
}
}
#endregion
已创建ValidateConsignment方法以简化代码读取,但由SSRQRequisition RowPersisting事件调用。通过这次将异常处理提高为ERROR并引发异常,可以警告用户,警告现在可以阻止保存记录而不保留记录。
#region ValidateConsignment
protected virtual void ValidateConsignment()
{
int lineCounter = 0;
SSRQRequisition req = Requisitions.Current;
List<SSRQLine> list = new List<SSRQLine>();
foreach (SSRQLine line in Caches[typeof(SSRQLine)].Updated)
{
AddWithoutDuplicates(list, line);
}
foreach (SSRQLine line in Caches[typeof(SSRQLine)].Inserted)
{
AddWithoutDuplicates(list, line);
}
foreach (SSRQLine line in Lines.Select())
{
AddWithoutDuplicates(list, line);
}
foreach (SSRQLine line in list)
{
lineCounter++;
if (line.SiteID == null)
{
throw new PXSetPropertyException(Messages.NoWhse, PXErrorLevel.Error);
}
if (line.OrderQty == null || line.OrderQty == 0)
{
this.Lines.Cache.RaiseExceptionHandling<SSRQLine.orderQty>(line, line.OrderQty, new PXSetPropertyException(Messages.InvalidQuantity, PXErrorLevel.Error));
throw new PXSetPropertyException(Messages.InvalidQuantity, PXErrorLevel.Error);
}
}
if (lineCounter == 0)
{
this.Lines.Cache.RaiseExceptionHandling<SSRQRequisition.hold>(req, req.Hold, new PXSetPropertyException(Messages.NoLines, PXErrorLevel.Error));
throw new PXSetPropertyException(Messages.NoLines, PXErrorLevel.Error);
}
}
#endregion
ValidateConsignment方法当前在缓存的插入和更新副本之间循环,但是我可以删除这些副本,因为在将更新应用于缓存之前不再对其进行测试。正如现在从RowPersisting方法中调用的那样,所有用于在缓存中插入和更新记录的字段和行事件处理程序都应该已经应用。但是,在删除它们之前,我将做进一步的测试。初步测试确认所提供的代码已达到目标。为了提供所需的最终用户体验,只需将代码分散到3个不同的事件中,而不是将代码全部塞入最初打算启动检查的“保留”复选框中。行为最终与最初预期的行为略有不同,但是结果是更加用户友好,并实现了相同的目标。