0

I wrote an Opportunity Trigger that should run when an Opportunity is Closed Won.

This trigger should change the status of a custom object we use to record the status of subscriptions to specific products on a per account basis.

The idea was to change the status of all of these objects to "Deferred" and then change the ones that are being purchased to "Purchased".

Here's the code:

trigger ConvertProducts on Opportunity (after update) {

    List<Id> accIds = new List<Id>();
    List<Id> oppIds = new List<Id>();

    for(Opportunity a : Trigger.new){
        if(a.StageName == 'Closed Won'){
            accIds.add(a.Account.Id);
            oppIds.add(a.Id);
        }
    }

    if(oppIds != null){
        List<OpportunityLineItem> oppLineItemList = new List<OpportunityLineItem>([SELECT Id, OpportunityId, Opportunity.Account.Id, Name,  Product2Id, UnitPrice FROM OpportunityLineItem WHERE OpportunityId IN :oppIds]);
        List<ProductInformation__c> prodInfoList = new List<ProductInformation__c>([SELECT Id, Name, Account__c, Status__c, Product__c, Purchased_Date__c FROM ProductInformation__c WHERE Account__c IN :accIds]);

        for(ProductInformation__c c : prodInfoList){
            c.Status__c = 'Deferred';
            c.Purchased_Date__c = null;
        }

        for(OpportunityLineItem a : oppLineItemList){
            for(ProductInformation__c b : prodInfoList){
                if(a.Opportunity.Account.Id == b.Account__c && a.Product2Id == b.Product__c){
                    b.Status__c = 'Purchased';
                    b.Purchased_Date__c = date.today();
                }
            }
        }

        update prodInfoList;
    }
}
6
  • 3
    What's "not working"?
    – TSmith
    Commented Sep 1, 2017 at 12:38
  • what error your getting ?
    – NITHESH K
    Commented Sep 1, 2017 at 12:40
  • 1
    Add system.debug for accIds and oppIds is not null ? and check in log file
    – NITHESH K
    Commented Sep 1, 2017 at 12:41
  • @TSmith the status' of the custom objects is not changing at all after making the Opportunity Stag = Closed Won Commented Sep 1, 2017 at 12:45
  • @NITHESHK I'm not receiving any error, it just doesn't seem to be doing anything. I will add debug statements and see what I get. Commented Sep 1, 2017 at 12:45

1 Answer 1

3

The issue in your code is on a single line, and is very subtle

for(Opportunity a : Trigger.new){
    if(a.StageName == 'Closed Won'){
        accIds.add(a.Account.Id); // <== This is where your error is
        oppIds.add(a.Id);
    }
}

What you're trying to do is fetch the Id of the Account related to your Opportunity, but you're trying to pull the Id from the Account itself.

Trigger context variables only contain data of the immediate object that the trigger is for (Opportunity, in your case). Anything that isn't on Opportunity is what I call 'related' data (i.e. it's data that's on a record that has some relationship with the record you're working on. Account being the parent of an Opportunity), and is not included in the trigger context variables (you'd need to query for it).

Another way to think of it is that if you need to use more than one dot/period/full-stop to access the data, it won't be available in trigger context variables.

Since a.Account.Id will always return null, your accIds list is full of nothing but repeated null values. This, in turn, is likely causing your query for ProductInformation__c to return 0 rows.

Fixing this particular issue is simple

for(Opportunity a : Trigger.new){
    if(a.StageName == 'Closed Won'){
        // This way is wrong, because it tries to access a parent object's field
        //   through a trigger context variable.
        // This will always result in a 'null' being added to your list.
        //accIds.add(a.Account.Id);

        // This is the correct way to do things in this case.
        // The AccountId field on Opportunity stores the Id of the related Account.
        // There's only one dot required to access this field, so it will be included
        //   in the trigger context variable.
        accIds.add(a.AccountId);
        oppIds.add(a.Id);
    }
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .