You need to sign in to do that
Don't have an account?
Trigger Help Please
This is my first trigger and I am struggling with it. I have a "OrderContract" custom object and it is attached to Account via a lookup field. I have a trigger on Opportunity that when a new opportunity is inserted if the record type is "Order" then it should do a lookup on the related account and get the OrderContract and populate that value into the related OrderContract field in the Opportunity. Here is the code when I try to save it gives me this compile error:
unexpected token: 'opportunityMap.get' at line 18 column 103
trigger SetContractOnOpportunity on Opportunity (after insert) { Map<Id, Opportunity> opportunityMap = new Map<Id, Opportunity>(); RecordType rt = [select Id from RecordType where Name = 'Order' and SobjectType = 'Opportunity' limit 1]; for (Opportunity oppNew : Trigger.new) { if (oppNew.RecordType == rt && oppNew.Order_Contract__c != Trigger.oldMap.get(oppNew.Id).Order_Contract__c) opportunityMap.put(oppNew.Id, oppNew); } if (opportunityMap.size() > 0) { for (Opportunity opportunity : opportunityMap) { //pull the Order_Contract__c custom field defined on Account List<Order_Contract__c> contractsList = [SELECT Order_Contract__c FROM Account where Id = opportunityMap.get(opportunity.Id).AccountId]; opportunity.Order_Contract__c = contractsList; } update opportunityMap ; } }
I am new at this so any help with how this trigger is wrong in general would be very much appreciated.
Thanks,
Adam
Hi Adam,
You will be able to get it work correctly as per your last comment, however, you are having a query inside a FOR loop. So if ever you do a bulk insert/update of records, your code will hit governor limits. (too many soql queries).
The reason why you have to explicitly fire a query on Account to get the 'Order_Contracts__c' is because in TRIGGER.NEW list, you have access to only the first level of relationship. So you can access the Opportunity.AccountId, but not Opportunity.Account.Name or any other field on Account.
All Answers
Looking a bit more I am wondering if I can simplyfy things like this somehow:
Still not sure if that would work and if so do I need to call "update" on the opportunity after assigning the Order_Contract__c property on opportunity? I assume so.
Figured it out this line doesn't work:
opportunity.Order_Contract__c = opportunity.Account.Order_Contract__c;
instead I had to do this:
Account account = [Select Order_Contracts__c from Account where Id = :opportunity.AccountId limit 1];
opportunity.Trace_Contracts__c = account.Trace_Contracts__c;
I also changed the event to 'before insert' and I removed the last update line since it wasn't needed.
Hi Adam,
You will be able to get it work correctly as per your last comment, however, you are having a query inside a FOR loop. So if ever you do a bulk insert/update of records, your code will hit governor limits. (too many soql queries).
The reason why you have to explicitly fire a query on Account to get the 'Order_Contracts__c' is because in TRIGGER.NEW list, you have access to only the first level of relationship. So you can access the Opportunity.AccountId, but not Opportunity.Account.Name or any other field on Account.
Thanks vishal you were right about the loop. I thought that would be the case thanks for the helpful code also.
Adam