function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
ColaCola 

Trigger on Opportunity checks all other related Opportunities in Account

I'm currently trying to create a trigger that runs whenever an Opportunity is created or updated. The trigger needs to check all the other Opportunities related to the Account of the Opportunity being updated. It should check to see if any of the Opportunities have a StageName equal to 'Closed Won - One Time' or 'Closed Won - Recurring' and if so, it should update the account Type to 'Customer'. If none of the Opportunities are closed won, the Account Type should be 'Prospect'. 

This is the code I currently have but it doesn't seem to work. I'm not exactly sure how to check all the related opportunitites. 

trigger updateAccountIfOppCustomer on Opportunity (after insert, after update) {
    Map<Id, Account> accounts = new Map<Id, Account>();
    for (Opportunity opp : Trigger.new) {
        Account a = accounts.get(opp.AccountId);
        if (opp.StageName == 'Closed Won - One Time' || opp.StageName == 'Closed Won - Recurring') {
            if (a == null) {
                a = new Account(Id = opp.AccountId);
                accounts.put(opp.AccountId, a);
            }
            a.Type = 'Customer'; 
        } else {
            a.Type = 'Prospect';
        }
    }
    if (!accounts.isEmpty()) {
        update accounts.values();
    }
}

Any suggestions are appreciated! 
AshwaniAshwani
It may not work.

Account object has required "name" which you are not using whrn creating new Account. Add nasme field also otherwise this will throw exception. Also, can't you use Set<Account> Why you are using Map if there is no use of its keyset? You can create instance of List from Set.
Avidev9Avidev9
Few points
  • The trigger you want is on insert only so the event should be "before insert"
  • You need to query for Opportunity Where AccountId = Opportunity.AccountId and you can count on the records
Ashutosh (Independent SFDC Consultant)Ashutosh (Independent SFDC Consultant)
Trigger is updating an out of context trigger object. It should be after insert and after update.

Also,  need to change this line as:

line 07, a = new Account(Id = opp.AccountId, name='Some Name');


Abilash Kosigi 8Abilash Kosigi 8
The following code that I have written is working perfect. Please go through this. I think it satisfies your requirements. May be you need to customize it a bit to suit your requirements.  Here is the code

Trigger:


trigger updateAccount on Opportunity (after insert, after update) {
if(CheckRecursiveTrigger.runOnce())
{
for (Opportunity opp: Trigger.new)
{
Opportunity k = [select Id,  Account.Name from Opportunity where Id IN : trigger.new];
String Actname= k.Account.Name;
List<Opportunity> Opps = [select stagename from Opportunity where Account.Name = :Actname];

for (Opportunity o: Opps)
{
Account a = [Select Id,name,type from Account where name = :Actname limit 1];
if (o.stagename == 'Closed Won - One Time' || opp.StageName == 'Closed Won - Recurring' )
{

  a.type= 'Customer';

}
else
{
  a.type='Prospect';
}
update a;
}
}
}



CheckRecursiveTrigger Class:

public class CheckRecursiveTrigger {
    private static boolean run = true;
    public static boolean runOnce(){
        if (run)
        {
            run=false;
            return true;
        }
        else
        {
            return false;
        }
    }

}


Please do not forget to mark this as Best answer if this helps you :)
ColaCola
So I've updated my code to reflect some of the comments, and now I have the following: 

trigger updateAccountIfOppCustomer on Opportunity (after insert, after update) {
    List<Account> accts = new List<Account>();
    List<Opportunity> opps = new List<Opportunity>(); 
    
    for (Opportunity opp : Trigger.new) {
        accts = [SELECT Id, Name, Type FROM Account WHERE Id =: opp.AccountId LIMIT 1]; 
        opps = [SELECT Id, AccountId, StageName, Account.Type FROM Opportunity WHERE AccountId =: opp.AccountId];
    }

    for (Account a : accts) {
        for (Opportunity o : opps) {
            if (o.StageName == 'Closed Won - One Time' || o.StageName == 'Closed Won - Recurring' || o.StageName == 'Customer Reseller') {
                if (a == null) {
                    a = new Account(Id = o.AccountId, name='TestingName');
                }
                a.Type = 'Customer'; 
            } else {
                a.Type = 'Prospect';
            }
        }
    }
    update accts;
}

However, the account type still isn't being updated. Any ideas?