0

Using a Webform (FormAssembly) to create an Interaction & Getting an error. Using the same form multiple times. it sometimes errors at the first submit and sometimes after the third submission, I receive an error. I have a form that can be resubmitted multiple times if the subscriber wishes to update information being submitted. It works perfectly for the first two submissions from the same subscriber and by the third, it fails. Which doesn't make sense? I could add a new subscriber via the same form and it's the same thing, the new subscriber will error out on the third one.

I've reached out to FormAssembly Support and they said the error regards a trigger in Salesforce so it's out of their hands.

Error Message: 9. Create Interaction__c - INT_Interaction: execution of AfterInsert caused by: System.TypeException: Invalid conversion from runtime type Account to Contact Class.INT_InteractionProcessor.convertLeads: line 451, column 1 Class.INT_InteractionProcessor.pr

the error is occurring because of the trigger associated with Apex class "INT_InteractionProcessor" which is associated with HEDA

For the Create Interaction mapping, I removed everything except Name and email. Then it was a success. Started adding them back in one by one and when it came to mapping Mailing City. The error occurs.

This is telling that name and billingCIty is matching and standard contact matching rules are triggered to stop it..so it is not converting the lead but there is no need for lead ..it should not create a lead in this case. when I created manually with interactions it is working fine.

public class INT_InteractionProcessor { private List dupeInteractions = new List(); private List leadsToDelete = new List(); private List opportunitiesToUpsert = new List(); private Map interactionIdToLead = new Map(); private Map interactionMap = new Map(); private Map leadIdToInteractionMap = new Map(); private Set contactIds = new Set(); private Set existingLeadIds = new Set();

private INT_InteractionMappingService intMappingService {
    get {
        if (intMappingService == null) {
            intMappingService = new INT_InteractionMappingService();
        }

        return intMappingService;
    }

    set;
}

private Map<String, Id> campaignIdMap {
    get {
        if (campaignIdMap == null) {
            campaignIdMap = new Map<String, Id>();
            Set<String> referenceIds = new Set<String>();

            for (SObject interaction : Trigger.new) {
                if (interaction.get('Campaign_Key__c') != null) {
                    referenceIds.add(String.valueOf(interaction.get('Campaign_Key__c')));
                }

                if (interaction.get('Additional_Campaign_Key__c') != null) {
                    referenceIds.add(String.valueOf(interaction.get('Additional_Campaign_Key__c')));
                }
            }

            for (Campaign aCampaign : [
                SELECT Id, Campaign_Key__c
                FROM Campaign
                WHERE (Campaign_Key__c IN :referenceIds OR Id IN :referenceIds)
            ]) {
                campaignIdMap.put(aCampaign.Campaign_Key__c, aCampaign.Id);
            }
        }

        return campaignIdMap;
    }

    set;
}

private Map<String, CampaignMember> campaignMemberMap {
    get {
        if (campaignMemberMap == null) {
            campaignMemberMap = new Map<String, CampaignMember>();

            // Loop through current Campaign Members and build campaignMemberMap
            for (CampaignMember cm : [
                SELECT Status, CampaignId, Campaign.Campaign_Key__c, Lead_Contact_ID__c
                FROM CampaignMember
                WHERE ContactId IN :contactIds
            ]) {
                if (!String.isEmpty(cm.Campaign.Campaign_Key__c)) {
                    campaignMemberMap.put(String.valueOf(cm.Lead_Contact_ID__c + '.' + cm.Campaign.Campaign_Key__c), cm);
                } else {
                    campaignMemberMap.put(String.valueOf(cm.Lead_Contact_ID__c + '.' + cm.CampaignId), cm);
                }
            }
        }

        return campaignMemberMap;
    }

    set;
}

// Grab Lead conversion master label.
private LeadStatus convertStatus {
    get {
        if (convertStatus == null) {
            convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted = true LIMIT 1];
        }

        return convertStatus;
    }

    set;
}

// Populate a Map of Existing Leads to map fields to new Interactions.
private Map<Id, Lead> existingLeadMap {
    get {
        if (existingLeadMap == null
            && !existingLeadIds.isEmpty()
            && intMappingService.intMappingMap != null
            && intMappingService.intMappingMap.containsKey('Interaction__c')
        ) {
            String soqlString = 'SELECT Id';

            for (Interaction_Mapping__c mapping : intMappingService.intMappingMap.get('Interaction__c')) {
                soqlString += ', ' + mapping.Source_Field_API_Name__c;
            }

            soqlString = soqlString.removeEnd(',').trim();
            soqlString += ' FROM Lead WHERE Id IN :existingLeadIds';
            existingLeadMap = new Map<Id, Lead>((List<Lead>) Database.query(soqlString));
        } else if (existingLeadMap == null) {
            existingLeadMap = new Map<Id, Lead>();
        }

        return existingLeadMap;
    }

    set;
}

/**
 * @description Inserts Leads only from new Interaction__c records.
 * @param interactionsToProcess, the List of new Interaction__c objects to process.
 */
public void processLeads(List<Interaction__c> newInteractions) {
    // Run duplicate pre-processing
    List<Interaction__c> interactionsToProcess = duplicatePreProcessing(newInteractions);

    // Set up Interaction Map for reference during processing.
    interactionMap = new Map<Id, Interaction__c>(interactionsToProcess);

    // Insert Leads from the new Interaction records.
    List<Database.LeadConvert> newLeads = insertLeadsFromInteractions(interactionsToProcess);

    // Apply Interaction Mappings to all Leads
    List<Lead> leadsToUpdate = new List<Lead>();
    for (String leadId : leadIdToInteractionMap.keySet()) {
        Lead leadToUpdate = new Lead(Id = leadId);
        intMappingService.applyDataToSObject(leadIdToInteractionMap.get(leadId), leadToUpdate);
        leadsToUpdate.add(leadToUpdate);
    }

    // Update Leads with data from the mapping service.
    if (leadsToUpdate.size() > 0) {
        logPossibleErrors(Database.update(leadsToUpdate, false));
    }

    // Create CampaignMembers to upsert from the Leads inserted if they have the proper Campaign Keys
    List<CampaignMember> campaignMembersToUpsert = createCampaignMembersFromLeads(true);

    // Upsert Campaign Members from Leads
    if (campaignMembersToUpsert.size() > 0) {
        logPossibleErrors(Database.upsert(campaignMembersToUpsert, CampaignMember.Campaign_Member_Key__c, false));
    }

    // Finally set Interaction_Status__c after processing and flag if errored.
    for (Interaction__c interaction : interactionsToProcess) {
        interaction.Interaction_Status__c = (!String.isEmpty(interaction.Audit_Reason__c)) ? 'Audit Required' : 'Imported';
    }

    // Add any duplicates found and update the Interactions with new Status from processing.
    interactionsToProcess.addAll(dupeInteractions);
    logPossibleErrors(Database.update(interactionsToProcess, false));
}

/**
 * @description Main method for processing new Interaction__c records.
 * @param interactionsToProcess, the List of new Interaction__c objects to process.
 */
public void processInteractions(List<Interaction__c> newInteractions) {
    List<Contact> contactsToUpdate = new List<Contact>();
    List<hed__Affiliation__c> affiliationsToUpsert = new List<hed__Affiliation__c>();

    // Run duplicate pre-processing
    List<Interaction__c> interactionsToProcess = duplicatePreProcessing(newInteractions);

    // Set up Interaction Map for reference during processing.
    interactionMap = new Map<Id, Interaction__c>(interactionsToProcess);

    // Create Leads from new Interactions records.
    List<Database.LeadConvert> newLeads = insertLeadsFromInteractions(interactionsToProcess);

    // Attempt initial conversion of leads.
    List<Database.LeadConvert> possibleLeadsToReconvert = convertLeads(newLeads);

    // Reconvert Leads with matched Contacts if duplicate errors.
    if (possibleLeadsToReconvert.size() > 0) {
        convertLeads(possibleLeadsToReconvert);
    }

    // Create CampaignMembers to upsert from the Leads inserted if they have the proper Campaign Keys
    List<CampaignMember> campaignMembersToUpsert = createCampaignMembersFromLeads(false);

    // Upsert Campaign Members from Leads
    if (campaignMembersToUpsert.size() > 0) {
        logPossibleErrors(Database.upsert(campaignMembersToUpsert, CampaignMember.Campaign_Member_Key__c, false));
    }

    // Upsert associated Opportunities using Opportunity_Key__c as the lookup Id.
    if (opportunitiesToUpsert.size() > 0) {
        logPossibleErrors(Database.upsert(opportunitiesToUpsert, Opportunity.Opportunity_Key__c, false));
    }

    // Finally, associate referenced Opportunity and set Interaction_Status__c after processing and flag if errored.
    for (Interaction__c interaction : interactionsToProcess) {
        if (!String.isEmpty(interaction.Contact__c)) {
            Contact newCont = new Contact(Id = interaction.Contact__c);
            intMappingService.applyDataToSObject(interaction, newCont);
            contactsToUpdate.add(newCont);
        }

        if (interaction.Affiliation_Key__c != null) {
            affiliationsToUpsert.add(createUpsertAffilFromInteraction(interaction));
        }

        // Set the new referenced Opportunity's Id on the Interaction__c lookup field.
        if (interaction.Opportunity__r != null) {
            interaction.Opportunity__c = interaction.Opportunity__r.Id;
            interaction.Opportunity__r = null;
        }

        // Check for Interactions that have Opportunity Keys, but no Opportunity associated, flag them.
        if ((interaction.Opportunity_Key__c != null) && (interaction.Opportunity__c == null)) {
            String error = ' Reason: Interaction has an Opportunity Key, but could not find ' +
                'associated Opportunity in the system. Please verify that the Opportunity Key is valid.';
            interaction.Audit_Reason__c += error;
        }

        interaction.Interaction_Status__c = (!String.isEmpty(interaction.Audit_Reason__c)) ? 'Audit Required' : 'Imported';
    }

    // Update Contacts
    if (contactsToUpdate.size() > 0) {
        logPossibleErrors(Database.update(contactsToUpdate, false));
    }

    // Upsert Affiliations using the Upsert_Key__c
    if (affiliationsToUpsert.size() > 0) {
        logPossibleErrors(Database.upsert(affiliationsToUpsert, hed__Affiliation__c.Upsert_Key__c, false));
    }

    // Add any duplicates found and update the Interactions with new Status from processing.
    interactionsToProcess.addAll(dupeInteractions);
    logPossibleErrors(Database.update(interactionsToProcess, false));

    // Cleanup converted Leads.
    if (leadsToDelete.size() > 0) {
        Database.delete(leadsToDelete, false);
    }
}

/**
 * @description Does basic pre-processing for duplicates of the Interactions in the import. If it finds a possible
 * duplicate, it removes it from the import and flags it for future processing.
 * @param interactions, the List of new Interaction__c records.
 * @return the List of filtered Interaction__c records for processing.
 */
private List<Interaction__c> duplicatePreProcessing(List<Interaction__c> interactions) {
    // If the custom setting is turned off, return the List and do not run any pre-processing for duplicates.
    if (Interactions_PreProcessing__c.getAll().values() != null) {
        for (Interactions_PreProcessing__c ipp : Interactions_PreProcessing__c.getAll().values()) {
            if (!ipp.Active__c) return interactions;
        }
    }

    Map<String, Interaction__c> filteredMap = new Map<String, Interaction__c>();

    for (Interaction__c interaction : interactions) {
        String filterKey = interaction.First_Name__c + interaction.Last_Name__c + interaction.Email__c;
        if (!filteredMap.containsKey(filterKey)) {
            filteredMap.put(filterKey, interaction);
        } else {
            interaction.Interaction_Status__c = 'Audit Required';
            String error = ' Reason: this Interaction was not processed because it is a possible ' +
                'duplicate of - ' + filteredMap.get(filterKey).Id + ': ' + filteredMap.get(filterKey).First_Name__c +
                ' ' + filteredMap.get(filterKey).Last_Name__c + ' ' + filteredMap.get(filterKey).Email__c;
            interaction.Audit_Reason__c = error;
            dupeInteractions.add(interaction);
        }
    }

    return filteredMap.values();
}

/**
 * @description Kick off the Interactions process by creating Leads to convert.
 * @param interactions, the list of new Interaction__c objects to insert Leads from.
 * @return leadConverts, the Lead Convert records to convert.
 */
private List<Database.LeadConvert> insertLeadsFromInteractions(List<Interaction__c> interactions) {
    List<Database.LeadConvert> leadConverts = new List<Database.LeadConvert>();

    // Associate Campaigns and create new Leads from Interaction records.
    for (Interaction__c interaction : interactions) {
        // Set Campaign__c on Interaction
        if (!String.isEmpty(interaction.Campaign_Key__c)
            && campaignIdMap.containsKey(interaction.Campaign_Key__c)
        ) {
            interaction.Campaign__c = campaignIdMap.get(interaction.Campaign_Key__c);
        }

        // Set Additional_Campaign__c on Interaction.
        if (!String.isEmpty(interaction.Additional_Campaign_Key__c)
            && campaignIdMap.containsKey(interaction.Additional_Campaign_Key__c)
        ) {
            interaction.Additional_Campaign__c = campaignIdMap.get(interaction.Additional_Campaign_Key__c);
        }

        Lead newLead = new Lead(
            FirstName = interaction.First_Name__c,
            LastName = interaction.Last_Name__c,
            Company = interaction.Last_Name__c + ', ' + interaction.First_Name__c
        );

        interactionIdToLead.put(interaction.Id, newLead);
        intMappingService.applyDataToSObject(interaction, newLead);
    }

    leadConverts.addAll(insertLeads(interactionIdToLead.values(), interactions));

    return leadConverts;
}

/**
 * @description Inserts a collection of Leads. If there are failures, log issues to Interaction Audit Status.
 * @param leads, a List of Lead objects to insert.
 * @return leadsToConvert, a List of Database.LeadConvert records to convert.
 */
private List<Database.LeadConvert> insertLeads(List<Lead> leadsToInsert, List<Interaction__c> interactions) {
    Integer leadIndex = 0;
    Database.SaveResult[] srlist = Database.insert(leadsToInsert, false); // Insert Leads
    List<Database.LeadConvert> leadsToConvert = new List<Database.LeadConvert>();

    for (Database.SaveResult sr : srlist)  {
        Interaction__c interaction = interactions[leadIndex];

        if (sr.isSuccess()) { // Check if insert was a success
            // On success, prepare to convert inserted lead.
            Id leadId = sr.getId();
            leadsToConvert.add(createLeadConvert(interactionMap.get(interaction.Id), leadId, true));
            interaction.Lead__c = leadId; // Copy new Lead Id to the Interaction__c record.
            if (!interaction.Lead_Only__c) leadsToDelete.add(new Lead(Id = leadId)); // Newly created leads will be deleted
        } else {
            /**
             * If there are errors, loop through them and either log the error on the Interaction.
             * or see if there's a duplicate and use that instead.
             */
            for (Database.Error error : sr.getErrors()) {
                if (error.getStatusCode() == StatusCode.DUPLICATES_DETECTED) {
                    Database.DuplicateError dupErrorError = (Database.DuplicateError) error;

                    for (Datacloud.MatchResult matchResult : dupErrorError.getDuplicateResult().getMatchResults()) {
                        for (Datacloud.MatchRecord match : matchResult.getMatchRecords()) {
                            // Grab matched record to use instead of the new one.
                            interaction.Lead__c = match.getRecord().Id;

                            // Add existing Lead Ids to List to query for data to copy to the Interaction later.
                            existingLeadIds.add(match.getRecord().Id);

                            if (interaction.Lead_Only__c == true) {
                                leadIdToInteractionMap.put(interaction.Lead__c,interaction);
                            } else {
                                // The matched Lead doesn't exist in the current transaction, so add it to List to convert.
                                if (leadIdToInteractionMap.get(match.getRecord().Id) == null) {
                                    leadsToConvert.add(createLeadConvert(interaction, match.getRecord().Id, true));
                                }
                            }
                        }
                    }
                } else { // Catch-all for all other errors
                    interaction.Audit_Reason__c += ' Reason: Error during Lead insert - ' + error.getMessage() + '.';
                    System.debug('Error during Lead insert - ' + error.getMessage() + '.');
                }
            }
        }

        leadIndex++;
    }

    return leadsToConvert;
}

/**
 * @description Creates a Database.LeadConvert Object from supplied Interaction record.
 * @param interaction, the Interaction__c to create Database.LeadConvert from.
 * @param leadId, the Id of the Lead to convert.
 * @param createOppty, whether or not to create an Opportunity from the Database.LeadConvert.
 */
private Database.LeadConvert createLeadConvert(Interaction__c interaction, String leadId, Boolean createOppty) {
    // Prepare to convert matching lead
    leadIdToInteractionMap.put(leadId, interaction);
    Database.LeadConvert leadConvert = new Database.LeadConvert();
    leadConvert.setLeadId(leadId);
    leadConvert.setConvertedStatus(convertStatus.MasterLabel);
    leadConvert.setContactId(interaction.Contact__c);
    leadConvert.setAccountId(interaction.Contact_Account_ID__c);
    leadConvert.setDoNotCreateOpportunity(createOppty);

    return leadConvert;
}

/**
 * @description Converts Leads, returns any Database.LeadConvert errors found to be reconverted later.
 * @param leadsToConvert, the List of Lead records to convert.
 * @return leadsToReconvert, a List of possible Database.LeadConvert error records to try and reconvert.
 */
private List<Database.LeadConvert> convertLeads(List<Database.LeadConvert> leadsToConvert) {
    List<Database.LeadConvert> leadsToReconvert = new List<Database.LeadConvert>();
    Database.LeadConvertResult[] leadConvertResults = Database.convertLead(leadsToConvert, false); // Convert Leads

    for (Database.LeadConvertResult lcr : leadConvertResults) {
        Interaction__c interaction = (leadIdToInteractionMap.containsKey(lcr.getLeadId())) ? leadIdToInteractionMap.get(lcr.getLeadId()) : null;

        if (lcr.isSuccess()) {
            // Add Contact Id to set to be updated from its Interaction record.
            interaction.Contact__c = lcr.getContactId();
            contactIds.add(lcr.getContactId());

            // If we had an existing Lead in SF, copy the values to the Interaction based upon the custom mdt.
            if (existingLeadMap.containsKey(lcr.getLeadId())) {
                intMappingService.applyDataToInteraction(existingLeadMap.get(lcr.getLeadId()), interaction);
            }

            // Create new Opportunity for upsert if Opportunity Key is populated.
            if (!String.isEmpty(interaction.Opportunity_Key__c)) {
                Opportunity newOppty = new Opportunity(
                    CloseDate = System.today(),
                    StageName = interaction.Opportunity_Stage__c,
                    Opportunity_Key__c = lcr.getContactId() + interaction.Opportunity_Key__c,
                    AccountId = lcr.getAccountId()
                );
                intMappingService.applyDataToSObject(interaction, newOppty);
                interaction.Opportunity__r = newOppty;
                opportunitiesToUpsert.add(newOppty);
            }
        } else {
            // Find all of the errors for Lead conversion.
            for (Database.Error error : lcr.getErrors()) {
                if (error.getStatusCode() == StatusCode.DUPLICATES_DETECTED) {
                    Database.DuplicateError dupError = (Database.DuplicateError) error;

                    for (Datacloud.MatchResult matchResult : dupError.getDuplicateResult().getMatchResults()) {
                        Contact matchedContact;

                        for (Datacloud.MatchRecord match : matchResult.getMatchRecords()) {
                            // We want to use the oldest matched record, it will be the source Contact.
                            Contact compareContact = (Contact) match.getRecord();
                            if (matchedContact == null || (compareContact.CreatedDate < matchedContact.CreatedDate)) {
                                matchedContact = new Contact();
                                matchedContact = compareContact;
                            }
                        }

                        // Build new Lead convert with matching records.
                        if (matchedContact != null) { // NPE handling
                            Database.LeadConvert leadConvert = new Database.LeadConvert();
                            leadConvert.setConvertedStatus(convertStatus.MasterLabel);
                            leadConvert.setLeadId(lcr.getLeadId());
                            leadConvert.setContactId(matchedContact.Id);
                            leadConvert.setAccountId(matchedContact.AccountId);
                            leadConvert.setDoNotCreateOpportunity(true);
                            leadsToReconvert.add(leadConvert);
                        }
                    }
                } else {
                    interaction.Audit_Reason__c += ' Reason: Error during Lead conversion - ' + error.getMessage() + '.';
                    System.debug('Error during Lead conversion - ' + error.getMessage() + '.');
                }
            }
        }
    }

    return leadsToReconvert;
}

/**
 * @description Creates a new Affiliation record for upsert from the data on the Interaction__c. provided.
 * @param interaction, the Interaction__c record to copy data from.
 * @return newAffil, the Affiliation__c record for upsert.
 */
private hed__Affiliation__c createUpsertAffilFromInteraction(Interaction__c interaction) {
    hed__Affiliation__c newAffil = new hed__Affiliation__c();

    intMappingService.applyDataToSObject(interaction, newAffil);
    newAffil.Upsert_Key__c = interaction.Contact__c + interaction.Affiliation_Key__c;

    return newAffil;
}

/**
 * @description Creates a List of CampaignMember records to upsert from the Leads that have been inserted.
 * @return campaignMembersToUpsert, the List of CampaignMember records to upsert.
 */
private List<CampaignMember> createCampaignMembersFromLeads(Boolean leadOnly) {
    List<CampaignMember> campaignMembersToUpsert = new List<CampaignMember>();

    for (String leadId : leadIdToInteractionMap.keySet()) {
        if (!String.isEmpty(leadIdToInteractionMap.get(leadId).Campaign_Member_Status__c)
            && !String.isEmpty(leadIdToInteractionMap.get(leadId).Campaign_Key__c)
        ) {
            campaignMembersToUpsert.add(createUpsertCMFromInteraction(leadIdToInteractionMap.get(leadId), false, leadOnly));
        }

        // Create a CampaignMember to Upsert for the Additional_Campaign_Key__c if it is populated.
        if (!String.isEmpty(leadIdToInteractionMap.get(leadId).Additional_Campaign_Key__c)
            && !String.isEmpty(leadIdToInteractionMap.get(leadId).Additional_Campaign_Member_Status__c)
            && !String.isEmpty(leadIdToInteractionMap.get(leadId).Lead__c)
        ) {
            campaignMembersToUpsert.add(createUpsertCMFromInteraction(leadIdToInteractionMap.get(leadId), true, leadOnly));
        }
    }

    return campaignMembersToUpsert;
}

/**
 * @description Creates a new CampaignMember record for upsert from the data on the Interaction__c provided.
 * @param interaction, the Interaction__c record to copy data from.
 * @param additionalCampaign, a bool telling the method to use Campaign or Additional Campaign fields on the Interaction__c.
 * @return memberToUpsert, the CampaignMember to upsert.
 */
private CampaignMember createUpsertCMFromInteraction(Interaction__c interaction, Boolean additionalCampaign, Boolean leadOnly) {
    CampaignMember memberToUpsert;
    String leadOrContactId = (leadOnly) ? interaction.Lead__c : interaction.Contact__c;
    String campaignKey = (!additionalCampaign) ? interaction.Campaign_Key__c : interaction.Additional_Campaign_Key__c;
    String campaignMemberStatus = (!additionalCampaign) ? interaction.Campaign_Member_Status__c : interaction.Additional_Campaign_Member_Status__c;
    String campaignMemberKey = String.valueOf(leadOrContactId + '.' + campaignKey);

    if (campaignMemberMap.containskey(campaignMemberKey)) {
        memberToUpsert = campaignMemberMap.get(campaignMemberKey);
        memberToUpsert.Campaign_Member_Key__c = leadOrContactId + '.' + campaignIdMap.get(campaignKey);
    } else {
        memberToUpsert = new CampaignMember(
            CampaignId = campaignIdMap.get(campaignKey),
            Campaign_Member_Key__c = leadOrContactId + '.' + campaignIdMap.get(campaignKey)
        );

        if (leadOnly) {
            memberToUpsert.LeadId = interaction.Lead__c;
        } else {
            memberToUpsert.ContactId = interaction.Contact__c;
        }
    }

    memberToUpsert.Status = campaignMemberStatus;
    intMappingService.applyDataToSObject(interaction, memberToUpsert);

    return memberToUpsert;
}

/**
 * @description Debugs SaveResult errors if they happen.
 * @param saveResults, the Database.SaveResult List to check.
 */
private static void logPossibleErrors(Database.SaveResult[] saveResults) {
    for (Database.SaveResult result : saveResults) {
        if (!result.isSuccess()) {
            System.debug('Save Result Error: ' + result.getErrors() + ' ' + result.getId());
        }
    }
}

/**
 * @description Debugs UpsertResult errors if they happen.
 * @param saveResults, the Database.UpsertResult List to check.
 */
private static void logPossibleErrors(Database.UpsertResult[] saveResults) {
    for (Database.UpsertResult result : saveResults) {
        if (!result.isSuccess()) {
            System.debug('Upsert Error: ' + result.getErrors() + ' ' + result.getId());
        }
    }
}

}

  • I have a SF Debug log. Not sure how to upload a file here. One part of the logs seems to indicate a duplicate error on Mailing City: – Robert Wynter Jan 25 at 15:22
  • Seeing the relevant class INT_InteractionProcessor and the method which is failing would be helpful. Seems like something is calling down to this class/method when a duplicate rule is fired - and causing some kind of type exception. Providing the text values of the fields would also be helpful. – battery.cord Jan 25 at 15:31
  • how do I add a file to the post, please? And the text field value for the mapped field Mailing City + Whitby – Robert Wynter Jan 25 at 15:39
  • 1
    edit the post and add code snippets. SFSE is nt a file sharing sit so it wont support file upload. Add only relevant bit – Pranay Jaiswal Jan 25 at 15:41
  • 1
    Thats a lot of code - I used your debug logs to narrow it down but cutting the class down to just the method thats failing would be prudent. – battery.cord Jan 25 at 16:08
2

I think the problem lies in this line:

for (Datacloud.MatchRecord match : matchResult.getMatchRecords()) {
     Contact compareContact = (Contact) match.getRecord();

I bet your duplicate rule is triggering on an account with the same mailing/billing address as your lead. Your code thinks only contacts can be matched, but when you match with an account, you end up causing the cast error you mention in your post.

You should be able to make this method type-safe using instanceof or by checking the describe of the MatchRecord.getRecord() object.

for (Datacloud.MatchRecord match : matchResult.getMatchRecords()) {
     if (match.getRecord() instanceof Contact) {
         Contact compareContact = (Contact) match.getRecord();
     }
  • Thank you so much for nailing it down for me and I apologize for pasting the whole code. I commented this section out to test and there was no error. Then I inserted your if statement suggestion, which also processed without the trigger error. However, it's not creating the Opportunity with related contact – Robert Wynter Jan 25 at 17:57
  • Seems like a problem with some other class logic - I'm not even sure where to start on that. For the branch that checks for duplicates has leadConvert.setDoNotCreateOpportunity(true); marked explicitly false, any failure in another branch is a separate problem with a different cause. You might want to open another question, once you localize the problem with a repeatable test case. – battery.cord Jan 25 at 19:15
  • I received some info from support and they said: The error is appeared from the following code statement convertLeads(newLeads) from where the explicit dynamic typeCasting is done – Robert Wynter Jan 29 at 14:17
  • for (Datacloud.MatchRecord match : matchResult.getMatchRecords()) { // We want to use the oldest matched record, it will be the source Contact. Contact compareContact = (Contact) match.getRecord() Here match.getRecord is fetching the account and since the account and contact aren't the same type of objects which are explicitly like Account(parent) and Contact(Child).. Here we are modifying the objects from one another which is not allowed. Instead we need to have the check of getSobjectType() and further compare name and based on it we need to mention the if condition – Robert Wynter Jan 29 at 14:18
  • The Standard Matching rules were the issue. Once I deactivated the Stand Contact and Standard Account rules. FA processed successfully. Thank you so much for your help. – Robert Wynter Jan 31 at 18:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.