PXFormula属性未正确计算

时间:2016-12-08 15:19:00

标签: acumatica

我对SalesOrder(SO301000)屏幕进行了自定义,如下所示:

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

enter image description here

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

enter image description here

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

3 个答案:

答案 0 :(得分:2)

Brendan建议的解决方案肯定会起作用,但是它似乎不再是基于SOOrderEntry BLC的可能的变化,并且可能在未来增加维护成本。

在销售订单屏幕上,由于在BLC中实施了SOOrder_RowSelected处理程序,所有原始聚合值都不会重复 - 它确保始终将所有基本聚合字段的PXUIFieldAttribute的Enabled属性设置为False。这是唯一需要的额外步骤,因为在SOOrder_RowSelected处理程序的中间调用了PXUIFieldAttribute.SetEnabled(cache, 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);

            ...
        }

        ...
    }

    ...
}

话虽如此,要解决双倍自定义聚合字段值的问题,您应该按照下面列出的两个步骤。从粘贴文档时使用的模板中排除自定义聚合字段是必要的。

  1. 在SOOrderEntry BLC扩展中为SOOrder DAC实现RowSelected处理程序,以便为自定义字段将PXUIFieldAttribute的Enabled属性设置为False:

    public class SOOrderEntryExt : PXGraphExtension<SOOrderEntry>
    {
        public void SOOrder_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
        {
            var doc = e.Row as SOOrder;
            if (doc == null) return;
    
            if (doc != null && doc.Completed != true && doc.Cancelled != true && sender.AllowUpdate)
            {
                PXUIFieldAttribute.SetEnabled<SOOrderExt.usrTotalRevenue>(sender, doc, false);
            }
        }
    }
    
  2. 对于自定义聚合字段输入控件,请在Aspx页面中将Enabled属性设置为False:

    <px:PXNumberEdit DataField=“UsrTotalRevenue” Enabled="False" runat="server" ID="CstPXNumberEdit19" />
    
  3. 关于@Dmitry Kasatsky分享的问题:周五晚上,Peter通过电子邮件向我发送了他的定制,我用它来验证上述两步法。根据报告的方案,PXFormulaAttribute和自定义字段未发现任何问题。如果您关心PXFormulaAttribute和Copy-Paste功能,请将基本OrderQty字段输入控件的enabled属性设置为True(等于默认属性值):

    <px:PXNumberEdit ID="edOrderQty" runat="server" DataField="OrderQty" Enabled="True" />
    

    并在SOOrderEntry BLC扩展中为SOOrder DAC实现RowSelected处理程序以从SOOrderEntry BLC撤消PXUIFieldAttribute.SetEnabled<SOOrder.orderQty>(cache, doc, false);命令:

    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);
        }
    }
    

    这将启用Ordered Qty。字段并最终导致复制粘贴文档中的重复值:

    enter image description here

    enter image description here

    供将来参考,检查文档模板是否包含自定义字段:

    1. 重新启动IIS或回收应用程序池以清除以前缓存的Acumatica ScreenInfo

    2. 从剪贴板菜单中选择 另存为模板... 选项,并验证生成的文档模板中是否存在自定义字段: enter image description here

    3. 请注意:具有空值的字段将始终从文档模板中排除

答案 1 :(得分:1)

如果您需要从复制中排除字段值,则可以在数据视图中使用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;

sumcalc公式的工作方式是增加差异,而不是总和。因此,对已经脱离了wack的值进行更改将不会“自我修复”。例如,如果您添加一个值为11的销售线,则只需添加11与尝试总结所有销售线。如果你删除它也一样,它只会减去11.这就是为什么你不能删除你的用户字段中的行回到零的原因。

编辑:其他人的FYI,PXCopyPasteHiddenFieldsAttribute可以直接在DAC上使用,而不仅仅是图数据视图属性。

示例:

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

答案 2 :(得分:0)

根据我们今天早些时候与Peter的讨论,最初有2个不同的场景导致自定义聚合字段值加倍:

  1. 从剪贴板菜单中使用复制粘贴按钮(在上面的答案中解决): enter image description here

  2. “操作”下拉按钮中的“复制顺序”操作: enter image description here

  3. 通过探索SOOrderentry.CopyOrderProc方法的源代码,您应该注意到在复制顺序功能期间有一堆具有指定0值的字段(其中包括最初在“销售订单”屏幕上找到的聚合字段):

        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;
                    ...
                }
                ...
            }
            ...
        }
    

    要解决“复制顺序”操作中双重自定义聚合字段值的问题,您应该简单地覆盖SOOrderEntry BLC扩展中的CopyOrderProc方法,并在方法内部订阅RowSelecting处理程序,以将0值分配给自定义聚合基础产品流程后面的字段:

    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);
        }
    }