4

sorry for the vague title. Essentially, I have a trigger I've created to change ownership of an opportunity based on some business rules our company has. When a sales user places a call to a customer, our system creates a Call Task. If the call is made on the opportunity, the task attributed to that opportunity. If all business rules are met, this call triggers an update on the ownership field to the person that placed the call.

While this seems to work some of the time, it is throwing errors the rest of the time:

"List has no rows for assignment to SObject".

I thought my if statement makes it impossible for this trigger to fire, however I'll let you be the judge.

With that explanation out of the way, here is my trigger code:

trigger Trg_SAMOwnership on Task (before insert) 
// This trigger involves Core Sales Team Groups and transferring ownership of opportunities to their senior account managers.  If an opportunity hasn't been sold after
// 3 business days, and the senior account manager places a call to the customer regarding the opportunity, the ownership will transfer to the senior account manager.  This
// replaces the old workflow rules regarding transfer of ownership of opportunities in this case.
{
    for (Task t : Trigger.new)
    {
        final Id PAUL = '00560000001QdqW';
        final Id MICHAEL = '00560000001OXAB';
        final Id ERIC = '00560000001OWrs';
        final Id ROBERT = '00560000003bHkM';
        final Id SHELLEY = '005600000035iXB';
        final Id SCOTT = '00560000003cncJ';

        if ((t.OwnerId == PAUL || t.OwnerId == MICHAEL || t.OwnerId == ERIC || t.OwnerId == ROBERT || t.OwnerId == SHELLEY || t.OwnerId == SCOTT) && t.Type == 'Call' & t.WhatId != null)
        {
        Opportunity o = [select Id, OwnerId, Business_Day_Counter__c, Sales_Team_Group_Owner__c, StageName from Opportunity where Id =: t.WhatId];

        if (o.Sales_Team_Group_Owner__c != null && o.Business_Day_Counter__c >= 4 && (o.StageName != '9 - Sold' && o.StageName != '0 - Lost' && o.StageName != 'Closed Lost'))
        {
            if (o.Sales_Team_Group_Owner__c == 'Deal $ealer$')
            {
                o.OwnerId = PAUL;
                update o;
            }
            if (o.Sales_Team_Group_Owner__c == 'Gold Fingers')
            {
                o.OwnerId = MICHAEL;
                update o;
            }
            if (o.Sales_Team_Group_Owner__c == 'Senior Queso and the Good Vibrations')
            {
                o.OwnerId = ERIC;
                update o;
            }
            if (o.Sales_Team_Group_Owner__c == 'Sultans of Sales')
            {
                o.OwnerId = ROBERT;
                update o;
            }
            if (o.Sales_Team_Group_Owner__c == 'Shellz Bellz')
            {
                o.OwnerId = SHELLEY;
                update o;
            }
            if (o.Sales_Team_Group_Owner__c == 'Kind of a Big Deal')
            {
                o.OwnerId = SCOTT;
                update o;
            }
        }
        }
    }
}

Originally, this trigger was throwing that exception every time when a user placed a call, but was not on an opportunity's page. Because it couldn't find an opportunity, it (understandably) threw the exception. However, with the addition of "& t.WhatId != null", I would think this trigger would never fire if it cannot find the opportunity.

Am I missing something? What would cause this trigger to fire after meeting all conditions in the if statement, but fail because it cannot find the opportunity?

  • 2
    Yikes! Hard coded ids are really bad practice. – Adrian Larson Jun 29 '15 at 22:58
  • Also SOQL and DML in a for loop. This is all sorts of mess. – Adrian Larson Jun 29 '15 at 22:59
4

WhatId is a polymorphic reference field which can point to more than one object type. so if we simply check for whatId != null, this trigger will still run for tasks thats not created for opportunity but for Accounts

here's the definition of whatId from salesforce reference for task object

The WhatId represents nonhuman objects such as accounts, opportunities, campaigns, cases, or custom objects. WhatIds are polymorphic. Polymorphic means a WhatId is equivalent to the ID of a related object. The label is Releated To ID.

So if you want to restrict this only to opportunity, you can check the Id prefix to see if it starts with '006'. something like this..

String whatIdStr = t.whatId;
string.isNotBlank(whatIdStr) && whatIdStr.startsWith('006')
| improve this answer | |
3

No, this can definitely fail. The problem here is that WhatId can be something other than an opportunity. It could be an account, a case, or even a custom object. You should check to make sure that...

t.WhatId != null && t.WhatId.getSObjectType() == Opportunity.SObjectType
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.