You need to enable JavaScript to run this app. Acumatica如何将销售订单折扣明细自定义字段复制到发票折扣明细
优惠活动
大模型
产品
解决方案
定价
更多

Acumatica如何将销售订单折扣明细自定义字段复制到发票折扣明细

方案答复

方法合理性说明

你选择重写SOInvoiceEntry.InvoiceOrder方法是可行的,该方法是销售订单生成发票流程的核心入口,在原生逻辑执行完成后追加自定义字段同步逻辑,不会破坏原生流程的稳定性。

完整实现代码

你已经完成了两个DAC的扩展,接下来只需要对SOInvoiceEntry做图扩展,并重写InvoiceOrder方法追加同步逻辑即可,代码如下:

// SOInvoiceEntry 图扩展代码
using PX.Data;
using PX.Objects.AR;
using PX.Objects.SO;
using System.Collections.Generic;
using System.Linq;

public class SOInvoiceEntryExt : PXGraphExtension<SOInvoiceEntry>
{
    public delegate IEnumerable InvoiceOrderDelegate(SOOrder order, DateTime? invoiceDate, DateTime? postDate, DateTime? finPeriodId, bool createInvoice, bool invoiceShipped, bool ignoreInvoiceGrouping, bool useShippedDateAsInvoiceDate, string operation);
    
    [PXOverride]
    public IEnumerable InvoiceOrder(SOOrder order, DateTime? invoiceDate, DateTime? postDate, DateTime? finPeriodId, bool createInvoice, bool invoiceShipped, bool ignoreInvoiceGrouping, bool useShippedDateAsInvoiceDate, string operation, InvoiceOrderDelegate baseMethod)
    {
        // 执行原生发票生成逻辑
        var result = baseMethod(order, invoiceDate, postDate, finPeriodId, createInvoice, invoiceShipped, ignoreInvoiceGrouping, useShippedDateAsInvoiceDate, operation);
        
        // 仅当实际生成发票单据时执行字段同步
        if (createInvoice)
        {
            // 遍历本次生成的所有AR发票
            foreach (ARInvoice invoice in Base.ARDocument.Cache.Created)
            {
                // 获取当前发票的所有折扣明细
                List<ARInvoiceDiscountDetail> arDiscountDetails = Base.ARDiscountDetails.SelectMain().ToList();
                
                foreach (ARInvoiceDiscountDetail arDiscount in arDiscountDetails)
                {
                    // 根据订单类型、订单号、折扣ID、行号匹配对应的SO订单折扣明细
                    SOOrderDiscountDetail soDiscount = PXSelect<SOOrderDiscountDetail,
                        Where<SOOrderDiscountDetail.orderType, Equal<Required<SOOrderDiscountDetail.orderType>>,
                            And<SOOrderDiscountDetail.orderNbr, Equal<Required<SOOrderDiscountDetail.orderNbr>>,
                            And<SOOrderDiscountDetail.discountID, Equal<Required<SOOrderDiscountDetail.discountID>>,
                            And<SOOrderDiscountDetail.lineNbr, Equal<Required<SOOrderDiscountDetail.lineNbr>>>>>>
                        .Select(Base, order.OrderType, order.OrderNbr, arDiscount.DiscountID, arDiscount.LineNbr)
                        .FirstOrDefault() as SOOrderDiscountDetail;
                    
                    if (soDiscount != null)
                    {
                        // 读取SO折扣明细自定义字段值
                        SOOrderDiscountDetailExt soDiscountExt = soDiscount.GetExtension<SOOrderDiscountDetailExt>();
                        // 赋值给AR折扣明细自定义字段
                        ARInvoiceDiscountDetailExt arDiscountExt = Base.ARDiscountDetails.Cache.GetExtension<ARInvoiceDiscountDetailExt>(arDiscount);
                        arDiscountExt.UsrCustomField = soDiscountExt.UsrCustomField;
                        // 更新缓存生效
                        Base.ARDiscountDetails.Cache.Update(arDiscount);
                    }
                }
            }
        }
        
        return result;
    }
}

注意事项

  • 如果你有特殊的折扣明细匹配规则,可以调整PXSelect的查询条件,避免匹配错误导致字段赋值异常
  • 更轻量的替代方案:可以直接订阅ARInvoiceDiscountDetail的RowInserting事件,在折扣明细插入缓存时直接从关联的SO折扣行取值,不需要重写整个InvoiceOrder方法,适合单字段同步场景
  • 不要修改原生方法的入参、返回值和核心执行逻辑,避免影响其他关联的发票生成功能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 01:06:02