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

时间:2018-01-21 02:37:40

标签: acumatica

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

我尝试从StackOverflow文章Add Attributes fields on Inventory Lookup实施步骤,但它对我不起作用。

1 个答案:

答案 0 :(得分:2)

InventoryItem InventoryCD 字段InventoryRawAttributeCustomerRawAttribute上使用的VendorRawAttribute不同,装饰 AcctCD 客户供应商 DAC中的strong>字段分别在其构造函数中明确定义选择器网格列。如API Reference中所述,如果没有为选择器网格指定列,则将 PXUIField 属性的可见性属性设置为{{{ 1}}将自动添加到选择器网格中。

PXUIVisibility.SelectorVisible

要将属性字段添加到客户ID选择器,我们将首先实现自定义 AttributesFieldWithColumnsAttribute

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

我们的下一步是创建自定义 CustomerRawWithAttributes 属性,重复密封的 CustomerRaw 属性的功能,并使用<中定义的属性扩展选择器列的列表strong> AttributesFieldWithColumns 属性:

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

我们的最后一步是在 CustomerMaint BLC扩展程序中定义2个 CacheAttached 处理程序,以修改客户的属性< strong> AcctCD 和属性字段:

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

应采取类似步骤将属性字段添加到供应商ID选择器。我们创建自定义 VendorRawWithAttributes 属性,重复密封的 VendorRaw 属性的功能,并使用 AttributesFieldWithColumns 中定义的属性扩展选择器列的列表属性:

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

之后我们需要在 VendorMaint BLC扩展程序中定义2个 CacheAttached 处理程序,以修改供应商的属性< strong> AcctCD 和属性字段:

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

请注意,AR303000.aspx或AP303000.aspx不需要进行其他更改,以允许用户按自定义选择器中的属性值进行搜索。