将未绑定字段中的行总数相加

时间:2018-10-01 12:26:24

标签: acumatica

我正在尝试修改PO301000以在“文档”视图中添加一个“总计”未绑定字段,该字段求和“网格事务”选项卡上POLine的OrderQty。

我想使用PXUnboundFormula,但该字段保持为0。

这就是我尝试过的:

dac定义:

public abstract class usrTotalLignes : IBqlField { }
[PXDecimal]
[PXDefault(TypeCode.Decimal, "0.0")]
[PXUIField(DisplayName = "Total des lignes")]
public virtual Decimal? UsrTotalLignes { get; set; }

这似乎可行。

我也遵循了T100:

protected virtual void POLine_RowInserted(PXCache sender, PXRowInsertedEventArgs e)
        {
            POLine orderLine = (POLine)e.Row;
            POOrder order = Base.Document.Current;
            POOrderExt orderExt = order.GetExtension<POOrderExt>();
            bool isLineUpdated = false;

            if (orderLine != null)
            {
                orderExt.UsrTotalLignes += orderLine.OrderQty;
                isLineUpdated = true;
            }

            if (isLineUpdated)
            {
                Base.Document.Update(order);
            }
        }

        protected virtual void POLine_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
        {
            POLine newOrderLine = (POLine)e.Row;
            POLine oldOrderLine = (POLine)e.OldRow;
            POOrder order = Base.Document.Current;
            POOrderExt orderExt = order.GetExtension<POOrderExt>();
            bool isLineUpdated = false;

            if (!sender.ObjectsEqual<POLine.orderQty>(newOrderLine, oldOrderLine))
            {
                if (oldOrderLine.OrderQty != null)
                {
                    orderExt.UsrTotalLignes -= oldOrderLine.OrderQty;
                }
                if (newOrderLine.OrderQty != null)
                {
                    orderExt.UsrTotalLignes += newOrderLine.OrderQty;
                }
                isLineUpdated = true;
            }

            if (isLineUpdated)
            {
                Base.Document.Update(order);
            }
        }

        protected virtual void POLine_RowDeleted(PXCache sender, PXRowDeletedEventArgs e)
        {
            POLine orderLine = (POLine)e.Row;
            POOrder order = Base.Document.Current;
            POOrderExt orderExt = order.GetExtension<POOrderExt>();
            bool isLineUpdated = false;

            if (orderLine != null)
            {
                orderExt.UsrTotalLignes -= orderLine.OrderQty;
                isLineUpdated = true;
            }

            if (isLineUpdated)
            {
                Base.Document.Update(order);
            }
        }

我在添加,编辑或删除行时可以使用。

现在我的问题是,当我想在页面加载时设置此未绑定字段的值时,这是我尝试过的事情:

[PXDecimal]
[PXDefault(TypeCode.Decimal, "0.0")]
[PXUIField(DisplayName = "Total des lignes")]
[PXUnboundFormula(typeof(POLine.orderQty), typeof(SumCalc<POOrderExt.usrTotalLignes>))]
public virtual void POOrder_UsrTotalLignes_CacheAttached(PXCache sender)
{

}

我尝试了:

[PXDecimal]
[PXDefault(TypeCode.Decimal, "0.0")]
[PXUIField(DisplayName = "Total des lignes")]
[PXUnboundFormula(typeof(Sum<POLine.orderQty>), typeof(SumCalc<POOrderExt.usrTotalLignes>))]
public virtual void POOrder_UsrTotalLignes_CacheAttached(PXCache sender)
{

}

但是它仍然保持为0。

我也尝试添加:

[PXParent(typeof(Select<POOrder, Where<POOrder.orderNbr, Equal<Current<POLine.orderNbr>>, 
            And<POOrder.orderType, Equal<Current<POLine.orderType>>>>>))]

但是它无限循环并崩溃。

这是我尝试过的东西(在t300中找到):

protected void POOrder_RowSelecting(PXCache sender, PXRowSelectingEventArgs e)
{
    POOrder order = (POOrder)e.Row;
    if (order == null) return;

    var extension = PXCache<POOrder>.GetExtension<POOrderExt>(order);
    using (PXConnectionScope cs = new PXConnectionScope())
    {
        extension.UsrTotalLignes = 0;
        foreach(POLine line in PXSelectReadonly<POLine, 
            Where<POLine.orderNbr, Equal<Required<POOrder.orderNbr>>, 
                And<POLine.orderType, Equal<Required<POOrder.orderType>>>>>.Select(Base, order.OrderNbr, order.OrderType))
        {
            extension.UsrTotalLignes += line.OrderQty;
        }
    }
}

这实际上是可行的,但是仅当我修改一个字段时(如果我加载一个较旧的记录,直到我对其进行修改,它才写入值,它才起作用),如何要求UI刷新缓存的值?

我的错误在哪里?

编辑:

我设法将其与之配合使用:

protected void POOrder_RowSelecting(PXCache sender, PXRowSelectingEventArgs e)
        {
            POOrder order = (POOrder)sender.Current;
            if (order == null) return;

            var extension = PXCache<POOrder>.GetExtension<POOrderExt>(order);
            using (PXConnectionScope cs = new PXConnectionScope())
            {
                extension.UsrTotalLignes = 0;
                foreach(POLine line in PXSelectReadonly<POLine, 
                    Where<POLine.orderNbr, Equal<Required<POOrder.orderNbr>>, 
                        And<POLine.orderType, Equal<Required<POOrder.orderType>>>>>.Select(Base, order.OrderNbr, order.OrderType))
                {
                    extension.UsrTotalLignes += line.OrderQty;
                }
            }
            Base.Document.Current.GetExtension<POOrderExt>().UsrTotalLignes = extension.UsrTotalLignes;
        }

我必须使用:

POOrder order = (POOrder)sender.Current;

代替

POOrder order = (POOrder)e.Row 

由于某种原因我没有得到,第一次加载记录时它工作正常。然后,当我更改其中包含“提交”的任何字段时,它再次调用rowSelectingEvent,而这次e.row是列表中的下一个POOrder。

有人知道为什么这样做吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

您可以使用现有的字段“ OrderQty”,但不会在UI中显示。您可以直接编辑.aspx文件,并将DataField =“ OrderQty”替换为要添加的新字段,也可以从自定义项目中添加字段。看看下面的截图。 enter image description here enter image description here

答案 1 :(得分:2)

正如John的回答所提到的那样,在POLine.OrderQty DAC字段中有一个PXFormula属性,该属性具有一个SumCalc BQL元素,该元素以POOrder.orderQty的总字段为目标。

#region OrderQty
public abstract class orderQty : PX.Data.IBqlField
{
}
protected Decimal? _OrderQty;
[PXDBQuantity(typeof(POLineS.uOM), typeof(POLineS.baseOrderQty), HandleEmptyKey = true, BqlField = typeof(POLine.orderQty))]
[PXDefault(TypeCode.Decimal, "0.0")]
[PXFormula(null, typeof(SumCalc<POOrder.orderQty>))]
[PXUIField(DisplayName = "Order Qty.", Visibility = PXUIVisibility.Visible)]
public virtual Decimal? OrderQty
{
    get
    {
        return this._OrderQty;
    }
    set
    {
        this._OrderQty = value;
    }
}
#endregion

有时候,您可能需要实现更复杂的逻辑,而这对于简单的公式总和计算而言并不适合。

您可以扩展POOrderEntry并在Base Transactions DataView上调用Select以迭代“文档详细信息”选项卡中显示的所有记录,并手动求和每行的OrderQty:

public class POOrderEntry_Extension : PXGraphExtension<POOrderEntry>
{      
  public virtual void POOrder_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
  {
      POOrder order = e.Row as POOrder;

      if (order != null)
      {
        sender.SetValue<POOrderExt.usrTotalQuantiteCommande>(order, ComputeQuantiteCommandeTotal());
      }
  }

  public virtual void POOrder_UsrTotalQuantiteCommande_FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
  {
      e.ReturnValue = ComputeQuantiteCommandeTotal();
  }

  public virtual decimal ComputeQuantiteCommandeTotal()
  {
      decimal total = 0M;

      foreach (POLine line in Base.Transactions.Select())
      {
          total += (line.OrderQty != null ? line.OrderQty.Value : 0M);
      }

      return total;
  }
}