--- title: "Pre-entry Fields Configurer" slug: "pre-entry-fields-configurer" updated: 2023-06-27T14:46:17Z published: 2023-06-27T14:46:17Z canonical: "docs.zilliant.com/pre-entry-fields-configurer" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.zilliant.com/llms.txt > Use this file to discover all available pages before exploring further. # Pre-Entry Fields Configurer Class Use this hook to remove **Product** records from the **Add Lines** component when it is displayed. The logic for removing the records is written into the hook. You can use this hook only if the same functional filtering cannot be done with the **Add Lines Dialogue** filters. The Apex hook occurs when the **Add Lines** component is displayed in a Lightning **Record** page and when the page is refreshed in the browser. This hook does not require user input on the component to execute. ## Apex hook class - It must implement one of the following interfaces: - **zpl.AddLinePreEntryFieldsConfigurer** (non-scoped) - **AddLineScopedPreEntryFieldsConfigurer** (scoped) - It must have a global access modifier. - You must specify the Apex hook class name in the **Pre-entry Fields Configurer Class Name** field of the **Product Selector Configuration** that is mapped to the **Add Lines** component affected by the hook. ## Interface definition ``` /** * Interface for a hook class that encapsulates custom Products pre-entry fields * filtering logic on Add-Lines page. This version of the interface extends * AddLinePreEntryFieldsConfigurer to add the option to include scoping restrictions. * To ignore scope, use AddLinePreEntryFieldsConfigurer directly. */ global interface AddLineScopedPreEntryFieldsConfigurer extends AddLinePreEntryFieldsConfigurer { /** * @param lineLevel the line level * @param headerRecordId the ID of current Header object record (ID of Contract or Price Lookup record) * @param preEntryFields list of the Pre-entry Fields defined on the UI * @param preEntryFieldsValues map of the user-entered values for the each Pre-entry Field defined * KEY: API name of the pre-entry field (SalesforceField__c), VALUE: user-entered field value * Note: if pre-entry field allows multi select then VALUE will hold List, * otherwise - single Object * @param scope map of system-defined values by which to constrain the available records * KEY: name of the scoping element, VALUE: value of the scoping element * * @returns a condition that should be used on selecting Products or NULL if no pre-entry fields filtering is needed. */ zal.Condition getPreEntryFieldsCondition(LineLevel__c lineLevel, Id headerRecordId, List preEntryFields, Map preEntryFieldsValues, Map scope); } ``` ## Example: AddLineScopedPreEntryFieldsConfigurer interface ``` global with sharing class SimpleAddLineScopedConfigurer implements zpl.AddLineScopedPreEntryFieldsConfigurer { global zal.Condition getPreEntryFieldsCondition(LineLevel__c lineLevel, Id headerRecordId, List preEntryFields, Map preEntryFieldsValues, Map scope) { //return null; return new zal.AndCondition() .add(new zal.FieldCondition(Schema.SObjectType.Product2.fields.zpl__HierarchyLevel__c .getName(), zal.Operator.EQUALS, scope.get('zpl__HierarchyLevel__c'))) .add(new zal.FieldCondition(Schema.SObjectType.Product2.fields.zpl__LevelValue__c .getName(), zal.Operator.EQUALS, scope.get('zpl__LevelValue__c'))); } global zal.Condition getPreEntryFieldsCondition(LineLevel__c lineLevel, Id headerRecordId, List preEntryFields, Map preEntryFieldsValues) { return null; } } ``` ## Example: zpl.AddLinePreEntryFieldsConfigurer interface ``` global with sharing class SimplePreEntryFieldsConfigurer implements zpl.AddLinePreEntryFieldsConfigurer { global zal.Condition getPreEntryFieldsCondition(zpl__LineLevel__c lineLevel, Id headerRecordId, List preEntryFields, Map preEntryFieldsValues) { zal.AndCondition andCondition = new zal.AndCondition(); // Pre-filtering andCondition.add(getProductFamilyCondition()); andCondition.add(getProductCostCondition()); // Pre-entry String product2sObjectName = Schema.SObjectType.Product2.getName(); String lineItemTypeName = zpl__ContractLineItem__c.getSObjectType().getDescribe().getName(); for (zpl__PreEntryField__c preEntryField : preEntryFields) { String salesforceFieldName = preEntryField.zpl__SalesforceField__c; Object value = preEntryFieldsValues.get(salesforceFieldName); Schema.DescribeFieldResult fieldDescribe = zpf.MetadataUtil.getFieldDescribe(lineItemTypeName, salesforceFieldName); String fieldNameWithoutPrefixes = fieldDescribe.getLocalName().replaceAll('__c',''); // comparing field from ContractLineItem__c and Product2 objects with equal names if (zpf.MetadataUtil.containsFieldName(product2sObjectName, salesforceFieldName)) { // custom field on Product2 object andCondition.add(createFieldCondition(salesforceFieldName, value)); } else if (zpf.MetadataUtil.containsFieldName(product2sObjectName, fieldNameWithoutPrefixes)) { // default field on Product2 object andCondition.add(createFieldCondition(fieldNameWithoutPrefixes, value)); } /* if you need to map fields with different names and compare them example of custom condition - comparing ContractPrice__c from ContractLineItem__c and Cost__c from Product2 */ /*else if (salesforceFieldName.equals(Schema.SObjectType.zpl__ContractLineItem__c.fields.zpl__ContractPrice__c.getName())) { andCondition.add(new zal.FieldCondition(Schema.SObjectType.Product2.fields.Cost__c.getName()).equals(value)); }*/ } return andCondition; } private static zal.Condition createFieldCondition(String fieldName, Object value) { if (value instanceof List) { zal.OrCondition orCondition = new zal.OrCondition(); List multiSelectValues = (List)value; for (Object multiSelectValue : multiSelectValues) ```