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

Acumatica自定义需求:实现销售订单到发货单及发票的自定义字段复制

Acumatica自定义字段复制解决方案

错误原因

你遇到的“销售表不存在‘Test Field’列”错误,是因为直接使用PXSelect<SOOrder,...>查询时,Acumatica会尝试从数据库表中读取字段,但自定义字段UsrTestField是定义在SOOrderExt扩展类中的,并非数据库原生列,因此无法直接通过基础表查询获取。

修复后的代码实现

1. 自定义字段扩展类(保留原有正确定义)

public class SOOrderExt : PXCacheExtension<SOOrder>
{
    [PXDBString(50, IsUnicode = true)]
    [PXUIField(DisplayName = "Test Field")]
    public string UsrTestField { get; set; }
    public abstract class usrTestField : PX.Data.BQL.BqlString.Field<usrTestField> { }
}

public class SOShipmentExt : PXCacheExtension<SOShipment>
{
    [PXDBString(50, IsUnicode = true)]
    [PXUIField(DisplayName = "Test Field")]
    public string UsrTestField { get; set; }
    public abstract class usrTestField : PX.Data.BQL.BqlString.Field<usrTestField> { }
}

public class SOInvoiceExt : PXCacheExtension<SOInvoice>
{
    [PXDBString(50, IsUnicode = true)]
    [PXUIField(DisplayName = "Test Field")]
    public string UsrTestField { get; set; }
    public abstract class usrTestField : PX.Data.BQL.BqlString.Field<usrTestField> { }
}

2. 发货单复制销售订单字段扩展

改用RowInserting事件在发货单创建时处理字段复制,通过Acumatica的Cache机制自动加载扩展字段,避免直接数据库查询的问题:

public class SOShipmentEntryExt : PXGraphExtension<SOShipmentEntry>
{
    protected void _(Events.RowInserting<SOShipment> e)
    {
        SOShipment shipment = e.Row;
        if (shipment == null) return;

        // 获取发货单关联的第一条销售订单行
        SOShipLine shipLine = Base.Transactions.Select().FirstTableItems.FirstOrDefault();
        if (shipLine == null) return;

        // 从Cache中获取销售订单数据,自动加载扩展字段
        SOOrder soOrder = PXSelect<SOOrder, 
            Where<SOOrder.orderType, Equal<Required<SOOrder.orderType>>, 
            And<SOOrder.orderNbr, Equal<Required<SOOrder.orderNbr>>>>>.Select(Base, shipLine.OrigOrderType, shipLine.OrigOrderNbr);
        if (soOrder == null) return;

        SOOrderExt soExt = soOrder.GetExtension<SOOrderExt>();
        SOShipmentExt shipmentExt = shipment.GetExtension<SOShipmentExt>();

        // 复制自定义字段
        shipmentExt.UsrTestField = soExt.UsrTestField;
    }
}

3. 发票复制发货单字段扩展

同样使用RowInserting事件,在发票创建时复制发货单的自定义字段:

public class SOInvoiceEntryExt : PXGraphExtension<SOInvoiceEntry>
{
    protected void _(Events.RowInserting<SOInvoice> e)
    {
        SOInvoice invoice = e.Row;
        if (invoice == null) return;

        // 获取发票关联的第一条发货单行
        SOInvoiceLine invoiceLine = Base.Transactions.Select().FirstTableItems.FirstOrDefault();
        if (invoiceLine == null) return;

        // 从Cache中获取发货单数据,自动加载扩展字段
        SOShipment shipment = PXSelect<SOShipment, 
            Where<SOShipment.shipmentType, Equal<Required<SOShipment.shipmentType>>, 
            And<SOShipment.shipmentNbr, Equal<Required<SOShipment.shipmentNbr>>>>>.Select(Base, invoiceLine.ShipmentType, invoiceLine.ShipmentNbr);
        if (shipment == null) return;

        SOShipmentExt shipmentExt = shipment.GetExtension<SOShipmentExt>();
        SOInvoiceExt invoiceExt = invoice.GetExtension<SOInvoiceExt>();

        // 复制自定义字段
        invoiceExt.UsrTestField = shipmentExt.UsrTestField;
    }
}

关键说明

  • 使用RowInserting事件替代Persist方法,确保字段在创建单据时立即复制,而非等到保存阶段。
  • 依赖Acumatica的Cache机制获取主记录,系统会自动加载对应的扩展类字段,避免直接查询数据库导致的列不存在错误。
  • 针对发票场景新增SOInvoiceExt扩展类,确保自定义字段能存储到发票单据中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 22:31:25