You need to sign in to do that
Don't have an account?
my first trigger
Hi all,
I wonder if anyone can help or direct me.
I am trying to write my first trigger from scratch (until now I've only really updated existing ones and very rarely at that).
I have an object called "Audit" which has a lookup relationship to another object called "Reviewer".
What I need to happed is the following.
If within the Audit object the lookup for the reviewer changes, then two things need to happen:
1. Within the OLD Reviewer object I need to update a field called "Workload" and decrement the value within it by 1.
2. Within the NEW Reviewer object I need to update a field called "Workload" and increment the value within it by 1.
(If either old or new are blank/null then do nothing for that step but continue with the other step)
I think the above sounds pretty straightforward really but I'm stuck.
Any assistance would be gratefully received.
Thank you,
mi5tery
Hi,
Create a class
public class FutureTriggerController{
public static boolean isFutureUpdate = false;
}
Modified Trigger
trigger reAllocateReviewer on AuditResponse__c (after update)
{
string oldReviewerID = null;
string newReviewerID = null;
if(FutureTriggerController.isFutureUpdate != true){
FutureTriggerController.isFutureUpdate =true;
if(Trigger.old[0].Reviewer__c != NULL)
{
oldReviewerID = Trigger.old[0].Reviewer__c;
}
if(Trigger.new[0].Reviewer__c)
{
newReviewerID = Trigger.new[0].Reviewer__c;
}
if (oldReviewerID != null && oldReviewerID != newReviewerID )
{
Reviewer__c oldReviewer = [SELECT Current_workload__c FROM Reviewer__c WHERE ID=:oldReviewerID];
System.debug('Old Reviewer = ' + oldReviewer.Id);
System.debug('Workload = ' + oldReviewer.Current_workload__c);
oldReviewer.Current_workload__c -= 1;
upsert oldReviewer;
}
if (newReviewerID != null && newReviewerID != oldReviewerID )
{
Reviewer__c newReviewer = [SELECT Current_workload__c FROM Reviewer__c WHERE ID=:newReviewerID];
System.debug('New Reviewer = ' + newReviewer.Id);
System.debug('Workload = ' + newReviewer.Current_workload__c);
newReviewer.Current_workload__c += 1;
upsert newReviewer;
}
}
THIS WILL PREVENT FROM CALLING THE TRIGGER TWICE
If this post is helpful please throw Kudos.If this post solves your problem kindly mark it as solution.
Thanks
All Answers
Here's what I have so far:
I think (but i'm not sure) you could do this with workflows, however it does not look complicated, i would say :
[edit :]
well i'm wrong you probably can't update reviewer from the trigger context, forget this one :)
trigger reAllocateReviewer on SKAResponse__c (before update)
{
for(SKAResponse__c s:trigger.new)
{
string oldReviewerID = Trigger.oldMap.get(ID).Reviewer__c
string newReviewerID = Trigger.newMap.get(ID).Reviewer__c
Map<Id,String> reviewersMap=new Map<String,Id>();
if (oldReviewer != null && oldReviewerID!=newReviewerID)
{
reviewersMap.put(oldReviewerID,'Old');
reviewersMap.put(newReviewerID, 'New');
}
} List<Reviewer__c> reviewers=new List<Reviewer__c>();
if(reviewersMap.size()>0)
{
for(Reviewer r:[SELECT Current_workload__c
FROM Reviewer__c wHERE ID IN :reviewersMap.keyset()]
{
if(reviewersMap.get(r.id)=='Old')
{
r.Current_workload__c -=1;
}
else
{
r.Current_workload__c +=1;
}
reviewers.add(r);
}
}
if(!reviewers.isEmpty())
Database.update(reviewers);
}
Try this,
trigger reAllocateReviewer on AuditResponse__c (after update)
{
if(Trigger.old(0).Reviewer__c != NULL){
string oldReviewerID = Trigger.old(0).Reviewer__c;
}
if(Trigger.new(0).Reviewer__c){
string newReviewerID = Trigger.new(0).Reviewer__c;
}
if (oldReviewer != null)
{
Reviewer__c oldReviewer = [SELECT Current_workload__c
FROM Reviewer__c
WHERE ID=:oldReviewerID];
System.debug('Old Reviewer = ' + oldReviewer.Id);
System.debug('Workload = ' + oldReviewer.Current_workload__c);
oldReviewer.Current_workload__c = oldReviewer.Current_workload__c - 1;
upsert oldReviewer;
}
if (newReviewer != null)
{
Reviewer__c newReviewer = [SELECT Current_workload__c
FROM Reviewer__c
WHERE ID=:newReviewerID];
System.debug('New Reviewer = ' + newReviewer.Id);
System.debug('Workload = ' + newReviewer.Current_workload__c);
newReviewer.Current_workload__c = newReviewer.Current_workload__c + 1;
upsert newReviewer;
}
}
If this post is helpful please throw Kudos.If this post solves your problem kindly mark it as solution.
Thanks
These are really nice articles for beginners to begin with:
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_context_variables.htm
and
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers.htm
Thanks,
Hey try this
trigger reAllocateReviewer on SKAResponse__c (before update)
{
for(SKAResponse__c s:trigger.new)
{
string oldReviewerID = Trigger.oldMap.get(s.ID).Reviewer__c
string newReviewerID = Trigger.newMap.get(s.ID).Reviewer__c
Map<Id,String> reviewersMap=new Map<String,Id>();
if (oldReviewer != null && oldReviewerID!=newReviewerID)
{
reviewersMap.put(oldReviewerID,'Old');
reviewersMap.put(newReviewerID, 'New');
}
} List<Reviewer__c> reviewers=new List<Reviewer__c>();
if(reviewersMap.size()>0)
{
for(Reviewer r:[SELECT Current_workload__c
FROM Reviewer__c wHERE ID IN :reviewersMap.keyset()]
{
if(reviewersMap.get(r.id)=='Old')
{
r.Current_workload__c -=1;
}
else
{
r.Current_workload__c +=1;
}
reviewers.add(r);
}
}
if(!reviewers.isEmpty())
Database.update(reviewers);
}
Hi souvik9086,
I amended a few typo's (my fault really) and got this:
Unfortunately for some reason the dev console says: "Variable does not exist: Trigger" - on line 8
Hi,
Try this
I think you are looking for this
Code :
trigger reAllocateReviewer on AuditResponse__c (after update)
{
for(AuditResponse__c a : Trigger.New)
{
string oldReviewerID = Trigger.oldMap.get(a.ID).Reviewer__c;
string newReviewerID = Trigger.newMap.get(a.ID).Reviewer__c;
System.debug('@@Old Reviewer = ' + oldReviewerID);
System.debug('@@Old Reviewer = ' + newReviewerID);
Reviewer__c oldReviewer = [SELECT Current_workload__c FROM Reviewer__c WHERE ID=:oldReviewerID];
Reviewer__c newReviewer = [SELECT Current_workload__c FROM Reviewer__c WHERE ID=:newReviewerID];
if (oldReviewer!= null)
{
System.debug('Old Reviewer = ' + oldReviewer.Id);
System.debug('Workload = ' + oldReviewer.Current_workload__c);
oldReviewer.Current_workload__c = oldReviewer.Current_workload__c - 1;
update oldReviewer;
}
if (newReviewer!= null)
{
System.debug('New Reviewer = ' + newReviewer.Id);
System.debug('Workload = ' + newReviewer.Current_workload__c);
newReviewer.Current_workload__c = newReviewer.Current_workload__c + 1;
update newReviewer;
}
}
}
I also do have a little fault there
Can you check now?
If this post is helpful please throw Kudos.If this post solves your problem kindly mark it as solution.
Thanks
Hi Neha Lund,
I've tried this:
I changed line 8 from this:
Map<Id, String> reviewersMap=new Map<String, ID>();
as it was throwing this error: "Illegal assignment from MAP<String, ID> to MAP<Id, String>"
but now it throws this: "Variable does not exist: Current_workload__c" - line 22 - I have confirmed this is the exact api name.
Hi mritesh,
You solution works except... it increments and decrements twice!
so previous reviewer workload decreases by 2, and new reviewer workload increases by 2
hey
I think you r missing something,cos i tried this in mine n its working fine as u wished.
increments by 1 n decrement by 1 .
Hi souvik 9086,
Your solution seems to work too - and as with mritesh the increments and decrements seem to happen twice.
I think it might be something on my elnd that I'm missing.
Let me get back to you both
the double-run of a trigger is often caused by a workflow who updates the object after the trigger. Have a look on this way ?
I think gedeef is right workflow is running this trigger again.Check that
Can you change like this
If this post is helpful please throw Kudos.If this post solves your problem kindly mark it as solution.
Thanks
Looking at the debug log I can see it is definitely running the trigger twice.
Is there anyway I can prevent this running twice in the code? I'm struggling to find the right workflow as there are lots on this object.
Should be one who updates a field...
Hi,
Create a class
public class FutureTriggerController{
public static boolean isFutureUpdate = false;
}
Modified Trigger
trigger reAllocateReviewer on AuditResponse__c (after update)
{
string oldReviewerID = null;
string newReviewerID = null;
if(FutureTriggerController.isFutureUpdate != true){
FutureTriggerController.isFutureUpdate =true;
if(Trigger.old[0].Reviewer__c != NULL)
{
oldReviewerID = Trigger.old[0].Reviewer__c;
}
if(Trigger.new[0].Reviewer__c)
{
newReviewerID = Trigger.new[0].Reviewer__c;
}
if (oldReviewerID != null && oldReviewerID != newReviewerID )
{
Reviewer__c oldReviewer = [SELECT Current_workload__c FROM Reviewer__c WHERE ID=:oldReviewerID];
System.debug('Old Reviewer = ' + oldReviewer.Id);
System.debug('Workload = ' + oldReviewer.Current_workload__c);
oldReviewer.Current_workload__c -= 1;
upsert oldReviewer;
}
if (newReviewerID != null && newReviewerID != oldReviewerID )
{
Reviewer__c newReviewer = [SELECT Current_workload__c FROM Reviewer__c WHERE ID=:newReviewerID];
System.debug('New Reviewer = ' + newReviewer.Id);
System.debug('Workload = ' + newReviewer.Current_workload__c);
newReviewer.Current_workload__c += 1;
upsert newReviewer;
}
}
THIS WILL PREVENT FROM CALLING THE TRIGGER TWICE
If this post is helpful please throw Kudos.If this post solves your problem kindly mark it as solution.
Thanks
It seems someone else had a similar problem:
http://boards.developerforce.com/t5/Apex-Code-Development/Apex-Trigger-Firing-Twice-How-to-Prevent/td-p/97897
I can't however work out how to apply that solution into mine.
Hi soivik9086,
I'll have a try with your solution
Thank you everyone for your very speedy responses and assistance.