Skip to content

Product Search User Defined Service

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

Product Search User Defined Service

ProductSearchService is an Interface that uses UserDefinedService. ProductSearchService Implementations implement the doesProductExist method and the reduceProductQuantity method. UserDefinedService is a Vault SDK API that allow reusable logic to be wrapped into a service that can be used by other Vault Java SDK code. Vault SDK code such as triggers, actions or user-defined classes can use a a user-defined service by locating it using ServiceLocator. Unlike user-defined classes, user-defined services are stateless; nothing is retained beyond the service method execution.

doesProductExist Method

The doesProductExist Method checks whether the provided model name has a matching part record.It accepts a list of string values representing the product names and a list of string values representing the manufacturer names as parameters. It returns a map containing the bicycle part name as key and an BicyclePartData object as value.

The doesProductExist method uses QueryService to query for the products the user entered in their order.

// Build our query strings
// Turn our lists into strings to be used in contains queries.
String productsToQuery = String.join (",",productAndManufacturerMap.keySet());
String manufacturersToQuery = String.join (",",productAndManufacturerMap.values());

// Build our entire query string

StringBuilder partAndManufacturerQuerySB = new StringBuilder();
partAndManufacturerQuerySB.append("SELECT id, name__v, quantity__c FROM bicycle_part__c WHERE caseinsensitive(name__v) CONTAINS (");
partAndManufacturerQuerySB.append(productsToQuery);
partAndManufacturerQuerySB.append(") AND caseinsensitive(bicycle_part_manufacturer__cr.name__v) CONTAINS (");
partAndManufacturerQuerySB.append(manufacturersToQuery);
partAndManufacturerQuerySB.append(")");

After fetching the results of the query, the map is constructed if the results count is greater than 0.

  // If the query results count is greater than 0, then the query returned result
  if(queryResponse.getResultCount() > 0) {
      // Iterate over query results, get the id, name and quantity and add to bicyclePartData map.
      queryResponse.streamResults().forEach(queryResult -> {

        // Get id, name and quantity
        String id = queryResult.getValue("id", ValueType.STRING);
        String name = queryResult.getValue("name__v", ValueType.STRING);
        BigDecimal quantity = queryResult.getValue("quantity__c", ValueType.NUMBER);

        // Add to map with key as name and BicyclePartData object as value.
        bicycleModelDataMap.put(name, new BicyclePartData(name, id != null, id, quantity));
      });

      // Log the memory used in the method.
      logService.logResourceUsage("Memory Usage In doesProductExist: ");

      // Return the results.
      return bicycleModelPartMap;
    }

reduceProductQuantity Method

The reduceProductQuantity Method reduces the bicycle part object record quantity by the amount specified in the bicycle part order record.It accepts a collection of BicyclePartData objects and a map of the bicycle part name and bicycle order quantity. part The reduceProductQuantity Method uses Record Service to update the bicycle part records. If the order quantity is found to be greater than the model quantity or the part quantity or order quantity is null, then a RollBackException is thrown.

  // Iterate over BicycleModelData objects which hold the bicycle model name, record id, and order quantity
  for(BicyclePartData currentBicyclePartData : BicyclePartData) {

      // Check if the record was found before continuing
      if(currentBicyclePartData.getIdExists()) {

         // Instantiate a record with the id that was found before and stored in the BicyclePartData object
         Record bicyclePartRecord = recordService.newRecordWithId("bicycle_part__c", currentBicyclePartData.getId());

         // Get the bicycle part quantity
         BigDecimal bicyclePartQuantity = currentBicyclePartData.getQuantity();

         // Get the bicycle part order quantity
         BigDecimal orderQuantity = orderQuantityMap.get(currentBicyclePartData.getBicyclePartName());

         if(bicyclePartQuantity != null && orderQuantity != null) {

            // If the order quantity is less than or equal to the part quantity, then set the new quantity and add to the updateRecords list
             if(bicyclePartQuantity.compareTo(orderQuantity) >= 0) { // Will be 0 if equal, 1 if bicyclePartQuantity is greater
                BigDecimal updatedQuantity = bicyclePartQuantity.subtract(orderQuantity);
                bicyclePartRecord.setValue("quantity__c", updatedQuantity);

                 updatedRecords.add(bicyclePartRecord);
              } else {
                  throw new RollbackException("INVALID_ARGUMENT", "Order Quantity is greater than bicycle part quantity");
                }
              } else {
                // If the bicycle part quantity or the order quantity is null then throw an error.
                throw new RollbackException("INVALID_ARGUMENT", "Quantity not found");
              }
          }
      }

When all the updated records have been added to the list, the batchSaveRecords Method provided by the Record Service is used to save all the updated Bicycle Part Records in bulk. This approach is more efficient than iterating over each record and saving them individually.

  // Bulk save updated records
  recordService.batchSaveRecords(updatedRecords).onErrors(batchOperationErrors -> {

    // Throw errors
    batchOperationErrors.stream().findFirst().ifPresent(error -> {

      // Get the error message
      String errMsg = error.getError().getMessage();

      // Get which record the error occurred on
      int errPosition = error.getInputPosition();
      String name = updatedRecords.get(errPosition).getValue("name__v", ValueType.STRING);

      // Throw error
      throw new RollbackException("OPERATION_NOT_ALLOWED", "Unable to save: " + name +
                                  " because of " + errMsg);
    });
  }).execute();