+ Start a Discussion
Joe HayesJoe Hayes 

Simple trigger to run a controller and update fields

Hi Everyone,

I am just writing a very simple trigger but have got stuck with it.

It needs to evaluate 3 fields on a custom object called course_sale__c and then run a controller, after the controller has ran it needs to then update the field has_confirmation_been_sent__c to True.
 
trigger SendTrainingConfirmationTrigger on Course_Sale__c (after insert, after update) {
  
    for (Course_Sale__c cs : Trigger.new) {
      if (cs.AttachmentId__c != null) && (cs.Send_Confirmation_Automatically__c == True) && (cs.has_confirmation_been_sent__c == FALSE)
      {
            ApexPages.StandardController sc = new ApexPages.StandardController(cs);
			TrainingConfirmationSend obj = new TrainingConfirmationSend(sc);

			obj.emailAtt();
          
            cs.has_confirmation_been_sent__c = true;
      }    
    }
}

Thanks for your help,

Joe

 
Best Answer chosen by Joe Hayes
Neetu_BansalNeetu_Bansal
Hi Joe,

Triggers are synchronous, so in below code the trigger will not wait for the controller to run and will immediately update the field. Do you want the trigger for controller code to run, if not, you need to update the field in controller itself.
trigger SendTrainingConfirmationTrigger on Course_Sale__c( before insert, before update )
{
	for( Course_Sale__c cs : trigger.new )
	{
		if( cs.AttachmentId__c != null && cs.Send_Confirmation_Automatically__c && !cs.has_confirmation_been_sent__c )
		{
            ApexPages.StandardController sc = new ApexPages.StandardController( cs );
			TrainingConfirmationSend obj = new TrainingConfirmationSend( sc );
			obj.emailAtt();
          
            cs.has_confirmation_been_sent__c = true;
		}    
    }
}
Let me know if this helps you.

All Answers

Neetu_BansalNeetu_Bansal
Hi Joe,

Triggers are synchronous, so in below code the trigger will not wait for the controller to run and will immediately update the field. Do you want the trigger for controller code to run, if not, you need to update the field in controller itself.
trigger SendTrainingConfirmationTrigger on Course_Sale__c( before insert, before update )
{
	for( Course_Sale__c cs : trigger.new )
	{
		if( cs.AttachmentId__c != null && cs.Send_Confirmation_Automatically__c && !cs.has_confirmation_been_sent__c )
		{
            ApexPages.StandardController sc = new ApexPages.StandardController( cs );
			TrainingConfirmationSend obj = new TrainingConfirmationSend( sc );
			obj.emailAtt();
          
            cs.has_confirmation_been_sent__c = true;
		}    
    }
}
Let me know if this helps you.
This was selected as the best answer
Joe HayesJoe Hayes
Hi Neetu,

Thanks for the reply, I dont think it does need to wait for the controller no, it can just update the field and let the controller run.

The updated code you have given me works brilliantly thank you for your help.

Cheers
Joe
 
Siddharth83JainSiddharth83Jain
Hi Joe,

I can see the issue, you cannot update the same record with in the loop incase or AFTER trigger event. Break the currect scope of the record by placing that into a new collection of Course Sale and then update that. But be sure to stop the recurrsion since this is an AFTER scenario.

If this helps then please mark this as a Selected Answer.

Thanks
Siddharth
OSI Consulting
 
Joe HayesJoe Hayes
Hi Siddharth,

Thanks for the reply, that does make sense. I was wondering if that would cause an issue,
Would you be able to give me an example of how I would write that? I'm a little stuck with it.

Thanks
Joe
Neetu_BansalNeetu_Bansal
Hi Joe,

I have already updated the events to before in my tirgger. You can see the code I provided.

Thanks,
Netu
Siddharth83JainSiddharth83Jain
Hi Joe,

See below

trigger SendTrainingConfirmationTrigger on Course_Sale__c( before insert, before update )
{
    if (!TrainingConfirmationSend.trainingTriggerExecuted)
    {    
        TrainingConfirmationSend.trainingTriggerExecuted = true;
        List<Course_Sale__c> lstCS = new List<Course_Sale__c>();
        
        for( Course_Sale__c cs : trigger.new )
        {
            if( cs.AttachmentId__c != null && cs.Send_Confirmation_Automatically__c && !cs.has_confirmation_been_sent__c )
            {
                ApexPages.StandardController sc = new ApexPages.StandardController( cs );
                TrainingConfirmationSend obj = new TrainingConfirmationSend( sc );
                obj.emailAtt();
                
                Course_Sale__c csTemp = new Course_Sale__c(id = cs.Id, has_confirmation_been_sent__c = true);
                lstCS.add(csTemp);
            }    
        }
    
        if (lstCS.size()>0)
            update lstCS;
    }
}

//Define this in your controller if need be to stop recursive action on trigger.
public static trainingTriggerExecuted {get;set;}

If possible move your controller call out out of the trigger. Just for example if you are sending emails from within the controller method then in case of bulk requests it would fail. Let me know if you need any further help here.

Thanks
Siddharth
OSI Consulting