Salesforce coding lessons for the 99%
Finally, Apex tutorials for point-and-click admins! Written by a self-taught Google engineer.
  • Beginner Tutorials
    • Apex
    • Certifications
    • Career Info
    • Technical Architect
    • Visualforce
    • Videos
  • Apex Academy
  • Success Stories
  • About Me
  • Misc
    • Mailbag
    • Challenges
    • Links
    • Login to my Org
Follow @dvdkliuor SUBSCRIBE!

The SFDC99 live event recording and recap!

August 10, 2015

To the hundreds of people who spent 3 hours of their Saturday to code with me: you’re all crazy!
…that’s exactly the kind of craziness that will make you a coder!

Thank you to everyone who joined – the event exceeded my expectations and I’d like to do it again!

Video Recording
Full event playlist – note that it’s split into four parts!

Challenge and flow chart

I used a free flow chart website called Gliffy to build this.

Main Code

trigger Stream1_CreateOppContactRole 
  on Opportunity (after insert) {

  for (Opportunity opp : Trigger.new) {      

    // Step 0: Check to see if any OCRs already exist
    List<OpportunityContactRole> dupeOcrList = 
      [SELECT Id
         FROM OpportunityContactRole
        WHERE OpportunityId = :opp.Id
        LIMIT 1];

    // Move on to the next Opp is a Contact Role exists
    if (opp.Converted_Lead_ID__c != null 
        || (dupeOcrList != null && dupeOcrList.size() != 0)) {
      continue;
    }
        
    // Step 1: Get the recently closed Task by the current User
    List<Task> taskList = 
      [SELECT Id, WhoId
         FROM Task
        WHERE IsClosed  = true
          AND AccountId = :opp.AccountId
          AND OwnerId   = :UserInfo.getUserId()
        ORDER BY ActivityDate DESC, CreatedDate DESC
        LIMIT 1];
    System.debug('Task: ' + taskList);
        
    // Step 2: Get Custom Settings values
    Stream1_Settings__c settings = 
      Stream1_Settings__c.getValues('defaultSettings');
    String defaultRole           = '';
    Boolean defaultPrimary       = false;
    if (settings != null) {
      defaultRole           = settings.Default_Role__c;
      defaultPrimary        = settings.Default_Primary__c ;
    }
        
    // Step 3: Create the Contact Role
    if (taskList != null && taskList.size() != 0) {
      Task t = taskList[0];
      // This makes sure it's a Contact object
      String whoIdString = String.valueOf(t.WhoId);
      if (whoIdString.startsWith('003')) {
        OpportunityContactRole ocr = new OpportunityContactRole();
        ocr.ContactId              = t.WhoId;
        ocr.OpportunityId          = opp.Id;
        ocr.Role                   = defaultRole;
        ocr.IsPrimary              = defaultPrimary;
        insert ocr;
        System.debug('Opp Contact Role was created! ' + ocr);
      }
    }
  }
}

Test Class

@isTest 
public class Stream1_TestCreateOppContactRole {
  static testMethod void testStuff() {
    // Create the base data
    Account a = new Account();
    a.Name    = 'Ritzy';
    insert a;
        
    Contact c   = new Contact();
    c.FirstName = 'SoloAdmin';
    c.LastName  = 'Randi';
    c.AccountId = a.Id;
    insert c;
        
    Task t          = new Task();
    t.Status        = 'Completed';
    t.WhoId         = c.Id;
    t.ActivityDate  = Date.today();
    t.Subject       = 'Phone Call';
    insert t;
        
    // Create the Custom Setting
    Stream1_Settings__c settings = new Stream1_Settings__c();
    settings.Name                = 'defaultSettings';
    String defaultRole           = 'Big Spender RobStrunk';
    Boolean defaultPrimary       = true;
    settings.Default_Role__c     = defaultRole;
    settings.Default_Primary__c  = defaultPrimary;
    insert settings;
        
    Test.startTest();

    // NON Setup code. Things we actually want to test
    Opportunity o = new Opportunity();
    o.AccountId   = a.Id;
    o.Amount      = 9999999;
    o.CloseDate   = Date.today();
    o.StageName   = 'Prospecting';
    o.Name        = 'Tesla Motors';
    insert o;
        
    // Make sure things work!
    List<OpportunityContactRole> ocrs = 
      [SELECT Id, ContactId, Role, IsPrimary
         FROM OpportunityContactRole 
        WHERE OpportunityId = :o.Id];
    
    // Make sure only 1 OCR is created
    System.assertEquals(1, ocrs.size());        
    OpportunityContactRole ocr = ocrs[0];
        
    // Make sure the defaults are correct
    System.assertEquals(defaultRole, ocr.Role);
    System.assertEquals(defaultPrimary, ocr.IsPrimary);
    System.assertEquals(c.Id, ocr.ContactId);
        
    // Test the weird use case
    Lead l = new Lead();
    l.LastName = 'Kishore';
    l.Company  = a.Name;
    l.Status   = 'Open - Not Contacted';
    insert l;
        
    // Convert the lead
    Database.LeadConvert lc = new Database.LeadConvert();
    lc.setLeadId(l.id);
    lc.setAccountId(a.Id);
    lc.setContactId(c.Id);
    lc.setConvertedStatus('Closed - Converted');
    Database.LeadConvertResult lcr = Database.convertLead(lc);
        
    List<OpportunityContactRole> ocrsConvert = 
      [SELECT Id, ContactId, Role, IsPrimary
         FROM OpportunityContactRole 
        WHERE OpportunityId = :lcr.getOpportunityId()];
        
    // Make sure only 1 OCR is created
    System.assertEquals(1, ocrsConvert.size());     
    OpportunityContactRole ocrConvert = ocrsConvert[0];
        
    // Make sure the Salesforce defaults are correct
    System.assertEquals(null, ocrConvert.Role);
    System.assertEquals(true, ocrConvert.IsPrimary);
    System.assertEquals(c.Id, ocrConvert.ContactId);
        
    Test.stopTest();
  }
}

Hope you all had fun and see you next time!

David

14 Comments
Anonymous
August 15, 2015 @ 7:57 pm

Hi David,am planning to buy the Head First Java book ! advice me which edition to buy.Thanks

Reply
    David Liu
    August 17, 2015 @ 10:34 am

    Get the newest one =)

    Reply
Anonymous
August 15, 2015 @ 5:33 am

your code will fail when creating more than 200 records.

Reply
    David Liu
    August 17, 2015 @ 10:35 am

    Next time: how to bulkify!

    I find that learning how to bulkify is difficult for people brand new, so I cover it in later chapters (ie ch. 5)

    Reply
ashish
August 15, 2015 @ 5:30 am

This code scares me as I dont understand any of this…how can some one a layman person understand this code..email me at ashish.pargaonkar@gmail.com. ..it seems u need to understand the salesforce objects along with their relationship and how does lead or any other object convert to different object…also need to learn data dictionary. …from a business process perspective can we understand how to map the reqiirement of sales on the various sales objects available like lead prospectaccount deal client…where to use what is a big question I would like to get answer on…thanks pls email me if u get time..

Reply
    David Liu
    August 17, 2015 @ 10:35 am

    Understanding admin techniques in critical before learning to code in Salesforce, check out this page for more info!
    https://www.sfdc99.com/2014/08/13/how-to-learn-the-admin-side-of-salesforce/

    Reply
neevenn
August 12, 2015 @ 12:13 pm

David, I missed your earlier live code session. when is the next?

Reply
    David Liu
    August 12, 2015 @ 1:17 pm

    Haven’t planned out the next one yet!

    Reply
Anonymous
August 11, 2015 @ 6:20 pm

David….you are so amazing to have done this for us. I am more confident than before, feel I can do this and I am ecstatic that you will do it again. Thank you for your generosity!

Reply
Anonymous
August 11, 2015 @ 4:18 pm

Thank you David.Can also provide some tips on searching on google for code related questions !!!

Reply
    David Liu
    August 11, 2015 @ 6:47 pm

    I talk a little about this in the stream because I end up Googling A LOT! Check it out!

    Reply
Nicholas McBride
August 11, 2015 @ 11:37 am

Thank you for sharing your expertise, and time with us. Your site has helped me more than once. For everyone looking for an IDE, I would like to recommend the one I use, elastify CodeFusion: https://appexchange.salesforce.com/listingDetail?listingId=a0N3000000B5SYEEA3 This along with the debugger in the developer console and I have everything I need. It is not offline like eclipse or some of the others, but I don’t need that. Anyways, thank you again David, you’re a rock star!

Reply
Anonymous
August 10, 2015 @ 8:08 pm

Thanks so much for offering this session. Even though I have coded before; Apex intimidated me. I am following you very well.

Reply
Chris (Marzella88)
August 10, 2015 @ 1:25 pm

The event was great David. Thanks for doing this. I think we all learned a lot from watching you code live.

Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *


*

*

Theme: Simple Style by Fimply