You need to sign in to do that
Don't have an account?
Help with trigger
I'm having trouble with a trigger I'm trying to write. When new accounts are loaded into my org the owner field is sometimes defaulted to a placeholder user 'x x'. There is another field on the account called market assignment which is a forumula that pulls the market assignment on the market assignment custom object. Also on the market assignement custom object is the manager which should also be the account owner. The trigger is trying to update accounts where owner = 'x x' with the manager from the corresponding market assignement. Any help would be much appreciated. Thanks!!
Trigger
Trigger marketassignmenttrigger on Account (before Insert, before Update) { Map<String, Market_Assignments__c> junctionMap = new Map<String, Market_Assignments__c>{}; for (Account a : Trigger.new) { if (a.owner != null && (Trigger.isInsert || (Trigger.isUpdate && Trigger.oldMap.get(a.id).Market_assignment_copy__c == a.Market_assignment_copy__c))) { //Ignore casing in the map junctionMap.put(a.Market_assignment_copy__c.toLowerCase(), null); } } if (!junctionMap.isEmpty()) { for (Market_Assignments__c item : [ select Id, market_manager__c, name from Market_Assignments__c where market_manager__c IN :junctionMap.keySet()] ) { junctionMap.put(item.name.toLowerCase(), item); } for (Account a : Trigger.new) { if (a.ownerid == '00560000001267d') { Market_Assignments__c m = junctionMap.get(a.market_assignment_copy__c.toLowerCase()); { a.ownerid = m.market_manager__c; } } } } }
Megan,
I guess the trigger had been very geared towards updates. I think the following changes should help with the Inserts.
Just add the following line in bold wherever you have the first line (should be two places like that)
Account a1 = accountsMap.get(a.id);
if (a1 == null) a1 = a;
Ram
for (Account a : Trigger.new)
{
if (a.ownerid != null && Trigger.isInsert) {
junctionMap.put(a.Market_assignment_copy__c, null);
System.debug(' market assignment = ' + a.Market_assignment_copy__c);
System.debug('a.ownerid:' + a.ownerid);
}
else
if (a1.ownerid != null &&
(Trigger.isInsert || (Trigger.isUpdate && Trigger.oldMap.get(a.id).Market_assignment_copy__c == a1.Market_assignment_copy__c))) */
{
//Ignore casing in the map
junctionMap.put(a1.Market_assignment_copy__c, null);
System.debug(' market assignment = ' + a1.Market_assignment_copy__c);
System.debug('a1.ownerid:' + a1.ownerid);
}
}
All Answers
I'm not getting an error, but it's not changing the owner
Thanks!
I suspect you're not getting the owner id on the trigger and may have to fetch it explicitly. You may want to put a debug statement to see what Ids you get for owner.
ok thanks! I'll try to figure it out.
Try something like this:
if (a.ownerid != null && a.ownerid.startsWith( '00560000001267d'))
Thanks!
When I try that I get Error: Compile Error: Method does not exist or incorrect signature: [Id].startsWith(String) at line 25 column 36.
I also tried
(a.owner = 'x x);
{
Market_Assignments__c m = junctionMap.get(a.market_assignment_copy__c.toLowerCase());
{
a.owner = m.market_manager__c;
but when I do that I get this error
Illegal assignment from String to SOBJECT:User at line 25 column 15
May be you can assign it to a string before doing the test:
String ownerIdStr = a.ownerid;
if (ownerIdStr != null && ownerIdStr.startsWith( '00560000001267d'))
Thanks. I can see in the debug logs that the trigger is firing but it's still not changing anything.
You may want to put a debug to print the owner id both before the if statement and also within the if - just to make sure the match is occurring based on owner id.
Thank you. I'm pretty new to this, would the way I added the debug below be correct?
This is what I'm getting from the debug logs
I suspect the condition Trigger.oldMap.get(a.id).Market_assignment_copy__c == a.Market_assignment_copy__c
is not occurring. Is it the right conditon to check for? Perhaps you an disable that condition for now and see if it goes into the code that it's not hitting.
Maybe I'm making this too complicated. I can add a formula fied that pulls the correct manager from the market object but then I need that value to beocme the owner, which is where I'm struggeling.
Thanks. I wanted to use a workflow but the field I need to update is a lookup so I can't use a formula. Is that correct?
I don't know offhand whether that's not allowed. But it should be easy enough to create a workflow and see if you can use your formula. Is the owner coming thru' on the trigger?
No the owner isn't coming through on the trigger. And a workflow won't work becuase of the lookup field.
ok. Give the following a try. This is mostly oriented towards an Update rather than an Insert. I suspect you will not need the trigger on an Insert - but can address it once the Update works correcty.
Trigger marketassignmenttrigger on Account (before Insert, before Update) {
Map<String, Market_Assignments__c> junctionMap = new Map<String, Market_Assignments__c>{};
List<Id> accountIds = new List<Id>();
for (Account a : Trigger.new)
{
accountIds.add(a.id);
}
List<Account> accounts = [select id, ownerId, Market_assignment_copy__c from Account where id in :accountIds];
Map<Id, Account> accountsMap = new Map<Id, Account>();
for (Account a : accounts)
{
accountsMap.put(a.id, a);
}
for (Account a : Trigger.new)
{
Account a1 = accountsMap.get(a.id);
System.debug('a1.owner = ' + a1.owner + ' a1.ownerid:' + a1.ownerid);
if (a1.owner != null &&
(Trigger.isInsert || (Trigger.isUpdate && Trigger.oldMap.get(a.id).Market_assignment_copy__c == a1.Market_assignment_copy__c))) */
{
//Ignore casing in the map
junctionMap.put(a.Market_assignment_copy__c.toLowerCase(), null);
System.debug('a.ownerid:' + a.ownerid);
}
}
if (!junctionMap.isEmpty())
{
for (Market_Assignments__c item : [ select Id, market_manager__c, name from Market_Assignments__c where market_manager__c IN :junctionMap.keySet()] )
{
junctionMap.put(item.name.toLowerCase(), item);
}
for (Account a : Trigger.new)
{
Account a1 = accountsMap.get(a.id);
String ownerIdStr = a1.ownerid;
if (ownerIdStr != null && ownerIdStr.startsWith( '00560000001267d'))
{
System.debug('a1.ownerid:' + a1.ownerid);
Market_Assignments__c m = junctionMap.get(a1.market_assignment_copy__c.toLowerCase());
{
a.ownerid = m.market_manager__c;
}
}
}
}
}
One minor change:
if (a1.ownerid != null
instead of
if (a1.owner != null
Thank you so much! I put that in and then got this error when I tried to update an account.
Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger marketassignmenttrigger caused an unexpected exception, contact your administrator: marketassignmenttrigger: execution of BeforeUpdate caused by: System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Account.Owner: Trigger.marketassignmenttrigger: line 18, column 1
Megan,
Change this:
System.debug('a1.owner = ' + a1.owner + ' a1.ownerid:' + a1.ownerid);
to this:
System.debug(' a1.ownerid:' + a1.ownerid);
Thanks, I made the change and am getting this error.
Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger marketassignmenttrigger caused an unexpected exception, contact your administrator: marketassignmenttrigger: execution of BeforeUpdate caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.marketassignmenttrigger: line 49, column 1
I think you're dealing with a null object for m:
Market_Assignments__c m = junctionMap.get(a1.market_assignment_copy__c.toLowerCase());
// add this check
if (m != null)
{
a.ownerid = m.market_manager__c;
}
You may want to put a debug in your for statement earlier and make sure you're loading your map correctly:
for (Market_Assignments__c item : [ select Id, market_manager__c, name from Market_Assignments__c where market_manager__c IN :junctionMap.keySet()] )
{
System.debug(' item name ' + item.name.toLowerCase());
junctionMap.put(item.name.toLowerCase(), item);
}
Ram
Thank you very much. I'm not getting any errors, but when I update the account the owner is still not changing.
Try copying this and running it. You'll need to resort to looking at the debug logs to see what is happening. I've highlighted the portions of the code you'll need to focus on and tweak if needed:
Trigger marketassignmenttrigger on Account (before Insert, before Update) {
Map<String, Market_Assignments__c> junctionMap = new Map<String, Market_Assignments__c>{};
List<Id> accountIds = new List<Id>();
for (Account a : Trigger.new)
{
accountIds.add(a.id);
}
List<Account> accounts = [select id, ownerId, Market_assignment_copy__c from Account where id in :accountIds];
Map<Id, Account> accountsMap = new Map<Id, Account>();
for (Account a : accounts)
{
accountsMap.put(a.id, a);
}
for (Account a : Trigger.new)
{
Account a1 = accountsMap.get(a.id);
System.debug('a1.owner = ' + a1.owner + ' a1.ownerid:' + a1.ownerid);
if (a1.ownerid != null &&
(Trigger.isInsert || (Trigger.isUpdate && Trigger.oldMap.get(a.id).Market_assignment_copy__c == a1.Market_assignment_copy__c))) */
{
//Ignore casing in the map
junctionMap.put(a1.Market_assignment_copy__c.toLowerCase(), null);
// do we see anything in the logs?
System.debug('a1.ownerid:' + a1.ownerid);
}
}
if (!junctionMap.isEmpty())
{
for (Market_Assignments__c item : [ select Id, market_manager__c, name from Market_Assignments__c where market_manager__c IN :junctionMap.keySet()] )
{
// do we see anything in the logs?
System.debug('item name:' + item.name.toLowerCase());
junctionMap.put(item.name.toLowerCase(), item);
}
for (Account a : Trigger.new)
{
Account a1 = accountsMap.get(a.id);
String ownerIdStr = a1.ownerid;
if (ownerIdStr != null && ownerIdStr.startsWith( '00560000001267d'))
{
System.debug('a1.ownerid:' + a1.ownerid);
Market_Assignments__c m = junctionMap.get(a1.market_assignment_copy__c.toLowerCase());
if (m != null)
{
a.ownerid = m.market_manager__c;
}
}
}
}
}
Below is the debug log. I think the problem that when it's querying the market assignments its not bringing anything back but I'm not sure why.
Try printing the market assignment value and see if that is as it should be. Since you are converting to lower case, perhaps you may not be getting a match (SOQL typically ignores case but just to make sure). Use the code below:
Trigger marketassignmenttrigger on Account (before Insert, before Update) {
Map<String, Market_Assignments__c> junctionMap = new Map<String, Market_Assignments__c>{};
List<Id> accountIds = new List<Id>();
for (Account a : Trigger.new)
{
accountIds.add(a.id);
}
List<Account> accounts = [select id, ownerId, Market_assignment_copy__c from Account where id in :accountIds];
Map<Id, Account> accountsMap = new Map<Id, Account>();
for (Account a : accounts)
{
accountsMap.put(a.id, a);
}
for (Account a : Trigger.new)
{
Account a1 = accountsMap.get(a.id);
System.debug('a1.owner = ' + a1.owner + ' a1.ownerid:' + a1.ownerid);
if (a1.ownerid != null &&
(Trigger.isInsert || (Trigger.isUpdate && Trigger.oldMap.get(a.id).Market_assignment_copy__c == a1.Market_assignment_copy__c))) */
{
//Ignore casing in the map
junctionMap.put(a1.Market_assignment_copy__c.toLowerCase(), null);
System.debug(' market assignment = ' + a1.Market_assignment_copy__c.toLowerCase());
System.debug('a1.ownerid:' + a1.ownerid);
}
}
if (!junctionMap.isEmpty())
{
for (Market_Assignments__c item : [ select Id, market_manager__c, name from Market_Assignments__c where market_manager__c IN :junctionMap.keySet()] )
{
System.debug('item name:' + item.name.toLowerCase());
junctionMap.put(item.name.toLowerCase(), item);
}
for (Account a : Trigger.new)
{
Account a1 = accountsMap.get(a.id);
String ownerIdStr = a1.ownerid;
if (ownerIdStr != null && ownerIdStr.startsWith( '00560000001267d'))
{
System.debug('matched default owner - a1.ownerid:' + a1.ownerid);
Market_Assignments__c m = junctionMap.get(a1.market_assignment_copy__c.toLowerCase());
if (m != null)
{
a.ownerid = m.market_manager__c;
}
}
}
}
}
It's grabbing the correct market assignment. I don't know why I set it to lower case. I dont' think I needed to do that. Can I just remove everywhere it has it as lower case?
Yep - you can try removing the lower case altogether and see if it makes a difference.
I removed it and am getting the same result.
Megan,
I suspect you're not querying with the right selection criteria:
Your junction map key is Market_assignment_copy__c - is this the same value as market_manager__c in Market_Assignments__c ?
Is hanoi the name of a marketing manager? I suspect you're comparing this with market_manager__c which I'm guessing is an id. If that is the case, your query below needs to change so that it is grabbing the right value to compare (perhaps market_manager__r.Name?)
for (Market_Assignments__c item : [ select Id, market_manager__c, name from Market_Assignments__c where market_manager__c IN :junctionMap.keySet()] )
Market_assignment_copy__c in accounts would be the same as the name in the market assignement object
Market_Manager__c in market assignments is a lookup of the user and the value I want to populate in the owner field.
Should I be looking up the name in the query?
Yep - try this:
for (Market_Assignments__c item :
[ select Id, market_manager__c, name from Market_Assignments__c where Name IN :junctionMap.keySet()] )
Still nothing : ( I'm sorry this is so frustrating, thank you for your help! This is what I'm working with now
I think you should leave the debug statements in there so that you can see what's happening. Actually, I see you commented out the line that was putting these items into junctionMap and that is probably why it's not working. I was just saying you should remove the .toLowerCase call, not the entire lines.
Thank you. It's still not working but the debug statements look right. It's pulling the correct value for market but the owner is not changing. Is the problem where it says [29]|MAP<String,Market_Assignments__c>.isEmpty()?
Yea, I figured that was it. It's chaning the Owner now, but capturing the wrong market and therefore changing it to the wrong owner. The market was Las Vegas but it's capturing Chicago.
"market assignment = Chicago"
Sorry, I know what happened there.
Thank you so much for all your help I really appreciate it!
Ram
Would it be possible for you to take a look at my test class? I can't get the assertion to work becuase I'm comparing id vs name. Any suggestions would be great. Thank you so much!
Megan,
I thought market_manager__c was a lookup to a user. A tad confused with what's going on the test class. You may want to assign the id to a String and see if you can compare two strings.
Ram
It is a lookup to the user.
I'm sorry but I have yet another question!
The trigger is failing when I try to do an insert from the (x, x) user ID. I think it's becuase the market assignment field it looks at is a formula field pulling it from another object and therefore isn't populated yet. Do you have any suggestions on how to fix this?
Thanks
Megan,
I guess the trigger had been very geared towards updates. I think the following changes should help with the Inserts.
Just add the following line in bold wherever you have the first line (should be two places like that)
Account a1 = accountsMap.get(a.id);
if (a1 == null) a1 = a;
Ram
for (Account a : Trigger.new)
{
if (a.ownerid != null && Trigger.isInsert) {
junctionMap.put(a.Market_assignment_copy__c, null);
System.debug(' market assignment = ' + a.Market_assignment_copy__c);
System.debug('a.ownerid:' + a.ownerid);
}
else
if (a1.ownerid != null &&
(Trigger.isInsert || (Trigger.isUpdate && Trigger.oldMap.get(a.id).Market_assignment_copy__c == a1.Market_assignment_copy__c))) */
{
//Ignore casing in the map
junctionMap.put(a1.Market_assignment_copy__c, null);
System.debug(' market assignment = ' + a1.Market_assignment_copy__c);
System.debug('a1.ownerid:' + a1.ownerid);
}
}
Thanks! That worked.
Glad to hear it, Megan!
Ram
Hi Ram,
I'm running into problems with this tirgger and thought that you may be able to help. Some of our makret managers on market assignements are out of date so it's trying to assign the account to an inactive owner and failing.
Where would I add an if statement to check if the user is active?
Megan,
If the assignment fails in the trigger for an inactive user, the easies thing would be to catch the exception and assign a "fall back" owner:
Thanks Ram. I think I should try to cath it more upstream and creat a trigger on the market assignements that checks if the user in market manager field there is active and if not assign it to a default owner. Is that reasonable?
I agree, Megan. I think that's a good strategy.
Ram
Thank you,
I tried doing that, but I keep getting a complile error on line 3 .
Error: Invalid type: market_manager__c at line 3 column 63
Any idea why?
Thanks!
Is market_manager__c of type Id? If I recollect, it is a field storing the id of a user. I don't think it's a type by itself. Try using Id instead.
Ram
market_manager __c is a lookup to the user
Map<string, Id> junctionmap = new Map <string, Id>{};
or
Map<string, User> junctionmap = new Map <string, User>{};
depending on what you want to store in the map value (an id vs a User)
Thank you! I'm getting an error I haven't gotten before when I put that in
Error: Compile Error: Expression cannot be assigned at line -1 column -1
Here's what I changed it to.
Careful with your comparisons. It thinks you're assigning (=) rather than comparing (==)
if(user.isActive = true) should be
if(user.isActive == true)
Hi Ram,
That's what I thought but when I had
if(user.isActive == true) earlier I got this error
Error: Compile Error: Comparison arguments must be compatible types: Schema.SObjectField, Boolean at line 11 column 8
Megan,
You will need to iterate through the List<Users> with a for loop and use a lop variable for user. RIght now you're just jumping right into
If (User.IsActive...)
which it interprets as the standard object User and its field type IsActive
Thank you very much!
The trigger is executing but not changing anything. When I look at the debug logs it looks like its not returning anything in the soql query.
So add something like the following?
Megan,
I'd suggest putting together a simple flow chart or pseudo code so there's understanding of what is being built. Here are some of the steps involved.
Get all record ids from the trigger invocation into a list, recIds. Also load it into a map, trigMap (Id to Marketing_Assignments__c)
Query the object that has the trigger on it (Marketing_Assignments__c) where id is in recIds. Make sure to to get IsActive as part of the query by going against Marketing_Manager__r.IsActive.
Loop through the records from the query checking the user isActive status on each. if user is inactive, fetch the corresponding trigger record from the map and make the change in it.
Hope that helps.
Ram
Thank you. I really appreciate your help, I'm trying to teach myself this and it's not easy : ). The trigger is changing the user every time, not just when the user is not active so I think I'm having a problem looping through all the records and checking the status on each. Below is my code, is that the problem?
Hey Megan,
No worries. Not sure what you mean by "it's changing the user every time". You don't need the following redundant assignment for sure. Change that and see if you still see the same behavior.
Actually, you need to get the full record from the map so you can check the isActive value properly:
minor change:
That didn't work. Whether the user is acitve or not its changing the manager to the default user in the else statement
Yes, I did. Thank you so much. That seemed to do the trick!
Ram
all about Quotes (https://www.100quotes4you.online)
new attitude status (https://www.100quotes4you.online/2020/02/New-attitude-status.html)
New single WhatsApp status (https://www.100quotes4you.online/2020/02/New-single-whatsapp-status.html)
Deep love Quotes (https://www.100quotes4you.online/2020/02/deep-love-quotes-and-status.html)
Benjamin FRANKLIN quotes (https://www.100quotes4you.online/2020/02/benjamin-franklin-quotes.html) by 100quotes4you.online