Acumatica 将属性字段添加到客户ID和供应商ID查找中

Acumatica 将属性字段添加到客户ID和供应商ID查找中,acumatica,Acumatica,如何将属性(来自CSAnswer)作为选择器列分别添加到客户和供应商数据输入屏幕上的客户ID和供应商ID查找中 我试图实现StackOverflow文章中的步骤,但它对我不起作用。与InventoryItemInventoryCD字段、CustomerRawAttribute和VendorRawAttribute上使用的InventoryRawAttribute不同,分别在客户和供应商DAC中装饰AcctCD字段,在其构造函数中明确定义选择器网格列。如中所述,如果没有为选择器网格指定任何列,则将

如何将属性(来自CSAnswer)作为选择器列分别添加到客户和供应商数据输入屏幕上的客户ID和供应商ID查找中


我试图实现StackOverflow文章中的步骤,但它对我不起作用。

InventoryItemInventoryCD字段、
CustomerRawAttribute
VendorRawAttribute
上使用的
InventoryRawAttribute
不同,分别在客户供应商DAC中装饰AcctCD字段,在其构造函数中明确定义选择器网格列。如中所述,如果没有为选择器网格指定任何列,则将PXUIField属性的可见性属性设置为
PXUIVisibility的所有字段将自动添加到选择器网格中

[PXDBString(InputMask = "", IsUnicode = true)]
[PXUIField(DisplayName = "Inventory ID", Visibility = PXUIVisibility.SelectorVisible)]
public sealed class InventoryRawAttribute : AcctSubAttribute
{
    ...
    public InventoryRawAttribute()
        : base()
    {
        ...
        PXDimensionSelectorAttribute attr = new PXDimensionSelectorAttribute(
            DimensionName, SearchType, typeof(InventoryItem.inventoryCD));
        ...
    }
    ...
}

[PXDBString(30, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Customer ID", Visibility = PXUIVisibility.Visible)]
public sealed class CustomerRawAttribute : AcctSubAttribute
{
    ...
    public CustomerRawAttribute()
        : base()
    {

        ...
        _Attributes.Add(new PXDimensionSelectorAttribute(
            DimensionName, SearchType, typeof(Customer.acctCD), 
            typeof(Customer.acctCD), 
            typeof(Customer.acctName), 
            typeof(Customer.customerClassID), 
            typeof(Customer.status), 
            typeof(Contact.phone1), 
            typeof(Address.city), 
            typeof(Address.countryID), 
            typeof(Contact.eMail)));
        ...
    }
}

[PXDBString(30, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Vendor", Visibility = PXUIVisibility.Visible)]
public sealed class VendorRawAttribute : AcctSubAttribute
{
    ...

    public VendorRawAttribute(Type where) 
    {           
        ... 
        PXDimensionSelectorAttribute attr;
        _Attributes.Add(attr = new PXDimensionSelectorAttribute(
            DimensionName, SearchType, typeof(Vendor.acctCD), 
            typeof(Vendor.acctCD), 
            typeof(Vendor.acctName), 
            typeof(Vendor.vendorClassID), 
            typeof(Vendor.status), 
            typeof(Contact.phone1), 
            typeof(Address.city), 
            typeof(Address.countryID));
        ...
    }
}
要将属性字段添加到客户ID选择器,我们将首先实现一个自定义的属性字段with columnsattribute

public class AttributesFieldWithColumnsAttribute : CRAttributesFieldAttribute
{
    private string[] attributeNames;

    public AttributesFieldWithColumnsAttribute(string[] attributeNames, Type classIDField, Type noteIdField, Type[] relatedEntityTypes)
        : base(classIDField, noteIdField)
    {
        this.attributeNames = attributeNames;
    }

    public string[] GetAttributeColumns()
    {
        return attributeNames;
    }

    public override void CacheAttached(PXCache sender)
    {
        _IsActive = true;
        base.CacheAttached(sender);
    }

    public override void CommandPreparing(PXCache sender, PXCommandPreparingEventArgs e)
    {
        base.CommandPreparing(sender, e);
        if (e.BqlTable == null && aggregateAttributes && sender.GetItemType().IsDefined(typeof(PXProjectionAttribute), true))
        {
            e.BqlTable = _BqlTable;
        }
    }

    protected override void AttributeFieldSelecting(PXCache sender, PXFieldSelectingEventArgs e, PXFieldState state, string attributeName, int idx)
    {
        if (attributeNames.Any(attributeName.Equals))
        {
            state.Visible = true;
            state.Visibility = PXUIVisibility.Visible;
            //Out-of-the-box DisplayName is prefixed with "$Attributes$-" - if you need to take that off.
            state.DisplayName = (!String.IsNullOrEmpty(state.DisplayName)) ? (state.DisplayName.Replace("$Attributes$-", "")) : attributeName;
        }
        base.AttributeFieldSelecting(sender, e, state, attributeName, idx);
    }

    protected override void AttributeCommandPreparing(PXCache sender, PXCommandPreparingEventArgs e, PXFieldState state, string attributeName, int iField)
    {
        if (e.Operation == PXDBOperation.External && e.Table != null && 
            e.Table.IsDefined(typeof(PXSubstituteAttribute), false))
        {
            e = new PXCommandPreparingEventArgs(e.Row, e.Value, e.Operation, e.Table.BaseType, e.SqlDialect);
        }
        base.AttributeCommandPreparing(sender, e, state, attributeName, iField);
    }
}
我们的下一步是创建自定义CustomerRawWithAttributes属性,重复密封的CustomerRaw属性的功能,并使用AttributesFieldWithColumns属性中定义的属性扩展选择器列列表:

[PXDBString(30, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Customer ID", Visibility = PXUIVisibility.Visible)]
public sealed class CustomerRawWithAttributesAttribute : AcctSubAttribute
{
    public const string DimensionName = "CUSTOMER";
    public CustomerRawWithAttributesAttribute()
        : base()
    {
        Type SearchType = typeof(Search2<Customer.acctCD,
            LeftJoin<Contact, On<Contact.bAccountID, Equal<Customer.bAccountID>, And<Contact.contactID, Equal<Customer.defContactID>>>,
            LeftJoin<Address, On<Address.bAccountID, Equal<Customer.bAccountID>, And<Address.addressID, Equal<Customer.defAddressID>>>>>,
            Where<Match<Current<AccessInfo.userName>>>>);

        _fields = new Type[] { typeof(Customer.acctCD), typeof(Customer.acctName),
            typeof(Customer.customerClassID), typeof(Customer.status), typeof(Contact.phone1),
            typeof(Address.city), typeof(Address.countryID), typeof(Contact.eMail) };

        _Attributes.Add(new PXDimensionSelectorAttribute(DimensionName, SearchType, typeof(Customer.acctCD), _fields));
        _SelAttrIndex = _Attributes.Count - 1;

        ((PXDimensionSelectorAttribute)_Attributes[_SelAttrIndex]).CacheGlobal = true;
        Filterable = true;
    }

    public override void CacheAttached(PXCache sender)
    {
        base.CacheAttached(sender);

        string name = _FieldName.ToLower();
        sender.Graph.FieldSelecting.RemoveHandler(sender.GetItemType(), name, GetAttribute<PXDimensionSelectorAttribute>().FieldSelecting);
        sender.Graph.FieldSelecting.AddHandler(sender.GetItemType(), name, FieldSelecting);
    }

    private readonly Type[] _fields;
    private string[] _FieldList = null;
    private string[] _HeaderList = null;

    private void PopulateFields(PXCache sender)
    {
        if (_FieldList == null)
        {
            var attributeFields = new Dictionary<string, string>();
            foreach (var fAttr in sender.GetAttributesOfType<AttributesFieldWithColumnsAttribute>(null, null))
            {
                foreach (string attribute in fAttr.GetAttributeColumns())
                {
                    attributeFields.Add(attribute, fAttr.FieldName);
                }
            }

            _FieldList = new string[_fields.Length + attributeFields.Count];
            _HeaderList = new string[_fields.Length + attributeFields.Count];

            for (int i = 0; i < _fields.Length; i++)
            {
                Type cacheType = BqlCommand.GetItemType(_fields[i]);
                PXCache cache = sender.Graph.Caches[cacheType];
                if (cacheType.IsAssignableFrom(typeof(BAccountR)) ||
                    _fields[i].Name == typeof(BAccountR.acctCD).Name ||
                    _fields[i].Name == typeof(BAccountR.acctName).Name)
                {
                    _FieldList[i] = _fields[i].Name;
                }
                else
                {
                    _FieldList[i] = cacheType.Name + "__" + _fields[i].Name;
                }
                _HeaderList[i] = PXUIFieldAttribute.GetDisplayName(cache, _fields[i].Name);
            }

            int index = _fields.Length;
            foreach (var attributeField in attributeFields)
            {
                string fieldName = attributeField.Key + "_" + attributeField.Value;
                var fs = sender.GetStateExt(null, fieldName) as PXFieldState;
                if (fs != null)
                {
                    _FieldList[index] = fieldName;
                    _HeaderList[index] = fs.DisplayName;
                }
                index++;
            }
        }

        var attr = GetAttribute<PXDimensionSelectorAttribute>().GetAttribute<PXSelectorAttribute>();
        attr.SetColumns(_FieldList, _HeaderList);
    }

    public void FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
    {
        if (AttributeLevel == PXAttributeLevel.Item || e.IsAltered)
        {
            PopulateFields(sender);
        }

        PXFieldSelecting handler = GetAttribute<PXDimensionSelectorAttribute>().FieldSelecting;
        handler(sender, e);
    }
}
[PXDBString(30, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Vendor", Visibility = PXUIVisibility.Visible)]
public sealed class VendorRawWithAttributesAttribute : AcctSubAttribute
{
    public const string DimensionName = "VENDOR";
    public VendorRawWithAttributesAttribute()
        : base()
    {
        Type SearchType = typeof(Search2<Vendor.acctCD,
            LeftJoin<Contact, On<Contact.bAccountID, Equal<Vendor.bAccountID>, And<Contact.contactID, Equal<Vendor.defContactID>>>,
            LeftJoin<Address, On<Address.bAccountID, Equal<Vendor.bAccountID>, And<Address.addressID, Equal<Vendor.defAddressID>>>>>,
            Where<Match<Current<AccessInfo.userName>>>>);

        _fields = new Type[] { typeof(Vendor.acctCD), typeof(Vendor.acctName),
            typeof(Vendor.vendorClassID), typeof(Vendor.status), typeof(Contact.phone1),
            typeof(Address.city), typeof(Address.countryID) };

        _Attributes.Add(new PXDimensionSelectorAttribute(DimensionName, SearchType, typeof(Customer.acctCD), _fields));
        _SelAttrIndex = _Attributes.Count - 1;

        ((PXDimensionSelectorAttribute)_Attributes[_SelAttrIndex]).CacheGlobal = true;
        Filterable = true;
    }

    public override void CacheAttached(PXCache sender)
    {
        base.CacheAttached(sender);

        string name = _FieldName.ToLower();
        sender.Graph.FieldSelecting.RemoveHandler(sender.GetItemType(), name, GetAttribute<PXDimensionSelectorAttribute>().FieldSelecting);
        sender.Graph.FieldSelecting.AddHandler(sender.GetItemType(), name, FieldSelecting);
    }

    private readonly Type[] _fields;
    private string[] _FieldList = null;
    private string[] _HeaderList = null;

    private void PopulateFields(PXCache sender)
    {
        if (_FieldList == null)
        {
            var attributeFields = new Dictionary<string, string>();
            foreach (var fAttr in sender.GetAttributesOfType<AttributesFieldWithColumnsAttribute>(null, null))
            {
                foreach (string attribute in fAttr.GetAttributeColumns())
                {
                    attributeFields.Add(attribute, fAttr.FieldName);
                }
            }

            _FieldList = new string[_fields.Length + attributeFields.Count];
            _HeaderList = new string[_fields.Length + attributeFields.Count];

            for (int i = 0; i < this._fields.Length; i++)
            {
                Type cacheType = BqlCommand.GetItemType(_fields[i]);
                PXCache cache = sender.Graph.Caches[cacheType];
                if (cacheType.IsAssignableFrom(typeof(BAccountR)) ||
                    _fields[i].Name == typeof(BAccountR.acctCD).Name ||
                    _fields[i].Name == typeof(BAccountR.acctName).Name)
                {
                    _FieldList[i] = _fields[i].Name;
                }
                else
                {
                    _FieldList[i] = cacheType.Name + "__" + _fields[i].Name;
                }
                _HeaderList[i] = PXUIFieldAttribute.GetDisplayName(cache, _fields[i].Name);
            }

            int index = _fields.Length;
            foreach (var attributeField in attributeFields)
            {
                string fieldName = attributeField.Key + "_" + attributeField.Value;
                var fs = sender.GetStateExt(null, fieldName) as PXFieldState;
                if (fs != null)
                {
                    _FieldList[index] = fieldName;
                    _HeaderList[index] = fs.DisplayName;
                }
                index++;
            }
        }

        var attr = GetAttribute<PXDimensionSelectorAttribute>().GetAttribute<PXSelectorAttribute>();
        attr.SetColumns(_FieldList, _HeaderList);
    }

    public void FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
    {
        if (AttributeLevel == PXAttributeLevel.Item || e.IsAltered)
        {
            PopulateFields(sender);
        }

        PXFieldSelecting handler = GetAttribute<PXDimensionSelectorAttribute>().FieldSelecting;
        handler(sender, e);
    }
}
[PXDBString(30,IsUnicode=true,InputMask=”“)]
[PXUIField(DisplayName=“客户ID”,可见性=PXUIVisibility.Visible)]
公共密封类CustomerRawWithAttributes属性:AcctSubAttribute
{
public const string DimensionName=“客户”;
公共CustomerRawWithAttributesAttribute()
:base()
{
类型SearchType=typeof(Search2);
_字段=新类型[]{typeof(Customer.accctcd),typeof(Customer.acctName),
typeof(Customer.customerClassID)、typeof(Customer.status)、typeof(Contact.phone1),
typeof(Address.city)、typeof(Address.countryID)、typeof(Contact.eMail)};
_添加(新的PXDimensionSelectorAttribute(维度名称、搜索类型、类型(Customer.acctCD),_字段));
_seAttrIndex=_Attributes.Count-1;
((PXDimensionSelectorAttribute)_属性[_SelAttrIndex])。CacheGlobal=true;
可过滤=真;
}
公共覆盖无效缓存已附加(PXCache发送方)
{
基缓存已附加(发送方);
字符串名称=_FieldName.ToLower();
sender.Graph.FieldSelecting.RemoveHandler(sender.GetItemType(),name,GetAttribute().FieldSelecting);
sender.Graph.FieldSelecting.AddHandler(sender.GetItemType(),名称,FieldSelecting);
}
私有只读类型[]字段;
私有字符串[]_FieldList=null;
私有字符串[]_HeaderList=null;
私有void PopulateFields(PXCache发送方)
{
如果(_FieldList==null)
{
var attributeFields=新字典();
foreach(sender.GetAttributesOfType中的var fAttr(null,null))
{
foreach(fAttr.GetAttributeColumns()中的字符串属性)
{
attributeFields.Add(属性,fAttr.FieldName);
}
}
_FieldList=新字符串[_fields.Length+attributeFields.Count];
_HeaderList=新字符串[_fields.Length+attributeFields.Count];
对于(int i=0;i<\u fields.Length;i++)
{
类型cacheType=BqlCommand.GetItemType(_字段[i]);
PXCache cache=sender.Graph.Caches[cacheType];
if(cacheType.IsAssignableFrom(typeof(BAccountR))||
_字段[i].Name==typeof(BAccountR.accctcd).Name||
_字段[i].Name==typeof(BAccountR.acctName).Name)
{
_字段列表[i]=\u字段[i]。名称;
}
其他的
{
_FieldList[i]=cacheType.Name+“_”+\u字段[i].Name;
}
_HeaderList[i]=PXUIFieldAttribute.GetDisplayName(缓存,_字段[i].Name);
}
int index=_fields.Length;
foreach(attributeFields中的var attributeField)
{
字符串字段名=attributeField.Key+“”+attributeField.Value;
var fs=sender.GetStateExt(null,fieldName)作为PXFieldState;
如果(fs!=null)
{
_字段列表[索引]=字段名;
_标题列表[索引]=fs.DisplayName;
}
索引++;
}
}
var attr=GetAttribute().GetAttribute();
属性设置列(_字段列表,_标题列表);
}
公共无效字段选择(PXCache发送方,PXFieldSelectingEventArgs e)
{
if(AttributeLevel==PXAttributeLevel.Item | | e.IsAltered)
{
公共领域(发送方);
}
PXFieldSelecting handler=GetAttribute()。FieldSelecting;
处理人(发送者,e);
}
}
最后一步是在CustomerMainBLC扩展中定义2个CacheAttached处理程序,以修改客户的AcctCD属性字段的属性:

public class CustomerExt : PXGraphExtension<CustomerMaint>
{
    [PXMergeAttributes(Method = MergeMethod.Append)]
    [PXRemoveBaseAttribute(typeof(CustomerRawAttribute))]
    [CustomerRawWithAttributes(IsKey = true)]
    public void Customer_AcctCD_CacheAttached(PXCache sender) { }

    [AttributesFieldWithColumns(new[] { "COMPREV", "COMPSIZE" },
        typeof(Customer.customerClassID),
        typeof(BAccount.noteID),
        new[]
        {
            typeof(BAccount.classID),
            typeof(Vendor.vendorClassID)
        })]
    public void Customer_Attributes_CacheAttached(PXCache sender) { }
}
public class VendorMaintExt : PXGraphExtension<VendorMaint>
{
    [PXMergeAttributes(Method = MergeMethod.Append)]
    [PXRemoveBaseAttribute(typeof(VendorRawAttribute))]
    [VendorRawWithAttributes(IsKey = true)]
    public void VendorR_AcctCD_CacheAttached(PXCache sender) { }

    [AttributesFieldWithColumns(new[] { "CONFIGURAB", "COMPREV", "COMPSIZE" },
       typeof(Vendor.vendorClassID),
       typeof(BAccount.noteID),
       new[]
       {
            typeof(BAccount.classID),
            typeof(Customer.customerClassID)
       })]
    public void VendorR_Attributes_CacheAttached(PXCache sender) { }
}
public类CustomerExt:PXGraphExtension
{
[PXMergeAttributes(Method=MergeMethod.Append)]
[PXRemoveBaseAttribute(typeof(CustomerRawAttribute))]
[CustomerRawWithAttributes(IsKey=true)]
public void Customer\u AcctCD\u CacheAttached(PXCache发送方){}
[AttributesFieldWithColumns(新[]{“compev”,“COMPSIZE”},
类型(Customer.customerClassID),
类型(BAccount.noteID),
新[]
{
类型(BAccount.classID),
类型(Vendor.vendorClassID)
})]
public void Customer_Attributes_CacheAttached(PXCache sender){}
}
类似的步骤