Teach Me Salesforce

A community approach to learning salesforce.com

Archive for the ‘Beginner’ Category

Apex Workshop Webinar 3: Collections

leave a comment »

In the third Apex Workshop Webinar we explored Collections: Lists, Sets and Maps.

In the exercise we again work with an Collections Exercises to practice manipulating Apex Collections (Answers to the exercises here). With Lists we learned different ways to populate a list while exploring the List Methods from the Apex Documentation. We practiced working with List indexes and expanded the concept to Lists of Lists and how to return values from anywhere in them. And we used a simple SOQL query to populate a list and noted how you must include any fields that you want to later reference.

From Lists we moved on to Sets. We described the differences between List (an ordered collection) and Sets (an unordered collection of unique value). We learned that with Sets, you can reference individual collection members by using the contains() Set Method and studied the Set Methods from the Apex Documentation. We also Lists into Sets and observed how duplicate values are automatically de-duped when added to Sets.

With Maps, we emphasize how very essential this collection type is to efficient Apex development. We explored different methods of putting key-value pairs in to Maps and retrieving the data with the keyset() and values() methods. And along the way we checked out the Map Methods from the Apex Documentation.

Through out the exercises, we used the Apex test methods of assert() and assertEquals() to test our work and to familiarize ourselves with unit testing.

Unfortunately we had technical difficulties with the recording and lost the first 20 minutes, but the most important discussions are in the 84 minutes we captured.

Advertisements

Written by Always Thinkin

March 20, 2017 at 7:49 pm

Posted in Apex, Beginner, Code Sample

Apex Workshop Webinar 2: Data Types

leave a comment »

Welcome to the written accompaniment to the Apex Workshop Series presented as Webinars in 2016!

This edition of the series introduces Data Types with an examination of the Primitive Data Types described in the official Apex Documentation. We then proceed on to work on an Apex Test Class that gives us a chance to experiment with the concepts as well as get familiar with the Developer Console environment (Answers to the exercises). We explore Test Classes & Methods, System Debug statements and String methods while working with the Debug Logs and the Execute Anonymous panel to see our output. Other Apex programming concepts introduced: String concatenation, escape characters, converting data types, indexes in strings, incrementation and operators.

Questions from the live webinar:

  1. What data type are Geolocation fields? Geolocation fields are doubles.

Questions from the Community:

If you watch the video or work on the exercises and have questions, post them to the comments!

Written by Always Thinkin

March 20, 2017 at 7:13 pm

Simplest Apex Trigger Patterns: Updates

leave a comment »

Last time I shared two very simple triggers for modifying records on Insert, which is to say, when the record is created. Which only happens once. So most of the time you probably want triggers that are working on Update since that happens a lot more often. In fact, the After Insert trigger I posted last time results in an Update event on the records; but the Before Insert does not. Why? Well it’s sort of like this: before the record is inserted, it doesn’t exist, so any change you make to it is just all wrapped up in that insert event. But after insert, the record exists in the database and any change you make to it is considered an update. But now we’re getting complex and this is suppose to be about simple patterns, so here you go…

The Before Update triggers can be written just like Before Insert triggers: if you want to set a value on a field, you just need to say SomeField = “some value”. Here we are setting the Email Opt Out checkbox (API name is HasOptedOutOfEmail) to true, so as a Boolean, we don’t need quotes, just true or false.

trigger ContactBeforeUpdate on Contact (before update) {
    For(Contact c : Trigger.new){
        c.HasOptedOutOfEmail = true;
    }
}

But After Update triggers get tricky fast. First there’s the need to use “DML” or Data Manipulation Language to perform an additional update to the just-updated record. We did this in the first post on Inserts too. And if we do another update that means the record will go through the Update events again and you’re going to get recursion – it’s going to keep trying to update over and over!

We’re going to do a very simple way of avoiding recursion, but using a condition like we did in the last post on Trigger Conditions. Since we are setting Email Opt Out to be true, our condition will only do this for Contacts on which Email Opt Out is false. So after our first update to the record, the next time through the After Update event, the record doesn’t meet the condition and no further updates to the record are executed.

trigger ContactAfterUpdate on Contact (after update){
    List<Contact> consToUpdate = new List<Contact>();
    
    for(Contact conInTrigger : trigger.new){
        if(!conInTrigger.HasOptedOutOfEmail){
            Contact c = new Contact(Id = conInTrigger.Id, HasOptedOutOfEmail = true);
        	consToUpdate.add(c); 
        }
    }
    update consToUpdate;
}

Now, let’s look at that line by line to see what’s going on:

trigger ContactAfterUpdate on Contact (after update){

This is the busiest line. It tells Apex that the code is a trigger (must be this, changing it will just break it), then it sets the name of this particular trigger (your choice, pretty much anything is allowed), then is says which object the trigger is on (but only one object!) and finally in the parentheses it tells Apex which events the trigger should be executed on (can be any or all: before insert, before update, after insert, after update, before delete, after delete & after undelete). Oh yeah, and a must-have curly bracket to start things off right.

List<Contact> consToUpdate = new List<Contact>();

This line prepares a list for the Contacts that we will want to update later. It starts out empty and we’ll add Contacts to it.

for(Contact conInTrigger : Trigger.new){

This line is the start of the “for loop” and is necessary because you might just be dealing with lots of records, not just one. Think of a situation where you’re uploading hundreds of new Contacts and need to evaluate each one independently. The for loop allows you to do that by saying “for each single thing in this collection of things, do something”. In this case it is saying: for each Contact (which I’m going to nickname “conInTrigger”) that is inserted at the same time (Trigger.new is a list of all the inserted Contacts) do what ever I tell you between this next set of curly braces.

if(!conInTrigger.HasOptedOutOfEmail){

This line is the conditional (like a Workflow filter criteria) and says “as you go through each record in the for loop, which we nicknamed ‘conInTrigger’, get the value of HasOptedOutOfEmail…and make it the opposite. That’s what the exclamation point is doing in front of conInTrigger.HasOptedOutOfEmail: changing true to false and false to true. The if() condition only proceeds if it’s true, so since we only want to change HasOptedOutOfEmail to true for records that were false, we use that value to check first. And this helps us to prevent repeated updates to the same record.

Contact c = new Contact(Id = conInTrigger.Id, HasOptedOutOfEmail = true);

Here we finally get around to updating our record. To do this we have to tell Apex that we want to work with a Contact, which we’ll call “c”. The next part if a little counterintuitive because you say first new Contact, but then in the parentheses, you give tell Apex that this Contact already has an Id. If we were actually creating a new Contact, we wouldn’t provide the Id, that would get added after its inserted. Here we use the “conInTrigger” nickname to refer to the Contact record that is in this iteration of the for loop and .Id to get its record ID. After that, we are going to set a new value, so we don’t need “conInTrigger” again, we just say that to set this Contact’s HasOptedOutOfEmail field equal to true.

consToUpdate.add(c); 

The next line adds this Contact record to the consToUpdate List we created on Line 2. If we have updated more than one Contact (maybe using Mass Edits in a List View), the for loop goes on to the next contact and keeps going until all Contacts that were updated together have been addressed.

update consToUpdate;

Our final line tells Apex that we want to update any and all Contact records that we’ve added to the consToUpdate list.

The Unit Test

Now that we’re updating records, our unit test has to first prepare some test records by inserting them and then update those same records so we can confirm that our trigger works. It’s a good idea to make sure that the trigger is actually doing the work by verifying that before the update, Email Opt Out is false and that after the update, Email Opt Out is true so we know that it was caused by the update.

 

@isTest
public class ContactAfterUpdateTest {
    public static testMethod void testContactUpdate(){
        Contact aNewContact = new Contact(LastName = 'New-Contact');
        insert aNewContact;
        
        //first let's confirm that Email Opt Out is false
        Contact theInsertedContact = [Select HasOptedOutOfEmail from Contact limit 1];
        System.assertEquals(false, theInsertedContact.HasOptedOutOfEmail);
        
        aNewContact.FirstName = 'Some First Name';
        update aNewContact;
        
        //now that we've updated the Contact, we'll confirm that 
        Contact theUpdatedContact = [Select HasOptedOutOfEmail from Contact limit 1];
        System.assertEquals(true, theUpdatedContact.HasOptedOutOfEmail);
    }
}

Written by Always Thinkin

April 2, 2016 at 1:39 pm

Simplest Apex Patterns: Trigger Conditions

with one comment

The Trigger

Triggers fire every time for every change: inserts, updates, deletes…and it’s pretty rare that you want to execute your actions for every change. So that means you need to code in some conditions to only change the records you want changed. Just like building Workflow Rules with Rule Criteria, in Apex you’ll want to add criteria and for that you need if() statements. Probably the trickiest thing about learning to use if() statements is remember that you have to use two equals signs to say “this equals that”. Why, well, it’s just common coding syntax because you need a way to distinguish between the idea of “make something equal some value” (e.g. x = 5) and “check if two things are already equal” (e.g. a == b). And the second trickiest thing is remember whether you use single quotes, double quotes or no quotes because it depends on whether you’re criteria is checking text, numbers, IDs or booleans.

But enough chit-chat, let’s just take a look at the ContactBeforeInsert trigger we made last time with it’s new filter criteria condition that says “if the contact’s last name is ‘Hates-email'” then we want to opt them out of email.

trigger ContactBeforeInsert on Contact (before insert) {
	for(Contact c : Trigger.new){
            if(c.LastName == 'Hates-email'){
                c.HasOptedOutOfEmail = true;
        }
    }
}

Let’s break that down line-by line:

trigger ContactBeforeInsert on Contact (before insert) {

This is the busiest line. It tells Apex that the code is a trigger (must be this, changing it will just break it), then it sets the name of this particular trigger (your choice, pretty much anything is allowed), then is says which object the trigger is on (but only one object!) and finally in the parentheses it tells Apex which events the trigger should be executed on (can be any or all: before insert, before update, after insert, after update, before delete, after delete & after undelete). Oh yeah, and a must-have curly bracket to start things off right.

for(Contact c : Trigger.new){

This line is the start of the “for loop” and is necessary because you might just be dealing with lots of records, not just one. Think of a situation where you’re uploading hundreds of new Contacts and need to evaluate each one independently. The for loop allows you to do that by saying “for each single thing in this collection of things, do something”. In this case it is saying: for each Contact (which I’m going to nickname “c”) that is inserted at the same time (Trigger.new is a list of all the inserted Contacts) do what every I tell you between this next set of curly braces.

if(c.LastName == 'Hates-email'){

Now we finally get to our filter criteria conditional which says “as you go through each record in the for loop, check whether it’s last name is ‘Hates-email’ and if so, then do whatever is between the next set of curly braces. And if not, don’t do what’s in the curly braces, just go to the next record. This is where our nickname of “c” for Contacts is used because c.LastName means “this contact’s last name”. And those double equal signs say to check that the Last Name is already equal to ‘Hates-email’.

c.HasOptedOutOfEmail = true;

And at last we get around to doing something: setting Email Opt Out to true. Again we use our nickname for Contacts, “c”, to say set this Contact’s Email Opt Out field (which we refer to in Apex by the field’s API Name of HasOptedOutOfEmail) to true (see how that single equal signs is saying “make it equal…”?).

After that, we just have to close up all those curly braces we started earlier.

The Unit Test

So of course to put this in production, you need a unit test so you can get the code coverage. More importantly, you want to know that it works and for that you need to two unit tests because now we have a conditional. So we have one tests that confirms that if the last name is “Hates-email” that the Email Opt Out is set to true. And a second test that checks if last name is something else, that Email Opt Out is false.

@isTest
public class ContactBeforeInsertTest {
    public static testMethod void testHatesEmail(){
        
        Contact aNewContact = new Contact(LastName = 'Hates-email');
        
        Insert aNewContact;
        
        Contact theInsertedContact = [Select HasOptedOutOfEmail from Contact limit 1];
        
        System.assert(theInsertedContact.HasOptedOutOfEmail);
        
    }
    
    public static testMethod void testLikesEmail(){
        
        Contact aNewContact = new Contact(LastName = 'Likes-email');
        
        Insert aNewContact;
        
        Contact theInsertedContact = [Select HasOptedOutOfEmail from Contact limit 1];
        
        System.assert(!theInsertedContact.HasOptedOutOfEmail);
        
    }
}

Written by Always Thinkin

March 20, 2016 at 6:45 pm

Simplest Apex Trigger Patterns: Inserts

with 3 comments

The Trigger

Because sometimes you just want to see the basic programming patterns for Apex and reverse engineer them to fit your needs.

These two are the most basic trigger patterns. They both do the same thing: set a field’s value on a record when that record is added to Salesforce. It only happens on insert, not on update because that’s slightly less simple (and a different post). The only difference is one does it Before Insert and one does it After Insert. Why? Because they can. Maybe someday we’ll discuss here why you use one or the other but today we just want code that works, so here you go:

Trigger ContactBeforeTrigger on Contact (before insert) {
    for(Contact c : Trigger.new){
        c.HasOptedOutOfEmail = true;
    }
}

 

Trigger ContactAfterInsert on Contact (after insert) {
    List<Contact> conList = new List<Contact>();
    
    for(Contact conInTrigger : trigger.new){
        Contact c = new Contact(Id = conInTrigger.Id, HasOptedOutOfEmail = true);
        conList.add(c);    
    }
    update conList;
}

 

The Unit Test

And of course anything you want to use in Production needs a test class, so here you go, one that works for both!

@isTest
public Class TestContactTrigger{
    public static testMethod void testContactInsert(){
    
    Contact aNewContact = new Contact(LastName = 'qwerty');
    
    Insert aNewContact;
    
    Contact theInsertedContact = [Select HasOptedOutOfEmail from Contact limit 1];
    
    System.assert(theInsertedContact.HasOptedOutOfEmail);
    
    }

}

Written by Always Thinkin

February 28, 2016 at 4:53 pm

One Little Change; So Much Clearer Dashboards

with 6 comments

I discovered a quick little tweak you can make to reports so you can help rid the world of a blight known as “Record Count”. When you look at a Dashboard component about “Contacts created last week”, why do we make the reader interpret “Record Count” to mean Contacts? I know it’s implied by nature of the report, but just this one little tweak can make information so much clearer. I add this to my reports all the time now and it’s really helpful. Check out the demo video and help rid the world of that dreaded “Record Count”.

Written by crmfyi

June 30, 2011 at 8:15 am

Posted in Beginner

Tagged with ,

How Salesforce 18 Digit Id Is Calculated

with 6 comments

As we know that each record Id represents a unique record within an organization. There are two versions of every record Id in salesforce :

  • 15 digit case-sensitive version which is referenced in the UI
  • 18 digit case-insensitive version which is referenced through the API
The last 3 digits of the 18 digit Id is a checksum of the capitalization of the first 15 characters, this Id length was created as a workaround to legacy system which were not compatible with case-sensitive Ids. The API will accept the 15 digit Id as input but will always return the 18 digit Id.
Now how we can calculate the 18 digit Id from 15 digit Id ??? Just copy paste the below code in system logs and pass your 15 digit id in String id
//Your 15 Digit Id
String id= '00570000001ZwTi' ;

string suffix = '';
integer flags;

for (integer i = 0; i < 3; i++)
{
	flags = 0;
	for (integer j = 0; j < 5; j++)
	{
		string c = id.substring(i * 5 + j,i * 5 + j + 1);
		//Only add to flags if c is an uppercase letter:
		if (c.toUpperCase().equals(c) && c >= 'A' && c <= 'Z')
		{
			flags = flags + (1 << j);
		}
	}
	if (flags <= 25)
	{
		suffix = suffix + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.substring(flags,flags+1);
	}
	else
	{
		suffix = suffix + '012345'.substring(flags-25,flags-24);
	}
}

//18 Digit Id with checksum
System.debug(' ::::::: ' + id + suffix) ;

This debug will return the 18 digit Id.

This is a cross post to my Blog

Written by Ankit Arora (forceguru)

June 6, 2011 at 3:47 pm

Posted in Apex, Beginner, Code Sample