Как включить пользовательские атрибуты? (можно назначить по классу, но не отображать для транзакции) - PullRequest
0 голосов
/ 09 апреля 2019

Я определил несколько новых экранов в Acumatica 2018R2 и должен включить поддержку атрибутов в соответствии с классом, назначенным для транзакции.Появляется экран класса, позволяющий присоединять атрибуты, но экран транзакций не отображает никаких атрибутов.Я нашел несколько примеров переполнения стека, но единственная подсказка, которую я вижу, состоит в том, что если идентификатор класса не может быть определен, то никакие атрибуты не будут отображаться.Однако после отладки я вижу, что идентификатор класса найден.

Это мой тестовый код, в котором я попытался перейти к очень простому тесту.

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
    }
}

Как я понимаюразличные сообщения для этой темы, ключевые требования:

  • Определение MAPPING на экране обслуживания класса

    [PXViewName("Attributes")]
    public CSAttributeGroupList<AAClass, AATag> Mapping;
    
  • Определение ОТВЕТОВ в транзакцииэкран ввода

    [PXViewName("Answers")]
    public CRAttributeList<AATag> Answers;
    
  • Включить NoteID в таблицу транзакций

  • Добавить ATTRIBUTES в таблицу транзакций, включая поле для ClassID

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

Ответы [ 2 ]

0 голосов
/ 17 апреля 2019

Как предложил HB_Acumatica в комментариях, проблема заключалась в том, что поля ClassID определялись как целое число.

Я удалил исходные поля ClassID (int) и переименовал поля ClassCD (string) в ClassЦАП.Затем я изменил поля ClassID в транзакционном ЦАП на строки.Задача решена.На вкладке атрибутов на экранах ввода транзакций теперь отображаются атрибуты, назначенные выбранному классу.

Извлеченный урок: ЦАП «Класс» не должен иметь пару ClassID / ClassCD, а должно представлять собой простое строковое поле ClassID.(Обычно именуется в зависимости от типа класса, т. Е. TagClassID). Идентификатор класса, используемый в транзакционных таблицах, будет затем использовать строковый идентификатор класса.

0 голосов
/ 09 апреля 2019
Атрибут

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;
}

Таким образом, ключевая часть запроса where будет:

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);
   }
}

Если оно равно нулю, вам нужно присоединитьсяAATag в соответствующем DataView (предпочтительно) или установить его явно в некоторых событиях.Использование Acumatica Request Profiler (SM205070) также может помочь определить, почему запрос не возвращает ни одной записи.

...