Search code examples
acumaticaacumatica-kb

How to include field from a linked entity into Full-Text Entity Index?


I've added Customer Location to the Full-Text Entity Index, but cannot figure out how to get Address Line 1 from the Location to be part of the Full-Text Index and be displayed in the result.


Solution

  • To includes fields of linked entities (those which are in one-to-one relationship with the top-level entity on a data entry screen), it's required to specify what top-level entity field should be used along with the PXSelectorAttribute to retrieve the linked entity. Right after the top-level entity field acting as a bridge between the linked entities, you will specify fields of the secondary entity, which should be included into the Full-Text Index and/or be displayed in the result. Keep in mind, that only top-level entity fields decorated with PXSelectorAttribute or PXDimensionSelectorAttribute have the ability to act as a bridge between the linked entities.

    For example, to include fields from the Address DAC into the Customer Location Full-Text Entity Index, you must add the DefAddressID field from the Location DAC before listing fields from the Address DAC:

    public partial class Location : PX.Data.IBqlTable, IPaymentTypeDetailMaster, ILocation
    {
        ...
        public abstract class defAddressID : IBqlField { }
        [PXDBInt()]
        [PXDBChildIdentity(typeof(Address.addressID))]
        [PXUIField(DisplayName = "Default Address", Visibility = PXUIVisibility.Invisible)]
        [PXSelector(typeof(Search<Address.addressID>), DirtyRead = true)]
        public virtual int? DefAddressID { get; set; }
        ...
    }
    

    The CustomerLocation DAC found in the following code snippet can serve as a perfect example of a custom DAC used to add Customer Location to the Full-Text Entity Index:

    [Serializable]
    [PXCacheName("Customer Location")]
    [PXBreakInheritance]
    public partial class CustomerLocation : SelectedCustomerLocation
    {
        public new abstract class bAccountID : IBqlField { }
    
        [Customer(typeof(Search<Customer.bAccountID,
            Where<Customer.type, Equal<BAccountType.customerType>,
                Or<Customer.type, Equal<BAccountType.prospectType>,
                Or<Customer.type, Equal<BAccountType.combinedType>>>>>),
            IsKey = true)]
        public override int? BAccountID { get; set; }
    
        public new abstract class locationCD : IBqlField { }
    
        public new abstract class descr : IBqlField { }
    
        public new abstract class defAddressID : IBqlField { }
    
        public new abstract class locType : IBqlField { }
    
        public new abstract class noteID : IBqlField { }
    
        [PXNote()]
        [PXSearchable(SM.SearchCategory.CR, "{1} {2}: {3}",
            new Type[] {
                typeof(CustomerLocation.bAccountID),
                typeof(Customer.acctCD),
                typeof(CustomerLocation.locationCD),
                typeof(CustomerLocation.descr) },
            new Type[] {
                typeof(CustomerLocation.bAccountID),
                typeof(Customer.acctCD),
                typeof(CustomerLocation.locationCD),
                typeof(CustomerLocation.descr),
                typeof(CustomerLocation.defAddressID),
                typeof(Address.addressLine1),
                typeof(Address.addressLine2),
                typeof(Address.city),
                typeof(Address.countryID) },
            Line1Format = "{0} {2}",
            Line1Fields = new Type[] {
                typeof(CustomerLocation.descr),
                typeof(CustomerLocation.defAddressID),
                typeof(Address.addressLine1) },
            Line2Format = "{1}",
            Line2Fields = new Type[] {
                typeof(CustomerLocation.defAddressID),
                typeof(Address.addressLine2) },
            WhereConstraint = 
                typeof(Where<CustomerLocation.locType, Equal<LocTypeList.customerLoc>,
                    Or<CustomerLocation.locType, Equal<LocTypeList.combinedLoc>>>),
            MatchWithJoin = typeof(InnerJoin<Customer, 
                On<Customer.bAccountID, Equal<CustomerLocation.bAccountID>>>),
            SelectForFastIndexing = typeof(Select2<CustomerLocation, 
                InnerJoin<Customer, 
                    On<CustomerLocation.bAccountID, Equal<Customer.bAccountID>>>>)
        )]
        public override Guid? NoteID { get; set; }
    }
    

    Becides the DefAddressID field, which is used to include fields from the Address DAC to the Full-Text Entity Index, CustomerLocation also utilize CustomerAttribute attached to the BAccountID field to include Customer's natural application-wise AcctCD keys instead of the surrogate DB-level BAccountID keys. Last thing to mention is the PXBreakInheritanceAttribute required to prevent initialization of PXCache objects corresponding to base DACs when on Rebuild Full-Text Entity Index screen the system generates list of entities to be used by Full-Text Entity Index.