You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Acumatica中PORecieptEntry事件更新PO自定义复选框不生效问题

问题描述

在Acumatica中更新对应PO Receipt的行记录时,需要将PO屏幕内的UsrSendPONotifications复选框值设为true。原有代码执行后该字段始终保持为false,未生效。
原有实现代码:

protected void POReceipt_RowUpdated(PXCache cache, PXRowUpdatedEventArgs e)
{
      
    var row = (POReceipt)e.Row;
    if (row == null) return;
    else
    {
        POReceiptLine receiptLine = new PXSelect<POReceiptLine, Where<POReceiptLine.receiptNbr, 
        Equal<Required<POReceiptLine.receiptNbr>>>>(Base).Select(row.ReceiptNbr);
        if(receiptLine == null) return;  
        else
        {
            POOrder poOrder = new PXSelect<POOrder, Where<POOrder.orderType, 
            Equal<Required<POOrder.orderType>>, And<POOrder.orderNbr, 
            Equal<Required<POOrder.orderNbr>>>>>(Base).Select(receiptLine.POType, 
            receiptLine.PONbr);

            if(poOrder == null) return;
            else
            {
                POOrderExt poExt = poOrder.GetExtension<POOrderExt>();
                poExt.UsrSendPONotifications = true;
                cache.SetValueExt<POOrderExt.usrSendPONotifications> 
                (poOrder,poExt.UsrSendPONotifications);
                    
             }
       }
 }
失效原因
  • 缓存对象使用错误:事件传入的cache是POReceipt类型的缓存,修改POOrder记录必须调用POOrder自身对应的缓存对象,跨缓存调用SetValueExt不会生效。
  • 缺少更新标记:给字段赋值后没有调用对应缓存的Update方法标记记录变更,系统不会识别到这条PO记录有修改,自然不会保存字段变更。
  • 收货行查询逻辑有漏洞:一张PO Receipt通常关联多条收货行,原代码仅查询第一条收货行匹配PO,若第一条行未关联PO、或一张收货单对应多个PO,会出现匹配失败、漏更新的问题。
  • 未优先读取缓存数据:直接从数据库查询PO记录,可能覆盖当前上下文中已经存在的缓存修改,造成数据不一致。
修复代码
protected void POReceipt_RowUpdated(PXCache cache, PXRowUpdatedEventArgs e)
{
    var receipt = e.Row as POReceipt;
    if (receipt == null) return;

    // 获取POOrder类型对应的正确缓存对象
    PXCache poOrderCache = Base.Caches[typeof(POOrder)];
    // 对PO去重,避免重复更新同一条PO
    HashSet<(string, string)> processedPO = new HashSet<(string, string)>();

    // 遍历当前收货单所有关联的收货行
    foreach (POReceiptLine line in PXSelect<POReceiptLine,
        Where<POReceiptLine.receiptNbr, Equal<Required<POReceiptLine.receiptNbr>>>>
        .Select(Base, receipt.ReceiptNbr))
    {
        if (string.IsNullOrEmpty(line.PONbr)) continue;
        var poKey = (line.POType, line.PONbr);
        if (processedPO.Contains(poKey)) continue;
        processedPO.Add(poKey);

        // 优先从缓存中读取PO记录,保证数据一致性
        POOrder poOrder = (POOrder)poOrderCache.Locate(new POOrder
        {
            OrderType = line.POType,
            OrderNbr = line.PONbr
        });
        if (poOrder == null)
        {
            poOrder = PXSelect<POOrder,
                Where<POOrder.orderType, Equal<Required<POOrder.orderType>>,
                    And<POOrder.orderNbr, Equal<Required<POOrder.orderNbr>>>>>
                .Select(Base, line.POType, line.PONbr);
        }
        if (poOrder == null) continue;

        POOrderExt poExt = poOrder.GetExtension<POOrderExt>();
        // 字段已经是目标值时跳过,减少无效操作
        if (poExt.UsrSendPONotifications == true) continue;

        // 通过POOrder缓存设置字段值,标记更新
        poOrderCache.SetValueExt<POOrderExt.usrSendPONotifications>(poOrder, true);
        poOrderCache.Update(poOrder);
    }
}
优化建议
  • 如果需要保证收货单保存成功后才更新PO标记,建议将逻辑迁移到POReceipt_RowPersisted事件,仅在e.Operation为PXDBOperation.Insert或PXDBOperation.Update时执行,避免用户取消收货单编辑时误修改PO数据。
  • 若业务要求PO标记更新后立刻持久化到数据库,可在Update调用后追加poOrderCache.Persist(poOrder, PXDBOperation.Update),注意做好循环触发判断,避免出现死循环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:15:27