Acumatica - 修订版

Acumatica - Revision

我们有 2 个 DAC - Master 和 Child

主DAC

#region MasterID
public abstract class masterID:PX.Data.BQL.BqlInt.Field<masterID> { }
protected int? _MasterID;
[PXDBIdentity()]
[PXUIField(Visibility = PXUIVisibility.Invisible)]
[PXReferentialIntegrityCheck]
public virtual int? MasterID
{
    get {return this._MasterID;}
    set {this._MasterID = value;}
}
#endregion

#region MasterCD
public abstract class masterRoutingCD:PX.Data.BQL.BqlString.Field<masterCD> { }
protected string _MasterRoutingCD;
[BomID(DisplayName = "Master #", IsKey = true, Required = true,
    Visibility = PXUIVisibility.SelectorVisible)]
[PXDefault]
[Rev.Key(typeof(Setup.pMMasterNumberSequenceID),
         typeof(Master.masterCD),
         typeof(Master.revisionNo),
         typeof(Master.masterCD),
         typeof(Master.revisionNo)
    )]

public virtual string MasterCD
{
    get {return this._MasterCD;}
    set {this._MasterCD = value;}
}
#endregion

#region RevisionNo
public abstract class revisionNo:PX.Data.IBqlField { }
protected string _RevisionNo;
[RevisionIDField(IsKey = true, Visibility = PXUIVisibility.SelectorVisible,
    Required = true)]
[PXDefault(typeof(Master.defaultRevisionNo),
    PersistingCheck = PXPersistingCheck.Nothing)]
[Rev.ID(typeof(Master.defaultRevisionNo),
        typeof(Master.masterCD),
        typeof(Master.revisionNo),
        typeof(Master.revisionNo),
        typeof(Master.description),
        typeof(Master.fromDate),
        typeof(Master.toDate))]
public virtual string RevisionNo
{
    get {return this._RevisionNo;}
    set {this._RevisionNo = value;}
}
#endregion

子DAC

public abstract class childID:PX.Data.BQL.BqlInt.Field<childID> { }
protected int? _ChildID;
[PXDBIdentity()]
//[PXReferentialIntegrityCheck]
public virtual int? ChildID
{
  get {return this._ChildID;}
  set {this._ChildID = value;}
}
#endregion

#region MasterID
public abstract class masterID:PX.Data.BQL.BqlInt.Field<masterID> { }
protected int? _MasterID;
[PXDBInt()]
[PXDBDefault(typeof(Master.masterID))]
[PXParent(typeof(Select<Master, Where<Master.masterRoutingCD, Equal<Current<masterCD>>,
    And<Master.revisionNo, Equal<Current<revisionNo>>>>>))]
public virtual int? MasterID
{
  get {return _MasterID;}
  set {_MasterID = value;}
}
#endregion MasterID

#region MasterCD
public abstract class masterCD:PX.Data.BQL.BqlString.Field<masterCD> { }
protected string _MasterCD;
[PXDBDefault(typeof(Master.masterCD))]
[PXDBString(IsKey = true, IsUnicode = true)]
public virtual string MasterCD
{
    get {return this._MasterCD;}
    set {this._MasterCD = value;}
}
#endregion

#region Revision
public abstract class revisionNo:PX.Data.BQL.BqlString.Field<revisionNo> {}
[PXDBString(15, IsKey = true, IsUnicode = true)]
[PXDBDefault(typeof(Master.revisionNo))]
public virtual string RevisionNo { get; set; }
#endregion Revision

public abstract class stepsID:PX.Data.BQL.BqlInt.Field<stepsID> { }
[OperationCDField(IsKey =true, DisplayName = "Steps ID",
    Visibility = PXUIVisibility.SelectorVisible)]
[PXDefault(PersistingCheck = PXPersistingCheck.NullOrBlank)]
//[PXUIField(DisplayName = "Process Steps ID")]
public virtual string StepsID { get; set; }

图 - MasterMaint

public class MasterMaint:PXRevisionableGraph<MasterMaint, Master,
    Master.masterCD, Master.revisionNo>
{
    public PXSelect<Child, Where<Child.masterCD, Equal<Current<Master.masterCD>>,
        And<Child.revisionNo, Equal<Current<Master.revisionNo>>>>> ChildRecords;

    #region Override

    public override bool CanClipboardCopyPaste()
    {
        return false;
    }

    public override bool CanCreateNewRevision(MasterMaint fromGraph, MasterMaint toGraph,
        string keyValue, string revisionValue, out string error)
    {
        // Always returns true as new revisions can be created at any time
        error = string.Empty;
        return true;
    }
   
    public override void CopyRevision(MasterMaint fromGraph, MasterMaint toGraph,
        string keyValue, string revisionValue)
    {
        if(toGraph?.Documents?.Current == null || fromGraph?.Documents?.Current == null)
        {
            // api calls should create new revs on their own - this causes issues
            // when calling from api so we need to turn the copy rev logic off
            return;
        }
        toGraph.Documents.Cache.SetDefaultExt<EWPMMasterRouting.status>
            (toGraph.Documents.Current);
        if(SkipAutoCreateNewRevision())
        {
            return;
        }
        CopyChildRecords(fromGraph.Documents.Current.MasterRoutingCD,
            fromGraph.Documents.Current.RevisionNo, toGraph.Documents.Current.MasterID,
            keyValue, revisionValue, false);
    }

  
    internal virtual void CopyChildRecords(string sourceID, string sourceRevisionNo,
        int? newMasterID, string newMasterCD, string newRevisionID, bool copyNotes)
    {
        foreach(Child fromRow in PXSelect<Child,
            Where<Child.masterCD, Equal<Required<Child.masterCD>>,
                And<Child.revisionNo, Equal<Required<Child.revisionNo>>>>>
            .Select(this, sourceID, sourceRevisionNo))
        {
            var toRow = PXCache<Child>.CreateCopy(fromRow);
            toRow.MasterID = newMasterRoutingID;
            toRow.ChildID = null;
            toRow.MasterCD = newMasterCD;
            toRow.RevisionNo= newRevisionID;
            toRow = ChildRecords.Insert(toRow);
        }
    }

    #endregion
}

问题 - 当版本中的值发生更改时,记录会显示新的版本号,同时保留 CD 字段与之前的版本和所有子版本一样。 没错,但是保存记录时,出现错误“另一个进程更新了记录,您的更改将会丢失” 为什么会出现错误

在 Acuamtica 中,我们的 NoteID 列在整个系统中是唯一的如果您尝试使用重复的 NoteID 字段值创建记录,您将收到“另一个进程已更新记录”异常,因为它认为您正在更新相同的记录. 在您复制修订版的情况下,您没有重置记录的 NoteID 值,因此您实际上尝试插入具有相同值的另一条记录。

您需要将以下行添加到 CopyRevision 方法

toGraph.Documents.Cache.SetDefaultExt<EWPMMasterRouting.noteID>(toGraph.Documents.Current);