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

Initial term of field expression must be a concrete SObject
I'm hitting the error that Initial term of field expression must be a concrete SObject: LIST<UserTerritory> at line 8 column 79 in my Test class. I'm trying to call the list but apparently I'm doing something wrong. Can someone please help me get the Territory ID out of the list of TerritoryUsers?
Thanks so much,
Amanda
@IsTest(SeeAllData=true)
public class TestOpportunityTerritory {
static testMethod void testOpportunityTerritory() {
user u = [select id from User where name = 'Will Culbertson'];
List <UserTerritory> ut = [Select ut.UserId, ut.TerritoryId From UserTerritory ut Where ut.userId =:u.Id];
List <Territory> t = [select t.id, t.name from Territory t where t.id IN :ut.territoryid];
Account a = new Account(Name='Test Account');
insert a;
test.startTest();
System.RunAs(u){
//Perform the dml action on which trigger gets fired , like insert, update ,delete , undelete, in your case you have to update the opportunity record that you created in above
Opportunity o = new Opportunity(Name='Test Opportunity',closedate=system.today(), stagename='Prospecting', AccountID=a.id, ownerid=u.id);
insert o;
test.stopTest();
for(Opportunity opp:[SELECT Territoryid FROM Opportunity
WHERE CreatedDate = TODAY
and CreatedById = :u.id])
System.assertEquals(ut.TerritoryID, opp.territoryid);
}
}
}
Thanks so much,
Amanda
@IsTest(SeeAllData=true)
public class TestOpportunityTerritory {
static testMethod void testOpportunityTerritory() {
user u = [select id from User where name = 'Will Culbertson'];
List <UserTerritory> ut = [Select ut.UserId, ut.TerritoryId From UserTerritory ut Where ut.userId =:u.Id];
List <Territory> t = [select t.id, t.name from Territory t where t.id IN :ut.territoryid];
Account a = new Account(Name='Test Account');
insert a;
test.startTest();
System.RunAs(u){
//Perform the dml action on which trigger gets fired , like insert, update ,delete , undelete, in your case you have to update the opportunity record that you created in above
Opportunity o = new Opportunity(Name='Test Opportunity',closedate=system.today(), stagename='Prospecting', AccountID=a.id, ownerid=u.id);
insert o;
test.stopTest();
for(Opportunity opp:[SELECT Territoryid FROM Opportunity
WHERE CreatedDate = TODAY
and CreatedById = :u.id])
System.assertEquals(ut.TerritoryID, opp.territoryid);
}
}
}
All Answers
List <Territory> t = [select t.id, t.name from Territory t where t.id IN :ut.territoryid];
ut is a list of UserTerritories, but you are treating it like a single instance. If you are expecting a single instance in the list, you can simply specify to use the first element in the list:
List <Territory> t = [select t.id, t.name from Territory t where t.id IN :ut[0].territoryid];
Thanks. To give some more details I had originally tried creating the user and territories and user territories from scratch but the user territory does not allow dml actions so I have to pull an existing user. They may have multiple territories so I want to sort by territory name and limit to just the last territory in the list. I couldn't get the UserTerritory to give me Territory names in order to sort by them so I was then trying to list the territories based on the ones in the UserTerritory List. So how do I get the Territory list to show all the territories in the UserTerritory list? Or is there a simpler way to do this? Instead of grabbing a specific user I could tell it to pick a user with one territory but that seems even more complicated than what I'm already struggling with. What do you think? Ideally it shouldn't grab a specific user but I'm not even sure how to tell it to find the territories for the user territories I already have nevermind trying to say something like "get a random user with just one territory". Any advice or direction would be greatly appreciated.
Thanks so much,
Amanda
Thanks,
Amanda
trigger OpportunityTerritoryUpdate on Opportunity (before insert, before update)
// map tracks records on OpportunityID
{
Map<String, Opportunity> OpportunityMap = new Map<String, Opportunity>();
{
for (Opportunity opp : Trigger.new)
{
if( opp.TerritoryId == null)
{
OpportunityMap.put( opp.ownerID, opp );
}
if( OpportunityMap.keySet().size() > 0 ) // if there are no eligible Opportunity records, end
{
//map to keep track of the opportunity owner
Map<Id,UserTerritory> UserTerritoryCurrentUserMap = new Map<Id,UserTerritory>();
List<User> UpdateDemo = new List<User>();
//select User for the opportunities with territory required
for(UserTerritory ut : [Select UserId, TerritoryId, IsActive, Id From UserTerritory Where isActive=true and userId in :OpportunityMap.keySet() ])
{
opp.TerritoryId = ut.territoryID;
}
}
}}}
I'm not sure what doesn't work means, but in the final loop, if the user has three territories, you will iterate through all three of those territories, applying each of them in turn before the trigger finishes and the last value sticks. The value could well change for the same user in different executions, as the order that records are returned from the database depends on a number of variables.
Thanks,
Amanda
trigger OpportunityTerritoryUpdate on Opportunity (after insert, after update)
{
List <Opportunity> opportunities = [select Id, Name, OwnerID, Territoryid from Opportunity where ID IN :Trigger.newMap.keySet()];
Set<Id> OppOwnerIds=new Set<Id>();
for (Opportunity oppid : opportunities)
{
OppOwnerIds.add(oppid.ownerid);
}
// now query back the territory records matching the ids in the set
List <UserTerritory> ut = [select userid, territoryId from UserTerritory where isActive=true and userid IN :oppownerIds];
List<Opportunity> UpdateTerritory = new List<Opportunity>{};
for(Opportunity opp : opportunities)
{
if( opp.TerritoryId == null)
{
opp.TerritoryId = ut.territoryID;
UpdateTerritory.add(opp);
}
}
// setup the save point for rollback
Savepoint sp = Database.setSavepoint();
update UpdateTerritory;
}
trigger OpportunityTerritoryUpdate on Opportunity (after insert, after update)
// map tracks records on OpportunityID
{
List <Opportunity> opportunities = [select Id, Name, OwnerID, Territoryid from Opportunity where ID IN :Trigger.newMap.keySet()];
List<Opportunity> UpdateTerritory = new List<Opportunity>{};
for(Opportunity opp : opportunities)
{
if( opp.TerritoryId == null)
{
//select User for the opportunities with territory required
for(UserTerritory ut : [Select UserId, TerritoryId, IsActive, Id From UserTerritory Where isActive=true and userId = :opp.Ownerid limit 1])
{
opp.TerritoryId = ut.territoryID;
UpdateTerritory.add(opp);
}
}
}
// setup the save point for rollback
Savepoint sp = Database.setSavepoint();
update UpdateTerritory;
}
@IsTest(SeeAllData=true)
public class TestOpportunityTerritory {
static testMethod void testOpportunityTerritory() {
List <UserTerritory> ut = [Select ut.UserId, ut.TerritoryId From UserTerritory ut Where ut.isActive=true Limit 1];
user u = [select id from User where id = :ut[0].userid];
// build the set of territory ids
Set<Id> terrIds=new Set<Id>();
for (UserTerritory uTerr : ut)
{
terrIds.add(uTerr.TerritoryId);
}
// now query back the territory records matching the ids in the set
List <Territory> t = [select t.id, t.name from Territory t where t.id IN :terrIds order by t.name ASC];
Account a = new Account(Name='Test Account', Industry='Other');
insert a;
test.startTest();
System.RunAs(u){
//Perform the dml action on which trigger gets fired , like insert, update ,delete , undelete, in your case you have to update the opportunity record that you created in above
Opportunity o = new Opportunity(Name='Test Opportunity Territory',closedate=system.today()+30, stagename='Prospecting', AccountID=a.id, ownerid=u.id);
insert o;
test.stopTest();
for(Opportunity opp:[SELECT Territoryid FROM Opportunity
WHERE CreatedDate = TODAY
and Name = 'Test Opportunity Territory'
and CreatedById = :u.id])
System.assertEquals(t[0].ID, opp.territoryid);
}
}
}