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
相关产品推荐
相关产品推荐

