You need to sign in to do that
Don't have an account?

How do I trigger Account.AnnualRevenue to update when Product is updated?
In my developer environment, I've added two custom fields to the Product standard object:
Account: Lookup (Account)
Annual Revenue: Formula (Currency)
The formula for Product2.Annual_Revenue is:
Annual_Revenue = Estimated_Monthly_Sales_Volume__c * Total_CO2_Footprint__c *0.0024
I'm trying to create a trigger so that when a Product is added or modified, the AnnualRevenue field in Accounts will automatically reflect the total value of all Products which lookup that account.
This is the trigger I've created:
trigger UpdateAccountAnnualRevenue
on Product2 (after delete, after insert, after undelete, after update)
{
for (Product2 productModified: Trigger.new)
{
List <Product2> accountProduct =
[
select Annual_Revenue__c
from Product2
where ID = :productModified.Account__r.id
];
double Total_Revenue = 0.00;
for (Product2 AP: accountProduct)
{
Total_Revenue += AP.Annual_Revenue__c;
}
for (Account productAccount:
[
select AnnualRevenue
from Account
where ID = :productModified.Account__r.id
]
)
{
productAccount.AnnualRevenue = Total_Revenue;
update productAccount;
}
}
}
However, there seems to be a problem with this code.
For example, GenWatt Diesel 200kW has an Annual Revenue of $18.67.
However, the account Burlington Textiles Corp of America, which has no other assigned products, has an Annual Revenue of $350,000,000
What am I doing wrong and how do I fix it?
Cheers for the solution above!
I think you're looking for "Account__c"?
I noticed when I tried to get the code to work, I needed to add a semi-colon to line 9, as well as add "Account_c" to line 13.
But other than that, the code works great and it would have taken me a long time to figure this out without you! :-)
Corrected code, in case anyone else is interested:
trigger UpdateAccountAnnualRevenue
on Product2 (after delete, after insert, after undelete, after update)
{
Set<Id> accIds = new Set<Id>();
for (Product2 productModified: Trigger.new)
{
if(productModified.Account__c == null) return;
accIds.add(productModified.Account__c);
}
List<Product2> prodList = new List<Product2>([
Select Id, Account__c, Annual_Revenue__c
from Product2
where Account__c In : accIds]);
Map<Id, double> accountTotalRevenueMap = new Map<Id, double>();
for (Product2 productModified: Trigger.new)
{
if(productModified.Account__c == null) return;
if(!prodList.isEmpty())
{
double Total_Revenue = 0.00;
for(Product2 oldProd : prodList)
{
if(oldProd.Account__c == productModified.Account__c
&& oldProd != productModified)
{
Total_Revenue += oldProd.Annual_Revenue__c;
}
}
accountTotalRevenueMap.put(productModified.Account__c, Total_Revenue);
}
}
for(List<Account> accList : [Select Id, AnnualRevenue From Account Where Id In : accIds] )
{
for(Account a : accList)
{
if(accountTotalRevenueMap.get(a.Id) == null)return;
a.AnnualRevenue = accountTotalRevenueMap.get(a.Id);
}
update accList;
}
}
All Answers
try this
List <Product2> accountProduct =
[
select Annual_Revenue__c
from Product2
where ID = productModified.Account__c
];
but i see loads of problems with ur trigger it is not bulk safe.
If it's not too much trouble, I don't suppose you can provide a complete code that will make this work correctly?
I'm quite new at SalesForce.com and Apex...
Thanks in advance,
-Brian.
[Note: I haven't tested Accounts with multiple products yet since I don't expect it to work with 2 Products when it doesn't work for accounts with 1.]
Right.
Each Product is attached to an Account by a lookup field.
The standard Account object already has "AnnualRevenue" as a Currency (18,0) field.
My client wishes for the value of this field to be the total value of all Products which lookup this account.
Because I can't (for reasons that are beyond me) add Account as a Master in a Master-Detail relationship to Product, it isn't possible for me to simply create this sum as a Rollup field in Account.
So, for lack of any better idea how to do this, I thought I'd try to do this with a trigger. (I am, however, open to alternative suggestions.)
-Brian.
try this:
Set<Id> accIds = new Set<Id>();
for (Product2 productModified: Trigger.new)
{
if(productModified.Account__c == null) return;
accIds.add(productModified.Account__c)
}
List<Product2> prodList = new List<Product2>([
Select Id, Annual_Revenue__c
from Product2
where Account__c In : accIds]);
Map<Id, double> accountTotalRevenueMap = new Map<Id, double>();
for (Product2 productModified: Trigger.new)
{
if(productModified.Account__c == null) return;
if(!prodList.isEmpty())
{
double Total_Revenue = 0.00;
for(Product2 oldProd : prodList)
{
if(oldProd.Account__c == productModified.Account__c
&& oldProd != productModified)
{
Total_Revenue += oldProd.Annual_Revenue__c;
}
}
accountTotalRevenueMap.put(productModified.Account__c, Total_Revenue);
}
}
for(List<Account> accList : [Select Id, AnnualRevenue From Account Where Id In : accIds] )
{
for(Account a : accList)
{
if(accountTotalRevenueMap.get(a.Id) == null)return;
a.AnnualRevenue = accountTotalRevenueMap.get(a.Id);
}
update accList;
}
Cheers for the solution above!
I think you're looking for "Account__c"?
I noticed when I tried to get the code to work, I needed to add a semi-colon to line 9, as well as add "Account_c" to line 13.
But other than that, the code works great and it would have taken me a long time to figure this out without you! :-)
Corrected code, in case anyone else is interested:
trigger UpdateAccountAnnualRevenue
on Product2 (after delete, after insert, after undelete, after update)
{
Set<Id> accIds = new Set<Id>();
for (Product2 productModified: Trigger.new)
{
if(productModified.Account__c == null) return;
accIds.add(productModified.Account__c);
}
List<Product2> prodList = new List<Product2>([
Select Id, Account__c, Annual_Revenue__c
from Product2
where Account__c In : accIds]);
Map<Id, double> accountTotalRevenueMap = new Map<Id, double>();
for (Product2 productModified: Trigger.new)
{
if(productModified.Account__c == null) return;
if(!prodList.isEmpty())
{
double Total_Revenue = 0.00;
for(Product2 oldProd : prodList)
{
if(oldProd.Account__c == productModified.Account__c
&& oldProd != productModified)
{
Total_Revenue += oldProd.Annual_Revenue__c;
}
}
accountTotalRevenueMap.put(productModified.Account__c, Total_Revenue);
}
}
for(List<Account> accList : [Select Id, AnnualRevenue From Account Where Id In : accIds] )
{
for(Account a : accList)
{
if(accountTotalRevenueMap.get(a.Id) == null)return;
a.AnnualRevenue = accountTotalRevenueMap.get(a.Id);
}
update accList;
}
}
On another note u should probably build a class out of that trigger and get the trigger to call the class function
as for after delete you probably have to get the trigger.old
public class Product2Utils {
static void CheckAnnualRevenue(List<Product2> prodList)
{
//put code here
}
}
or try this :
trigger UpdateAccountAnnualRevenue on Product2 (after delete, after insert, after undelete, after update) { List<Product2> triggerList = (trigger.isDelete || trigger.isUndelete ? trigger.old : trigger.new); Set<Id> accIds = new Set<Id>(); for(Product2 productModified: triggerList) { if(productModified.Account__c == null) return; accIds.add(productModified.Account__c); } List<Product2> prodList = new List<Product2>([ Select Id, Account__c, Annual_Revenue__c from Product2 where Account__c In : accIds]); Map<Id, double> accountTotalRevenueMap = new Map<Id, double>(); for(Product2 productModified: triggerList) { if(productModified.Account__c == null || prodList.isEmpty())return; Double total_Revenue = 0.00; for(Product2 oldProd : prodList) { if(oldProd.Account__c == productModified.Account__c && oldProd != productModified) { total_Revenue += oldProd.Annual_Revenue__c; } } accountTotalRevenueMap.put(productModified.Account__c, total_Revenue); } if(!accountTotalRevenueMap.isEmpty()) { for(List<Account> accList : [Select Id, AnnualRevenue From Account Where Id In : accIds] ) { for(Account a : accList) { if(accountTotalRevenueMap.get(a.Id) == null)return; a.AnnualRevenue = accountTotalRevenueMap.get(a.Id); } update accList; } } }
-Brian.