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