如何启用自定义属性?(可以在类上分配,但不能为事务显示)



我在 Acumatica 2018R2 中定义了几个新屏幕,需要根据分配给事务的类启用属性支持。 类屏幕显示允许附加属性,但事务屏幕不显示任何属性。 我在 Stack Overflow 上找到了几个示例,但我看到的唯一线索似乎是,如果无法确定类 id,则不会显示任何属性。 但是,在调试时,我看到找到了类 id。

这是我的测试代码,我尝试剥离到一个非常基本的测试。

AAClass

using PX.Data;
using System;
namespace Attributes
{
[Serializable]
public class AAClass : IBqlTable
{
#region ClassID
[PXDBIdentity]
[PXUIField(DisplayName = "Class ID")]
public virtual int? ClassID { get; set; }
public abstract class classID : IBqlField { }
#endregion
#region ClassCD
[PXDBString(15, IsKey = true, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Class CD")]
public virtual string ClassCD { get; set; }
public abstract class classCD : IBqlField { }
#endregion
#region Descr
[PXDBString(256, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Descr")]
public virtual string Descr { get; set; }
public abstract class descr : IBqlField { }
#endregion
#region CreatedByID
[PXDBCreatedByID()]
public virtual Guid? CreatedByID { get; set; }
public abstract class createdByID : IBqlField { }
#endregion
#region CreatedByScreenID
[PXDBCreatedByScreenID()]
public virtual string CreatedByScreenID { get; set; }
public abstract class createdByScreenID : IBqlField { }
#endregion
#region CreatedDateTime
[PXDBCreatedDateTime()]
[PXUIField(DisplayName = SSCS.IN.Messages.FldCreatedDateTime)]
public virtual DateTime? CreatedDateTime { get; set; }
public abstract class createdDateTime : IBqlField { }
#endregion
#region LastModifiedByID
[PXDBLastModifiedByID()]
public virtual Guid? LastModifiedByID { get; set; }
public abstract class lastModifiedByID : IBqlField { }
#endregion
#region LastModifiedByScreenID
[PXDBLastModifiedByScreenID()]
public virtual string LastModifiedByScreenID { get; set; }
public abstract class lastModifiedByScreenID : IBqlField { }
#endregion
#region LastModifiedDateTime
[PXDBLastModifiedDateTime()]
[PXUIField(DisplayName = SSCS.IN.Messages.FldLastModifiedDateTime)]
public virtual DateTime? LastModifiedDateTime { get; set; }
public abstract class lastModifiedDateTime : IBqlField { }
#endregion
#region Tstamp
[PXDBTimestamp()]
public virtual byte[] Tstamp { get; set; }
public abstract class tstamp : IBqlField { }
#endregion
#region NoteID
[PXNote]
public virtual Guid? NoteID { get; set; }
public abstract class noteID : IBqlField { }
#endregion
}
}

AAClassMaint

using PX.Data;
using PX.Objects.CR;
namespace Attributes
{
public class AAClassMaint : PXGraph<AAClassMaint, AAClass>
{
#region Data Views
[PXViewName("Classes")]
public PXSelect<AAClass> Classes;
[PXViewName("Attributes")]
public CSAttributeGroupList<AAClass, AATag> Mapping;
#endregion
}
}

AATag

using PX.Data;
using PX.Objects.CR;
using PX.Objects.CS;
using System;
namespace Attributes
{
[Serializable]
public class AATag : IBqlTable
{
#region TagID
[PXDBIdentity]
public virtual int? TagID { get; set; }
public abstract class tagID : IBqlField { }
#endregion
#region TagCD
[PXDBString(15, IsKey = true, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Tag ID")]
public virtual string TagCD { get; set; }
public abstract class tagCD : IBqlField { }
#endregion
#region MyClassID
[PXDBInt()]
[PXSelector(
typeof(AAClass.classID),
typeof(AAClass.classCD),
typeof(AAClass.descr),
SubstituteKey = typeof(AAClass.classCD)
)]
[PXUIField(DisplayName = "My Class ID")]
public virtual int? MyClassID { get; set; }
public abstract class myClassID : IBqlField { }
#endregion
#region CreatedByID
[PXDBCreatedByID()]
public virtual Guid? CreatedByID { get; set; }
public abstract class createdByID : IBqlField { }
#endregion
#region CreatedByScreenID
[PXDBCreatedByScreenID()]
public virtual string CreatedByScreenID { get; set; }
public abstract class createdByScreenID : IBqlField { }
#endregion
#region CreatedDateTime
[PXDBCreatedDateTime()]
[PXUIField(DisplayName = SSCS.IN.Messages.FldCreatedDateTime)]
public virtual DateTime? CreatedDateTime { get; set; }
public abstract class createdDateTime : IBqlField { }
#endregion
#region LastModifiedByID
[PXDBLastModifiedByID()]
public virtual Guid? LastModifiedByID { get; set; }
public abstract class lastModifiedByID : IBqlField { }
#endregion
#region LastModifiedByScreenID
[PXDBLastModifiedByScreenID()]
public virtual string LastModifiedByScreenID { get; set; }
public abstract class lastModifiedByScreenID : IBqlField { }
#endregion
#region LastModifiedDateTime
[PXDBLastModifiedDateTime()]
[PXUIField(DisplayName = SSCS.IN.Messages.FldLastModifiedDateTime)]
public virtual DateTime? LastModifiedDateTime { get; set; }
public abstract class lastModifiedDateTime : IBqlField { }
#endregion
#region Tstamp
[PXDBTimestamp()]
public virtual byte[] Tstamp { get; set; }
public abstract class tstamp : IBqlField { }
#endregion
#region NoteID
[PXNote]
public virtual Guid? NoteID { get; set; }
public abstract class noteID : IBqlField { }
#endregion
#region Attributes
public abstract class attributes : IBqlField { }
[CRAttributesField(typeof(AATag.myClassID))]
public virtual string[] Attributes { get; set; }
public virtual int? ClassID
{
get { return MyClassID; }
}
#endregion
}
}

AATagEntry

using PX.Data;
using PX.Objects.CR;
namespace Attributes
{
public class AATagEntry : PXGraph<AATagEntry, AATag>
{
#region Data Views
[PXViewName("Classes")]
public PXSelect<AATag> Tags;
[PXViewName("Answers")]
public CRAttributeList<AATag> Answers;
#endregion
}
}

据我了解该主题的各种帖子,关键要求是:

  • 在类维护屏幕中定义映射

    [PXViewName("Attributes")]
    public CSAttributeGroupList<AAClass, AATag> Mapping;
    
  • 在事务输入屏幕中定义答案

    [PXViewName("Answers")]
    public CRAttributeList<AATag> Answers;
    
  • 在事务表中包括 NoteID

  • 将属性添加到事务表,包括类 ID 的字段

    public abstract class attributes : IBqlField { }
    [CRAttributesField(typeof(AATag.myClassID))]
    public virtual string[] Attributes { get; set; }
    public virtual int? ClassID
    {
    get { return MyClassID; }
    }
    

CRAttributesField属性将使用其参数中提供的泛型类型(classIdField)构建请求。在您的情况下,这将是AATag.myClassID

protected static Type GetAttributesSearchCommand(Type classIdField)
{
var cmd = BqlCommand.Compose(typeof (Search2<,,>), typeof (CSAttribute.attributeID),
typeof (InnerJoin<,>), typeof (CSAttributeGroup),
typeof (On<,>), typeof (CSAttributeGroup.attributeID), typeof (Equal<>),
typeof (CSAttribute.attributeID),
typeof(Where<,,>), typeof(CSAttributeGroup.entityType), typeof(Equal<>), typeof(Required<>), typeof(CSAttributeGroup.entityType),
typeof (And<,>), typeof (CSAttributeGroup.entityClassID), typeof (Equal<>), typeof (Current<>),
classIdField);
return cmd;
}

因此,请求中子句的关键部分将是:

And<CSAttributeGroup.entityClassID, Equal<Current<AATag.myClassID>>>

这意味着内存中必须有当前的 AATag 记录:

Caches[typeof(AATag)].Current

我建议您首先跟踪值(帮助>跟踪窗口)以验证它是否为空:

public void AATag_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
if (e.Row is AATag)
{
PXTrace.WriteInformation(((AATag)e.Row).myClassID);
}
}

如果为 null,则必须在相关的 DataView 中加入 AATag(首选)或在某些事件中显式设置它。 使用 Acumatica 请求分析器 (SM205070 ) 还可以帮助确定请求未返回任何记录的原因。

正如HB_Acumatica评论中所建议的那样,问题似乎出在将 ClassID 字段定义为整数上。

我删除了原始的ClassID(int)字段,并重命名了Class DAC中的ClassCD(字符串)字段。接下来,我将事务性 DAC 中的 ClassID 字段更改为字符串。 问题解决了。 事务输入屏幕上的属性选项卡现在显示分配给所选类的属性。

经验教训:"类"DAC不应具有ClassID/ClassCD对,而应具有简单的字符串ClassID字段。 (通常特定于类的类型命名,即 TagClassID) 然后,事务表中使用的类 ID 将使用字符串类 ID。

相关内容

最新更新