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
Chris EdwardsChris Edwards 

Where am I going wrong? Trailhead: Bulk Apex Triggers

Hello developer heroes!

I'm working through the Apex modules on Trailhead and can't seem to get past this one: https://developer.salesforce.com/en/trailhead/force_com_programmatic_beginner/apex_triggers/apex_triggers_bulk.

Hopefully this doesn't read like a 'please complete the course for me' kinda post, but I have written a trigger that I believe meets the criteria but it isn't passing the check, so I wanted to seek the guidance of the experts.

The challenge is to do this:

Create an Apex trigger for Opportunity that adds a task to any opportunity set to 'Closed Won'.

To complete this challenge, you need to add a trigger for Opportunity. The trigger will add a task to any opportunity inserted or updated with the stage of 'Closed Won'. The task's subject must be 'Follow Up Test Task'.The Apex trigger must be called 'ClosedOpportunityTrigger'

- With 'ClosedOpportunityTrigger' active, if an opportunity is inserted or updated with a stage of 'Closed Won', it will have a task created with the subject 'Follow Up Test Task'.
- To associate the task with the opportunity, fill the 'WhatId' field with the opportunity ID.
- This challenge specifically tests 200 records in one operation.


And here is the trigger I have come up with, which compiles OK and stands up to a manual (though admittedly unbulkified) test:
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {

    List<Task> taskList = new List<Task>();
    
    for (Opportunity opp : [SELECT Id, StageName FROM Opportunity WHERE StageName = 'Closed Won' AND Id IN :Trigger.new]){
                    
            taskList.add(new Task(Subject = 'Follow Up Test Task',
                                  WhatId = opp.Id));
       
    }

    if(taskList.size()>0){
        
        insert taskList;
        
    }
    
}
I have tried replacing the SOQL with a straightforward 'for (Opportunity opp : Trigger.new)' and having the taskList.add inside an IF that checks for Closed Won - no luck. I also thought about checking to see if the stage was being changed to Closed Won, rather than the trigger firing on every edit, but I don't think this is what the module is asking for.

Where do you think I'm going wrong?

Huge thanks in advance!
Best Answer chosen by Chris Edwards
Adam Purkiss 99Adam Purkiss 99
Hi Chris,

It's possible for something else in your DE org to cause an assessment to fail. For example, if you had a workflow, validation rule or another trigger that threw an error during the course of testing, the Trailhead assessment would be unable to finish its execution. We're making a change to Trailhead to provide more detailed information about unexpected errors to help resolve these issues, which should be released soon. But in general, it's best to use a fresh DE org to avoid such conflicts.

Thanks!

All Answers

AmulAmul
Hi Chris,

use following below code.


trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {

    List<Task> taskList = new List<Task>();
    
    
        
    for(opportunity opp: Trigger.New){
    
        if(opp.StageName!=trigger.oldMap.get(opp.id).stageName)
        {
            
            taskList.add(new Task(Subject = 'Follow Up Test Task',
                                  WhatId = opp.Id));
        }
    
    }

    
    if(taskList.size()>0){
        
        insert taskList;
        
    }
    
}


please mail me at amulhai@gmail.com. if it wont works for you. thanks
 
Sumitkumar_ShingaviSumitkumar_Shingavi
Your code should entry criterials like:
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {

    List<Task> taskList = new List<Task>();
    
    for(Opportunity opp : Trigger.new) {
		
		//Only create Follow Up Task only once when Opp StageName is to 'Closed Won' on Create
		if(Trigger.isInsert) {
			if(Opp.StageName == 'Closed Won') {
				taskList.add(new Task(Subject = 'Follow Up Test Task', WhatId = opp.Id));
			}
		}
		
		//Only create Follow Up Task only once when Opp StageName changed to 'Closed Won' on Update
		if(Trigger.isUpdate) {
			if(Opp.StageName == 'Closed Won' 
			&& Opp.StageName != Trigger.oldMap.get(opp.Id).StageName) {
				taskList.add(new Task(Subject = 'Follow Up Test Task', WhatId = opp.Id));
			}
		}       
    }

    if(taskList.size()>0) {        
        insert taskList;        
    }    
}

PS: if this answers your question then hit Like and mark it as solution!
Chris EdwardsChris Edwards
Thanks very much for your answers, Amul and Sumitkumar.

They make sense to me, but I have tried both of them and no joy. The check is still failing. To be clear - I have no doubt these triggers would work in real life, it is just that Trailhead isn't validating them. 

I also tried moving to (after insert, before update) but still nope. 

Could it just be an issue with the Trailhead checking mechanism (as with https://developer.salesforce.com/forums/#!/feedtype=SINGLE_QUESTION_SEARCH_RESULT&id=906F0000000AnOCIA0), or does anyone else have any suggestions?
Sumitkumar_ShingaviSumitkumar_Shingavi
Can you tell me what TrailHead says? It should work as it is!
Chris EdwardsChris Edwards
Sure - this is probably the most frustrating part, as the error is so generic as to be useless:
Trailhead Generic Error
Sumitkumar_ShingaviSumitkumar_Shingavi
I will suggest you to run same trigger in an new developer org (you might need to create one if you don't have it already) which is separate than trailhead. You might get towards more correct solution but this requirement is fairly straight.
Chris EdwardsChris Edwards
The trigger is already in my dev org. I don't particularly want to spin up a new one just for the purposes of getting Trailhead to work, especially as my dev org ID is how Trailhead knows I am me.

And I don't quite understand why the same trigger being checked by the same system would work simply because it is in a different org. 

But anyway, thank you for your assistance and for trying to help. I appreciate it!
Sumitkumar_ShingaviSumitkumar_Shingavi
Oh got it! Put some debug logs and see the result after your testing. If you still see things working in dev org then TrailHead might make it a GO in it's next synch or something.
Chris EdwardsChris Edwards
Have set up a debug log and checked the log but no obvious hints. All seems to have happened as expected. 
Adam Purkiss 99Adam Purkiss 99
Hi Chris,

It's possible for something else in your DE org to cause an assessment to fail. For example, if you had a workflow, validation rule or another trigger that threw an error during the course of testing, the Trailhead assessment would be unable to finish its execution. We're making a change to Trailhead to provide more detailed information about unexpected errors to help resolve these issues, which should be released soon. But in general, it's best to use a fresh DE org to avoid such conflicts.

Thanks!
This was selected as the best answer
Sandeep BhanotSandeep Bhanot
Chris - first of all, apologies on behaof of the Trailhead team that you're having trouble with this challenge. I just tried your code in an own DE Org and was able to pass the challenge successfully. As Adam mentioned earlier, this means that there must be some code or config in your DE Org (probably related to the Opportunity object) that is causing the challenge to fail for you.
The fastest path for you is to try the challenge in a fresh DE Org as Adam recommended. I do understand that it is painful to spin up a new DE, but as you can imagine, it is impossible for us to write challenges that work in every possible combination of code/config in a DE Org. As Adam also said, we're working on improving our error reporting functionality as well so that its easier for you to know that something unexpected occured (vs the generic error that you're seeing now).
Aplogies again for these "challenges" (sorry, I couldn't resist!), but thank you for trying Trailhead and sending us your feedback.

Sandeep
Chris EdwardsChris Edwards
Thank you very much Adam and Sandeep!

I didn't like the thought of spinning up a new DE since even if it worked it would mean that my 'real' DE still didn't get the green tick for that challenge, so I hunted high and low for another trigger, VR and WFR that could have been tripping me up. Didn't find any. But then... I found it was a new process I'm building with the Process Builder that was causing the issue! So I deactivated it and passed the check.

Great to hear that the error messages are going to be improved. That will be a huge win. 

Thanks a lot for your help everyone! 
Adam Purkiss 99Adam Purkiss 99
Great to hear, Chris! Thanks for letting us know!
Sandeep BhanotSandeep Bhanot
Great to know Chris! Also remember that you can login to Trailhead with one DE login so that your profile gathers all the points and badges in one place, but you can attempt challenges in different DE Orgs. The points/badges would still acrrue to the profile/login that you logged into Trailhead with. Hope this isn't too confusing. You can watch the short video associated with the '?' icon to the right of the Challenge section to see how login and challenges work in Trailhead. Happy trails! 
Chris EdwardsChris Edwards
Ah, cool - I didn't know that! That's a big help. Thanks Sandeep!
Satyanarayana PusuluriSatyanarayana Pusuluri
Hi,

The below code working fine.

trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {

    List<Task> taskList = new List<Task>();
    
    for(Opportunity opp : Trigger.new) {
        
        if(Trigger.isInsert) {
            if(Opp.StageName == 'Closed Won') {
                taskList.add(new Task(Subject = 'Follow Up Test Task', WhatId = opp.Id));
            }
        }
        
        if(Trigger.isUpdate) {
            if(Opp.StageName == 'Closed Won' && Opp.StageName != Trigger.oldMap.get(opp.Id).StageName) {
                taskList.add(new Task(Subject = 'Follow Up Test Task', WhatId = opp.Id));
            }
        }       
    }

    if(taskList.size()>0) {        
        insert taskList;        
    }    
}

Thanks & Regards,
Satya P
Kishan MalepuKishan Malepu
Hi ,
 This code is working for me..

trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
   List<Task> taskList = new List<Task>();
    for (Opportunity o :[SELECT Id,StageName FROM Opportunity WHERE StageName ='Closed Won' AND Id IN :Trigger.New]) 
    {
        if(o.StageName == 'Closed Won')    
        {
            taskList.add(new task (Subject ='Follow Up Test Task' , WhatId=o.Id));
        }
            
    }
    if(taskList.size() > 0){
         insert taskList;
   }
}

Regards,
Kishan
Venkat K 27Venkat K 27
Chris's original code worked for me
Chris Kim 9Chris Kim 9
I was able to complete the challenge using the 'or' operator for the trigger 'isInsert' and 'isUpdate'.  See below.
 
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
	List <Task> todoList = new List <Task>();
   
    for (Opportunity opp :Trigger.new){
        if(Trigger.isInsert || Trigger.isUpdate) {
            if(opp.StageName == 'Closed Won') {
                todoList.add(new Task(Subject = 'Follow Up Test Task', WhatId = opp.Id));
            }
        }
    }
    if(todoList.size()>0) {
        insert todoList;
    }
}

 
Ashraful Islam 19Ashraful Islam 19
Hi @Chris Edwards

Try once using : (colon) in 'WHERE' clause.

 for (Opportunity opp : [SELECT Id, StageName FROM Opportunity WHERE StageName =: 'Closed Won' AND Id IN :Trigger.new]){


Thanks
Ashraful
Tripathi_SankalpTripathi_Sankalp
TRY WITH THIS

trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {

    List<Task> tl = new List<Task>();
    
    for(Opportunity op : Trigger.new) {
        
        
        if(Trigger.isInsert) {
            if(Op.StageName == 'Closed Won') {
                tl.add(new Task(Subject = 'Follow Up Test Task', WhatId = op.Id));
            }
        }
        
        
        if(Trigger.isUpdate) {
            if(Op.StageName == 'Closed Won' 
            && Op.StageName != Trigger.oldMap.get(op.Id).StageName) {
                tl.add(new Task(Subject = 'Follow Up Test Task', WhatId = op.Id));
            }
        }       
    }

    if(tl.size()>0) {        
        insert tl;        
    }    
}
Prem Kumar Gupta 8Prem Kumar Gupta 8
Easiest Approch:

trigger ClosedOpportunityTrigger on Opportunity (after insert,after update) {
    List<Opportunity> oppo = Trigger.new;
    system.debug('oppo----'+oppo);
    List<Task> taskList = new List<Task>();
    for(Opportunity o : oppo){
        if(o.StageName =='Closed Won'){
            Task task = new task();
            task.WhatId = o.id;
            task.Subject = 'Follow Up Test Task';
            task.status = 'Not Started';
            task.description = 'New  Work';
            taskList.add(task);
        }
    }
    if(taskList.size()>0)
        insert taskList;
}
Sindhura ManthapuriSindhura Manthapuri
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
    List<Task> t = new List<Task>();
    for(Opportunity o : Trigger.new) {
        if(o.StageName == 'Closed Won'){
            Task task = new task();
            task.WhatId = o.id;
            task.Subject = 'Follow Up Test Task';
            task.status = 'Not Started';
            task.description = 'New  Work';
            t.add(task);
       }
    }
if(t.size()>0)
    insert t;
}

This Worked for me.
Verma, ManishVerma, Manish
Hi,

Use the code below, it works perfectly:
 
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {

    List <Task> tasks = new List<Task>();
    for(Opportunity opp : [SELECT Id, StageName FROM Opportunity WHERE StageName='Closed Won' 
                           AND Id IN :Trigger.new]){
        tasks.add(new Task(Subject = 'Follow Up Test Task' , WhatId = opp.Id));
    }
    
    if(tasks.size() > 0){
        insert tasks;
    }
}

Hope this helps!!
 
Muhammad AlaaMuhammad Alaa
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
    //adds a 'Follow Up Test Task' to any opportunity set to 'Closed Won'
    List<Task> lstTask = new List<Task>();
    //Iterate over Opptys that are in this trigger and Closed Won
    for (Opportunity o : [SELECT Id, StageName FROM Opportunity WHERE Id IN :Trigger.New AND StageName = 'Closed Won']){
        //add Follow Up Task to this Oppty
        lstTask.add(new Task(Subject = 'Follow Up Test Task',
                            WhatId = o.Id));
    }
    
    if (lstTask.size() > 0)
        insert lstTask;
}

 
naresh shettynaresh shetty
Way to use standard way 
trigger ClosedOpportunityTrigger on Opportunity (after insert,after update) {

 List<Opportunity> relatedOpps = [SELECT Id,OwnerId,StageName FROM Opportunity WHERE id in :Trigger.New]; 
   List<Task> tasks = new List<Task>();
   for(Opportunity opp : relatedOpps) {
    if(opp.StageName == 'Closed Won')
    {
     
      Task tsk = new Task(whatID = Opp.ID, Ownerid = Opp.OwnerId, Subject='Follow Up Test Task'); tasks.add(tsk); 
         
    }   
   
  } 
  insert tasks;

}
Ruchir SinghalRuchir Singhal

I am getting this error

 

" There was an unexpected error in your org which is preventing this assessment check from completing: System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Discount_Percent__c]: [Discount_Percent__c] '

Can someone help

Below is the code used

trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
    
    List<Task> taskList = new List<Task>();

    for(Opportunity opp : Trigger.new) {
        
        if(Trigger.isInsert) {

            if(Opp.StageName == 'Closed Won') {

                taskList.add(new Task(Subject = 'Follow Up Test Task', WhatId = opp.Id));

            }

            //Only create Follow Up Task only once when Opp StageName changed to 'Closed Won' on Update

        if(Trigger.isUpdate) {

            if(Opp.StageName == 'Closed Won' && Opp.StageName != Trigger.oldMap.get(opp.Id).StageName) 
            {

                taskList.add(new Task(Subject = 'Follow Up Test Task', WhatId = opp.Id));

            }

        }
        }
        
        if(taskList.size()>0) {       

        insert taskList;       

    }
    }
            
    

}
 

 

Ruchir SinghalRuchir Singhal
Fixed it.. Had a Discount_Percent__c as a compulsory variable. Post removal of mandatory field it works
lorenzo d'aleolorenzo d'aleo
Hi all, i do this and perfectly work 
trigger ClosedOpportunityTrigger on Opportunity (before insert, before update) {
	list<task> a =new list<task>();
    for(Opportunity o: Trigger.New)
        if(o.stagename=='Closed Won')
        	a.add(new Task(Subject='Follow Up Test Task', WhatId=o.Id));
    insert a;
}

I hope it will be useful
santosh_sahanisantosh_sahani
Thank you @Satyanarayana Pusuluri .It workes for me.
RbnRbn

Thanks Sandeep Bhanot,Adams and Chris.

The only reason the trigger was failing in the trailhead was a Process builder  named Opportunity Management which was created in earlier topics
Saumyajit Mishra 9Saumyajit Mishra 9
The main issue with the above answers was no one has checked the 200 record limit. Please refer the below code to solve the trailhead challenge.

trigger ClosedOpportunityTrigger on Opportunity (after insert,after update)
{
    List<Task> l = new List<Task>();
    for(Opportunity o:[SELECT Id, StageName FROM Opportunity WHERE StageName = 'Closed Won' AND Id IN :Trigger.new])
    {
        
            Task t = new Task();
            t.subject='Follow Up Test Task';
            t.WhatId=o.id;
            l.add(t);
     }
    if(l.size()>0 && l.size()-1<=200)
    {
        insert l;
    }
}
Luis Angel Granados Cuello 2Luis Angel Granados Cuello 2
In my case i solved the problem by including "OwnerId=Opp.OwnerId" in the new task. In the Task Object the OwnerId is mandatory.
Luis Angel Granados Cuello 2Luis Angel Granados Cuello 2
trigger ClosedOpportunityTrigger on Opportunity (before insert, before update) {
    
    List<Task> NewTasks=new List<task>();
    For(opportunity selectedOpps : Trigger.new){
        NewTasks.add(new task(WhatId=selectedOpps.id, Subject = 'Follow Up Test Task', OwnerId=selectedOpps.OwnerId));
    }
    if(NewTasks.size()>0){
        insert NewTasks;
    }
}

Complete Code
pulak biswaspulak biswas
Hi,
I have done the trail head and tested it okay. New task being created with 'Closed Won' opportunity. However the challenge has failed. Showing the following error description:
"Challenge Not yet complete... here's what's wrong: 
There was an unexpected error in your org which is preventing this assessment check from completing: System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Discount_Percent__c]: [Discount_Percent__c]"

My code is as below -->
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
    
    
    List<Task> listTask = new List<Task>();
    Try{
    for (Opportunity opp:[select Id,AccountId,StageName,Name,CloseDate,Discount_Percent__c,(select WhatId from tasks) from Opportunity 
                          where Id in:Trigger.New and StageName='Closed Won']){
        if(opp.tasks.size()==0){
        listTask.add( new task(subject='Follow Up Test Task',
                               WhatId=opp.id,
                              Priority='Normal',
                              Status='In Progress' ));
        
        }
                          }
    insert listTask;
    }catch (exception e)
    {system.debug('exception is '+ e.getTypeName());
     system.debug('exception cause is '+ e.getCause());
     system.debug('exception line is '+ e.getLineNumber());}

}

-----------------------------
This is a bit frustrating. Can any one help?
Note : this same has happened with other trail head challenges too.
Ben RowleyBen Rowley
The instructions actually say description but if you check the assertion failures in the debug logs it will likely say assertion failed when running a query for 'where subject = 'Follow up test task'.

Below should do it for you. 

trigger ClosedOpportunityTrigger on Opportunity (after insert,after update) {
     
    List<Task> tasksToInsert = new List<Task>();
    
    for(Opportunity o: Trigger.new){
        if(o.StageName == 'Closed won'){
           tasksToInsert.add(new Task(Subject = 'Follow Up Test Task',
                                      whatId = o.id,
                                      Priority = 'High',
                                      Status = 'Complete'));
        }
    }
       if(tasksToInsert.size() >0)
    insert tasksToInsert;
}
Ben RowleyBen Rowley
Also remember you don't need to requery the opportunity object for the ID as you already have this from Trigger.new
Christian BäthgeChristian Bäthge
Hello,

after some work the coe is now fine. Watch out for the Process in the Processbuilder

trigger ClosedOpportunityTrigger on Opportunity (after insert, after update)
{
    List <Task> newTask = new List <Task>();

    for(Opportunity opp :Trigger.new)
    {       newtask.add(new Task(  Subject='Follow Up Test Task', Priority='Normal',Status='Completed'));        }
        
    If (newTask.size()>0)
    {        insert newtask;    }
}
 
chaitanya motupallichaitanya motupalli
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
   List<Task> taskList = new List<Task>();
    for (Opportunity o :[SELECT Id,StageName FROM Opportunity WHERE StageName ='Closed Won' AND Id IN :Trigger.New]) 
    {
      taskList.add(new task (Subject ='Follow Up Test Task' , WhatId=o.Id));
    }
    upsert taskList;
}

I just simplified Kishan Malepu work. thank you ALL.
it is working fine.
JKubertJKubert
Thank you all for your answers here. They helped me get my badge! The Bulk Apex Triggers unit made zero sense to me. Any recommendations on resources that break down triggers using layman terms for those of us that are not developer minded?
Sidhant JainSidhant Jain
this is what i wrote and it is working remember don't insert inside for loop and don't query inside for loop
trigger ClosedOpportunityTrigger on Opportunity (after insert,after update) {
    List<Task> taskList=new List<Task>();
    for(Opportunity objOpp :Trigger.New){
        if(objOpp.StageName =='Closed Won'){
            taskList.add(new Task(Subject ='Follow Up Test Task',WhatId =objOpp.Id));
        }
    }
    if(taskList.size()>0)
        insert taskList;
}
Alex Valavanis 10Alex Valavanis 10
I thought this was a module for beginners !

It would be highly appreciated if the module was a bit more "User Friendly" for those who know peanuts about Apex Triggers....
venkata Daggubativenkata Daggubati
Please Try this Can try both ways .Working fine

To complete this challenge, you need to add a trigger for Opportunity. The trigger will add a task to any opportunity inserted or updated with the stage of 'Closed Won'. The task's subject must be 'Follow Up Test Task'.
venkata Daggubativenkata Daggubati
trigger ClosedOpportunityTrigger on Opportunity (After insert, After Update) {

/*list<opportunity> opplist=new list<Opportunity> ([Select id, name, StageName from 
                         Opportunity Where (ID in :trigger.New AND  StageName='Closed Won') ]);
    
    list <Task> T=new List<Task>();
    
    for(Opportunity op:Opplist)
    {
        
        Task T1=new Task();
        T1.WhatId=op.id;
        T1.Subject='Follow Up Test Task';
        T.add(T1);
    }
 Insert T;
*/
    
 list<Opportunity> Op=New List<Opportunity>([SELECT ID, NAME ,(Select Subject from Tasks ) 
                                               From Opportunity Where (ID in :trigger.New AND  StageName='Closed Won') ]);
   
    List<Task> tasklist=new list<Task>();
    for(Opportunity Oplist:  Op)
    {
        if(oplist.Tasks.size()==0)
        {
           Task T=new Task(Subject='Follow Up Test Task', Whatid=Oplist.Id);
           Tasklist.add(T) ;           
        }
    }
    Insert Tasklist;
   
}
Krishnan MishraKrishnan Mishra
Hi Chris,
I had similar problem,try checking out the query you used in SOQL, there must be a simple error. YOu can first search your query in query editor and the ncopy past it in the apex code
sunil mali 11sunil mali 11
Working for code for this challenge:
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
    List<Task> taskList = new List<Task>();
    
    for(Opportunity opp : Trigger.new) {
        //create Follow Up Task only when Opportunity StageName is equal to 'Closed Won' on Create/Update
        if(Trigger.isInsert || Trigger.isUpdate) {
            if(opp.StageName == 'Closed Won') {
            taskList.add(new Task(Subject='Follow Up Test Task', WhatId =opp.Id));
        }
        }
        
    }
    if(taskList.size() > 0) {
        insert taskList;
    }
}
Mikhail RzhevskyMikhail Rzhevsky
I think that correct one is my version, but trailhead consider that correct commented lines.

trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {

    List<Task> taskList = new List<Task>(); 
    Opportunity[] opps = [SELECT Id,Name,StageName FROM Opportunity
        WHERE Id IN :Trigger.New];
    //for(opportunity opp: Trigger.New){
    	//if(opp.StageName=='Closed Won')
    	if(opps[0].StageName=='Closed Won')
        {
            
            taskList.add(new Task(Subject = 'Follow Up Test Task',
                                  //WhatId = opp.Id));
                                  WhatId = opps[0].Id));
        }   
    //}  
    if(taskList.size()>0){       
        insert taskList;       
    }
}

 
Vishal Sharma 126Vishal Sharma 126
What is the meaning of these lines?
1--- Opp.StageName != Trigger.oldMap.get(opp.Id).StageName) 
2---  WhatId = opp.Id
setiaman lee (Dev)setiaman lee (Dev)
I managed to clear this challenge after setting Discount Percentage field in the opportunity to not required. 
Gurdeep S RahiGurdeep S Rahi
Tried few different code examples from this thread but it did not work until I changed the field Discount_Percent to NOT Required as per the suggestion here.  It worked fine after the change.
 
Admin User 7969Admin User 7969
Hi guys
I got an issue with my trigger trailhead, I could find a lot of explanations but I want to understand why my SOQL request doesn't 'work' ;
Because I tried previously to fill a List, before looping on it, and System.debug the size of the List --> 0...
Here is my code,
Thanks by advance for your help / explanations :)
 
trigger ClosedOpportunityTrigger on Opportunity (before insert, before update) {
    // liste de Task ou ajouter les elements a updater / inserer
    List <Task> TaskToUpdate = new List <Task>();
 
    for (Opportunity op : [SELECT id FROM opportunity WHERE (stageName= 'Closed Won'
                                                             AND id IN :trigger.new)]) {
        // ajout d'une new task a liste de task (avec subject, et l'id de l'op)
        TaskToUpdate.add(new task(whatId=op.Id,
                                  Subject='Follow Up Test Task'));    
    }
    
    // upsert if usefull
    if (TaskToUpdate.size() > 0) {
        upsert TaskToUpdate;
    } 
}

 
Admin User 7969Admin User 7969
(sorry, I put my code inside the <> balise but it seems not to work ... An idea of why ?

Thanks !! )
Admin User 7969Admin User 7969
Ok, my mistake was just that I configured the trigger on BEFORE and it's a AFTER !!

Well done :)
xuer zoxuer zo
My experience is that Task.OwnerId has to be defined, this works for me:
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
    Task[] tasklist = new List<Task>();
    for (Opportunity opp : [SELECT Id, Name, OwnerId FROM Opportunity WHERE Id IN :Trigger.New AND StageName = 'Closed Won']) {
        tasklist.add(new Task(WhatId = opp.Id, Subject = 'Follow Up Test Task', OwnerId = opp.OwnerId));
        System.debug('inserted records: ' + opp.Id);
    }
    if (tasklist.size() > 0) {
    insert tasklist;
    }
}
Vivek HIngorani 2Vivek HIngorani 2
@xuer zo: Thanks for the solution. It was Owner Id that solved the issue. 
Swetaleena SalesforceSwetaleena Salesforce
it might be off topic and a silly question as i am new to SF.

I want to know where i can see the field label and its api name as 'Id' as its used in the query? 

I have tried seeing object manager, report and schma builder but didnt find it. can someone help me somewhere to see field api name as 'Id' and screen shot wud be great.

Thank you.
Gurdeep S RahiGurdeep S Rahi
Hi Swetaleena, every record your create has an automatic "id" assigned to it so that you can reference it uniquely.   When you create a new record, let's say for a new opportunity, on saving the record the id (i think it is 15 or 18 alphanumeric) is generated and stored in the metadata.  You can find the id using SQL on metadata table (but not really recommended approach).  Anyway, you can read more about it here,

https://help.salesforce.com/articleView?id=000004383&type=1
 
Swetaleena SalesforceSwetaleena Salesforce
thank you Gurdeep.
Devin Jacob 5Devin Jacob 5

This thread was very helpful to me, but it turned out that my version of the trigger works fine. I added it below in case that's helpful. The real reason I'm commenting on this thread is to warn people that you cannot complete this challenge if you have the Opportunity Management Process Builder from the Automate Simple Business Processes with Process Builder (https://trailhead.salesforce.com/en/modules/business_process_automation/units/process_builder) active in the same org. If you are getting an error about a missing required AccountId field when you run the check in Trailhead, try disabling that Process Builder. 

 

Another version of this that works:

 

trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
    List<Task> taskList = new List<Task>();
    
    for (Opportunity a : [SELECT ID, Name FROM Opportunity WHERE 
                          Id IN :Trigger.New AND StageName = 'Closed Won']){
                              taskList.add(new Task(Subject='Follow Up Test Task', 
                                                    WhatId=a.Id));
                          }
    
    if (taskList.size() > 0){
        insert taskList;
    }

}

Ilya IvanovskiyIlya Ivanovskiy

Hello everyone, what can I do?

Challenge not yet complete... here's what's wrong:
There was an unexpected error in your org which is preventing this assessment check from completing: System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_EXECUTE_FLOW_TRIGGER, We can't save this record because the “Closed Won Opportunities” process failed. Give your Salesforce admin these details. <b>An unhandled fault has occurred in this flow</b><br>An unhandled fault has occurred while processing the flow. Please contact your system administrator for more information. Error ID: 121744304-87777 (745827866): []

 

trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {

    List<Task> taskListToInsert = new List<Task>();
    
    for(Opportunity opp:Trigger.new) 
    {
			if(opp.StageName == 'Closed Won') 
            {
			   	Task t = new Task();
                t.Subject = 'Follow Up Test Task';
                t.WhatId = opp.Id;
                taskListToInsert.add(t);
            }
    }
                
    if(taskListToInsert.size() > 0) 
    {        
        insert taskListToInsert;        
    }    
}
Ilya IvanovskiyIlya Ivanovskiy
https://ap4.lightning.force.com/processui/processui.app?retURL=%2Fui%2Fsetup%2FSetup%3Fsetupid%3DWorkflow&setupid=ProcessAutomation

User-added image

Problem can be in active processes. Some processes should be disabled and the error will pass.
ArpitVikharArpitVikhar
try this one 
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update)
{
List<Task> tasklist= new List<Task>();
 for(Opportunity opp:[Select StageName,Id from Opportunity where ID =:Trigger.New])
{
    taskist.add(new Task(Subject='Follow Up Test Task', WhatId = opp.Id ))
}
if(tasklist.size() > 0)
{
 insert tasklist;
}
}
Aviroop Chowdhury 2Aviroop Chowdhury 2
// Below code handles both bulkification and Dev ORg limits.

trigger ClosedOpportunityTrigger on Opportunity (before insert, before update) 

   List<Task> tasklist = new List<Task>();
   if(Trigger.isBefore)
   {
       if((Trigger.isInsert) || (Trigger.isUpdate))
       { 
           for (Opportunity opp : Trigger.new)
           {
               if (opp.StageName=='Closed Won')
              {
                 Task t = new Task(Subject='Follow Up Test Task', WhatId=Opp.Id);
                  tasklist.add(t);
              }
           }
if(tasklist.size() > 0)
{
           insert tasklist;
 }
       }                
   }
}
Sreenu Reddy 16Sreenu Reddy 16
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
    List<Task> taskList = new List<Task>();   
    for(Opportunity opp : Trigger.new) {
        //Only create Follow Up Task only once when Opp StageName is to 'Closed Won' on Create
        if(Trigger.isInsert) {
            if(Opp.StageName == 'Closed Won') {
                taskList.add(new Task(Subject = 'Follow Up Test Task', WhatId = opp.Id));
            }
        }
        //Only create Follow Up Task only once when Opp StageName changed to 'Closed Won' on Update
        if(Trigger.isUpdate) {
            if(Opp.StageName == 'Closed Won' && Opp.StageName != Trigger.oldMap.get(opp.Id).StageName) {
                taskList.add(new Task(Subject = 'Follow Up Test Task', WhatId = opp.Id));
            }
        }       
    }
    if(taskList.size()>0) {        
        insert taskList;        
    }    
     if(taskList.size()>0 && taskList.size()<=200) {        
       update taskList;        
    }    
}
 
Asams TJAsams TJ
Try this :
trigger ClosedOpportunityTrigger on Opportunity (after insert,after update) { 
  List<Task> Task1 = new List<Task>();
    for(Opportunity a : [SELECT Id,StageName FROM Opportunity
                         WHERE Id IN :Trigger.new AND StageName='Closed Won'])
                         {
                             Task1.add(new task(Subject='Follow Up Test Task' , WhatId = a.Id));
                         }
    if(task1.size()>0){
        insert Task1;
    }
}

Just notice  to separate Id and StageName as below:
SELECT Id,StageName FROM Opportunity
WHERE Id IN :Trigger.new AND StageName='Closed Won']) 
This worked for me.
Raquel SantiagoRaquel Santiago
Hey guys! You should reaaaally fix this!

I had same mistake...If you follow the trailheads step by step you will have that process "Closed Won Opportunities" in the Process Builder, and for this trailhead you have to deactivate or you will get this error.

There was an unexpected error in your org which is preventing this assessment check from completing: System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_EXECUTE_FLOW_TRIGGER, We can't save this record because the “Closed Won Opportunities” process failed. Give your Salesforce admin these details. <b>An unhandled fault has occurred in this flow</b><br>An unhandled fault has occurred while processing the flow. Please contact your system administrator for more information.

I think maybe it's in the trailhead about data management these dates are charged? (I didn't write it) I can't remember, but you should put a warning about this in the trailhead Bulk Apex Triggers
Lokendra Pal Singh 6Lokendra Pal Singh 6
Create an Apex trigger for Opportunity that adds a task to any opportunity set to 'Closed Won'.

The code is working fine: 
 
trigger ClosedOpportunityTrigger on Opportunity (after insert) {
    
    List<Task> taskListToInsert = new List<Task>();
    for(Opportunity opp:Trigger.new)
    {
        if(opp.StageName == 'Closed Won')
        {
            Task t = new Task();
            t.Subject = 'Follow Up Test Task';
            t.WhatId = opp.Id;
            taskListToInsert.add(t);
        }
    }
    
    if(taskListToInsert.size() > 0)
    {
        insert taskListToInsert;
    }

}

#lopsact
piyush mittal 16piyush mittal 16
I'm facing the problem with this challenging task.


There was an unexpected error in your org which is preventing this assessment check from completing: System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_EXECUTE_FLOW_TRIGGER, We can't save this record because the “Closed Won Opportunities” process failed. Give your Salesforce admin these details. <b>An unhandled fault has occurred in this flow</b><br>An unhandled fault has occurred while processing the flow. Please contact your system administrator for more information. Error ID: 1847821517-256696 (-1958523062): []


Please share your suggestions.
Thanks in advance
piyush mittal 16piyush mittal 16
@Manish Verma @lorenzo d'aleo 
Guys I used both of your codes but got the same errors below:

Challenge not yet complete in My Trailhead Playground 1
There was an unexpected error in your org which is preventing this assessment check from completing: System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_EXECUTE_FLOW_TRIGGER, We can't save this record because the “Closed Won Opportunities” process failed. Give your Salesforce admin these details. <b>An unhandled fault has occurred in this flow</b><br>An unhandled fault has occurred while processing the flow. Please contact your system administrator for more information. Error ID: 1398289272-430204 (-1958523062): []
Malhar_Ulhas_AgaleMalhar_Ulhas_Agale
trigger ClosedOpportunityTrigger on Opportunity (after insert , after update) {
    list<task> tasklist = new list<task>();
    //TASK LIST CREATED FOR BULK OPPORTUNITIES
    
	list<opportunity> reloplist = [select id,StageName from opportunity where id in :Trigger.new];
    //QUERYING THE OPPORTUNITIES
	
    for(opportunity op : reloplist){
        if(op.StageName == 'Closed Won'){
            task tk = new task();
            tk.Subject = 'Follow Up Test Task';
                tk.WhatId = op.Id;
            tasklist.add(tk);
        }        
    }
    upsert tasklist; //USED UPSERT SINCE TRIGGER SHOULD FIRE WHEN OPPORTUNITY INSERTED OR UPDATED

}

Hello Guys, I wrote the trigger in this way, it works. Try doing it.
DAN LI 10DAN LI 10
Hi Guys,
I just passed the challenge right now.
The Code below worked fine. For your reference, hope it's helpful to you.

trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
       List<Task> tasklist = new List<Task>();
       for(Opportunity a : [SELECT Id FROM Opportunity
                     WHERE StageName='Closed Won']) {
          tasklist.add(new Task(subject='Follow Up Test Task',
                           WhatId=a.ID));   }
       
     insert tasklist;
}
Nikhil ShanuNikhil Shanu
Hi,

You can try this solution.

trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
    List<task> taskList=new list<task>();    
    for(opportunity opp :trigger.new){       
        if(opp.stagename== 'Closed Won')
            taskList.add(new task(subject='Follow Up Test Task',whatid=opp.id));
        
    }   
    if (taskList.size() > 0) {
        insert taskList;
    }
}
Dhruv Joshi 5Dhruv Joshi 5
Hello Chris, You can try below Code.


trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) 
{
    list<Task> taskList = new List<Task>();
    
    for(Opportunity o: [Select StageName,Discount_Percent__c  from Opportunity Where Id in: Trigger.New And StageName=:'Closed Won'])
    {
        if(o.Discount_Percent__c==null)
        {
            taskList.add(new task(Subject='Follow Up Test Task', WhatId=o.Id));
        }
    }
    upsert taskList;
}
Shrikanth G 2Shrikanth G 2
Try this :
trigger ClosedOpportunityTrigger on Opportunity (after insert,after update) {
    
    list<task> optask = new list<task>();
    for(opportunity op :trigger.new){
        if(op.stagename=='Closed Won'){
            
            optask.add(new task(subject='Follow Up Test Task',whatid=op.id));
       }
    }
    if(optask.size()>0){
        insert optask;
    }
}

 
Sierra VPSierra VP
@Sumitkumar_Shingavi got it right, I think. Your issue may not be addressed by his solution, but even though it works the way you're expecting, it will also "work" or fire in situations that you aren't anticipating. I had similar code as the OP and made the same mistake in this trailhead and didn't realize it until I saw Sumitkumar_Shingavi's answer: what if an opportunity is updated to closed won, receives the task as we expect, but then receives an update of something other kind? Another task will be created, unless you check first that the specific update was to change the Opportunity from some other Stage to Closed Won.
Uday MakwanaUday Makwana
@
piyush mittal 16 
deactive 'closed won opportunity' process, you created earlier while learning process builder.
 
Uday MakwanaUday Makwana
mates,
i have successfully passed the challange but having one question.
task object has many required field like priority...how can we perform DML insert without providing these required fields?
Saket Ranjan 3Saket Ranjan 3
Below code will work::


trigger ClosedOpportunityTrigger on Opportunity (before insert, before update) 
{
    List<Task> taskList = new List<Task>();
    
    //If an opportunity is inserted or updated with a stage of 'Closed Won'
    // add a task created with the subject 'Follow Up Test Task'.
    for (Opportunity opp : Trigger.new) 
    {
       //add a task with subject 'Follow Up Test Task'.
       if(opp.StageName == 'Closed Won')
           taskList.add(new Task(Subject='Follow Up Test Task', WhatId = opp.id ));                
    }
                          
    if (taskList.size() > 0) 
    {
        insert taskList;
    }

P.S:please selct if it works for you.
Thankls,
Saket.
Marissa KendrickMarissa Kendrick
My code solution is/was very similar to OP's, and I had issues as well. To complete the challenge, I had to disable a trigger from a previous challenge in a different unit called, "OpportunityChangeTrigger". I'm sure OP is past this problem now, but maybe it will help someone else. For reference, my solution is as follows: 
 
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
	List<Task> taskList = new List<Task>();
    
    for (Opportunity o : [SELECT Id,StageName FROM Opportunity WHERE id IN :Trigger.new AND StageName = 'Closed Won']) {
        taskList.add(new Task(Subject = 'Follow Up Test Task', WhatId = o.Id));
    }
    
    if(taskList.size() > 0) {
        insert taskList;
    }
}

 
shivam kumar 45shivam kumar 45
trigger ClosedOpportunityTrigger on Opportunity (before insert,before update) {
    List<Opportunity> oppList=[select id,StageName from Opportunity where id in :Trigger.new];
    List<Task> taskOpp=[Select id,subject,whatId from Task where whatId in :oppList];
    if(Trigger.isBefore){
        for(Opportunity opp:Trigger.new){
            if(opp.StageName=='Closed Won'){
                   taskOpp.add(new Task(subject='Follow Up Test Task'));
            }
        }
        Insert taskOpp;
    }
}
vanamamuralivanamamurali
Deactivate all process on opportunity which were created earlier.

and use below code 

trigger ClosedOpportunityTrigger on Opportunity (before insert, before update) 
{
    List<Task> taskList = new List<Task>();
    
    //If an opportunity is inserted or updated with a stage of 'Closed Won'
    // add a task created with the subject 'Follow Up Test Task'.
    for (Opportunity opp : Trigger.new) 
    {
       //add a task with subject 'Follow Up Test Task'.
       if(opp.StageName == 'Closed Won')
           taskList.add(new Task(Subject='Follow Up Test Task', WhatId = opp.id ));                
    }
                          
    if (taskList.size() > 0) 
    {
        insert taskList;
    }
    
}    
Cherukoori YashaswiCherukoori Yashaswi
can you please mention what to deactivate @vanamamurali
sahithi guntisahithi gunti
I am getting this Error!!!!
Please help me to solve this issue...

There was an unexpected error in your org which is preventing this assessment check from completing: System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_EXECUTE_FLOW_TRIGGER, We can't save this record because the “Opportunity Management” process failed. Give your Salesforce admin these details. This error occurred when the flow tried to create records: REQUIRED_FIELD_MISSING: Required fields are missing: [AccountId]. You can look up ExceptionCode values in the SOAP API Developer Guide. Error ID: 6111300-56995 (-667225970): []
Charles SchrijnemaekersCharles Schrijnemaekers
As @vanamamurali mention in June 20, 2020 I got other kind of errors but the problem was the same.
Therefore, I deactivated validations, process builders, flows, etc, on Opportunity object.
After that, I updated one of my records to Closed Won and, voilá, without any change on my code triiger runs just perfect.
For sure there were some logic inconsistance related to my "old" validations, flows, etc on Opportunity object and what my trigger was programmed to do ... I'll analyse in details what made it fails.

And here is my code, pretty much the same we saw from other developers here at this topic before:

trigger ClosedOpportunityTrigger on Opportunity(after insert, after update) {

    List<Task> taska = new List<Task>();  
    // Add a task for each opportunity if it has changed to Closed Won.
    for (Opportunity opp : [SELECT Id, StageName FROM Opportunity WHERE StageName = 'Closed Won'])
         // Create Task list
         taska.add(new Task(Subject = 'Follow Up Test Task', WhatId = opp.Id));
    
    if(taska.size()>0) insert taska;
}
 
Christopher KopecChristopher Kopec
As others have mentioned, the problem for me was a process created in a previous part of the trail that was causing the error. If you follow a trail and keep a hands-on org for the given trail, some of the exercises seem to conflict with the challenges. Kind of annoying but I guess it's good experience using the log to troubleshoot.
Ali Siddiqui 1Ali Siddiqui 1
trigger ClosedOpportunityTrigger on Opportunity (after insert,after update) {
    integer count =0;
    List<Task> taskList = new List<task>();
    System.debug(Trigger.new);
    for(Opportunity newOpp : Trigger.new){
        System.debug(newOpp);
        count = count +1;
        System.debug(count);
        if(Trigger.isUpdate && newOpp.IsClosed && newOpp.IsWon && trigger.oldMap.get(newOpp.id).StageName !='Closed Won' ){
            taskList.add(new Task(WhatId=newOpp.id,subject='Follow Up Test Task'));
        }
        else if(Trigger.isInsert && newOpp.StageName == 'Closed Won'){
            taskList.add(new Task(WhatId=newOpp.id,subject='Follow Up Test Task'));
        }
    }
    
    insert taskList;
}
bhrigu mahajan 9bhrigu mahajan 9
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
        List<Task> tasks = new List<Task>();
        for(Opportunity opp : [SELECT Id,StageName FROM Opportunity WHERE StageName ='Closed Won' AND Id IN :Trigger.New]) {
            if(opp.StageName == 'Closed Won'){
                Task task= new Task();
                task.Subject='Follow Up Test Task';
                task.WhatId= opp.Id;
                tasks.add(task);
            }
        } 
        insert tasks;
}
Ridima Shukla 9Ridima Shukla 9
trigger ClosedOpportunityTrigger on Opportunity (after insert,after update) {
    
    List <Task> taskList = new List<Task>();
    
    for(Opportunity op: [Select id,StageName from Opportunity where StageName='Closed Won' and id IN :Trigger.new]){
        
        taskList.add(new Task(Subject='Follow Up Test Task',WhatId = op.id));
    }
        
    if(taskList.size()>0){
        insert taskList;
    }
    
}
Ishika Gupta 3Ishika Gupta 3
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
    List<Task> tasklist = new List<Task>();
     for (Opportunity o : [SELECT Id,Name FROM Opportunity
                     WHERE Id IN :Trigger.New AND StageName like 'Closed Won%'
                     ]) {
        tasklist.add(new Task(Subject = 'Follow Up Test Task', WhatId= o.Id)); 
    }
    
    if (tasklist.size() > 0) {
        insert tasklist;
    }
}
Mohnish Madhukar 9Mohnish Madhukar 9
No need to check for insert or update condition. A simple upsert will do the job.

trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) 
{
    List<Task> tskList = new List<Task>();
    for(Opportunity opp: trigger.new)
    {
        Task tsk = new Task();
        if(opp.StageName=='Closed Won')
        {
            tsk.Subject='Follow Up Test Task';
            tsk.WhatId=opp.id;
            tskList.add(tsk);
        }
    }
    if(!tskList.isEmpty())
    {
        upsert tskList;
    }
}
Abhinav Yadhuvanshi 5Abhinav Yadhuvanshi 5
Hi Everone,
This code is very simple to understand the logic and understand how bulkified Trigger Work. And please like my code if you like it.


trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
    
   List<Task> tList = new List<Task>();
    
    for(Opportunity p : Trigger.New){
            
        if(p.StageName == 'Closed Won'){
            Task t = new Task();
            t.Subject = 'Follow Up Test Task';
            t.Status = 'In Progress';
            t.Priority = 'Normal';
            tList.add(t);
        }
        
    }
    
    if(tList.size() > 0){
        insert tList;
    }
    

}

 
James LaurieJames Laurie
This may help some people using the code blocks above and unsure why the challenge is not being accepted. I looked at my log and noticed that I was getting an error for required field missing of Discount Percent (I think we did this in a previous excercise or I just did it by mistake)

Anyway I went into that field and unmarked the required box for that field and then it worked!

User-added image
Samar Singh ChouhanSamar Singh Chouhan
As per previous assigment we have to enable Discount_Percent__c field as required in Opportunity object. every single post code is working here. Only we need to unmarked the required box for that field in Opportunity object.
abhilasha purohitabhilasha purohit
@samar singh thankyou so much that works . 
Md Rashidul SumyMd Rashidul Sumy
I did the following way and it worked for me.

trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
    List<Task> taskList = new List<Task>();
    
    List<Opportunity> oppList = [SELECT StageName FROM Opportunity WHERE StageName = 'Closed Won' AND Id IN :Trigger.New];
    
    for(Opportunity opp: oppList){
        taskList.add(new Task(Subject = 'Follow Up Test Task', Whatid = opp.ID));
    }
    
    if(taskList.size()>0){
        insert taskList;
    }
              
}
Andreas Beck 5Andreas Beck 5
For me this worked
 
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
    //New Object for Tasklist
    List<Task> tasklist = new List<Task>();
    
    //For all inserted Opportunities -> Supports BULK which are in the Closed Won Stage and ID from the Trigger New
    for (Opportunity o: [Select ID, Name, stagename 
                         from Opportunity 
                         Where ID in :Trigger.New
                         and StageName = 'Closed Won'
                        ])
    {
        //Adds Tasks with the Subject and WhatID (to link to Opportunity)
        tasklist.Add(New Task (Subject = 'Follow Up Test Task',
                               WhatId=o.id
                              ));
    }
    //Check if any task needs to be added and if so, perform insert
    if (tasklist.size() > 0) {
        insert tasklist;
    }

}

 
Abhi ChohanAbhi Chohan
This code worked for me at different Playground having no validation rules, no workflow on Opportunity and Tasks, and no existing trigger.
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update)
{
    if (Trigger.isInsert || Trigger.isUpdate) {
        if (Trigger.isAfter) {
            List<Task> taskList = new List<Task>();
            for (Opportunity opp : [SELECT Id, StageName FROM Opportunity WHERE StageName = 'Closed Won' AND Id IN :Trigger.new]){
                   taskList.add(new Task(Subject='Follow Up Test Task', WhatId=opp.Id));
            }
            if (taskList.size() > 0) {
                insert taskList;
            }
        }
    }
}
Rodolfo BarretoRodolfo Barreto
I am getting this Error!!!!
Please help me to solve this issue...

We created an opportunity and expected it to have an associated task, but it didn't. Have your Apex trigger insert the task into the database.

 
Marta Emanuela MeazzaMarta Emanuela Meazza

Hello,

I dont' know if this helps, but I also had issues with this challenge. The code was the same, but it didn't seem to work.

I tried to copy and paste into the code the names the challenge required (like Name: ClosedOpportunityTrigger, Condition: Stage is Closed Won, or Subject: Follow Up Test Task) instead of writing them on my own... and it worked. The challenge was complete.

Here's the code I used and the copied text in bold:
 

trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
    
    List<Task> taskToOpp = new List<Task>();
    
    for (Opportunity o : [ SELECT Id,StageName FROM Opportunity WHERE StageName = 'Closed Won' AND Id IN :Trigger.New ]) {
        taskToOpp.add(new Task( Subject = 'Follow Up Test Task', WhatId = o.Id));
    }
    
    if (taskToOpp.size() > 0)
    insert taskToOpp;

}
 

It already happened to me in other challenges and sometimes the solution was just to copy the text directly from the challenge (even if there are no typos in the code).

Indrani Mallik ThakurIndrani Mallik Thakur
Hi This code worked for me
Let me know if it helps!

trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {

    List<Opportunity> occ = [select id from Opportunity where StageName = 'Closed Won'];
    List<Task> tcc= new List<Task>();
    
    for ( Opportunity opp : occ)
    {
      tcc.add(new Task(Subject = 'Follow Up Test Task', WhatId = opp.Id));
    }
        insert tcc;  
}
Regan SmithRegan Smith

Disable the Required Status on Discount_Percent__c.

The Issue with this task is that previously users created the Discount_Percent__c as a required field. The task attempts to enter the data in bulk but encounters an issue as the discount percentage field is custom and required. 

By disabling this field as required then you code should work.

This is my code that didn't work until I disabled the required field.

trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) 
{
    List<Task> taskList = new List<Task>();
    for (Opportunity o: [Select Id FROM Opportunity Where Id IN :Trigger.New AND StageName = 'Closed Won'])
    {
        taskList.add(new Task(Subject = 'Follow Up Test Task', WhatId = o.I));
    }
    if (taskList.size()> 0)
    {
        insert taskList; 
    }
}

Hope this helps.

Mukesh RarMukesh Rar
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update)
{
    List<Task> taskList= new List<Task>();
    for(Opportunity opp: trigger.new)
    {
        if(opp.StageName=='Closed Won')
        {
            if(trigger.isInsert)
            {
                taskList.add(new Task(Subject= 'Follow Up Test Task', WhatId= opp.Id));
            }
            
            if(trigger.isUpdate)
            {
                if(opp.StageName!=trigger.oldMap.get(opp.Id).StageName)
                {
                    taskList.add(new Task(Subject= 'Follow Up Test Task', WhatId= opp.Id));
                }
            }
        }
    }
    if(taskList.size()>0)
    {
        insert taskList;
    }
}
Przemysław BąbelPrzemysław Bąbel
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
    List<Task> taskList = new List<Task>();
    
    for(Opportunity o : [SELECT Id, StageName FROM Opportunity WHERE StageName = 'Closed Won']) {
        taskList.add(new Task(Subject = 'Follow Up Test Task',
                                  WhatId = o.Id));
    }
    
    if(taskList.size()>0){
        
        insert taskList;
        
    }
    
}

This works in Trailhead
Andray GaustAndray Gaust
What type of CMS required to store Crypto Courses (https://fttuts.com/)?
Rahul Pande 12Rahul Pande 12
As Sandeep Bhanot said, I tried trigger in another org and it worked. Do check workflow, validation or any other changes opposing to trigger 
Nazli FatimaNazli Fatima
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {

    List<Task> taskLst = new List<Task>();
    
    for (Opportunity oppy : [SELECT Id, StageName FROM Opportunity WHERE StageName = 'Closed Won' AND Id IN :Trigger.new]){
                    
            taskLst.add(new Task(Subject = 'Follow Up Test Task',
                                  WhatId = oppy.Id));
    }

    if(taskLst.size()>0){
        insert taskLst;
    }    
}
Rameez Raza 11Rameez Raza 11
trigger ClosedOpportunityTrigger on Opportunity (after insert,after update) {
    
    List<task> Tasklist = New List<task>();
    
    For(opportunity opp : Trigger.New){
        If(opp.StageName == 'closed won'){
            Task T = new task();
            T.Subject = 'Follow Up Test Task';
            T.Priority = 'High';
            T.Status = 'Not started' ;
            T.WhatId = opp.Id ;
            Tasklist.add(T);
            }
    }
    
    If(Tasklist.size()>0)
            Insert Tasklist;

}
Farhat AkmuradovFarhat Akmuradov
My version:


trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
    List<Task> taskList = new List<Task>();
    for (Opportunity opp : [SELECT Id,Name FROM Opportunity
                     WHERE Id IN :Trigger.New AND
                     StageName='Closed Won']) {
        // Add a default Task for this Opportunity
        taskList.add(new Task(Subject='Follow Up Test Task',
                                   Status='Not Started',
                                   Priority='High',
                                   WhatId=opp.Id)); 
    }
    
    if (taskList.size() > 0) {
        insert taskList;
    }
}



 
alex mac 2alex mac 2
What type class or ID to use for forex courses? https://mydiscountcourses.com/