Loading ...

Custom Selector In Acumatica

Greetings to everybody,

today I want to document how to make selector in Acumatica. 

I had the following use case:

1. Acumatica dropdown, which can have three values ( for example a, b, c) .
 
1.1 In case if user select option a, I need to show in PXSelector values from Table A with some filtering condition.
1.2 In case if user select option b, I need to show in PXSelector values from Table  B with another filtering condition
1.3 In case if user select option c, I need to show in PXSelector value from Table C with another filtering condition

Due to the fact, that PXSelector can work only with one DAC, the only way to solve it was implementing custom selector which inherits from PXCustomSelectorAttribute class.

In order to do this, I made the following code:

public class SelectorCustomerContractAttribute : PXCustomSelectorAttribute
    {
        private Type selectorField;
        private Type contractFld;

        public SelectorCustomerContractAttribute(Type selectorField, Type contractField)
            : base(typeof(DRDocumentRecord.refNbr))
        {
            if (selectorField == null)
                throw new ArgumentNullException("selectorField");

            if (contractField == null)
                throw new ArgumentNullException("contractField");


            if (BqlCommand.GetItemType(selectorField).Name != BqlCommand.GetItemType(selectorField).Name)
            {
                throw new ArgumentException(string.Format("moduleField and docTypeField must be of the same declaring type. {0} vs {1}",
                    BqlCommand.GetItemType(selectorField).Name, BqlCommand.GetItemType(selectorField).Name));
            }

            this.selectorField = selectorField;
            contractFld = contractField;
        }

        public override void FieldVerifying(PXCache sender, PXFieldVerifyingEventArgs e)
        {           
        }

        protected virtual IEnumerable GetRecords()
        {
            var cache = this._Graph.Caches[BqlCommand.GetItemType(selectorField)];
            var cbs = (ContractBillingSchedule) cache.Current;
            cache = this._Graph.Caches[BqlCommand.GetItemType(contractFld)];
            var contract = (Contract) cache.Current;
            var result = new List<int>();

            if (cbs.BillTo == "M")
            {
                result.Add(1);
            }

            if (cbs.BillTo == "P")
            {
                result.Add(2);
            }
            if (cbs.BillTo == "S")
            {
                result.Add(3);
            }
            result.Add(4);
            return result;
        }
    }

NB. List is not feeting for result, but if you change it to something else, you can easily to achieve what you want. 

Usage of the selector can be like this:

public class ContractBillingScheduleExt : PXCacheExtension<ContractBillingSchedule>
    {
        #region UsrCustomerContact
        public abstract class usrCustomerContact : IBqlField, IBqlOperand
        {
        }
        [PXDBInt]
        [SelectorCustomerContract(typeof(ContractBillingSchedule.billTo), typeof(Contract.contractID))]
        [PXUIField(DisplayName = "Customer Contact", Visibility = PXUIVisibility.SelectorVisible)]
        public virtual int? UsrCustomerContact { get; set; }
        #endregion
        
    }

enjoy if you need