Acumatica 如何禁用销售订单屏幕折扣计算

Acumatica 如何禁用销售订单屏幕折扣计算,acumatica,Acumatica,我对销售订单进行了修改,需要使用派生值更新销售订单行单价。这很好,新的单价在项目被选中并且SOLine_RowUpdate事件中的我的代码被执行后显示。但是,在选择数量后,将再次执行SOLine_RowUpdate,然后系统会像通常一样计算折扣。由于我有我自己的价格,不应该打折,我想超车或取消这个标准的折扣计算,只留下我的价格是。下面是SOLine_Row更新代码,它运行良好 protected virtual void SOLine_RowUpdating(PXCache sender, PX

我对销售订单进行了修改,需要使用派生值更新销售订单行单价。这很好,新的单价在项目被选中并且SOLine_RowUpdate事件中的我的代码被执行后显示。但是,在选择数量后,将再次执行SOLine_RowUpdate,然后系统会像通常一样计算折扣。由于我有我自己的价格,不应该打折,我想超车或取消这个标准的折扣计算,只留下我的价格是。下面是SOLine_Row更新代码,它运行良好

protected virtual void SOLine_RowUpdating(PXCache sender, PXRowUpdatingEventArgs e)
 {
   if (e.NewRow == null) {return; }

  Customer customer = Base.customer.Current;
  if (customer == null) return;

  SOLine soLine = (SOLine)e.NewRow;
  int BAAccountID = Convert.ToInt32(customer.BAccountID);
  int lCompanyID = PX.Data.Update.PXInstanceHelper.CurrentCompany;
  int lInventoryID = Convert.ToInt32(soLine.InventoryID);

  LookupPriceAndDiscountDetails(BAAccountID, lCompanyID, lInventoryID);  // My own code
  sender.SetValueExt<SOLine.curyUnitPrice>(soLine, gdNewUnitPrice);      //New price is in gdNewUnitPrice

  Base.Transactions.Cache.RaiseRowUpdated(soLine, soLine);
  Base.Transactions.View.RequestRefresh();
}
protected virtual void SOLine\u行更新(PXCache sender,pxrowupdateingeventargs e)
{
如果(e.NewRow==null){return;}
客户=Base.Customer.Current;
如果(客户==null)返回;
索林索林=(索林)e.纽罗;
int-BAAccountID=Convert.ToInt32(customer.BAccountID);
int lCompanyID=PX.Data.Update.PXInstanceHelper.CurrentCompany;
int lInventoryID=Convert.ToInt32(soLine.InventoryID);
LookupPriceAndDiscountDetails(baaccounted、lCompanyID、lInventoryID);//我自己的代码
sender.SetValueExt(soLine,gdNewUnitPrice);//新价格在gdNewUnitPrice中
Base.Transactions.Cache.RaiseRowUpdated(soLine,soLine);
Base.Transactions.View.RequestRefresh();
}
经过大量调查后,我发现各种帖子都建议使用这种方法来清除/取消折扣,事实上,我可以在标准的PX.Objects.SO.SOOrderEntry Row_Updated事件中找到它,但当我在我的图形扩展中尝试时,它不会更新或清除soline(缓存)值仍然显示折扣数字。我一定错过了一些简单的东西

任何在这一点上被欣赏的想法

protected void SOLine_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
{
  SOLine row = e.Row as SOLine;
  DiscountEngine<SOLine>.ClearDiscount(sender,row);
  // RecalculateDiscounts(sender, row);  // ? (Maybe this) 
}
protectedvoid SOLine_RowUpdated(PXCache发送方,PXRowUpdatedEventArgs e)
{
SOLine行=e行作为SOLine;
折扣引擎.ClearDiscount(发件人,行);
//重新计算查询(发件人,行);/?(可能是这个)
}

你的思路是正确的。再多说几句。 1.Acumatica将始终执行基本SOLine_RowUpdate事件,然后执行您的SOLine_RowUpdate 2.如果要控制SOLine_RowUpdate事件的执行流,可以执行以下操作:

protected void SOLine_RowUpdated(PXCache cache, PXRowUpdatedEventArgs e, PXRowUpdated del)
{
    //some code
    //del or pointer to basic method can be called like this:
   del(cache, e);
}
  • del将是指向方法SOLine_的指针
  • 您将有以下选项:

    a。根本不要调用del(我不建议您使用这种方法,因为基本方法中有大量的工作人员,而不仅仅是折扣计算)

    b。调用del,然后删除折扣信息

    c。若您的方法ClearDiscount无法清除折扣信息,那个么可能是因为它试图通过简单的赋值来实现,也许您可以尝试使用SetValueExt方法


    还有一点要记住。默认情况下,Acumatica将调用基本的行更新方法,然后它将调用您的方法,所以您不需要使用委托。我建议您从行更新的图形扩展名中的SetValueExt开始,而不是从简单赋值开始。

    为了更简单,您可以使用以下图形扩展名关闭对RecreacteConsunts的调用:

    public class SOOrderEntryExtension : PXGraphExtension<SOOrderEntry>
    {
        [PXOverride]
        public virtual void RecalculateDiscounts(PXCache sender, SOLine line, Action<PXCache, SOLine> del)
        {
            // if no discounts wanted, just return
    
            // else call the base/standard Acumatica calc discounts on sales order...
            if (del != null)
            {
                del(sender, line);
            }
        }
    }
    
    public类SOOrderEntryExtension:PXGraphExtension
    {
    [PXOverride]
    公共虚拟空重新计算目录(PXCache发送方、SOLine行、Action del)
    {
    //如果不想打折,就退货
    //否则请调用销售订单上的基本/标准Acumatica calc折扣。。。
    如果(del!=null)
    {
    del(发送方,行);
    }
    }
    }
    
    您还可以使用ArsalePriceMaint上的图形扩展来编写自己的定价逻辑:

    public class ARSalesPriceMaintExtension : PXGraphExtension<ARSalesPriceMaint>
    {
        [PXOverride]
        public virtual decimal? CalculateSalesPriceInt(PXCache sender, string custPriceClass, int? customerID, int? inventoryID, int? siteID, CurrencyInfo currencyinfo, decimal? quantity, string UOM, DateTime date, bool alwaysFromBaseCurrency,
            Func<PXCache, string, int?, int?, int?, CurrencyInfo, decimal?, string, DateTime, bool, decimal?> del)
        {
            //run your custom price logic here and return
    
            // or return the base/standard Acumatica price logic...
            return del?.Invoke(sender, custPriceClass, customerID, inventoryID, siteID, currencyinfo, quantity, UOM, date, alwaysFromBaseCurrency);
        }
    }
    
    public类arSalesPriceMainTexttension:pxGrapherExtension
    {
    [PXOverride]
    公共虚拟十进制?计算LesPriceInt(PXCache发送方、字符串custPriceClass、int?customerID、int?inventoryID、int?siteID、CurrencyInfo CurrencyInfo、十进制?数量、字符串UOM、日期时间日期、bool alwaysFromBaseCurrency、,
    Func del)
    {
    //在此处运行自定义价格逻辑并返回
    //或者返回基本/标准Acumatica价格逻辑。。。
    return del?.Invoke(发送方、custPriceClass、customerID、inventoryID、siteID、currencyinfo、数量、计量单位、日期、alwaysFromBaseCurrency);
    }
    }
    

    通过这种方式,您不需要对抗事件,而是覆盖事件用于在销售订单上设置折扣和价格的调用。我还相信ArsalePriceMaint扩展将使用定价逻辑覆盖其他屏幕,这有助于减少不同订单输入屏幕上的重复代码

    谢谢你的建议。我一定会尝试,但我从您的回复中收到的最有趣的信息是当接口更改时事件触发的顺序。我看到del是基本的SOLine_RowUpdated类,行“del(cache,e)”真的告诉基类执行和处理缓存的内容。非常感谢。给出的第一个示例,在SOOrderEntryExtension代码中,RecalculateDiscounts覆盖非常适合我。别忘了在问题结束时标出答案