为Cost Projection新增修订历史标签页的两个开发问题求助
修复方案
问题1:新增修订日志记录只读无法编辑
根因
你自定义DAC PMCostProjectionRevisionLog 的 PXParent 配置错误:PMCostProjectionLine 的主键是ProjectID、RevisionID、LineNbr三个字段,你仅关联了LineNbr,系统无法匹配到有效的父级明细行,因此默认将子记录标记为只读,你在RowSelected中直接修改Cache级别的权限无法覆盖父级关联校验带来的行级只读限制。
修复方法
修正LineNbr字段的PXParent配置,补充完整父表主键匹配条件:
[PXParent(typeof(Select<PMCostProjectionLine, Where<PMCostProjectionLine.projectID, Equal<Current<PMCostProjectionRevisionLog.projectID>>, And<PMCostProjectionLine.revisionID, Equal<Current<PMCostProjectionRevisionLog.revisionID>>, And<PMCostProjectionLine.lineNbr, Equal<Current<PMCostProjectionRevisionLog.lineNbr>>>>>>))]
同时修改PMCostProjectionRevisionLog_RowSelected逻辑,改为对当前行设置可编辑属性即可:
protected void PMCostProjectionRevisionLog_RowSelected(PXCache cache, PXRowSelectedEventArgs e) { PMCostProjectionRevisionLog row = e.Row as PMCostProjectionRevisionLog; if (row == null) return; PXUIFieldAttribute.SetEnabled(cache, row, true); }
问题2:明细行Task、Cost Code默认值不生效
根因
Acumatica的Current<>语法仅能读取已经同步到当前视图上下文的缓存Current值,你切换标签页时Details缓存的Current没有被主动触发同步,因此Current<PMCostProjectionLine.taskID>这类默认值无法读取到正确值。你触发明细行编辑再取消的操作,刚好触发了Details缓存的Current同步,因此默认值临时生效。
修复方法
- 修正你
RowInserting事件中的赋值错误:你代码中给logRow.UnitCost赋值,但自定义DAC中对应字段是TotalCost,原赋值语句无效:
// 替换错误的赋值语句 // logRow.UnitCost = lineRow.Amount; logRow.TotalCost = lineRow.Amount;
- 新增
PMCostProjectionLine的RowSelected事件,主动同步明细行Current变更到修订日志视图:
protected void PMCostProjectionLine_RowSelected(PXCache cache, PXRowSelectedEventArgs e) { if (Base.Details.Current != null) { RevisionLog.View.RequestRefresh(); } }
- 可删除DAC字段上
Current<PMCostProjectionLine.xxx>的PXDefault配置,RowInserting中的赋值优先级高于DAC默认值,已经可以满足默认值填充需求。
修正后完整代码
using PX.Data; using PX.Data.ReferentialIntegrity.Attributes; using PX.Objects.PM; using System; namespace PX.Objects.CN.ProjectAccounting { public class CostProjectionEntry_Extension : PXGraphExtension<CostProjectionEntry> { #region Views public PXSelect<PMCostProjectionRevisionLog, Where<PMCostProjectionRevisionLog.projectID, Equal<Current<PMCostProjection.projectID>>, And<PMCostProjectionRevisionLog.date, LessEqual<Current<PMCostProjection.date>>>>>> RevisionLog; #endregion #region Event Handlers protected void PMCostProjectionRevisionLog_RowInserting(PXCache cache, PXRowInsertingEventArgs e) { var logRow = e.Row as PMCostProjectionRevisionLog; var lineRow = Base.Details.Current; var docRow = Base.Document.Current; if (logRow == null || lineRow == null || docRow == null) return; logRow.LineNbr = lineRow.LineNbr; logRow.ProjectID = lineRow.ProjectID; logRow.RevisionID = docRow.RevisionID; logRow.TaskID = lineRow.TaskID; logRow.CostCodeID = lineRow.CostCodeID; logRow.Date = docRow.Date; logRow.Description = docRow.Description; logRow.TotalCost = lineRow.Amount; } protected void PMCostProjectionRevisionLog_RowSelected(PXCache cache, PXRowSelectedEventArgs e) { PMCostProjectionRevisionLog row = e.Row as PMCostProjectionRevisionLog; if (row == null) return; PXUIFieldAttribute.SetEnabled(cache, row, true); } protected void PMCostProjectionLine_RowSelected(PXCache cache, PXRowSelectedEventArgs e) { if (Base.Details.Current != null) { RevisionLog.View.RequestRefresh(); } } #endregion #region Custom DAC [Serializable] public class PMCostProjectionRevisionLog : IBqlTable { #region LogNbr [PXDBIdentity(IsKey = true)] public virtual int? LogNbr { get; set; } public abstract class logNbr : PX.Data.BQL.BqlInt.Field<logNbr> { } #endregion #region LineNbr [PXDBInt] [PXForeignReference(typeof(Field<lineNbr>.IsRelatedTo<PMCostProjectionLine.lineNbr>))] [PXParent(typeof(Select<PMCostProjectionLine, Where<PMCostProjectionLine.projectID, Equal<Current<PMCostProjectionRevisionLog.projectID>>, And<PMCostProjectionLine.revisionID, Equal<Current<PMCostProjectionRevisionLog.revisionID>>, And<PMCostProjectionLine.lineNbr, Equal<Current<PMCostProjectionRevisionLog.lineNbr>>>>>>))] public virtual int? LineNbr { get; set; } public abstract class lineNbr : PX.Data.BQL.BqlInt.Field<lineNbr> { } #endregion #region ProjectID [ActiveProjectOrContractBase(Required = true)] [PXForeignReference(typeof(Field<projectID>.IsRelatedTo<PMProject.contractID>))] [PXDefault(typeof(Current<PMCostProjection.projectID>), PersistingCheck = PXPersistingCheck.Nothing)] [PXUIField(DisplayName = "Project")] public virtual int? ProjectID { get; set; } public abstract class projectID : PX.Data.BQL.BqlInt.Field<projectID> { } #endregion #region RevisionID [PXDBString(30, IsUnicode = true, InputMask = ">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")] [PXUIField(DisplayName = "Revision", Required = true, Enabled = true, Visibility = PXUIVisibility.SelectorVisible)] [PXDefault(typeof(Current<PMCostProjection.revisionID>), PersistingCheck = PXPersistingCheck.Nothing)] [PXForeignReference(typeof(Field<revisionID>.IsRelatedTo<PMCostProjection.revisionID>))] [PXSelector(typeof(Search<PMCostProjection.revisionID, Where<PMCostProjection.projectID, Equal<Current<projectID>>>, OrderBy<Desc<PMCostProjection.revisionID>>>), DescriptionField = typeof(PMCostProjection.description))] [PXRestrictor(typeof(Where<PMCostProjection.projectID, Equal<projectID>>), "Revision does not exist for the selected project.")] public virtual string RevisionID { get; set; } public abstract class revisionID : PX.Data.BQL.BqlString.Field<revisionID> { } #endregion #region TaskID [BaseProjectTaskAttribute(typeof(projectID), AllowInactive = false, AllowCanceled = false, AllowCompleted = false, Required = true)] [PXForeignReference(typeof(Field<taskID>.IsRelatedTo<PMTask.taskID>))] [PXUIField(DisplayName = "Task")] public virtual int? TaskID { get; set; } public abstract class taskID : PX.Data.BQL.BqlInt.Field<taskID> { } #endregion #region CostCodeID [CostCode(null, typeof(taskID), AllowNullValue = false, Required = true)] [PXForeignReference(typeof(Field<costCodeID>.IsRelatedTo<PMCostCode.costCodeID>))] [PXUIField(DisplayName = "Cost Code")] public virtual int? CostCodeID { get; set; } public abstract class costCodeID : PX.Data.BQL.BqlInt.Field<costCodeID> { } #endregion #region Date [PXDBDate] [PXUIField(DisplayName = "Date", Required = true, Enabled = true)] [PXDefault(typeof(Current<PMCostProjection.date>), PersistingCheck = PXPersistingCheck.Nothing)] public virtual DateTime? Date { get; set; } public abstract class date : PX.Data.BQL.BqlDateTime.Field<date> { } #endregion #region Description [PXDBString(500, IsUnicode = true, InputMask = "")] [PXUIField(DisplayName = "Description", Required = true, Enabled = true)] [PXDefault(typeof(Current<PMCostProjection.description>), PersistingCheck = PXPersistingCheck.Nothing)] public virtual string Description { get; set; } public abstract class description : PX.Data.BQL.BqlString.Field<description> { } #endregion #region TotalCost [PXDBDecimal()] [PXUIField(DisplayName = "Total Cost", Required = true, Enabled = true)] public virtual Decimal? TotalCost { get; set; } public abstract class totalCost : PX.Data.BQL.BqlDecimal.Field<totalCost> { } #endregion } #endregion } }
内容的提问来源于stack exchange,提问作者AAghaei
相关产品推荐
相关产品推荐

