1

I've been pulling my hair out trying to resolve a problem with a test class for a trigger that fires on update of Opportunity. When the Opp Owner is updated, the trigger updates the Owner of related Events and Tasks.

This is a very complex org. There's TONS of test data that's generated just to create the opportunity. There's also 2 other triggers that fire on Opportunity. Rather than posting all of the 600 lines of code, I'll only post what's relevant.

The root of the problem is that I need to emulate updating the Opportunity Owner after the Opportunity has been created. To do that, I need to ensure I have both the Opp Id and the Owner Id in a list. It seems I'm having difficulty updating the OwnerId's while keeping any kind of reference to the Opp Id's in the original list.

Without the Opp Id's, the DML operation throws an Exception. I've attempted a number of different methods, but nothing seems to be working, so I must be missing something obvious. I have maps of Opp Id's to old Owner Id's, Maps of Opp Id's to New Owner Id's, lists of both Old and New Owner Id's, Maps and lists of Opp Id's, and about every combination you could think of to do this task with!

With all that said, here's some code to show what I've tried...

    list<Opportunity>OppsOldOwnrs = new list<Opportunity>();
    OppsOldOwnrs = [SELECT Id, OwnerID FROM Opportunity WHERE OwnerID =: OldOwnrIds AND Id =: OppIds]; 

    for(i=0;i<10;i++){
        OppsOldOwnrs[i].Id=OppIdslst[i]; <-- obvious list exception here
        OppsOldOwnrs[i].OwnerID=OwnrNew[i].Id ;

    }

    update OppsOldOwnrs; 

That's one way I've attempted to do the update.

    for(Opportunity o:OppsOldOwnrs){

        OppsOldOwnrs.OwnerID=OpId2NewOwnrId.get(o.Id) ;

    }

    update OppsOldOwnrs;

The compiler won't accept the above, complaining that OppsOldOwnrs isn't a valid Opportunity List. I tried first assigning the new value to o.OwnerID and then to the list, but that didn't work either.

Because of a post I read related to Accounts that had a solution to the DML exception I was getting, I've also attempted using several variations on a loop with a statement like the one below, but could never get it to completely compile or work for me.

for(i=0;i<10;i++){

OppsNwOwnrs.add(Opportunity(Id=OppIdslst[i], OwnerID=OwnrNew[i].Id)) ;

}

update OppsNwOwnrs;

Obviously I'm missing something, but can't see the forest for the trees! Anyone see what I'm not catching or know some method I'm not utilizing to accomplish an after update change of Owners for this test class?

Here's some additional info: a list of sets and maps I have available to work with. Thanks @jkraybill, but still no joy. I was thinking I may not be using the right maps or something along those lines.

set<Id> --> OldOwnrIds.add(OwnrOld[i].Id); <-- User Id's
set<Id> --> NewOwnrIds.add(OwnrNew[i].Id);
map<Id,string> --> OwnrId2oldOwnrName.put(OwnrOld[i].Id,OwnrOld[i].Name);<-- User Id to User Name (old)
map<Id,string> --> OwnrId2newOwnrName.put(OwnrNew[i].Id,OwnrNew[i].Name);<-- User Id to User Name (new)
map<Id,Id> --> OldOwnr2NewOwnrIds.put(OwnrOld[i].Id,OwnrNew[i].Id); <--User Id (old) to User Id (new)
map<Id,Id>OpId2OldOwnrId = OpId2OldOwnrId.put(nwOpps[i].Id, nwOpps[i].OwnerID);<-- Opp Id to User Id (old)
map<Id,Id>OpId2NewOwnrId = OpId2NewOwnrId.put(nwOpps[i].Id,OldOwnr2NewOwnrIds.get(nwOpps[i].OwnerID));<-- Opp Id to User Id (new)
set<Id> --> OppIds = OpId2OldOwnrId.keySet(); <-- opp Id's     
list<Id> --> OppIdslst.add(nwOpps[i].Id); <-- opp Id's

As much as anything, I put these together to help me make certain I was using the correct maps and sets to get the correct fields and to verify that OwnerId's in the maps were references to User Ids (they were, thus the reason I included the code they came from and not just the definitions).

I've tried using the code that follows and still get a compiler error message that says: Compile Error: Initial term of field expression must be a concrete SObject: LIST at line 531 column 23 (start of OppsOldOwnrs) which happens regardless of whether I remove OppsOldOwnrs or not! :(

    list<Opportunity>OppsNewOwnrs = new list<Opportunity>();        
    list<Opportunity>OppsOldOwnrs = new list<Opportunity>();
    OppsOldOwnrs = [SELECT Id, OwnerID FROM Opportunity WHERE OwnerID =: OldOwnrIds AND Id =: OppIds]; 
    for(Opportunity o:OppsOldOwnrs){

        o.OwnerID= *OppsOldOwnrs*.OldOwnr2NewOwnrIds.get(OppsOldOwnrs.OwnerID);

        OppsNewOwnrs.add(o);            
    }

    update OppsNewOwnrs;
3
  • In your second code example, are you sure it wasn't complaining that OppsOldOwnrs IS a list, not a concrete SObject? Because the assignment should be against o.OwnerId (a single member of the list), not OppsOldOwnrs.OwnerId (the list itself).
    – jkraybill
    Jun 22 '13 at 2:01
  • Just checked again. For that one I got the following: Compile Error: Initial term of field expression must be a concrete SObject: LIST<Opportunity>... I've been working such long hours, that I figured I must be overlooking something really simple, like needing to loop a list against another list, but that didn't pan out either! I'm honestly brain dead from working too many long hours this week. :( BTW, I had tried the reverse, but couldn't get the record Id to xfer. Do I need to do a clone operation of some kind?
    – crmprogdev
    Jun 22 '13 at 4:29
  • 1
    That confusingly worded compile error means that you are trying to do an SObject operation against what is actually a List of SObjects. This line: OppsOldOwnrs.OwnerID=OpId2NewOwnrId.get(o.Id) ; should be: o.OwnerID=OpId2NewOwnrId.get(o.Id) ;
    – jkraybill
    Jun 22 '13 at 4:55
0

EDIT: It turns out the root cause of my problem was in creating the 2nd batch of users. My copy-paste of code didn't get completely edited, causing those users not to get inserted during the testing.

Even after fixing the glaringly obvious to where it appeared they were being inserted, unfortunately they all still had the same set of aliases which I suspect was either causing their ID's to merge or else for them to be deleted through system validation rules (didn't see it in the logs).

In any case, the Id error message, wasn't about the Opp Id, but instead about the User Id, which totally threw me off track!

Thanks @jkraybill for the help!

Here's the solution:

    list<Opportunity>OppsNewOwnrs = new list<Opportunity>();        
    list<Opportunity>OppsOldOwnrs = new list<Opportunity>();

    OppsOldOwnrs = [SELECT Id, OwnerID FROM Opportunity WHERE OwnerID =: OldOwnrIds AND Id =: OppIds]; 

    for(Opportunity o:OppsOldOwnrs){

        o.OwnerID= OldOwnr2NewOwnrIds.get(o.OwnerID);

        OppsNewOwnrs.add(o);            
    }

    update OppsNewOwnrs;

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.