Preface: This video is part 2 of the Official #Apex4Admins series presented by Salesforce and I!
Learn fundamental Apex tools and SOQL!
Basic SOQL
[SELECT Id, Name, Website, Sells_Chocolate__c FROM Account];
Cross-object
[SELECT Account.Owner.Manager.Needs_Chocolate__c FROM Contact];
WHERE
[SELECT Id, Name FROM Contact WHERE Eats_Chocolate__c = true];
Operators
[SELECT Id, Title FROM Lead WHERE Favorite_Chocolate__c != null];
AND
[SELECT Id, Name, Email, Birthdate, Account.Name FROM Contact WHERE Eats_Chocolate__c = trueAND Allergic_to_Nuts__c = false AND Chocolate_Rehab__c = false];
Mixing ANDs & ORs
[SELECT Id, Name, Email, Birthdate, Account.Name FROM Contact WHERE Eats_Chocolate__c = trueAND (Milk_Chocolate__c = true OR Dark_Chocolate__c = true)];
Text, Picklist, IDs
[SELECT Id, Name, Email, Birthdate, Account.Name FROM Contact WHERE Eats_Chocolate__c = trueAND Favorite_Chocolate__c = 'Snickers' AND OwnerId = '005i0000000OAOO'];
Numbers
[SELECT Id, Name, Email, Birthdate, Account.Name FROM Contact WHERE Eats_Chocolate__c = trueAND Chocolate_Bars_Consumed__c > 10 OR Broccoli_Consumed__c <= 1];
Dates
[SELECT Id, Name, Email, Birthdate, Account.Name FROM Contact WHERE Eats_Chocolate__c = true AND Diet_Start_Date__c = nullOR Diet_Start_Date__c > TODAY];
Fuzzy Matching
[SELECT Id, Name, Email, Birthdate, Account.Name FROM Contact WHERE Eats_Chocolate__c = trueAND Preferred_Fillings__c LIKE '%Caramel%'];
Sorting
[SELECT Id, Name, Email, Birthdate, Account.Name FROM Contact WHERE Eats_Chocolate__c = true AND Last_Chocolate_Consumption__c < 2014-01-01ORDER BY LastName ASC];
Limiting Results
[SELECT Id, Name, Email, Birthdate, Account.Name FROM Contact WHERE Eats_Chocolate__c = true AND Last_Chocolate_Consumption__c = YESTERDAYLIMIT 10];
Apex FUNdamentals
Variables
// Text String favoriteMovie = 'Frozen'; // Numbers Integer timesWatched = 8; Decimal merchandiseSpend = 55.20; // True or False Boolean ownsTheSoundtrack = true; // Dates Date dateLastWatched = Date.newInstance(2014, 5, 20); DateTime nextShowtime = DateTime.now().addHours(7); // SObjects Movie__c frozen = [SELECT Id FROM Movie__c WHERE Name = 'Frozen'];
IF Statements and Comparison Operators
// How to compare values Greater than: > Less than: < Equals: == Not Equals: != AND: && OR: || // IF Statementsif (david.Twtr_Follows__c < leeAnne.Twtr_Follows__c) {david.Emotions__c = 'Crushed.';} else if (david.Twtr_Follows__c == leeAnne.Twtr_Follows__c) {david.Emotions__c = 'Showdown! Last man standing!';} else if (david.Twtr_Follows__c < 1200 || david.Tweets__c < 500){david.Emotions__c = 'A petty victory.';} else {david.Emotions__c = 'Life is good.'; }
Loops
// FOR EACH Loop: Eat every Reeses in our trigger!for (Chocolate__c choco : Trigger.new) {if (choco.Name == 'Reeses') { choco.Status__c = 'In my belly!'; update choco; } } // FOR Loop: Eat 100 Reeses!for (Integer i = 0; i < 100; i++) {Chocolate__c choco = new Chocolate__c(); choco.Name = 'Reeses'; choco.Status__c = 'In my belly!'; insert choco; }
// Eat 10 Reeses every time you watch Frozen! trigger Snacks on Movie__c (after insert) { // Loop through all records in the triggerfor (Movie__c movie : Trigger.new) {if (movie.Name == 'Frozen') { // Loop a specific number of timesfor (Integer i = 0; i < 10; i++) {Chocolate__c choco = new Chocolate__c(); choco.Name = 'Reeses'; choco.Status__c = 'In my belly!'; insert choco; } } } }
Final “Non-Profit” Trigger:
trigger AutoCreateOpp on Account (after insert) { // Every trigger has this loop!for (Account a : Trigger.new) {// Check if it's a 'Prospect' Accountif (a.Type == 'Prospect') {// Create a new Opp (but don't save yet) Opportunity o = new Opportunity(); o.Name = 'Big Deal'; o.StageName = 'Prospecting'; o.CloseDate = Date.today().addDays(30); o.AccountId = a.Id; // Set the Opp amount based on the Industryif (a.Industry == 'Technology') {o.Amount = 5000000;} else if (a.Industry == 'Non-Profit') {o.Amount = 1000;} else {o.Amount = 5000; } // Double the Opp amount if there are many employees!Integer bigCompanyMultiplier = 2; if (a.NumberOfEmployees > 1000) { o.Amount = o.Amount * bigCompanyMultiplier; }// Don't forget to save! insert o; } } }
Continue to Part 3: Combine SOQL & Apex!
hey david
i am a huge fan of your’s i started learning salesforce here just a few weeks ago.. you are doing a great job i must say i am
always afraid of coding and now i am trying to learn apex from this site.. i just wanted to ask you a very normal question for an interview as a fresher which type of coding can a company expect ?? i mean if you are a beginner and just know the basics is that enough ?? and i wanted to ask you the soql queries you wrote here… where should i do the practice on ?? my developer console isn’t working and opened your account as well but it’s not working.. i opened the developer console and and then click to debug and then write my code on the open execute anonymous window it doesn’t shows anything… i don’t know what’s wrong :(
Hi David,
If I wanted the trigger below to bit a bit more conditional i.e. if the movie is Frozen the trigger inserts 10 Reeses but if I wanted to have another IF condition to say if the Movie is Batman then insert 10 skittles how could I do that. I have attempted a few times with what seems logical to me but it wasnt compiling, complaining about brackets in the wrong places etc …
trigger MovieAI on Movie__c (after insert) {
for(Movie__c movie : trigger.new) {
if (movie.Name == ‘Frozen’) {
for (Integer i = 0; i < 10; i++) {
Snack__c nomnoms = new Snack__c();
nomnoms.Name = 'Reeses';
nomnoms.Status__c = 'In my belly!';
nomnoms.Movie__c = movie.id;
insert nomnoms;
}
}
}
}
The logic in what you have looks good =)
As to the errors, it’s just a matter of counting your brackets =)
Post the whole code if you need more detailed help!
David
Hi David,
I copied the same trigger. I created a new account, type:prospect,indusry:non-profit, emp: 20K. However I get amount as 10,000. weird..
trigger AutoCreateOpp on Account (after insert) {
// Every trigger has this loop!
for (Account a : Trigger.new) {
// Check if it’s a ‘Prospect’ Account
if (a.Type == ‘Prospect’) {
// Create a new Opp (but don’t save yet)
Opportunity o = new Opportunity();
o.Name = ‘Big Deal’;
o.StageName = ‘Prospecting’;
o.CloseDate = Date.today().addDays(30);
o.AccountId = a.Id;
// Set the Opp amount based on the Industry
if (a.Industry == ‘Technology’) {
o.Amount = 5000000;
} else if (a.Industry == ‘Non-Profit’) {
o.Amount = 1000;
} else {
o.Amount = 5000;
}
// Double the Opp amount if there are many employees!
Integer bigCompanyMultiplier = 2; if (a.NumberOfEmployees > 1000) { o.Amount = o.Amount * bigCompanyMultiplier; }
// Don’t forget to save!
insert o;
}
}
}
Check out this post to debug!
https://www.sfdc99.com/2014/02/22/debug-your-code-with-system-debug/
Shouldn’t the final trigger ‘Autocreatopp’ write the new opportunities to the list, then ‘try’ to insert the list after closing the for loop? If 300 Accounts were inserted at once, you would hit limits with 300 insert DML statements, correct? Like this:
trigger AutoCreateOpp on Account (after insert) {
// Every trigger has this loop!
list oppsToInsert = new list ();
for (Account a : Trigger.new) {
// Check if it’s a ‘Prospect’ Account
if (a.Type == ‘Prospect’) {
// Create a new Opp (but don’t save yet)
Opportunity o = new Opportunity();
o.Name = ‘Big Deal’;
o.StageName = ‘Prospecting’;
o.CloseDate = Date.today().addDays(30);
o.AccountId = a.Id;
// Set the Opp amount based on the Industry
if (a.Industry == ‘Technology’) {
o.Amount = 5000000;
} else if (a.Industry == ‘Non-Profit’) {
o.Amount = 1000;
} else {
o.Amount = 5000;
}
// Double the Opp amount if there are many employees!
Integer bigCompanyMultiplier = 2;
if (a.NumberOfEmployees > 1000) {
o.Amount = o.Amount * bigCompanyMultiplier;
}
// Don’t forget to save!
oppsToInsert.add(o);
}
}
try {
insert oppsToInsert;
} catch (system.DmlException e) {
system.debug (e);
}
}
Great observation Sebastian!!
You’re ahead of the curve – we cover this topic in Chapter 5!
Thanks Dave :)
Please let me know how can I improve this Test Class on non-profit Trigger ? Its working fine and test results have covered 100% Trigger code
@isTest
public class TestAutoCreateOpty{
static testMethod void tester() {
//Create a list of Accounts
List-Account listOfAccounts = new List-Account();
//Create Technology Account as Prospect having less than 1000 emp
Account Techno = new Account();
Techno.Name = ‘Moserbaer’;
Techno.Industry = ‘Technology’;
Techno.Type = ‘Prospect’;
Techno.NumberOfEmployees = 999;
listOfAccounts.add(Techno);
//Create a Non-Profit Account as Prospect having 1000 emp
Account nonProf = new Account();
nonProf.Name = ‘RGV’;
nonProf.Industry = ‘Non-Profit’;
nonProf.Type = ‘Prospect’;
nonProf.NumberOfEmployees = 1000;
listOfAccounts.add(nonProf);
//Create an Agriculture Account as Prospect having more than 1000 emp
Account Agri = new Account();
Agri.Name = ‘BASF’;
Agri.Industry = ‘Agriculture’;
Agri.Type = ‘Prospect’;
Agri.NumberOfEmployees = 1001;
listOfAccounts.add(Agri);
//Create an Agriculture Account as Prospect having more than 1000 emp
Account App = new Account();
App.Name = ‘Nike’;
App.Industry = ‘Apparel’;
App.Type = ‘Other’;
App.NumberOfEmployees = 1002;
listOfAccounts.add(App);
insert listOfAccounts;
//System.AssertEquals(5000000, listOfAccounts[0].Opportunity__r.Amount);
//System.AssertEquals(1000, listOfAccounts[1].Opportunity__r.Amount);
//System.AssertEquals(10000, listOfAccounts[2].Opportunity__r.Amount);
//System.AssertEquals(null, listOfAccounts[3].Opportunity__r.Amount);
//Get the values in a List
List-Account check = [SELECT Id, Type, NumberOfEmployees, (SELECT Amount FROM Opportunities)
FROM Account
WHERE Name IN (‘Moserbaer’, ‘RGV’, ‘BASF’, ‘Nike’)];
//Assert the results
for (Account abc : check) {
for (Opportunity o : abc.Opportunities) {
if (abc.Type == ‘Prospect’) {
System.debug(‘Amount alloted =’ + o.Amount);
} else {
System.AssertEquals(null, o.Amount);
}
}
}
}
}
LOVE IT!!!!! Amazing work Nitin, you are learning very well!!!!
Nitin,
Thanks for asking for this as I needed it too to reverse engineer. Still learning by reading on the tests as I get lost very quickly. Amazing work doing this on your own Nitin!