You need to sign in to do that
Don't have an account?
Shruthi Narsi
Trigger to roll up
I have written a trigger to roll up opportunity amount on quota. The code is working fine. I have a problem in line 34.
If I add two new opportunity with amoth as 100 and 100. The roll up is 200.
Again if I edit it recaclulates and adds 200 which is euql to 400. This logic is wrong how to correct it.
trigger Roll on Opportunity (before insert,before update,after insert,after update){
Set<Id> setOpportunityIds=new Set<Id>();
for(Opportunity c:Trigger.new)
if(c.StageName == 'Closed Won' && c.Closed_Date__c == 'January' )
setOpportunityIds.add(c.id);
List<Quota__c> ListOfAllOrgs = [select id,RecordTypeId, Actual_Amount__c,Opportunity__c,Quota_Amount__c from Quota__c];
List<Quota__c> lstCommissionToUpdate=new List<Quota__c>();
for(AggregateResult result:[Select Quota__c,SUM(Amount) From Opportunity
WHERE Id IN :setOpportunityIds GROUP BY Quota__c LIMIT 1 ])
{
for(Quota__c org : ListOfAllOrgs)
{
System.debug('Amount value in Org is' + Decimal.ValueOf(String.ValueOf(result.get('expr0'))));
if(result.get('Quota__c') == org.Id && org.Actual_Amount__c == null )
{
if( org.RecordTypeId == '0122v000002KFRAAA4')
{
org.Actual_Amount__c = 0;
}
else{
org.Actual_Amount__c = org.Actual_Amount__c + Decimal.ValueOf(String.ValueOf(result.get('expr0')));
if(result.get('Quota__c') == org.Id && org.Actual_Amount__c != null )
{
if( org.RecordTypeId == '0122v000002KFRAAA4')
{
org.Actual_Amount__c = 0;
}
else{
org.Actual_Amount__c = org.Actual_Amount__c + Decimal.ValueOf(String.ValueOf(result.get('expr0')));
System.debug('Amount value in Org is' + Decimal.ValueOf(String.ValueOf(result.get('expr0'))));
}
lstCommissionToUpdate.add(org);
System.debug('Amount value in Org is' + Decimal.ValueOf(String.ValueOf(result.get('expr0'))));
}
}
}
if(lstCommissionToUpdate.size()>0){
update lstCommissionToUpdate;
System.debug('Amount value in Org is' + Decimal.ValueOf(String.ValueOf(result.get('expr0'))));
}
}
}
}
If I add two new opportunity with amoth as 100 and 100. The roll up is 200.
Again if I edit it recaclulates and adds 200 which is euql to 400. This logic is wrong how to correct it.
trigger Roll on Opportunity (before insert,before update,after insert,after update){
Set<Id> setOpportunityIds=new Set<Id>();
for(Opportunity c:Trigger.new)
if(c.StageName == 'Closed Won' && c.Closed_Date__c == 'January' )
setOpportunityIds.add(c.id);
List<Quota__c> ListOfAllOrgs = [select id,RecordTypeId, Actual_Amount__c,Opportunity__c,Quota_Amount__c from Quota__c];
List<Quota__c> lstCommissionToUpdate=new List<Quota__c>();
for(AggregateResult result:[Select Quota__c,SUM(Amount) From Opportunity
WHERE Id IN :setOpportunityIds GROUP BY Quota__c LIMIT 1 ])
{
for(Quota__c org : ListOfAllOrgs)
{
System.debug('Amount value in Org is' + Decimal.ValueOf(String.ValueOf(result.get('expr0'))));
if(result.get('Quota__c') == org.Id && org.Actual_Amount__c == null )
{
if( org.RecordTypeId == '0122v000002KFRAAA4')
{
org.Actual_Amount__c = 0;
}
else{
org.Actual_Amount__c = org.Actual_Amount__c + Decimal.ValueOf(String.ValueOf(result.get('expr0')));
if(result.get('Quota__c') == org.Id && org.Actual_Amount__c != null )
{
if( org.RecordTypeId == '0122v000002KFRAAA4')
{
org.Actual_Amount__c = 0;
}
else{
org.Actual_Amount__c = org.Actual_Amount__c + Decimal.ValueOf(String.ValueOf(result.get('expr0')));
System.debug('Amount value in Org is' + Decimal.ValueOf(String.ValueOf(result.get('expr0'))));
}
lstCommissionToUpdate.add(org);
System.debug('Amount value in Org is' + Decimal.ValueOf(String.ValueOf(result.get('expr0'))));
}
}
}
if(lstCommissionToUpdate.size()>0){
update lstCommissionToUpdate;
System.debug('Amount value in Org is' + Decimal.ValueOf(String.ValueOf(result.get('expr0'))));
}
}
}
}
For recordType Ids, the following will work - replace the string "myRecordTypeName" with the name of your Record Type.
I note also you are doing a query for all the Quota__c records, why not just get those that are affected by the Trigger?
You are then looping within a loop - not the most economical why of processing records, why not covert the list to a Map , and then you can test for keys rather than looping the list. Remember you were grabbing ALL the Quota__c records. So if there are 1000 Quota__c records, and there is one one Opportunity, you are doing 1000 loops for not real reason.
SO:
Then I can be more economical with my loop: And note that the other thing you were doing, your update method was inside the for loop for all the Quota__c records, so therefore you would have hit DML limits on any bulk update.
Stick that size test and update outside any loops.
And technically, to be better code, stick it in a try catch statement.
Regards
Andrew
All Answers
Can the code not be:
As an aside, I would also question the use of hardcoded Ids in Apex code. Is there a reason why you can't use
and also, when posting code, to make it easer to read on the forums, use the Code Snippet button
Regards
Andrew
Thanks for letting me know the corrections
Can you code if possible becuse I didnt understand what you are trying to tell me.
Thanks for letting me know the corrections
Can you code if possible becuse I didnt understand what you are trying to tell me.
For recordType Ids, the following will work - replace the string "myRecordTypeName" with the name of your Record Type.
I note also you are doing a query for all the Quota__c records, why not just get those that are affected by the Trigger?
You are then looping within a loop - not the most economical why of processing records, why not covert the list to a Map , and then you can test for keys rather than looping the list. Remember you were grabbing ALL the Quota__c records. So if there are 1000 Quota__c records, and there is one one Opportunity, you are doing 1000 loops for not real reason.
SO:
Then I can be more economical with my loop: And note that the other thing you were doing, your update method was inside the for loop for all the Quota__c records, so therefore you would have hit DML limits on any bulk update.
Stick that size test and update outside any loops.
And technically, to be better code, stick it in a try catch statement.
Regards
Andrew