The "Custom Query" functionality relies on the use of the Apex programming language, so it is a bit technical. If this is your first exposure to Apex, don't worry. This feature is optional and Maven Documents can work perfectly fine without it.
Custom Query enables you to define your custom Apex class which can enrich your current Salesforce data with, basically, anything. Having this tool at your disposal means that you are not dependent on only the data you can get with Query Builder but also on your custom logic.
The decision to use it would most likely occur in the following scenario:
You can find Custom Query details in the related list on the "Document Solution" Object.
Click on the "New" button to input Custom Query Name and Apex Class Name.
The Apex Class you plan to use has to implement the CustomQueryInterface global interface packaged in the "Maven Documents" app:
global interface CustomQueryInterface {
Object executeCustomQuery(Map<String, Object> GraphQLData, String requestId);
}
When implemented, with the "executeCustomQuery" method, you can return some of the following:
Furthermore, you also have the "Map<String, Object> GraphQL Data" map and "String requestId" at your disposal.
Feel free to use those bits of information in any shape, way, or form when returning the resulting value.
Here are a couple of examples of the Apex classes that are implementing mmdoc.CustomQueryInterface:
A:
Custom Query Name: MyCustomQueryName
Apex Class Name: MyCustomApexClass
global class MyCustomApexClass implements mmdoc.CustomQueryInterface {
public Object executeCustomQuery(Map<String, Object> GraphQLData, String requestId) {
return 'This is my custom value!';
}
}
B:
Custom Query Name: MyCustomQueryName2
Apex Class Name: MyCustomApexClass2
global class MyCustomApexClass2 implements mmdoc.CustomQueryInterface {
public Object executeCustomQuery(Map<String, Object> GraphQLData, String requestId) {
Map<String, String> myMap = new Map<String, String>();
myMap.put('myKey', 'This is my custom value inside a Map' );
return myMap;
}
}
C:
Custom Query Name: MyCustomQueryName3
Apex Class Name: MyCustomApexClass3
global class MyCustomApexClass3 implements mmdoc.CustomQueryInterface {
public Object executeCustomQuery(Map<String, Object> GraphQLData, String requestId) {
Map<String, String> myMap = new Map<String, String>();
myMap.put('myKey', 'This is my custom value inside a Map' );
List<Map<String, String>> myList = new List<Map<String, String>>();
myList.add(myMap);
return myList;
}
}
D:
Custom Query Name: MyCustomQueryName4
Apex Class Name: MyCustomApexClass4
When defining a custom class that will be returned in a Custom Query, make sure that:
So first, create the Apex Class below:
@JsonAccess(serializable='always' deserializable='always')
global class ProductDetail {
@AuraEnabled
global String name;
@AuraEnabled
global String provider;
@AuraEnabled
global String productCode;
}
Then, the following Class:
global class MyCustomApexClass4 implements mmdoc.CustomQueryInterface {
public Object executeCustomQuery(Map<String, Object> GraphQLData, String requestId) {
List<ProductDetail> myProducts = new List<ProductDetail>();
List<mmdoc__Document_Request__c> req = [SELECT Id, ProductGroupCode__c FROM mmdoc__Document_Request__c WHERE Id = :requestId];
List<Product2> filteredProducts = [SELECT Name, Description, ProductCode FROM Product2 WHERE GroupCode__c = :req.ProductGroupCode__c];
for (Database_Product__c currentProduct : filteredProducts) {
ProductDetail newProduct = new ProductDetail();
newProduct.name = currentProduct.Name;
newProduct.provider = currentProduct.Description;
newProduct.productCode = currentProduct.ProductCode;
myProducts.add(newProduct);
}
return myProducts;
}
}
With that logic in place, you are ready to reference Custom Query Name inside your Google Docs, Google Sheets, DOCX, or XLSX template!
Here is the side-by-side of the Google Docs template and the generated file, using the example from above: