function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
AdamSBealAdamSBeal 

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

Best Answer chosen by Admin (Salesforce Developers) 
vishal@forcevishal@force

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.

 

trigger SetContractOnOpportunity on Opportunity (before insert) 
{ 
  Map<Id, Opportunity> opportunityMap = new Map<Id, Opportunity>();
Set<Id> setRelatedAccountIds = new Set<Id>();
Map<Id, String> mapAccountToOrderContract = new Map<Id, String>(); RecordType rt = [select Id from RecordType where Name = 'Order' and SobjectType = 'Opportunity' limit 1];

// CAPTURE ALL THE RELATED ACCOUNT IDS
for(Opportunity o : Trigger.new)
{
setRelatedAccountIds.add(o.AccountId);
}

for(Account a : [Select Id, Order_Contract__c From Account Where Id IN : setRelatedAccountIds]) {
mapAccountToOrderContract.put(a.Id, a.Order_Contract__c);
} for (Opportunity opportunity : Trigger.new) { if (opportunity.RecordType == rt && opportunity.Order_Contract__c != Trigger.oldMap.get(opportunity.Id).Order_Contract__c) { opportunity.Order_Contract__c = mapAccountToOrderContract.get(opportunity.AccountId);
} } }

All Answers

AdamSBealAdamSBeal

Looking a bit more I am wondering if I can simplyfy things like this somehow:

 

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 opportunity : Trigger.new)
  {  
    if (opportunity.RecordType == rt && opportunity.Order_Contract__c != Trigger.oldMap.get(opportunity.Id).Order_Contract__c)
{
      opportunity.Order_Contract__c = opportunity.Account.Order_Contract__c;
update opportunity } } }

 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.

AdamSBealAdamSBeal

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.

vishal@forcevishal@force

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.

 

trigger SetContractOnOpportunity on Opportunity (before insert) 
{ 
  Map<Id, Opportunity> opportunityMap = new Map<Id, Opportunity>();
Set<Id> setRelatedAccountIds = new Set<Id>();
Map<Id, String> mapAccountToOrderContract = new Map<Id, String>(); RecordType rt = [select Id from RecordType where Name = 'Order' and SobjectType = 'Opportunity' limit 1];

// CAPTURE ALL THE RELATED ACCOUNT IDS
for(Opportunity o : Trigger.new)
{
setRelatedAccountIds.add(o.AccountId);
}

for(Account a : [Select Id, Order_Contract__c From Account Where Id IN : setRelatedAccountIds]) {
mapAccountToOrderContract.put(a.Id, a.Order_Contract__c);
} for (Opportunity opportunity : Trigger.new) { if (opportunity.RecordType == rt && opportunity.Order_Contract__c != Trigger.oldMap.get(opportunity.Id).Order_Contract__c) { opportunity.Order_Contract__c = mapAccountToOrderContract.get(opportunity.AccountId);
} } }
This was selected as the best answer
AdamSBealAdamSBeal

Thanks vishal you were right about the loop. I thought that would be the case thanks for the helpful code also. 

 

Adam