如何在选择器覆写中编写空值检查的If语句?ARPaymentEntry定制疑问
嘿,针对你在Acumatica里定制ARPaymentEntry逻辑、想基于ARRegister扩展字段控制「付款与应用」(P&A)屏幕行添加规则的需求,我整理了一套落地性很强的实现方案,核心是通过扩展ARPaymentEntry图+事件校验来搞定:
核心需求梳理
先把咱们要实现的规则明确下来:
- 给
ARRegister加个必填的自定义状态字段(仅支持A/B两个值),这个字段在「发票和备忘录」屏幕维护,同步到「付款与应用」的关联行 - 「付款与应用」的付款记录要遵循以下规则:
- 如果已经有状态为A的行,后续只能加状态为A的行
- 如果已经有状态为B的行,后续操作按业务规则限制(你原文没写完,下面我默认按「仅允许加B状态行」的常见场景实现,你可以按需修改)
具体实现步骤
1. 先搞定ARRegister的扩展字段配置
首先得确保你的状态字段已经正确定义在ARRegister的DAC扩展里,示例代码如下:
public class ARRegisterExt : PXCacheExtension<ARRegister> { #region UsrStatus [PXDBString(1, IsFixed = true, IsNullable = false)] [PXUIField(DisplayName = "自定义状态", Required = true)] [PXStringList( new string[] { "A", "B" }, new string[] { "状态A", "状态B" })] public virtual string UsrStatus { get; set; } public abstract class usrStatus : PX.Data.BQL.BqlString.Field<usrStatus> { } #endregion }
这个字段会自动在「发票和备忘录」屏幕显示,你可以通过屏幕配置调整它的位置。
2. 扩展ARPaymentEntry图,添加行校验逻辑
接下来要在ARPaymentEntry的扩展类里,给ARAdjust行加插入/更新时的校验逻辑,确保规则生效:
public class ARPaymentEntryExt : PXGraphExtension<ARPaymentEntry> { // 插入新行前校验 protected void _(Events.RowInserting<ARAdjust> e) { ValidateAdjustStatus(e.Row); } // 更新行时校验 protected void _(Events.RowUpdating<ARAdjust> e) { ValidateAdjustStatus(e.NewRow); } // 核心校验方法 private void ValidateAdjustStatus(ARAdjust adjust) { if (adjust == null) return; // 先拿到当前付款下所有已存在的行的状态 string existingStatus = null; foreach (ARAdjust adj in Base.Adjustments.Select()) { if (adj == adjust) continue; // 跳过当前正在操作的行 // 查询关联的ARRegister记录,获取状态字段 ARRegister adjdRegister = PXSelect<ARRegister, Where<ARRegister.docType, Equal<Required<ARRegister.docType>>, And<ARRegister.refNbr, Equal<Required<ARRegister.refNbr>>>>>.Select(Base, adj.AdjdDocType, adj.AdjdRefNbr); if (adjdRegister == null) continue; ARRegisterExt adjdExt = adjdRegister.GetExtension<ARRegisterExt>(); if (existingStatus == null) { existingStatus = adjdExt.UsrStatus; } else if (existingStatus != adjdExt.UsrStatus) { // 如果已有行状态不一致,直接报错(可根据业务需求调整) throw new PXException("当前付款记录中存在不同状态的行,请统一状态后再添加新行"); } } // 获取当前操作行对应的ARRegister状态 ARRegister currentRegister = PXSelect<ARRegister, Where<ARRegister.docType, Equal<Required<ARRegister.docType>>, And<ARRegister.refNbr, Equal<Required<ARRegister.refNbr>>>>>.Select(Base, adjust.AdjdDocType, adjust.AdjdRefNbr); if (currentRegister == null) return; ARRegisterExt currentExt = currentRegister.GetExtension<ARRegisterExt>(); string currentStatus = currentExt.UsrStatus; // 应用规则:已有A状态行,只能加A状态行 if (existingStatus != null && existingStatus == "A" && currentStatus != "A") { throw new PXException("当前付款记录已包含状态A的行,仅允许添加状态A的行"); } // 应用规则:已有B状态行,只能加B状态行(可按需修改) if (existingStatus != null && existingStatus == "B" && currentStatus != "B") { throw new PXException("当前付款记录已包含状态B的行,仅允许添加状态B的行"); } } }
3. 前端屏幕适配(可选但推荐)
为了让用户能直观看到每行的状态,建议在「付款与应用」屏幕的网格里添加这个自定义状态字段,代码实现如下:
public override void Initialize() { base.Initialize(); // 给Adjustments网格添加状态字段 if (Base.Adjustments.GetColumn<ARRegisterExt.usrStatus>() == null) { Base.Adjustments.AddColumn<ARRegisterExt.usrStatus>(); // 把字段放到参考编号后面,方便查看 Base.Adjustments.MoveColumn<ARRegisterExt.usrStatus>(after: typeof(ARAdjust.adjdRefNbr)); } }
关键逻辑说明
- 事件时机:选
RowInserting和RowUpdating是为了在数据真正保存前就拦住不符合规则的操作,避免事后回滚 - 状态校验:先检查已有行的状态是否统一,再对比当前行的状态是否符合规则,确保整个付款记录的状态一致性
- 数据关联:通过
PXSelect查询关联的ARRegister记录,拿到其扩展字段的状态值,保证数据来源准确
内容的提问来源于stack exchange,提问作者jhofer
相关产品推荐
相关产品推荐

