SCM-FFA Plugins

Note: If you are using any SCM plugins or custom Apex classes as part of you org settings, your classes must have a visible constructor to be initialized. This follows the Salesforce update applied on August 18, 2020. Ensure your custom Apex classes comply with this requirement to avoid any errors when executing them:

All Apex classes must have a visible constructor to be initialized

  • Public (Managed Classes)
  • Global (Unmanaged Classes)
For more information, see Restrict Reflective Access to Non-Global Constructors in Packages (Critical Update) in the Salesforce Spring '20 Release Notes.

The custom fields in the SCM-FFA Plugins custom setting enable you to specify a custom plugin to customize the way in which data is transferred to FinancialForce Accounting.

Fields Available on the SCM-FFA Plugins Custom Setting
Field Description
AP Voucher Export The name of an Apex class that implements the plugin interface for an AP Voucher Export.
Credit Invoice Export The name of an Apex class that implements the plugin interface for a Credit Invoice Export.
Invoice Export The name of an Apex class that implements the plugin interface for an Invoice Export.
Invoice Void Export The name of an Apex class that implements the plugin interface for a Invoice Void Export.
Journal Export The name of an Apex class that implements the plugin interface for a Journal Export.

Sample Plugin Classes

Invoice Export

Here is an example of a class that prevents invoices from being exported for a specific customer when referenced in the Invoice Export custom field of the SCM FFA Plugins custom setting.

Copy
global with sharing class SamplePluginRemoveInvoice extends SCMFFA.SCMFFAPlugin {
 
    global SamplePluginRemoveInvoice() {
         throwException = true;
    }
 
        // SAMPLE - Prevent export of invoices for a specific customer
        // When run on invoice export:
        // scmIdToFFARecord - the Id is the Id of the SCM Invoice
        // the sObject is the resulting FFA Sales Invoice
        // scmIdToFFALineRecords - the Id is the Id of the SCM Invoice
        // the sObject is the resulting FFA Sales Invoice Line Items
        // scmIdToFFALineRecords2 - not used
        global override void execute(Map<Id, sObject> scmIdToFFARecord, Map<Id, sObject[]> scmIdToFFALineRecords, Map<Id, sObject[]> scmIdToFFALineRecords2) {
        // query source SCM invoices
               SCMC__Invoicing__c[] invoices = [select Id, SCMC__Customer__c, SCMC__Customer__r.name
               from SCMC__Invoicing__c where Id in :scmIdToFFARecord.keySet()];
        // loop through source invoices and remove the FFA invoice from the passed in map
               for (SCMC__Invoicing__c inv : invoices) {
                       if (inv.SCMC__Customer__r.name.toLowerCase() == 'acme') {
                               scmIdToFFARecord.remove(inv.Id);
                               // not necessary - if there is no invoice being exported, none of its lines will be exported.
                               scmIdToFFALineRecords.remove(inv.Id);
                        }
               }
         }
}

Invoice Void Export

Copy
global with sharing class InvoiceVoidExportPlugin extends SCMC.SCMPlugin{
    global InvoiceVoidExportPlugin() {
        throwException = true;       
        doRollback = true;    
    }    
    global override void execute(Id[] recordIds) { 
        try {        
            Set<Id> invoiceIds = new Set<Id>(recordIds);        
            SCMFFA.InvoicesService.exportVoid(invoiceIds);   
        } 
        catch (Exception ex){     
            throw new MyException ('Voiding invoice plugin failed ' + ex.getMessage());
        }
    }
}

Modify Dimensions

Here is an example of a class that modifies Dimension 1 on sales invoice lines when referenced in the Invoice Export custom field of the SCM FFA Plugins custom setting.

Copy
global with sharing class SamplePluginModifyDimensions extends SCMFFAPlugin {   
    global SamplePluginModifyDimensions() { 
        throwException = true;   
    }
    
    // SAMPLE - modify SIN line's dimension 1 based on billing country   
    // When run on invoice export:    
    // scmIdToFFARecord - the Id is the Id of the SCM Invoice    
    // the sObject is the resulting FFA Sales Invoice   
    // scmIdToFFALineRecords - the Id is the Id of the SCM Invoice    
    // the sObject is the resulting FFA Sales Invoice Line Items    
    // scmIdToFFALineRecords2 - not used    
    global override void execute(Map<Id, sObject> scmIdToFFARecord, Map<Id, sObject[]> scmIdToFFALineRecords, Map<Id, sObject[]> scmIdToFFALineRecords2) {     
        
        // query source SCM invoices with shipping country            
        Map<Id, SCMC__Invoicing__c> invIdToInvoices = new Map<Id, SCMC__Invoicing__c>([
        select Id                        
        , SCMC__Ship_to_Country__c
        from SCMC__Invoicing__c
        where Id in :scmIdToFFARecord.keySet()                     
        ]);
        
        set<string> countries = new set<string>();  
        
        for (SCMC__Invoicing__c inv : invIdToInvoices.values()) {                     
            countries.add(inv.SCMC__Ship_to_Country__c);            
        }  
        
        // query the dimension we will be using 
        c2g__codaDimension1__c[] dim1s = [select Id, c2g__ReportingCode__c
        from c2g__codaDimension1__c
        where c2g__ReportingCode__c in :countries];
        
        Map<string, c2g__codaDimension1__c> repCodeToDim1 = new Map<string, c2g__codaDimension1__c>();   
        
        for (c2g__codaDimension1__c dim : dim1s) {
            repCodeToDim1.put(dim.c2g__ReportingCode__c, dim);
        }
        
        for (Id scmInvId : scmIdToFFALineRecords.keySet()) {
            SCMC__Invoicing__c scmInv = invIdToInvoices.get(scmInvId);
            c2g__codaDimension1__c dim1 = repCodeToDim1.get(scmInv.SCMC__Ship_to_Country__c);
            if (dim1 != null) {
                sObject[] lineSObjects = scmIdToFFALineRecords.get(scmInvId);
                for (c2g__codaInvoiceLineItem__c invLine : (c2g__codaInvoiceLineItem__c[])lineSObjects) {                                    
                    // simply set the new dimension on the SIN line. the connector will save any modifications that are made here.            
                    invLine.c2g__Dimension1__c = dim1.Id;                            
                }                    
            }            
        }    
    }
}