Skip to content

UserDefinedServiceSampleOrderFieldValueValidation Trigger

smehta-veeva edited this page Jul 24, 2020 · 1 revision

Business Requirement

  • Validate all Bicycle orders to ensure that the BicyclePart (bicycle_part__c) and Part Manufacturer (bicycle_part_manufacturer__c) specified in the order exist.
  • Reduce Bicycle Part(bicycle_part__c) quantity by the amount specified in the order(order_quantity_c).

Key Concepts

To run this trigger for every bicycle part order record create or update event, the events must be declared in the @RecordTriggerInfo annotation:

@RecordTriggerInfo(object = "bicycle_part_order__c", events = {RecordEvent.BEFORE_INSERT, RecordEvent.BEFORE_UPDATE}, order = TriggerOrder.NUMBER_1)

In order to use the ProductSearchUserDefinedService and its methods, it must first be located using ServiceLocater:

ProductSearchUserDefinedService productSearchUserDefinedService = ServiceLocator.locate(ProductSearchUserDefinedService.class);

In order to validate the business requirements, the order quantity, part name and manufacturer name must be extracted for each bicycle part order record created or updated and stored so that they can be searched for.

To extract these values, the PickList Service must be used to retrieve part and part manufacturer Picklist content.

PicklistService picklistService = ServiceLocator.locate(PicklistService.class);
// Picklist of bicycle parts in bicycle part orders
Picklist bicyclePartPicklist = picklistService.getPicklist("bicycle_part__c");
// Picklist of bicycle part manufacturers in bicycle part orders
Picklist bicyclePartManufacturersPicklist = picklistService.getPicklist("bicycle_part_manufacturer__c");

Next, maps need to be created to hold the part name, order quantity and part manufacturer information. For this, a map of part name and manufacturer name is created as well as a map of part name and order quantity.

@SuppressWarnings("unchecked")
Map<String, String> partAndManufacturerMap = VaultCollections.newMap();
@SuppressWarnings("unchecked")
Map<String, BigDecimal> orderQuantityMap = VaultCollections.newMap();

Lastly, a lambda expression is used with the recordChanges stream to extract the necessary values. Note, this snippet has been trimmed for brevity.

recordTriggerContext.getRecordChanges().forEach(recordChange -> {

            ....
 // Get the bicycle parts pick list values
 List<String> bicyclePartsListValues = recordChange.getNew().getValue("bicycle_part__c", ValueType.PICKLIST_VALUES);

 // Get the name(label) of the bicycle part using the bicyclePartPickList
 if (bicyclePartsListValues != null && !bicyclePartsListValues.isEmpty()) {
    // Get single-picklist value name selected by user
    String partPicklistValueName = bicyclePartsListValues.get(0);
    // Get picklist value label
    bicyclePartName = bicyclePartPicklist.getPicklistValue(partPicklistValueName).getLabel();
 }

 // Get the name(label) of the bicycle part manufacturer using the bicyclePartManufacturerPickList
 List<String> bicyclePartManufacturersListValues = recordChange.getNew().getValue("bicycle_part_manufacturer__c", ValueType.PICKLIST_VALUES);
 if (bicyclePartManufacturersListValues != null && !bicyclePartManufacturersListValues.isEmpty()) {
    // Get single-picklist value name selected by user
    String partManufacturerPicklistValueName = bicyclePartManufacturersListValues.get(0);
    // Get picklist value label
    bicyclePartManufacturerName = bicyclePartManufacturersPicklist.getPicklistValue(partManufacturerPicklistValueName).getLabel();
}
            .....
 // Get the order quantity
 BigDecimal orderQuantity = recordChange.getNew().getValue("order_quantity__c", ValueType.NUMBER);
 // Add part name, part manufacturer name and order quantity to maps
 partAndManufacturerMap.put("'" + bicyclePartName + "'", "'" + bicyclePartManufacturerName + "'");
orderQuantityMap.put(bicyclePartName, orderQuantity);
});

Next, the ProductSearchUserDefinedService is used to find the bicycle parts and manufacturers and fetch the relevant data and store into a map of bicycle mpart name(string) and BicyclePartData object. The logResourceUsage method of the logService is used to log the memory usage before and after the method call. It can be noted when viewing the debug logs that the memory used by the doesProductExist method is released after the method exits and only the memory used by the return value is retained.

 logService.logResourceUsage("Before doesProductExist Method Call: ");
 Map<String, BicyclePartData> doProductsExist = 
 productSearchUserDefinedService.doesProductExist(partAndManufacturerMap);
        logService.logResourceUsage("After doesProductExist Method Call: " );

Next, the return value of the doesProductExist method is inspected to validate that all bicyclepart records were found for all user entered bicycle part names.

 // Validate that all user entered bicycle part name were found, if not setError on the record change.
 for (RecordChange recordChange : recordTriggerContext.getRecordChanges()) {
     // If no results were found, all user inputted parts and manufacturer combinations are wrong.
     if (doProductsExist == null) {
         recordChange.setError("INVALID_ARGUMENT", "Product with specified manufacturer does not exist.");
                continue;
     }
     // Get the bicycle parts pick list values
     List<String> bicyclePartsListValues = recordChange.getNew().getValue("bicycle_part__c", ValueType.PICKLIST_VALUES);

     String bicyclePartName = "";
     // Get the name(label) of the bicycle part using the bicyclePartPickList
     if (bicyclePartsListValues != null && !bicyclePartsListValues.isEmpty()) {
        // Get single-picklist value name selected by user
        String partPicklistValueName = bicyclePartsListValues.get(0);
        // Get picklist value label
        bicyclePartName = bicyclePartPicklist.getPicklistValue(partPicklistValueName).getLabel();
     }

     if (bicyclePartName != null && !doProductsExist.get(bicyclePartName).getIdExists()) {
        // setError if the user specified bicycle part's record was not found.
        recordChange.setError("INVALID_ARGUMENT", "Product with specified manufacturer does not exist.");
     }

        }

Lastly, the reduceProductQuantity method of the ProductSearchUserDefinedService is used to reduce the quantity for each entry. This method takes a collection of the BicyclePartData objects which contain the bicycle part's name, id and original quantity as well as a map specifying the name and quantity to reduce by.

 // Reduce the quantity for the bicycle models that we are creating an order for.
        if(doProductsExist != null) {
            logService.logResourceUsage("Before reduceProductQuantity Method Call: ");
            productSearchUserDefinedService.reduceProductQuantity(doProductsExist.values(), orderQuantityMap);
            logService.logResourceUsage("After reduceProductQuantity Method Call: ");
        }

Clone this wiki locally