Acumatica 2017 R2中Create Shipment自动确认发货失效问题
解决Acumatica升级后自动确认发货逻辑失效的问题
嘿,我之前也踩过类似的版本升级坑!你遇到的这个情况核心原因是Acumatica在后续版本里对PXLongOperation的管理机制做了调整——原来6.x里用Base.UID追踪创建发货长操作状态的方式,在新版本已经不适用了,所以才会返回DoesNotExist,导致自动确认步骤完全没触发,只生成了未确认的发货单。
下面给你两个实操性的解决方案,你可以根据代码习惯选择:
方案1:改用回调式长操作(推荐)
新版本Acumatica更推荐用PXLongOperation.StartOperation的回调方法处理后续操作,能避开状态轮询的坑,代码也更稳定:
public PXAction<SOOrder> createShipment; [PXUIField(DisplayName = "Create Shipment", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)] [PXButton] public virtual IEnumerable CreateShipment(PXAdapter adapter) { // 先执行原生的创建发货逻辑 foreach (var item in Base.CreateShipment.Press(adapter)) { yield return item; } // 抓取刚生成的发货单 SOShipment newShipment = Base.Transactions.SelectSingle(); if (newShipment != null && newShipment.Status == SOShipmentStatus.Open) { // 启动异步长操作执行确认,避免阻塞UI PXLongOperation.StartOperation(Base, delegate () { SOShipmentEntry shipGraph = PXGraph.CreateInstance<SOShipmentEntry>(); // 定位到目标发货单 shipGraph.Document.Current = shipGraph.Document.Search<SOShipment.shipmentNbr>(newShipment.ShipmentNbr); if (shipGraph.Document.Current != null) { // 执行确认发货并保存 shipGraph.ConfirmShipment.Press(); shipGraph.Actions.PressSave(); } }); } }
方案2:修正状态轮询的操作ID获取方式
如果不想大改原有逻辑,就得调整长操作ID的获取方式——原来的Base.UID已经不是创建发货操作的对应ID了,要抓取当前的长操作ID:
public PXAction<SOOrder> createShipment; [PXUIField(DisplayName = "Create Shipment", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)] [PXButton] public virtual IEnumerable CreateShipment(PXAdapter adapter) { // 记录创建发货前的当前长操作ID Guid? shipOpId = PXLongOperation.GetCurrentOperationId(); // 执行原生创建发货动作 foreach (var item in Base.CreateShipment.Press(adapter)) { yield return item; } // 轮询操作状态直到完成 TimeSpan timespan; Exception ex; if (shipOpId.HasValue) { while (PXLongOperation.GetStatus(shipOpId.Value, out timespan, out ex) == PXLongRunStatus.InProcess) { System.Threading.Thread.Sleep(500); // 间隔500ms轮询一次,避免过度消耗资源 } // 操作完成后执行确认 SOShipment newShipment = Base.Transactions.SelectSingle(); if (newShipment != null && newShipment.Status == SOShipmentStatus.Open) { SOShipmentEntry shipGraph = PXGraph.CreateInstance<SOShipmentEntry>(); shipGraph.Document.Current = shipGraph.Document.Search<SOShipment.shipmentNbr>(newShipment.ShipmentNbr); shipGraph.ConfirmShipment.Press(); shipGraph.Actions.PressSave(); } } }
额外注意事项
- 权限检查:新版本Acumatica权限管控更严格,要确保当前用户角色拥有
SOShipment.ConfirmShipment的操作权限,不然确认步骤会静默失败。 - 日志排查:如果还是有问题,打开Acumatica的长操作日志(系统管理模块配置),能看到长操作的执行细节,方便定位问题。
- UI体验:尽量用方案1的异步回调,方案2的轮询不要把间隔设得太小,避免UI卡顿。
内容的提问来源于stack exchange,提问作者EricP.
相关产品推荐
相关产品推荐

