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

为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同步,因此默认值临时生效。

修复方法

  1. 修正你RowInserting事件中的赋值错误:你代码中给logRow.UnitCost赋值,但自定义DAC中对应字段是TotalCost,原赋值语句无效:
// 替换错误的赋值语句
// logRow.UnitCost = lineRow.Amount;
logRow.TotalCost = lineRow.Amount;
  1. 新增PMCostProjectionLine的RowSelected事件,主动同步明细行Current变更到修订日志视图:
protected void PMCostProjectionLine_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
    if (Base.Details.Current != null)
    {
        RevisionLog.View.RequestRefresh();
    }
}
  1. 可删除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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 15:45:01