【问题标题】:PXFormula attribute isn't calculating correctlyPXFormula 属性计算不正确
【发布时间】:2017-01-25 02:14:46
【问题描述】:

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

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

  • 我已将 PXFormula 属性添加到分机。网格中的价格字段 (SOLine.CuryLineAmt) 如下:

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

【问题讨论】:

  • 嗨,@pmfith。它看起来像从原始销售订单中复制的第一个值,然后公式添加自己的计算值。这个问题需要调查。也许公式不正确或不完整地支持自定义字段。
  • 您是说这需要 Acumatica 方面的调查吗?我们如何从这里开始?

标签: acumatica


【解决方案1】:

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

            ...
        }

        ...
    }

    ...
}

话虽如此,要解决自定义聚合字段值加倍的问题,您应该遵循下面列出的 2 个步骤。这些是从粘贴文档时使用的模板中排除自定义聚合字段所必需的。

  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" />
    

关于@Dmitry Kasatsky 分享的担忧:周五晚上,彼得通过电子邮件向我发送了他的自定义设置,我用它来验证上述两步方法。根据报告的场景,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&lt;SOOrder.orderQty&gt;(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);
    }
}

这将启用订购数量。字段并最终导致复制粘贴文档中的重复值:

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

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

  2. 从剪贴板菜单中选择 Save as Template… 选项并验证生成的文档模板中是否存在自定义字段:

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

【讨论】:

  • 我实际上已经禁用了该字段,就像您显示的那样(没有 if 语句,因为我总是希望它被禁用 - 并且使用 PXUIField 属性设置 enabled=false 什么都不做 - 它仍然处于启用状态) .它仍然是金额的两倍。顺便说一句,我完全按照您在上面指定的方式对其进行了编码,并且在您复制订单时它仍然会加倍。
  • 嗨,@RuslanDev。您可以创建有关此问题的支持案例吗?我需要一个正式的计划工作理由。我们知道自定义字段中的公式存在一些问题。这个问题必须全面探讨和解决。在应用程序代码中制作魔法拐杖 - 这是一种不好的做法。
  • 这种方法在 2018R2 中仍然行不通。上面接受的将数量初始化为 0 的答案确实有效。
【解决方案2】:

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

  1. 当使用剪贴板菜单中的复制粘贴按钮时(在上面的答案中解决):

  2. “操作”下拉按钮中的“复制订单”操作:

通过查看 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);
    }
}

【讨论】:

  • 此方法的工作原理是它以新顺序正确设置值。但它使原始订单(被复制的订单)的值为 0。有没有办法让原始订单和副本最终都获得正确的价值?
【解决方案3】:

如果您需要从复制中排除字段值,您可以在数据视图上使用 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 公式的工作方式是添加差异,而不是总和。因此,对已经不正常的值进行更改不会自行“修复”它。例如,如果您添加一条值为 11 的销售线,它只会添加 11,而不是尝试对所有销售线求和。如果你删除也是一样,它只会减去 11。这就是为什么你不能删除行以在你的用户字段中恢复为零。

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

例子:

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

【讨论】:

  • 我不太明白你的回答。我不确定这意味着什么。我了解 sumcalc 的工作方式,但我不明白您对 PXCopyPastHiddenFields 属性的评论。无论如何,我将该属性添加到我的图形扩展中的 CurrentDocument 视图中,它没有任何区别。仍然翻倍。
  • 您的问题似乎是在您的 usr 字段中复制了该值,然后 sumcalc 触发重新添加该值(结果为双倍)。通过使用 PXCopyPasteHiddenFields,您将不会复制 usr 字段中的值,然后让 sum calc 将其相加。如果做得正确,我不明白为什么这不起作用。
  • 仅供参考,PXCopyPasteHiddenFieldsAttribute 可用于直接在类上声明的 DAC,而不仅仅是图形数据视图属性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-02
  • 1970-01-01
  • 2020-11-26
  • 1970-01-01
相关资源
最近更新 更多