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

SOOrder多行更新异常:第二行SOLine的OrderQty未变更问题

问题分析与解决方案

问题原因

你遇到的第二行SOLine数量未更新的问题,核心原因有两个:

  1. SOLine对象未在图缓存中:原代码通过soOrderEntryMaint.Select<SOLine>().First()直接查询数据库,获取的对象不在SOOrderEntry图的缓存内。调用Transactions.Update(soLine)时,Acumatica无法识别该记录的原始状态,导致更新操作未被正确提交。
  2. 跨订单的缓存干扰:循环复用同一个SOOrderEntry实例并调用Clear(),处理不同订单的Split时,上下文状态混乱,导致后续记录加载和更新逻辑失效。

修正后的代码

protected void _(Events.RowPersisted<INLotSerialStatus> e)
{
    var remaining = /* 补充你的remaining初始值 */;
    var lotSerial = /* 补充你的lotSerial值 */;
    var siteID = /* 补充你的siteID值 */;

    // 用PXSelect替代直接查询,确保获取最新的Split记录
    var existingSHSoLineLineSplits = PXSelect<SOLineSplit,
        Where<SOLineSplit.orderType, Equal<Required<SOLineSplit.orderType>>,
            And<SOLineSplit.lotSerialNbr, Equal<Required<SOLineSplit.lotSerialNbr>>,
            And<SOLineSplit.siteID, Equal<Required<SOLineSplit.siteID>>>>>,
        OrderBy<Asc<SOLineSplit.qty>>>
        .Select(Base, SSIConstants.OrderTypes.SH, lotSerial, siteID)
        .ToList();

    foreach (SOLineSplit soLineSplit in existingSHSoLineLineSplits)
    {
        if (remaining <= 0) break;

        // 为每个订单创建独立的SOOrderEntry实例,彻底避免缓存干扰
        using (var soOrderEntryMaint = PXGraph.CreateInstance<SOOrderEntry>())
        {
            // 加载目标订单
            var soOrder = soOrderEntryMaint.Document.Search<SOOrder.orderNbr>(soLineSplit.OrderNbr, soLineSplit.OrderType);
            if (soOrder == null) continue;
            soOrderEntryMaint.Document.Current = soOrder;

            // 加载对应的订单行(从视图缓存获取,确保可被更新)
            var soLine = soOrderEntryMaint.Transactions.SelectSingleLine<SOLine.lineNbr>(soLineSplit.LineNbr);
            if (soLine == null) continue;
            soOrderEntryMaint.Transactions.Current = soLine;

            // 加载对应的Split记录(从视图缓存获取)
            var splitToUpdate = soOrderEntryMaint.splits.SelectSingleLine<SOLineSplit.splitLineNbr>(soLineSplit.SplitLineNbr);
            if (splitToUpdate == null) continue;
            soOrderEntryMaint.splits.Current = splitToUpdate;

            // 简化扣减数量计算
            decimal qtyToDecrement = Math.Min(remaining, splitToUpdate.Qty ?? 0);

            // 更新Split数量
            splitToUpdate.Qty = splitToUpdate.Qty - qtyToDecrement;
            soOrderEntryMaint.splits.Update(splitToUpdate);

            // 更新订单行数量,确保不小于0
            soLine.Qty = soLine.Qty - qtyToDecrement;
            soLine.Qty = soLine.Qty < 0 ? 0 : soLine.Qty;
            soOrderEntryMaint.Transactions.Update(soLine);

            // 保存当前订单的更改
            soOrderEntryMaint.Actions.PressSave();

            // 更新剩余待扣减数量
            remaining -= qtyToDecrement;
        }
    }
}

关键修改点

  • 独立实例处理每个订单:用using块为每个订单创建新的SOOrderEntry实例,彻底避免不同订单之间的缓存状态干扰。
  • 从视图缓存获取记录:通过Document.Search、Transactions.SelectSingleLine、splits.SelectSingleLine方法获取记录,确保对象存在于图的缓存中,Update操作能正确识别并提交变更。
  • 简化数量计算逻辑:用Math.Min直接确定扣减数量,减少分支判断的出错概率。
  • 移除Clear操作:由于每个循环都使用全新的图实例,无需手动清空缓存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 11:35:28