You need to sign in to do that
Don't have an account?
Trigger loop problem
In the following trigger I am taking the multi-value field named Subsidiaries_On_Contract__c and creating a new child record for each value within it. That is working fine. However, I am attempting to populate the lookup Subsidiaries_and_Brands field which is a lookup to the Subsidiary and Brands object with the name of the corresponding name from Subsdiaries_On_Contract and it is only working for the first new record which is being created each time.
Here is the code. The portion in red is the part which is where I am attempting to somehow use the Map method to to connect the name to the corresponding Subsidiaries and Brands object.
trigger AutoCreateSubsServOnContrOv on Contract_Overview__c (after insert, after update) { List<Subs_Serviced_On_Contract__c> subs = new List<Subs_Serviced_On_Contract__c>(); // get the full list of sub account names for all records being processed by the trigger List<String> subAccNames=new List<String>(); for (Contract_Overview__c newCont : Trigger.New) { if (newCont.Subsidiaries_On_Contract__c != '[]') { // split out the multi-select picklist using a comma delimiter System.debug('Subsidiaries_On_Contract__c ' + newCont.Subsidiaries_On_Contract__c); String temp = newCont.Subsidiaries_On_Contract__c; temp = temp.replace(']',''); temp = temp.replace('[',''); String[] all = temp.split(','); subAccNames.addAll(all); } } // get the ids for all sub accounts and store in a map keyed by name Map<String, Id> subAccIdsByName=new Map<String, Id>(); for (SubsidiariesAndBrands__c subAcc : [select id, Name from SubsidiariesAndBrands__c where Name in :subAccNames]) { subAccIdsByName.put(subAcc.Name, subAcc.id); } System.debug('SubsidiariesAndBrands ************ ' + subAccIdsByName); //For each position processed by the trigger, add a new //Subs_Serviced_On_Contract record for the specified Subsidiaries_On_Contract__c. //Note that Trigger.New is a list of all the new positions //that are being created. for (Contract_Overview__c newContract : Trigger.New) { if (newContract.Subsidiaries_On_Contract__c != '[]') { // split out the multi-select picklist using a comma delimiter System.debug('Subsidiaries_On_Contract__c ' + newContract.Subsidiaries_On_Contract__c); String temp = newContract.Subsidiaries_On_Contract__c; temp = temp.replace(']',''); temp = temp.replace('[',''); String[] all = temp.split(','); for(String subsoncontract: all) { subsoncontract = subsoncontract.normalizeSpace(); //for(String subsoncontract: newContract.Subsidiaries_On_Contract__c.split(',')){ Subs_Serviced_On_Contract__c ssoc = new Subs_Serviced_On_Contract__c( Name = subsoncontract, Contract_Overview__c = newContract.Id, Account__c = newContract.Account__c, Subsidiaries_and_Brands__c = subAccIdsByName.get(subsoncontract), // GET THE SUB ACCOUNT ID BASED ON NAME Contract_and_Sub__c = newContract.Name + '~' + subsoncontract, Contract_Start_Date__c = newContract.Contract_Start_Date__c, Contract_End_Date__c = newContract.Contract_End_Date__c, Logo_Usage_Allowed__c = 'Yes'); subs.add(ssoc); } } } upsert subs Contract_and_Sub__c; }
Since it is only working for the first value I am assuming I somehow have to reposition that portion of the code within the loop which is creating the records and somehow maybe use a Get to retrieve the individual values, but I can't figure out where\how exactly that should be done.
If you can give me any input I was love it.
Thank you very much.
Zoom,
I suspect the split may not be receiving the right delimiter. I'd suggest putting in one more debug for your subAccNames.
All Answers
System.debug('SubsidiariesAndBrands ************ ' + subAccIdsByName);
displaying the expected data?
Hi,
In the following line of code in your code is not inserting at all. you want to create subsidiariesand Brands too.
"Is this statement:
System.debug('SubsidiariesAndBrands ************ ' + subAccIdsByName);
displaying the expected data?"
No. I guess that's incorrect.
Thank you
Jake,
No, that's not true. All of the values in the Subsidiaries_On_Contract__c field have a corresponding profile. (object name SubsidiariesAndBrands__c). I know this to be true because a query populated the Subsidiaries_On_Contract__c field in the parent object Contract_Overview__c by pulling the names of all the SubsidiaryAndBrands__c records under the Account in the contract.
Just ignore that line SKA pointed out. It wasn't doing anything. I took it out. It shouldn't have been in there in the first place. Sorry for the confusion.
Thanks for the insight.
Here is a quick rundown of the data model if this will help :
Contract_Overview_c (parent object with following fields) - Account_c (main account for contract)
Subsidiaries_On_Contract__c (multi-value field showing all of the companies which are subsidiaries to Account which are on this particular contract. This trigger is automatically creating a new Subs_Serviced_On_Contract__c child record for each value in this field)
the rest of the fields are not important in the functioning of this trigger
Subs_Serviced_On_Contract__c (child object to Contract_Overview__c. The trigger creates a new one of these for every value in the above named field.
SubsidiariesandBrands__c (Subsidiary profile object. Object I am attempting to link to with the Subsidiaries_and_Brands__c field in the Subs_Serviced_On_Contract__c)
Thank you.
Zoom,
Puzzling, indeed. May need a couple of debug statements to see what you have in the map and what is being received on the .get
Subsidiaries_and_Brands__c = subAccIdsByName.get(subsoncontract),
Hi Zoom,
Can you try this code. I hope this will solve.
If that is true then your method of splitting the data must have issues. I would place a debug statement for string[] all and see if the data that is getting into that array matches the data in your object.
Thanks for the insight Ram.
I know this much after putting a bunch of debugs into the code :
The FOR loop is only passing through once. I only get one value for subAcc.Name (which is properly showing the Name and ID of the Account.). This is odd because subAccNames has 3 account names in it, but the query which uses it to look up the ID's only runs once.
So, because of that, subAccIdsByName only has values for one account (Name and ID).
So at the end when the values are being plugged into fields Subsidiaries_and_ Brands__c is only being populated for the first account because there are no other id's.
So, for some reason that query is only running once. Any ideas on what that's all about ?
Thanks Ram.
Zoom,
I suspect the split may not be receiving the right delimiter. I'd suggest putting in one more debug for your subAccNames.
Anusha,
Thank you very much for the code !
However, I'm getting an 'unexpected token =' error on the query line :
I couldn't really understand the whole query so I didn't really know what needed to be done.
Thanks again. I really appreciate you taking the time.
Zoom,
This is the relationship query between Contract_Overview__c and Subs_Serviced_On_Contract__c. use this query you can get all the child records corresponding to parent record.
You can replace Subs_Serviced_On_Contracts__r (because i dont know exact name relationshipname) in below query with child relationship name . This name you can see on detail page of the look up field on Subs_Serviced_On_Contract__c
for(Contract_Overview__c co : [Select Id, (Select Name,Contract_Overview__c,Account__c,Subsidiaries_and_Brands__c ,Contract_and_Sub__c,Contract_Start_Date__c , Contract_End_Date__c,logo_Usage_Allowed__c from Subs_Serviced_On_Contracts__r) from Contract_Overview__c where id in :contractMap.keySet()])
Ram,
I think you may have just figured out the problem with that. There is a space being left in front of the account names (acctName) from the 2nd value on.
So basically I'm now trying to figure out where to put a normalizeSpace(). In your debug acctName.normalizeSpace() works of course - but I can't figure out where to put it in the actual code. It won't work to use it on temp.
Thanks again Ram.
Ska,
There's a problem with subsoncontract. I'm getting an error saying it doesn't exist. It's coming from this line :
I think it's because it doesn't get identified until down here :
Thank you very much SKA.
Zoom,
Just do this:
Ram,
Doing that gave this error when I was creating a new record :
"nsert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, AutoCreateSubsServOnContrOv: execution of AfterInsert
caused by: System.FinalException: Cannot modify a collection while it is being iterated."
Thanks again.
Zoom,
Interesting. Just want to make sure you changed the iteration collection to "all" rather than "subAccNames" as it was before. If you did and still got the error, I would suggest trying this below (use a temp var).
It worked !
wow - that was a really stupid mistake on my part. I'm really really sorry about that. I'm gonna blame it on being late in the day and being tired.
Thank you so much Ram. You're awesome.
Ram