I have a flow and due to the complexity of the logic, I moved some of the logic into apex (However I need to use minimum apex).
I’m looping through some records and finding related records (I need only one to be added to the list). And if there are no records found, I’m adding the Id to a list of Strings (Later I need it to send an email from the flow).
But how can I pass the list of Strings back to the flow in addition to the list of records I’m returning? Is there a way to set flow variables from apex instead of returning?
@InvocableMethod public static List<List<Maintenance__c>> getMaintenanceRecordsToBeCloned(List<List<Maintenance__c>> mains){ List<Maintenance__c> maintenances = mains.get(0); List<Maintenance__c> listTobeCloned = new List<Maintenance__c>(); List<String> missingRecords = new List<String>(); Property_Agreement__c[] props = [SELECT Name, Id FROM Property_Agreement__c WHERE Active_c=True]; //doing the following to get only one Maintenance record per Agreement for(Property_Agreement__c prop : props){ Boolean isRecordFound = false; for(Maintenance__c main: maintenances){ if(main.Property_Agreement__c == prop.Id){ listTobeCloned.add(main); isRecordFound = true; break; } } if(!isRecordFound){ missingRecords.add(prop.Id); } } List<List<Maintenance__c>> result = new List<List<Maintenance__c>>(); result.add(listTobeCloned); //is there a way to return missingRecords too? return result; }
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You use InvocableVariable annotations in a custom class. A demonstration of this is included in the documentation.
global class ConvertLeadAction { @InvocableMethod(label='Convert Leads') global static List<ConvertLeadActionResult> convertLeads(List<ConvertLeadActionRequest> requests) { List<ConvertLeadActionResult> results = new List<ConvertLeadActionResult>(); for (ConvertLeadActionRequest request : requests) { results.add(convertLead(request)); } return results; } public static ConvertLeadActionResult convertLead(ConvertLeadActionRequest request) { Database.LeadConvert lc = new Database.LeadConvert(); lc.setLeadId(request.leadId); lc.setConvertedStatus(request.convertedStatus); if (request.accountId != null) { lc.setAccountId(request.accountId); } if (request.contactId != null) { lc.setContactId(request.contactId); } if (request.overWriteLeadSource != null && request.overWriteLeadSource) { lc.setOverwriteLeadSource(request.overWriteLeadSource); } if (request.createOpportunity != null && !request.createOpportunity) { lc.setDoNotCreateOpportunity(!request.createOpportunity); } if (request.opportunityName != null) { lc.setOpportunityName(request.opportunityName); } if (request.ownerId != null) { lc.setOwnerId(request.ownerId); } if (request.sendEmailToOwner != null && request.sendEmailToOwner) { lc.setSendNotificationEmail(request.sendEmailToOwner); } Database.LeadConvertResult lcr = Database.convertLead(lc, true); if (lcr.isSuccess()) { ConvertLeadActionResult result = new ConvertLeadActionResult(); result.accountId = lcr.getAccountId(); result.contactId = lcr.getContactId(); result.opportunityId = lcr.getOpportunityId(); return result; } else { throw new ConvertLeadActionException(lcr.getErrors()[0].getMessage()); } } global class ConvertLeadActionRequest { @InvocableVariable(required=true) global ID leadId; @InvocableVariable(required=true) global String convertedStatus; @InvocableVariable global ID accountId; @InvocableVariable global ID contactId; @InvocableVariable global Boolean overWriteLeadSource; @InvocableVariable global Boolean createOpportunity; @InvocableVariable global String opportunityName; @InvocableVariable global ID ownerId; @InvocableVariable global Boolean sendEmailToOwner; } global class ConvertLeadActionResult { @InvocableVariable global ID accountId; @InvocableVariable global ID contactId; @InvocableVariable global ID opportunityId; } class ConvertLeadActionException extends Exception {} }
Notice how you can set some to be required, or not, and you can choose multiple types; each can be input or output values, and will be exposed to the flow. Each corresponding index in the input should have a corresponding output in the return value.
In your example, it would look like:
@InvocableMethod public static List<CloneMaintenanceResult> getMaintenanceRecordsToBeCloned(List<CloneMaintenanceRequest> mains){
…
public class CloneMaintenanceResult { @InvocableVariable Maintenance__c[] records; ... } public class CloneMaintenanceRequest { @InvocableVariable Maintenance__c[] records; ... }
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0