An issue has been observed where document generation failed or was incorrect if the primary object of a Template Configuration record shared the API name with one of the Aveneer core objects e.g ave__Transaction__c vs Transaction__c. In such a case a new apex class has to be implemented and added under Custom Metadata Type section in Setup. The following class will allow Aveneer to retrieve correct data:
global with sharing class AveneerOverrideUtilsGlobal extends ave.AveneerPlugins {
global override List<SObject> query(String queryString) {
return Database.query(queryString);
}
global override List<SObject> queryWithBinds(String queryString, Map<String, Object> bindsMap) {
return Database.queryWithBinds(queryString, bindsMap, AccessLevel.SYSTEM_MODE);
}
global override Object createInstance(String className) {
return Type.forName('', 'Schema.' + className).newInstance();
}
global override List<SObject> getRecords(SObjectAccessDecision sObjectAccessDecision) {
return new List<SObject>(sObjectAccessDecision.getRecords());
}
}
Once the apex class is created, the next step is to navigate to Setup -> Custom Metadata Types -> Aveneer Configuration (manage) and paste its name AveneerOverrideUtilsGlobal under the AveneerPlugins_Override_Class_Name entry.
This change also affects the document generation from a List View of a given duplicate object. As a consequence another apex class has to be implemented to correctly handle the selection of records on the List View:
public with sharing class AveneerListButtonController {
public String[] objectIds {get;set;}
public String returnUrl {get;set;}
public Boolean hasErrors {get;set;}
private ApexPages.StandardSetController standardSetController;
public String getObjectIdsJson() {
return JSON.serialize(this.objectIds);
}
public AveneerListButtonController(ApexPages.StandardSetController standardSetController){
this.standardSetController = standardSetController;
this.hasErrors = false;
getRecordsDetails();
}
public PageReference getRecordsDetails(){
List<Id> selectedListViewRecords = getSelectedRecordsIds();
objectIds = (List<String>) selectedListViewRecords;
if(objectIds.isEmpty()){
this.hasErrors = true;
ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,'You should select at least one record.'));
} else {
returnUrl = objectIds[0].substring(0,3);
}
String objectApiName = getObjectApiName();
return null;
}
@TestVisible
private List<Id> getSelectedRecordsIds(){
return new List<Id>(new Map<Id, sObject>(standardSetController.getSelected()).keySet());
}
@TestVisible
private String getObjectApiName(){
return standardSetController.getRecord().getSObjectType().getDescribe().getName();
}
}
Once the apex class is implemented go to Setup -> Visualforce Pages OR Aveneer App -> Settings tab -> Create Visualforce Page tab and create a new VF page utilizing the new apex class
//The name of the extension should match the implemented class (AveneerListButtonController)
<apex:page standardController="Transaction__c" extensions="AveneerListButtonControllerOverride" recordSetVar="transactions" lightningStylesheets="true">
<apex:pageMessages />
<apex:outputPanel rendered="{!!hasErrors}">
<apex:includeLightning />
<div id="container"></div>
<script>
$Lightning.use("ave:GenerateDocumentsContainer", () => {
$Lightning.createComponent(
"ave:GenerateDocuments",
{
objectIds: {!objectIdsJson},
returnUrl: '{!JSINHTMLENCODE(returnUrl)}'
},
"container"
);
});
</script>
</apex:outputPanel>
</apex:page>
Once both the apex class and VF page are created proceed to new button creation as described in this section.
Following is the full list of Custom Object that would get mishandled as Aveneer Objects:
- Action__c
- Assignment_Rule__c
- Branch_Config__c
- Error_Log__c
- External_Generator_Log__c
- Notification__c
- Record_Picker_Cofiguration__c
- Signature__c
- Template_Configuration__c
- Template_Configuration_History__c
- Transaction__c
