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

技术问询:如何在Sales Order界面重写‘Create Shipment’动作自定义Location ID

入门指导:重写Sales Order的"Create Shipment"动作并修改SOShipLine的Location ID

Hey there! Let's walk through how to get started with customizing the 'Create Shipment' action on the Sales Order screen to update the Location ID on SOShipLine using your custom attribute value. Here's a step-by-step guide tailored to Acumatica development:

1. 定位原动作的实现逻辑

首先,你需要找到销售订单页面(SO301000)对应的后台图类SOOrderEntry,系统默认的"Create Shipment"动作就定义在这里,是一个PXAction类型的操作。我们的核心思路是通过扩展这个图类,重写该动作的逻辑,插入自定义的Location ID修改逻辑。

2. 创建自定义图扩展类

新建一个继承自PXGraphExtension<SOOrderEntry>的扩展类,在这个类里重写"Create Shipment"动作,注入我们的自定义逻辑。

以下是一个入门级的代码示例:

public class SOOrderEntryExtension : PXGraphExtension<SOOrderEntry>
{
    // 重写原有的Create Shipment动作
    public PXAction<SOOrder> createShipment;
    [PXUIField(DisplayName = "Create Shipment", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
    [PXButton(CommitChanges = true)]
    public virtual IEnumerable CreateShipment(PXAdapter adapter)
    {
        // 获取当前选中的销售订单
        SOOrder currentOrder = Base.Document.Current;
        if (currentOrder == null) yield break;

        // 先执行系统原有的创建发货单逻辑,保留默认的验证和生成规则
        foreach (var result in Base.createShipment.Press(adapter))
        {
            // 获取刚生成的发货单对应的后台图
            SOShipmentEntry shipmentGraph = Base.Transactions.Cache.Graph as SOShipmentEntry;
            SOShipment newShipment = shipmentGraph?.Document.Current;
            
            if (newShipment != null)
            {
                // 遍历所有发货单明细行,修改Location ID
                foreach (SOShipLine shipLine in shipmentGraph.Transactions.Select())
                {
                    // 获取对应的销售订单明细行,读取自定义属性值
                    SOOrderLine orderLine = Base.Transactions.Select(shipLine.SOOrderType, shipLine.SOOrderNbr, shipLine.SOLineNbr);
                    if (orderLine != null)
                    {
                        // 替换成你实际的自定义字段名称(比如UsrCustomLocation)
                        SOOrderLineExt orderLineExt = orderLine.GetExtension<SOOrderLineExt>();
                        if (orderLineExt.UsrCustomLocation != null)
                        {
                            // 更新发货单行的Location ID
                            shipLine.LocationID = orderLineExt.UsrCustomLocation;
                            shipmentGraph.Transactions.Update(shipLine);
                        }
                    }
                }
                // 保存修改后的发货单明细
                shipmentGraph.Save.Press();
            }
            yield return result;
        }
    }
}

3. 适配你的自定义属性

  • 如果你的自定义属性是在销售订单表头(而非明细行),直接从currentOrder.GetExtension<SOOrderExt>().UsrYourCustomField读取即可。
  • 替换代码中的UsrCustomLocation为你实际创建的自定义字段名称,确保已经为SOOrder或SOOrderLine创建了对应的DAC扩展类。

4. 部署自定义逻辑

  1. 将这个扩展类添加到你的Acumatica定制项目中;
  2. 发布项目,此时你的自定义逻辑会覆盖系统默认的"Create Shipment"动作。

5. 测试验证

  • 创建测试销售订单,设置好自定义属性的值;
  • 点击"Create Shipment"生成发货单;
  • 打开生成的发货单,切换到明细行标签页,检查Location ID是否已经替换为自定义属性的值。

关键注意事项

  • 保留原有逻辑:通过先调用Base.createShipment.Press(adapter),我们保留了系统原有的所有验证和发货单生成规则,只在后续修改明细行的Location ID,避免破坏原有流程;
  • 空值处理:一定要添加空值判断(比如自定义属性未赋值的情况),防止出现运行时错误;
  • 权限检查:确保你的定制项目拥有修改SOShipLine.LocationID和访问自定义字段的权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:13:59