Preface: this post is part of the Write Your First Trigger From Start to Finish series.
Let’s write a trigger that’s both simple and practical!
We’ll write a trigger on the User object – all it will do is check the “Allow Forecasting” checkbox on every newly created user. Salesforce won’t let us modify this permission in a workflow, but the joke’s on them… we can just write a trigger!
trigger ForceForecasting on User (before insert) {for (User userInLoop : Trigger.new) {userInLoop.ForecastEnabled = true;}}
I added some color to the code to help you focus on what’s important. More importantly though, the colors will show you what you can ignore… save your brain power!
For now, try to guess what each word/line does based on its color.
Next post: An extended look: How to write a simple Apex trigger
Why does this code not work?:
// Write a trigger that automatically creates an Account
// whenever a Lead is created. The Account must be named
// after the last name of the Lead.
trigger AccountCreater on Lead(after insert) {
for (Lead lead : Trigger.new) {
Account acc = new Account();
acc.Name = lead.Lastname;
insert acc;
}
}
Hi Noah, Do you think Lastname causing this problem? I am using LastName (CamelCase). I am new too so not sure if it helps.
it is case insenesitive
Hi Noah,
I’m having the same issue as well. My code is the same as yours, but the Account does not get created.
Any ideas?
acc.name line below new line
AccountId = lead.Id;
Hi Noah – when you click on the Accounts tab, you’d have to change List View from “Recently Viewed” to “All Contacts”. You should then be able to see the accounts that you create.
acc.Name=lead.LastName; // line 3
I think you also have to add id.
maybe bcoz of the variable name(lead) which creates confusion between a datatype and a variable to its compiler…just change the variable name and it’ll work
Well, I think the folks at SFDC are on to your little workaround.
After clicking save, an error appears next to he Allow Forecasting check box.
Error: Allow Forecasting is not allowed for this License Type.
But I get it, the trigger affected the field.
Hi David,
When I am trying to create a user to test this trigger, I am getting an error ” Allow Forecasting is not allowed for this License Type”, eventhough I have enabled Forecasting. I tried to create this user with every license type but I am getting the same error. Could you please help me out?
And, thank you for this awesome site!
Thanks,
Shefali
Check out some of the earlier comments in this post, some others have solved the issue!
To turn on forecasting:
Setup >> customize >> forecast >> forecast setting >> Enable forecast
To overcome the “Allow Forecasting…” error, User License = ‘Salesforce’ when creating a new user.
If a ‘Salesforce’ user license is not available, this means you have used up all allowed ‘Salesforce’ licenses and will have to change some of the users with ‘Salesforce’ license to a different license.
Iam new to salesforce. Thats why Iam asking this question.
“We’ll write a trigger on the User object – all it will do is check the “Allow Forecasting” checkbox on every newly created user. Salesforce won’t let us modify this permission in a workflow,”.
Why can’t we do this with field update operation through workbench?
Not possible through workflow but it is possible through process builder! This trigger really is just practice =)
Hai David,
I have started learning salesforce, but when iam trying to execute this trigger it is not working.
Everytime when iam creating a new user allow forecasting is not checked. but the trigger is correct.
The trigger definitely isn’t correct!
Hi David,
While executing above trigger, I get below error:
Error: Allow Forecasting is not allowed for this License Type.
Turn on Forecasting!
Please let me know how to turn on “Forecasting” and fix the error “Allow Forecasting is not allowed for this License Type”.
Iam new to salesforce as well. Please help me.
Please respond
To turn on forecasting:
Setup >> customize >> forecast >> forecast setting >> Enable forecast
To overcome the “Allow Forecasting…” error, User License = ‘Salesforce’ when creating a new user.
If a ‘Salesforce’ user license is not available, this means you have used up all allowed ‘Salesforce’ licenses and will have to change some of the users with ‘Salesforce’ license to a different license.
Hi David.. even am Turn on Forecasting I am getting the same Error :Allow Forecasting is not allowed for this License Type.
can you help me on this.
I got error Invalid field ForCastEnabled for Sobject user
Check the license type you have assigned to your user. Allow Forecasting is not available to certain license types.
Hi,
When i am running above trigger – I am getting compilation error. Variable does not exist: ForecastEnabled
please help to resolve this.
Make sure you have Forecasting turned on in your org!
Hi is was tryed to complete this first simple trigger but even if i copy the code into Salesforce im not able to run the APEX-Test Class. what am i doing wrong?
After running Test i become this Error Message:
Error Message System.DmlException: Insert failed. First exception on row 0; first error: INVALID_CROSS_REFERENCE_KEY, invalid cross reference id: []
could you please help me.
Thanks
The problem is because we hard code an ID in the test class, but that ID is different in your own org.
Check out the comments on the tutorial, you’ll see how a lot of other people solved it!
https://www.sfdc99.com/2013/05/14/how-to-write-a-test-class/
you make wrong test class pls check your test class again and insertion filed
Hello David, I think I am in a position to get my hands dirty, but can’t come up with multiple meaningful scenarios. So would you be able to help me find some beginner exercises for triggers, controllers etc on standard objects?
Try these!
Quizzes: https://www.sfdc99.com/beginner-tutorials/
Challenges: https://www.sfdc99.com/challenges/
Oh… sorry I missed to mentioned that I completed both of those sections from this site. I was hoping you could point me to some external resources or perhaps, come up with more on your own.
And, it would be best if the problem requires to implement a meaningful business scenario. I will prefer to come up with a solution on my own than fixing bugs in something that you presented. No big deal if you can’t, I was just hoping you would have some already. Wouldn’t be too bad to add to this site: 5 – 10 scenarios each that ask to implement trigger, web services, controllers etc. Something like a mini DEV501 programming assignment.
I have an unusually difficult time coming up with these scenarios surprisingly =)
When I do I’ll post em!
Actually, there seem to be some good scenarios right now on the forums =D
https://www.sfdc99.com/forums/forum/beginning-apex/
Hi david,
I am having a triggger in which it assigns an errormessage (if error occured) to the field.
I have used addError method for assigning the error message for field .
But in my code i have called again the addError method for same field to assign the another errormessage .
My question is did it overwrite the first error message assigned to the field.
Or can you please sepecify the method to get the error message assigned for the field in salesforce if available.
Thanks in advance.
You are definitely overwriting the error!
One thing you can do is create a String variable, add multiple errors to that, then add the single String variable as an error at the end.
Thanks David….:)
trigger Archive_OnUserStatus on User (before update, after update)
{
User[] u1 = Trigger.old;
Id feedID = u1[0].Id;
Id id1 = null;
ArchiveAllData CMFD = new ArchiveAllData();
/*
if(Trigger.isBefore)
{
CMFD.filterUserStatus(u1);
}
*/
if(Trigger.isAfter)
{
System.debug(‘After–u1[0].Id–‘+u1[0].Id);
//CMFD.filterUserStatus(u1);
}
}
I have created this trigger but the code coverage for this trigger is 0%, So, can you please tell me how can I cover the trigger. Can you please send me the test method for it.
Creating/updating a User in your test class should at least get you over 0%! Keep trying!
Hey David,
In an attempt to best learn this, I tried to write the code from scratch. This prompted a few questions:
1. Does “spacing” and line separation ever count in coding?
2. What about capslock?
3. I changed the variable “ForceForecasting” and called it something else. That worked fine but not so for UserinLoop?
4. Why the semi-colon after true?
Thanks a ton for doing this! I hope to make you proud
Great questions!
Spacing or caps never matters!
You can change basically anything that’s in purple text however just make sure to find/replace 100% of the matches. You might have forgotten to change one of the other references to userInLoop !
Semi-colon after every statement =) Don’t worry, you’ll get a better feel for this soon!
Rachel, to answer you questions:
1. yes, this is an essential part of coding, it tells the computer what it’s doing and when to do it and it keeps the code nice and tody
2. you can use capslock as apex isn’t like javascript for example, trigger TEST would be the same as trigger test or trigger TeST
3. if you changed the variable altogether, the computer won’t recognize the variable because you haven’t told the computer what it is
4. the semi colon is used to tell the computer where the line of code stops and is used anywhere the curly bracket isn’t used
Hope this helped!:)
Thank you sir, WELL SAID!!!
Hi David,
Kudos on the great job you are doing. I am signed up for all your Apex programming webinars for the next few weeks.
Meanwhile, I had a question to ask. I am trying to insert a new record in my custom object Trailer. There is a Trailer # field (API name Trailer__c), which is basically a one-up number. In the new record, I want the Trailer # field to be 1 plus the highest Trailer number from the DB (basically next one-up number). How do I achieve this ?
I have started off and reached up till this point. I don’t know how to take the Max Trailer # and assign it to new record’s trailer number. Thanks in advance for your help..
public class TestAddTrailer {
static testMethod void insertNewTrailer() {
Trailer__c TrailerToCreate = new Trailer__c();
List groupedResults = [Select MAX(Trailer__c) from Trailer__c];
Thanks
Mithun
Hey Mithun,
Why not simply use an auto-number field for this? =)
Then you can convert the text field into an integer using this method:
Integer myInt = Integer.valueOf(‘123’);
David
:) ..Thanks. Got tunnel-visioned. Worked fine
David,
I’m new to Apex. Created a custom object and was able to create, via a trigger, a calendar event and populate all the needed fields in the calendar event. Now I am moving on to updating the previously created calendar event fields when changes are made to the custom object record. Not sure how to find the previously created calendar event … assume I can use much of the original trigger code to update the fields…but not sure where to start or how. Can you provide some guidance or at least point me in the right direction?
Hey Steven,
If you keep progressing through the chapters you’ll find out exactly how!
https://www.sfdc99.com/beginner-tutorials/
Chapter 2 will teach you how to find existing records, and Chapter 3 and 4 will help you integrate them into your trigger =)
Hope this helps!
David
Yes, the subsequent chapters helped. But now I have different two triggers that each work in isolation: 1) one for a custom object that creates and updates a calendar event and 2) one which updates the customer object fields when the calendar event is updated. The problem appears to be that one trigger (the calendar event) is causing a custom object trigger to also trigger resulting in a recursive issue. Can you point me in the right direction to resolve?
Many ways to do this but one is to only run your trigger when specific fields are changed to and from specific values. Tull find a post on this in chapter 6!
Nice Explanation….
Hi David,
Thank you so much for all of your advice. I am new to writing triggers and was wondering if you could give me some insight to my issue. I have been working on activating the trigger below for one of our clients:
trigger Newfield on Event (after insert){
for (Event e: Trigger.old){
event.Description = Event.LAF_Comments__c;
}
}
We keep getting the error message: Error: Compile Error: Expression cannot be assigned at line -1 column -1
LAF_Comments_c is a custom formula field. Can you help me?
Hey Jennifer,
Here are a few tips to help you get along =)
1. Change it to before insert instead of after insert
– When to use before vs. after triggers: https://www.sfdc99.com/2014/01/25/use-vs-triggers/
2. Change it from Trigger.old to Trigger.new
– Detailed explanation of the trigger format: https://www.sfdc99.com/2013/05/12/an-extended-look-how-to-write-a-simple-apex-trigger/
3. Change the line from event.Description = Event.LAF_Comments__c to:
e.Description = e.LAF_Comments__c;
– How to do loops: https://www.sfdc99.com/2013/10/06/loops-for-and-foreach-loops/
Hope this helps =)
David
Hi David
I’m new in apex code, and I need your Help, I need a trigger When my Opportunity StageName==’Closed Won’, but I can’ t resolve this.
When StageName== Closed Won, the number of quantity in opportunity products go decrement the quantity in stock in Product object. How can I do this?
I have write code but don’t work
If you can help me …
trigger stocknumber on Opportunity (before insert, before update) {
for (opportunity a : trigger.new){
if (a.StageName == ‘Closed Won’){
List b = new List(SELECT Id, Quantidade_em_stock__c FROM Product2);
// Opportunity product quantity
//Quantidade_em_stock__c -Quantity;
}
}
insert b;
}
Thank you
Hey Isa,
This one is definitely possible with the knowledge on this site however it is on the more advanced side!
Here’s generally how you need to tackle this one:
1. Detect an opp changing to Closed Won:
https://www.sfdc99.com/2014/02/25/comparing-old-and-new-values-in-a-trigger/
2. Get a list of all Opportunity Products on your opps
3. Get a list of all Products related to the Opportunity Products in #2
4. For every Opportunity Product in #2, subtract its quantity from the relevant product in #3
I definitely want to help you here but I recommend you get a strong grasp of the concepts up until chapter 7 before tackling this one!
David
Hi David,
I’m sorry but my code not complet, I do copy/paste but some parts of code disapear sorry for that.
Thanks a lot for the help
It’s actually my site’s fault =( It reads everything like HTML so it doesn’t play well with these chars: < >
Why do you think Salesforce is not allowing this standard User field to be updated via workflow? Especially since custom User fields can now be used in a workflow.
I think the User object is inherently a different type of object in Salesforce, which is why it took so long for them to allow workflows on it in the first place.
On one hand, a User record is like any other record in that it has properties like Name, Email, Phone, etc. On the other hand, there’s an entire element of system permissions governed by this object. Although at face value it seems like these permissions are simply properties like Name and Email, I think in the back end it’s a little more complicated than that.
The “Allow Forecasting” checkbox falls into the latter category of system permissions instead of simple properties, which is why I think it’s not editable via the workflow.
Either that or it’s just one of those weird things in Salesforce that they just don’t allow, leaving you scratching your head all the time =)