• Mohammad Alazzouni 16
  • NEWBIE
  • 20 Points
  • Member since 2018

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 5
    Questions
  • 2
    Replies
We recently wrote a flow where when a certain field in a Lead (mk_fl_user_id__c) is populated, then the process builder will automatically convert that Lead into a Contact. We've used a comobination of a process builder to invoke the following APEX class:
 
public class AutoConvertLeads {
    @InvocableMethod
    public static void LeadAssign(List<Id> LeadIds)
    {
        LeadStatus CLeadStatus= [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true Limit 1];
        List<Database.LeadConvert> MassLeadconvert = new List<Database.LeadConvert>();
        for(id currentlead: LeadIds){
                Database.LeadConvert Leadconvert = new Database.LeadConvert();
                Leadconvert.setLeadId(currentlead);                
                Leadconvert.setConvertedStatus(CLeadStatus.MasterLabel);
                Leadconvert.setDoNotCreateOpportunity(TRUE); //Remove this line if you want to create an opportunity from Lead Conversion 
                MassLeadconvert.add(Leadconvert);
        }
        
        if (!MassLeadconvert.isEmpty()) {
            List<Database.LeadConvertResult> lcr = Database.convertLead(MassLeadconvert);
        }
    }
}
And this is the test class to push it to production
 
@isTest(seeAllData=false)
public class AutoConvertLeadsTest {

    public static Lead newLead;
    public static List<Id> leadIds;
    //public static String MK_fl_user_id; --ADD BACK IN
    public static String original_Source; //--DELETE
    
    //public AutoConvertLeads ACLClass;
    
    static void init(){
        leadIds = new List<Id>();
        //MK_fl_user_id = '1234';
        original_Source = 'test'; // --DELETE
        
        //Create a new Lead with MK_fl_user_id__c not Null
        // newLead = new Lead(MK_fl_user_id__c = MK_fl_user_id); --ADD BACK IN
        newLead = new Lead(Original_Source__c = original_Source); // --DELETE
        newlead.company = 'testLead';
        newlead.lastname = 'testOtherLead';
        insert newlead;
    }
    
    @isTest static void checkIfContactCreated(){
        init();
        Test.startTest();
        
        leadIds.add(newLead.Id);
        
        //Call Invokable Method
        AutoConvertLeads.LeadAssign(leadIds);
        
        Contact a;
        //Test that a contact was created.
        //a = [SELECT Id, MK_fl_user_id__c FROM Contact WHERE MK_fl_user_id__c = :MK_fl_user_id  LIMIT 1]; --ADD BACK IN
        a = [SELECT Id, Original_Source__c FROM Contact WHERE Original_Source__c = :original_Source  LIMIT 1]; // --DELETE
        
        //System.assertEquals(MK_fl_user_id, a.MK_fl_user_id__c); --ADD BACK IN
        System.assertEquals(original_Source, a.Original_Source__c); // --DELETE
        Test.stopTest();
    }
}

Everything was working perfectly fine, yesterday we were asked to change the API name from MK_fl_user_id__c to MKto71_fl_user_id__c for both the Lead and Contact Object.

After we did the changes, I double checked the mappings and double checked the process builder, everything seems to be in place. However, the flow is not working anymore!

I get the following error:

Error Occurred: An Apex error occurred: System.DmlException: ConvertLead failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, There was an error converting the lead. Please resolve the following error and try again: LH.LH_Contact: execution of AfterInsert caused by: System.SObjectException: Invalid field mk_fl_user_id__c for Contact (LH) : [] 

I am not sure where to start. Any advice would be highly appreciated.
Hi,

I am having difficulty writing a test class for an apex class that doesn't invoke any changes in Salesforce. Instead, it invokes changes to an external system. I don't even know where to begin with this test class. I figured it would help if I give you the code:
 
global class AsyncRequest {

    //@HttpPost
    @future (callout=true)
    global static void postRequest(string contactJSON, 
                                  string flAdminUser, 
                                  string flUserId,
                                  string sfUserId){
                Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://dev-api-example.com/api/v2.5/integrations/salesforce/profile');
        request.setMethod('POST');
        //request.setHeader('FL-SECRET', 'Example.secret');
        request.setHeader('FL-SECRET', 'SF2018/Example');
        request.setHeader('FL-ADMIN-USER', flAdminUser);
        request.setHeader('Content-Type', 'application/json');
        request.setHeader('FL-USER-ID', flUserId);
        request.setHeader('SF-USER-ID', sfUserId);
        // Set the body as a JSON object
        request.setBody(contactJSON);
        HttpResponse response = http.send(request);
        // Parse the JSON response
        if (response.getStatusCode() != 200) {
            System.debug('The status code returned was not expected: ' +
                response.getStatusCode() + ' ' + response.getStatus());
        } else {
            System.debug('The status code returned was not expected: ' +
                response.getStatusCode() + ' ' + response.getStatus());
            System.debug(response.getBody());
        }
            
    }
}

Then here is another .apext file that I would need to test as well
 
trigger AsyncToFarmLead on Contact (after update) {
    
    String FlAdminUser;
    String contactJSON;
    String FlUserId;
    String SfUserId;
    
    for(Contact a : Trigger.New) {
        
        Map<String,Object> conMap = (Map<String,Object>)JSON.deserializeUntyped(JSON.serialize(a));
        
        removeAttributes(conMap, 'Account');
        removeAttributes(conMap, 'FL_ADMIN_USER__c');
        removeAttributes(conMap, 'FarmLead_URL__c');
        removeAttributes(conMap, 'AccountId');
        removeAttributes(conMap, 'FarmLead_Secret_key__c');
        
        String contactJSON = (JSON.serializePretty(conMap));
        
        if(a.FL_ADMIN_USER__c != null) {
            FlAdminUser = a.FL_ADMIN_USER__c;
        } else {
            FlAdminUser = 'nullVal';
        }
        System.debug('FL_ADMIN_USER__c: ' + FlAdminUser);
        
        if(a.MK_fl_user_id__c != null) {
            FlUserId = a.MK_fl_user_id__c;
        } else {
            FlUserId = 'nullVal';
        }
        System.debug('MK_fl_user_id__c: ' + FlUserId);
        
        if(a.Id != null) {
            SfUserId = a.Id;
        } else {
            SfUserId = 'nullVal';
        }
        System.debug('Id: ' + SfUserId);

        try{
            System.debug('JSON being passed: ' + contactJSON);
            AsyncRequest.postRequest(contactJSON, FlAdminUser, FlUserId, SfUserId);
        } catch (Exception e) {
             Messaging.SingleEmailMessage mail=new Messaging.SingleEmailMessage();
             String[] toAddresses = new String[] {'EXAMPLE@Email.com'};
             mail.setToAddresses(toAddresses);
             mail.setReplyTo('EXAMPLE@Email.com');
             mail.setSenderDisplayName('Apex error message');
             mail.setSubject('Error from Org : ' + UserInfo.getOrganizationName());
             mail.setPlainTextBody(e.getMessage());
             Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
        }
    }
    
    private void removeAttributes(Map<String,Object> jsonObj, String attribute)  {
        for(String key : jsonObj.keySet()) {
            if(key == attribute) {
                jsonObj.remove(key);
            } else {
                if(jsonObj.get(key) instanceof Map<String,Object>) {
                    removeAttributes((Map<String,Object>)jsonObj.get(key), attribute);
                }
                if(jsonObj.get(key) instanceof List<Object>) {
                    for(Object listItem : (List<Object>)jsonObj.get(key)) {
                        if(listItem instanceof Map<String,Object>)  {
                            removeAttributes((Map<String,Object>)listItem, attribute);
                        }
                    }
                }
            }
        }  
    }
}

 
I have been going crazy trying to find out why my code coverage cannot go above 17%. 

I am trying to deply an Apex Class. I have never done tests before so I am not sure if my tests are appropriate.

The idea is to have a Process Builder workflow trigger an immediate action that will reference an Apex class to convert a Lead to a Contact 

This is my code:
 
public class AutoConvertLeads {
    @InvocableMethod
    public static void LeadAssign(List<Id> LeadIds)
    {
        LeadStatus CLeadStatus= [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true Limit 1];
        List<Database.LeadConvert> MassLeadconvert = new List<Database.LeadConvert>();
        for(id currentlead: LeadIds){
                Database.LeadConvert Leadconvert = new Database.LeadConvert();
                Leadconvert.setLeadId(currentlead);                
                Leadconvert.setConvertedStatus(CLeadStatus.MasterLabel);
                Leadconvert.setDoNotCreateOpportunity(TRUE); //Remove this line if you want to create an opportunity from Lead Conversion 
                MassLeadconvert.add(Leadconvert);
        }
        
        if (!MassLeadconvert.isEmpty()) {
            List<Database.LeadConvertResult> lcr = Database.convertLead(MassLeadconvert);
        }
    }
}
When I deply or run a test. I can never seem to get my code coverage above 17%. 

See below fo the error message. Not too sure what to do.

User-added image
 
So I've created an iframe that bring info from an external system. The thing is the UI is not the greatest, when I increased the length of the iframe, it does not seem to affect the (what I think is) the lightning component. My question is really in the image below:

User-added image
As part of a project, I am looking to achieve the following:
  1. I want to push salesforce specific fields in Contacts to update an external system that does not have an out of the box connection to SF.
  2. This system (let’s call it SYSTM) does not push data directly to Salesforce, instead, it pushes it first to Marketo, then Marketo pushed the record to Salesforce - what the project entails is that if a Sales rep in Salesforce changes information such as name or email, then than should push data into SYSTM even though they are not connected.
  3. This system requires a login access (that the sales reps have) - when in the Salesforce Contact page, I will need to send a request to a specific URL, I will need to also reference the following:
  • Sales Rep SF User ID
  • SYSTM User ID (which is already in Salesforce
  • SYSTM Secret: API key
  • SYSTM record ID - each contact would have a SYSTM record ID that is already in Marketo and Salesforce
If anyone can provide different approaches, it would be very much appreciated!

Thank you so much.

Mo
We recently wrote a flow where when a certain field in a Lead (mk_fl_user_id__c) is populated, then the process builder will automatically convert that Lead into a Contact. We've used a comobination of a process builder to invoke the following APEX class:
 
public class AutoConvertLeads {
    @InvocableMethod
    public static void LeadAssign(List<Id> LeadIds)
    {
        LeadStatus CLeadStatus= [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true Limit 1];
        List<Database.LeadConvert> MassLeadconvert = new List<Database.LeadConvert>();
        for(id currentlead: LeadIds){
                Database.LeadConvert Leadconvert = new Database.LeadConvert();
                Leadconvert.setLeadId(currentlead);                
                Leadconvert.setConvertedStatus(CLeadStatus.MasterLabel);
                Leadconvert.setDoNotCreateOpportunity(TRUE); //Remove this line if you want to create an opportunity from Lead Conversion 
                MassLeadconvert.add(Leadconvert);
        }
        
        if (!MassLeadconvert.isEmpty()) {
            List<Database.LeadConvertResult> lcr = Database.convertLead(MassLeadconvert);
        }
    }
}
And this is the test class to push it to production
 
@isTest(seeAllData=false)
public class AutoConvertLeadsTest {

    public static Lead newLead;
    public static List<Id> leadIds;
    //public static String MK_fl_user_id; --ADD BACK IN
    public static String original_Source; //--DELETE
    
    //public AutoConvertLeads ACLClass;
    
    static void init(){
        leadIds = new List<Id>();
        //MK_fl_user_id = '1234';
        original_Source = 'test'; // --DELETE
        
        //Create a new Lead with MK_fl_user_id__c not Null
        // newLead = new Lead(MK_fl_user_id__c = MK_fl_user_id); --ADD BACK IN
        newLead = new Lead(Original_Source__c = original_Source); // --DELETE
        newlead.company = 'testLead';
        newlead.lastname = 'testOtherLead';
        insert newlead;
    }
    
    @isTest static void checkIfContactCreated(){
        init();
        Test.startTest();
        
        leadIds.add(newLead.Id);
        
        //Call Invokable Method
        AutoConvertLeads.LeadAssign(leadIds);
        
        Contact a;
        //Test that a contact was created.
        //a = [SELECT Id, MK_fl_user_id__c FROM Contact WHERE MK_fl_user_id__c = :MK_fl_user_id  LIMIT 1]; --ADD BACK IN
        a = [SELECT Id, Original_Source__c FROM Contact WHERE Original_Source__c = :original_Source  LIMIT 1]; // --DELETE
        
        //System.assertEquals(MK_fl_user_id, a.MK_fl_user_id__c); --ADD BACK IN
        System.assertEquals(original_Source, a.Original_Source__c); // --DELETE
        Test.stopTest();
    }
}

Everything was working perfectly fine, yesterday we were asked to change the API name from MK_fl_user_id__c to MKto71_fl_user_id__c for both the Lead and Contact Object.

After we did the changes, I double checked the mappings and double checked the process builder, everything seems to be in place. However, the flow is not working anymore!

I get the following error:

Error Occurred: An Apex error occurred: System.DmlException: ConvertLead failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, There was an error converting the lead. Please resolve the following error and try again: LH.LH_Contact: execution of AfterInsert caused by: System.SObjectException: Invalid field mk_fl_user_id__c for Contact (LH) : [] 

I am not sure where to start. Any advice would be highly appreciated.
So I've created an iframe that bring info from an external system. The thing is the UI is not the greatest, when I increased the length of the iframe, it does not seem to affect the (what I think is) the lightning component. My question is really in the image below:

User-added image