Acumatica PXFormula属性为';计算不正确

Acumatica PXFormula属性为';计算不正确,acumatica,Acumatica,我对SalesOrder(SO301000)屏幕进行了如下定制: 我在标题部分(SOOrder)上创建了一个名为“总收入”(SOOrderExt.UsrTotalRevenue)的用户字段: 我在网格(SOLine.CuryLineAmt)的Ext.Price字段中添加了一个PXFormula属性,如下所示: 这将正确计算,直到有人试图复制订单以创建另一个订单。当这种情况发生时,该值将加倍-就好像它是原始订单加上复制订单的总和。此时,即使您删除了复制顺序中的行项目,它也会保留标题中的

我对SalesOrder(SO301000)屏幕进行了如下定制:

  • 我在标题部分(SOOrder)上创建了一个名为“总收入”(SOOrderExt.UsrTotalRevenue)的用户字段:

  • 我在网格(SOLine.CuryLineAmt)的Ext.Price字段中添加了一个PXFormula属性,如下所示:


这将正确计算,直到有人试图复制订单以创建另一个订单。当这种情况发生时,该值将加倍-就好像它是原始订单加上复制订单的总和。此时,即使您删除了复制顺序中的行项目,它也会保留标题中的摘要值。我不知道从哪里得到这个值。我漏了一步吗?是否需要在某处添加某种类型的刷新?

如果需要从复制中排除字段值,可以在数据视图上使用PXCopyPasteHiddenFieldsAttribute

这是销售订单条目的当前文档视图。您需要扩展图形,包括视图,并将字段添加到排除字段的列表中。类似于我下面的东西

[PXCopyPasteHiddenFields(typeof(SOOrder.cancelled), typeof(SOOrder.preAuthTranNumber), typeof(SOOrder.ownerID), typeof(SOOrder.workgroupID), typeof(SOOrder.UsrTotalRevenue))]
public PXSelect<SOOrder, Where<SOOrder.orderType, Equal<Current<SOOrder.orderType>>, And<SOOrder.orderNbr, Equal<Current<SOOrder.orderNbr>>>>> CurrentDocument;
[PXCopyPasteHiddenFields(typeof(SOOrder.cancelled)、typeof(SOOrder.preAuthTranNumber)、typeof(SOOrder.ownerID)、typeof(SOOrder.workgroupID)、typeof(SOOrder.UsrTotalRevenue))]
公共文件;
sumcalc公式的工作方式是它将差值相加,而不是求和。因此,对已经过时的值进行更改不会自行“修复”。例如,如果您添加了一个值为11的销售线,那么它将只添加11 vs,以尝试汇总所有销售线。同样,如果你删除,它只会减去11。这就是为什么您无法删除用户字段中的行以返回零


编辑:仅供参考,PXCopyPasteHiddenFieldsAttribute可直接用于DAC,而不仅仅是图形数据视图属性

例如:

[PXCopyPasteHiddenFields(
    typeof(MyBaseDacExtension.someField1), 
    typeof(MyBaseDacExtension.someField2)))]
[PXTable(typeof(MyBaseDac.keyField1), IsOptional = true)]
public class MyBaseDacExtension : PXCacheExtension<MyBaseDac>
{
...
}
[PXCopyPasteHiddenFields(
typeof(MyBaseDacExtension.someField1),
typeof(mybasedactension.someField2))]
[PXTable(typeof(MyBaseDac.keyField1),IsOptional=true)]
公共类MyBaseDacExtension:PXCacheExtension
{
...
}

如果需要从复制中排除字段值,可以在数据视图上使用PXCopyPasteHiddenFieldsAttribute

这是销售订单条目的当前文档视图。您需要扩展图形,包括视图,并将字段添加到排除字段的列表中。类似于我下面的东西

[PXCopyPasteHiddenFields(typeof(SOOrder.cancelled), typeof(SOOrder.preAuthTranNumber), typeof(SOOrder.ownerID), typeof(SOOrder.workgroupID), typeof(SOOrder.UsrTotalRevenue))]
public PXSelect<SOOrder, Where<SOOrder.orderType, Equal<Current<SOOrder.orderType>>, And<SOOrder.orderNbr, Equal<Current<SOOrder.orderNbr>>>>> CurrentDocument;
[PXCopyPasteHiddenFields(typeof(SOOrder.cancelled)、typeof(SOOrder.preAuthTranNumber)、typeof(SOOrder.ownerID)、typeof(SOOrder.workgroupID)、typeof(SOOrder.UsrTotalRevenue))]
公共文件;
sumcalc公式的工作方式是它将差值相加,而不是求和。因此,对已经过时的值进行更改不会自行“修复”。例如,如果您添加了一个值为11的销售线,那么它将只添加11 vs,以尝试汇总所有销售线。同样,如果你删除,它只会减去11。这就是为什么您无法删除用户字段中的行以返回零


编辑:仅供参考,PXCopyPasteHiddenFieldsAttribute可直接用于DAC,而不仅仅是图形数据视图属性

例如:

[PXCopyPasteHiddenFields(
    typeof(MyBaseDacExtension.someField1), 
    typeof(MyBaseDacExtension.someField2)))]
[PXTable(typeof(MyBaseDac.keyField1), IsOptional = true)]
public class MyBaseDacExtension : PXCacheExtension<MyBaseDac>
{
...
}
[PXCopyPasteHiddenFields(
typeof(MyBaseDacExtension.someField1),
typeof(mybasedactension.someField2))]
[PXTable(typeof(MyBaseDac.keyField1),IsOptional=true)]
公共类MyBaseDacExtension:PXCacheExtension
{
...
}

Brendan建议的解决方案肯定会起作用,但它似乎不能防弹,防止基础设施BLC的可能变化,并可能增加未来的维护成本

在Sales Orders(销售订单)屏幕上,由于BLC中实现的SOOrder_RowSelected处理程序,所有原始聚合值都不会重复-它确保始终将所有基本聚合字段的PXUIFieldAttribute的Enabled属性设置为False。这是唯一需要的额外步骤,因为
PXUIFieldAttribute.SetEnabled(缓存,doc,true)方法:

public class SOOrderEntry : PXGraph<SOOrderEntry, SOOrder>, PXImportAttribute.IPXPrepareItems
{
    ...

    protected virtual void SOOrder_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
    {
        SOOrder doc = e.Row as SOOrder;

        if (doc == null)
        {
            return;
        }

        ...

        bool allowAllocation = soordertype.Current != null && soordertype.Current.RequireAllocation != true
            || PXAccess.FeatureInstalled<FeaturesSet.warehouseLocation>()
            || PXAccess.FeatureInstalled<FeaturesSet.lotSerialTracking>()
            || PXAccess.FeatureInstalled<FeaturesSet.subItem>()
            || PXAccess.FeatureInstalled<FeaturesSet.replenishment>()
            || PXAccess.FeatureInstalled<FeaturesSet.sOToPOLink>();

        if (doc == null || doc.Completed == true || doc.Cancelled == true || !allowAllocation)
        {
            PXUIFieldAttribute.SetEnabled(cache, doc, false);
            cache.AllowDelete = false;
            cache.AllowUpdate = allowAllocation;

            ...
        }
        else
        {
            ...

            PXUIFieldAttribute.SetEnabled(cache, doc, true);
            PXUIFieldAttribute.SetEnabled<SOOrder.refTranExtNbr>(cache, doc, (doc.CreatePMInstance == true || doc.PMInstanceID.HasValue) && isCCPayment && isCashReturn && !isCCRefunded);
            PXUIFieldAttribute.SetEnabled<SOOrder.status>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.orderQty>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.orderWeight>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.orderVolume>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.packageWeight>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.curyOrderTotal>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.curyUnpaidBalance>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.curyLineTotal>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.curyMiscTot>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.curyFreightCost>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.freightCostIsValid>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.curyFreightAmt>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.curyTaxTotal>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.openOrderQty>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.curyOpenOrderTotal>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.curyOpenLineTotal>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.curyOpenTaxTotal>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.unbilledOrderQty>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.curyUnbilledOrderTotal>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.curyUnbilledLineTotal>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.curyUnbilledTaxTotal>(cache, doc, false);

            PXUIFieldAttribute.SetEnabled<SOOrder.curyPaymentTotal>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.curyID>(cache, doc, curyenabled);
            PXUIFieldAttribute.SetEnabled<SOOrder.preAuthTranNumber>(cache, doc, enableCCAuthEntering);
            PXUIFieldAttribute.SetEnabled<SOOrder.cCPaymentStateDescr>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.cCAuthExpirationDate>(cache, doc, enableCCAuthEntering && String.IsNullOrEmpty(doc.PreAuthTranNumber) == false);
            PXUIFieldAttribute.SetEnabled<SOOrder.curyCCPreAuthAmount>(cache, doc, enableCCAuthEntering && String.IsNullOrEmpty(doc.PreAuthTranNumber) == false);
            PXUIFieldAttribute.SetEnabled<SOOrder.pCResponseReasonText>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.captureTranNumber>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.curyCCCapturedAmt>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.origOrderType>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.origOrderNbr>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.curyVatExemptTotal>(cache, doc, false);
            PXUIFieldAttribute.SetEnabled<SOOrder.curyVatTaxableTotal>(cache, doc, false);

            ...
        }

        ...
    }

    ...
}
public类SOOrderEntry:PXGraph,PXImportAttribute.IPXPrepareItems
{
...
已选择受保护的虚拟空间(PXCache缓存、PXRowSelectedEventArgs e)
{
SOOrder doc=e.行作为SOOrder;
如果(doc==null)
{
回来
}
...
bool allowAllocation=soordertype.Current!=null&&soordertype.Current.requirereallocation!=true
||PXAccess.FeatureInstalled()
||PXAccess.FeatureInstalled()
||PXAccess.FeatureInstalled()
||PXAccess.FeatureInstalled()
||PXAccess.FeatureInstalled();
如果(doc==null | | | doc.Completed==true | | | doc.Cancelled==true | | | allowLocation)
{
PXUIFieldAttribute.SetEnabled(缓存、文档、假);
cache.AllowDelete=false;
cache.AllowUpdate=allowAllocation;
...
}
其他的
{
...
PXUIFieldAttribute.SetEnabled(缓存、文档、真);
PXUIFieldAttribute.SetEnabled(缓存,doc,(doc.CreatePMInstance==true | | | doc.PMInstanceID.HasValue)&&iscpayment&&isCashReturn&&isCCRefunded);
PXUIFieldAttribute.SetEnabled(缓存、文档、假);
PXUIFieldAttribute.SetEnabled(缓存、文档、假);
PXUIFieldAttribute.SetEnabled(缓存、文档、假);
PXUIFieldAttribute.SetEnabled(缓存、文档、假);
PXUIFieldAttribute.SetEnabled(缓存、文档、假);
PXUIFieldAttribute.SetEnabled(缓存、文档、假);
PXUIFieldAttribute.SetEnabled(缓存、文档、假);
PXUIFieldAttribute.SetEnabled(缓存、文档、假);
PXUIFieldAttribute.SetEnabled(缓存、文档、假);
PXUIFieldAttribute.SetEnab
<px:PXNumberEdit ID="edOrderQty" runat="server" DataField="OrderQty" Enabled="True" />
protected virtual void SOOrder_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
    SOOrder soorder = (SOOrder)e.Row;
    if (soorder == null) return;

    if (soorder != null && soorder.Completed != true && soorder.Cancelled != true && sender.AllowUpdate)
    {
        PXUIFieldAttribute.SetEnabled<SOOrder.orderQty>(sender, soorder, true);
    }
}
    public class SOOrderEntry : PXGraph<SOOrderEntry, SOOrder>, PXImportAttribute.IPXPrepareItems
    {
        ...

        public virtual void CopyOrderProc(SOOrder order, CopyParamFilter copyFilter)
        {
            ...
            foreach (PXResult<SOOrder, CurrencyInfo> res in PXSelectJoin<SOOrder, InnerJoin<CurrencyInfo, On<CurrencyInfo.curyInfoID, Equal<SOOrder.curyInfoID>>>, Where<SOOrder.orderType, Equal<Required<SOOrder.orderType>>, And<SOOrder.orderNbr, Equal<Required<SOOrder.orderNbr>>>>>.Select(this, order.OrderType, order.OrderNbr))
            {
                ...
                SOOrder copyorder = PXCache<SOOrder>.CreateCopy(quoteorder);
                ...
                copyorder.ShipmentCntr = 0;
                copyorder.OpenShipmentCntr = 0;
                copyorder.OpenLineCntr = 0;
                copyorder.ReleasedCntr = 0;
                copyorder.BilledCntr = 0;
                copyorder.OrderQty = 0m;
                copyorder.OrderWeight = 0m;
                copyorder.OrderVolume = 0m;
                copyorder.OpenOrderQty = 0m;
                copyorder.UnbilledOrderQty = 0m;
                copyorder.CuryInfoID = neworder.CuryInfoID;
                copyorder.Status = neworder.Status;
                copyorder.Hold = neworder.Hold;
                copyorder.Completed = neworder.Completed;
                copyorder.Cancelled = neworder.Cancelled;
                copyorder.InclCustOpenOrders = neworder.InclCustOpenOrders;
                copyorder.OrderDate = neworder.OrderDate;
                copyorder.RequestDate = neworder.RequestDate;
                copyorder.ShipDate = neworder.ShipDate;
                copyorder.CuryMiscTot = 0m;
                copyorder.CuryUnbilledMiscTot = 0m;
                copyorder.CuryLineTotal = 0m;
                copyorder.CuryOpenLineTotal = 0m;
                copyorder.CuryUnbilledLineTotal = 0m;
                copyorder.CuryVatExemptTotal = 0m;
                copyorder.CuryVatTaxableTotal = 0m;
                copyorder.CuryTaxTotal = 0m;
                copyorder.CuryOrderTotal = 0m;
                copyorder.CuryOpenOrderTotal = 0m;
                copyorder.CuryOpenTaxTotal = 0m;
                copyorder.CuryUnbilledOrderTotal = 0m;
                copyorder.CuryUnbilledTaxTotal = 0m;
                ...
            }
            ...
        }
        ...
    }
public class SOOrderEntryExt : PXGraphExtension<SOOrderEntry>
{
    public delegate void CopyOrderProcDel(SOOrder order, CopyParamFilter copyFilter);

    [PXOverride]
    public void CopyOrderProc(SOOrder order, CopyParamFilter copyFilter, CopyOrderProcDel del)
    {
        Base.RowSelecting.AddHandler<SOOrder>((sender, e) =>
        {
            if (e.Row == null) return;

            SOOrderExt orderExt = sender.GetExtension<SOOrderExt>(e.Row);
            orderExt.UsrTotalRevenue = 0m;
        });
        del(order, copyFilter);
    }
}