You need to enable JavaScript to run this app. Acumatica销售报价单自定义Action生成SO后无法即时更新字段与按钮状态
优惠活动
大模型
产品
解决方案
定价
更多

Acumatica销售报价单自定义Action生成SO后无法即时更新字段与按钮状态

问题根因
  • 长操作会话隔离导致缓存不同步:PXLongOperation.StartOperation委托内的代码运行在独立后台线程上下文,委托内直接调用Base.Save修改的是后台上下文的graph缓存,而非用户当前打开页面的graph实例。虽然修改后的数据已经写入数据库,但当前页面的本地缓存没有触发刷新,因此UI不会即时更新字段值、也不会触发RowSelected事件更新按钮状态,仅手动刷新页面时,系统重新从数据库拉取数据才能看到预期效果。
  • 冗余无效代码:CreateSalesOrder方法内定义的QuoteMaint graphObject = PXGraph.CreateInstance<QuoteMaint>();、CreateSalesOrderMethod内定义的QuoteMaint currGRPH = PXGraph.CreateInstance<QuoteMaint>();及对应的extension实例引用,从未参与业务逻辑,属于无效代码。
  • 缺少长操作完成后的UI刷新回调:长操作执行完成后没有主动通知当前页面更新缓存,导致UI状态与数据库状态脱节。
修复步骤
  1. 重构CreateSalesOrderMethod,将原方法返回值从void改为string,移除对页面级graph实例的直接依赖,改为新建独立graph操作数据库,最终返回生成的销售订单号
    替换原方法末尾的报价更新逻辑:
    if (var_orderCreated)
    {
        // 新建独立quote graph操作数据库,不依赖页面上下文
        using var quoteGraph = PXGraph.CreateInstance<QuoteMaint>();
        var quoteToUpdate = quoteGraph.Quote.Select(quote.QuoteID);
        if (quoteToUpdate != null)
        {
            var quoteExt = quoteGraph.Quote.Cache.GetExtension<CRQuoteExt>(quoteToUpdate);
            quoteExt.UsrOrderNbr = orderHeaderObject.OrderNbr;
            quoteGraph.Quote.Update(quoteToUpdate);
            quoteGraph.Actions.PressSave();
        }
        return orderHeaderObject.OrderNbr;
    }
    return string.Empty;
    
  2. 修改长操作启动逻辑,添加长操作完成后的UI回调,在当前页面上下文中更新缓存
    替换原有的长操作启动代码:
    PXLongOperation.StartOperation(
        () =>
        {
            // 后台线程执行SO创建、数据库写入
            var generatedSoNbr = CreateSalesOrderMethod(quote, QuoteList);
            // 将执行结果传递给UI层回调
            PXLongOperation.Exit(generatedSoNbr);
        },
        (result) =>
        {
            // 回调运行在当前页面graph的会话上下文中
            var generatedSoNbr = result as string;
            if (string.IsNullOrEmpty(generatedSoNbr)) return;
            
            // 更新当前页面缓存中的自定义SO号字段
            var currentQuote = Base.Quote.Current;
            var quoteExt = Base.Quote.Cache.GetExtension<CRQuoteExt>(currentQuote);
            quoteExt.UsrOrderNbr = generatedSoNbr;
            // 标记缓存已修改,触发RowSelected事件自动更新按钮启用状态
            Base.Quote.Cache.MarkUpdated(currentQuote);
            // 触发UI界面刷新
            Base.View.RequestRefresh();
        });
    
  3. 原有CRQuote_RowSelected中的按钮状态控制逻辑无需修改,只要缓存中UsrOrderNbr字段值更新,事件会自动判断字段是否为空,切换按钮的启用/禁用状态。
注意事项
  • 禁止在长操作的后台委托内直接引用页面级graph实例做数据库操作,Acumatica的graph实例与用户会话强绑定,跨会话的实例引用是导致缓存不一致的核心诱因。
  • 所有需要在长操作完成后同步到UI的状态,必须通过PXLongOperation的回调机制在页面上下文中更新,不能依赖后台线程的缓存修改。

内容的提问来源于stack exchange,提问作者SD Netsense

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.25 22:54:01