+ Start a Discussion
EvertonSzekeresEvertonSzekeres 

System.NullPointerException

I think my trigger is not bulk safe.

 

Any help?

 

Trigger CriarTarefaCase_Solicitacao_Pagamento on Case (after insert, after update) {

Set<Id> hasTask = new Set<Id>();    
    Task[] tasks = new Task[0];
    
     for (Case c: Trigger.new) {
        Case oldCase = Trigger.oldMap.get(c.ID);
         
         for(Task tsk:[SELECT Id, whatid FROM Task WHERE subject = 'Solicitação de Pagamento - Lançar PP' AND whatid IN :Trigger.new])
        hasTask.add(tsk.whatid);
         
        if ((c.Quantas_PP_s_pagamento__c != oldCase.Quantas_PP_s_pagamento__c || c.Quantidade_de_PP_s_Estojo__c != oldCase.Quantidade_de_PP_s_Estojo__c || c.motivo_a__c != oldCase.motivo_a__c) && !hasTask.contains(c.Id)) {                  
                
            if ((c.Quantas_PP_s_pagamento__c > 0 || c.Quantidade_de_PP_s_Estojo__c > 0) && c.motivo_a__c != 'Cache'){
                if ((c.Quantas_PP_s_pagamento__c > 0 || c.Quantidade_de_PP_s_Estojo__c > 0) && c.motivo_a__c != 'Mostruarios'){
                    if ((c.Quantas_PP_s_pagamento__c > 0 || c.Quantidade_de_PP_s_Estojo__c > 0) && c.motivo_a__c != 'Laboratórios por fora do sistema'){
                        if ((c.Quantas_PP_s_pagamento__c > 0 || c.Quantidade_de_PP_s_Estojo__c > 0) && c.motivo_a__c != 'Devolução de venda'){
          Task tsk = new Task
              (whatID = c.ID,
               Solicita_o_de_Pagamento__c = c.motivo_a__c,
               Subject = 'Solicitação de Pagamento - Lançar PP',
               ActivityDate = Date.today(),
               Ownerid = '005U0000001KrZy');
    tasks.add(tsk);
                        }}}}}
    
    for(Task tsk:[SELECT Id, whatid FROM Task WHERE subject = 'Solicitação de Pagamento - Malote' AND whatid IN :Trigger.new])
        hasTask.add(tsk.whatid);
    
        if ((c.Forma_de_pagamento__c != oldCase.Forma_de_pagamento__c || c.motivo_a__c != oldCase.motivo_a__c) && !hasTask.contains(c.Id)) {
            
            if (c.Forma_de_pagamento__c == 'MALOTE' && c.motivo_a__c != 'Cache'){
                if (c.Forma_de_pagamento__c == 'MALOTE' && c.motivo_a__c != 'Mostruarios'){
                    if (c.Forma_de_pagamento__c == 'MALOTE' && c.motivo_a__c != 'Laboratórios por fora do sistema'){
                        if (c.Forma_de_pagamento__c == 'MALOTE' && c.motivo_a__c != 'Devolução de venda'){
          Task t = new Task
              (whatID = c.ID,
               Solicita_o_de_Pagamento__c = c.motivo_a__c,
               Subject = 'Solicitação de Pagamento - Malote',
               ActivityDate = Date.today(),
               Tarefa_de_fechamento__c = 'SIM',
               Ownerid = '005U0000001KrZy');
      tasks.add(t);
                        }}}}}
    }
insert tasks;
}

 Thanks!

Best Answer chosen by Admin (Salesforce Developers) 
swatKatswatKat

"Execution of AfterUpdate caused by: System.ListException: List index out of bounds: 0: Trigger.CriarTarefaCase_Solicitacao_Pagamento: line 12, column 1"

 

 You are seeing this error, because the query is not returning any related tasks , and still you are trying to access  the 1st record with t[0]. In any case you have to instantiate a new task and then insert it. You seem to be reusing the list variable "t" to insert a new task.

 

There are few fundamental problems in your code.

1. You are queryng in the for loop.  (should never query within a for loop. You might hit governor limits. )

2. I am not able to understand the IF condition you have written. I thnk it can be written as in the following code.

 

As i see you are checking whther a case already has a related task with the specified subject. If not you are creating a new task. Am i right ? Tell me if u have any problems in understanding the following code :

 

 

Trigger CriarTarefaCase_Solicitacao_Pagamento on Case (after insert, after update) {
    
    Set<Id> setCaseId=new Set<Id>();
    List<Task> lstNewTask=new List<Task>();
    
    //query the task for what ids(cases) present in Trigger.new
    for(Task tsk:[SELECT Id, whatid FROM Task WHERE subject = 'Solicitação de Pagamento - Lançar PP' AND whatid IN :Trigger.new]){
        //add all the case ids which have the task with the specified subject to avoid dupliactes
        setCaseId.add(tsk.whatid);

    }
    for (Case c: trigger.new){    

         if ((c.Quantas_PP_s_pagamento__c > 0 || c.Quantidade_de_PP_s_Estojo__c > 0) 
             && c.motivo_a__c != 'Cache' && c.motivo_a__c != 'Mostruarios' && c.motivo_a__c != 'Devolução de venda'){     
           //check if the set does not contain the case Id
           if(!setCaseId.contains(c.Id)){  
               Task t=new Task();                           
               t.whatID = c.ID;
               t.Solicita_o_de_Pagamento__c = c.motivo_a__c;
               t.Subject = 'Solicitação de Pagamento - Lançar PP';
               t.ActivityDate = Date.today();
               t.Ownerid = '005U0000000EtIH';
               lstNewTask.add(t);             
            }
       }
    }
    
    insert t;
    
}       

 

 

 

 

 

All Answers

swatKatswatKat

First thing , You dont need nested for loops. To avoid the nested for loops and query within it, use a set to contain the case ids and while creating task , whether the set contains the case Id or not.

 

Set<Id> setCaseId=new Set<Id>();
for(Task tsk:[SELECT Id, whatid FROM Task WHERE subject = 'Solicitação de Pagamento - Lançar PP' AND whatid IN :Trigger.new]){
        setCaseId.add(tsk.whatid);

}


for(Case c:Trigger.New){

	//logic 
}

 

EvertonSzekeresEvertonSzekeres

I'm trying to avoid the duplicates.

 

I've readed some topics here in community.

 

And I changed the code to this:

 

Trigger CriarTarefaCase_Solicitacao_Pagamento on Case (after insert, after update) {
    
    List <Case> Caselist = new List <Case> ();
    for (Case c: trigger.new){    

                             if ((c.Quantas_PP_s_pagamento__c > 0 || c.Quantidade_de_PP_s_Estojo__c > 0) && c.motivo_a__c != 'Cache'){
                if ((c.Quantas_PP_s_pagamento__c > 0 || c.Quantidade_de_PP_s_Estojo__c > 0) && c.motivo_a__c != 'Mostruarios'){
                    if ((c.Quantas_PP_s_pagamento__c > 0 || c.Quantidade_de_PP_s_Estojo__c > 0) && c.motivo_a__c != 'Laboratórios por fora do sistema'){
                        if ((c.Quantas_PP_s_pagamento__c > 0 || c.Quantidade_de_PP_s_Estojo__c > 0) && c.motivo_a__c != 'Devolução de venda'){     
                            
                        List <Task> t = [SELECT subject FROM Task WHERE subject = 'Solicitação de Pagamento - Lançar PP' AND whatId =:c.Id];
               t[0].whatID = c.ID;
               t[0].Solicita_o_de_Pagamento__c = c.motivo_a__c;
               t[0].Subject = 'Solicitação de Pagamento - Lançar PP';
               t[0].ActivityDate = Date.today();
               t[0].Ownerid = '005U0000000EtIH';
                            insert t;
        }}}}}}

 

 But now its giving me:

"Execution of AfterUpdate caused by: System.ListException: List index out of bounds: 0: Trigger.CriarTarefaCase_Solicitacao_Pagamento: line 12, column 1"

 

Thank's

swatKatswatKat

"Execution of AfterUpdate caused by: System.ListException: List index out of bounds: 0: Trigger.CriarTarefaCase_Solicitacao_Pagamento: line 12, column 1"

 

 You are seeing this error, because the query is not returning any related tasks , and still you are trying to access  the 1st record with t[0]. In any case you have to instantiate a new task and then insert it. You seem to be reusing the list variable "t" to insert a new task.

 

There are few fundamental problems in your code.

1. You are queryng in the for loop.  (should never query within a for loop. You might hit governor limits. )

2. I am not able to understand the IF condition you have written. I thnk it can be written as in the following code.

 

As i see you are checking whther a case already has a related task with the specified subject. If not you are creating a new task. Am i right ? Tell me if u have any problems in understanding the following code :

 

 

Trigger CriarTarefaCase_Solicitacao_Pagamento on Case (after insert, after update) {
    
    Set<Id> setCaseId=new Set<Id>();
    List<Task> lstNewTask=new List<Task>();
    
    //query the task for what ids(cases) present in Trigger.new
    for(Task tsk:[SELECT Id, whatid FROM Task WHERE subject = 'Solicitação de Pagamento - Lançar PP' AND whatid IN :Trigger.new]){
        //add all the case ids which have the task with the specified subject to avoid dupliactes
        setCaseId.add(tsk.whatid);

    }
    for (Case c: trigger.new){    

         if ((c.Quantas_PP_s_pagamento__c > 0 || c.Quantidade_de_PP_s_Estojo__c > 0) 
             && c.motivo_a__c != 'Cache' && c.motivo_a__c != 'Mostruarios' && c.motivo_a__c != 'Devolução de venda'){     
           //check if the set does not contain the case Id
           if(!setCaseId.contains(c.Id)){  
               Task t=new Task();                           
               t.whatID = c.ID;
               t.Solicita_o_de_Pagamento__c = c.motivo_a__c;
               t.Subject = 'Solicitação de Pagamento - Lançar PP';
               t.ActivityDate = Date.today();
               t.Ownerid = '005U0000000EtIH';
               lstNewTask.add(t);             
            }
       }
    }
    
    insert t;
    
}       

 

 

 

 

 

This was selected as the best answer
EvertonSzekeresEvertonSzekeres

Perfect SwatKat !

 

I understood everything !!!

 

I don't know why, but my If just works in that way with my old code.

But with this new code works how it have to work!

 

Thanks SwatKat !

 

I'm trying to add more tasks with different subjects in the same trigger.

 

Do you know how?

EvertonSzekeresEvertonSzekeres

I changed the Set to find the subject and now works with more tasks.

 

Thanks agian SwatKat !

 

Trigger CriarTarefaCase_Solicitacao_Pagamento on Case (after insert, after update) {
    
    Set<String> setsubject=new Set<String>();
    List<Task> lstNewTask=new List<Task>();
    

    for(Task tsk:[SELECT Id, whatid, subject FROM Task WHERE subject = 'Solicitação de Pagamento - Lançar PP' AND whatid IN :Trigger.new]){

        setsubject.add(tsk.subject);

    }
    for (Case c: trigger.new){    

         if ((c.Quantas_PP_s_pagamento__c > 0 || c.Quantidade_de_PP_s_Estojo__c > 0) 
             && c.motivo_a__c != 'Cache' && c.motivo_a__c != 'Mostruarios' && c.motivo_a__c != 'Devolução de venda' && c.motivo_a__c != 'Laboratórios por fora do sistema'){     

           if(!setsubject.contains('Solicitação de Pagamento - Lançar PP')){
               
               Task t=new Task();                           
               t.whatID = c.ID;
               t.Solicita_o_de_Pagamento__c = c.motivo_a__c;
               t.Subject = 'Solicitação de Pagamento - Lançar PP';
               t.ActivityDate = Date.today();
               t.Ownerid = '005U0000000EtIH';
               lstNewTask.add(t);

            }
       }
    }
    
    for(Task tsk:[SELECT Id, whatid, subject FROM Task WHERE subject = 'Solicitação de Pagamento - Malote' AND whatid IN :Trigger.new]){

        setsubject.add(tsk.subject);
    }
    
    for (Case c: trigger.new){    

         if (c.forma_de_pagamento__c == 'MALOTE'
         && c.motivo_a__c != 'Cache' && c.motivo_a__c != 'Mostruarios' && c.motivo_a__c != 'Devolução de venda' && c.motivo_a__c != 'Laboratórios por fora do sistema'){     

           if(!setsubject.contains('Solicitação de Pagamento - Malote')){
               
               Task t=new Task();                           
               t.whatID = c.ID;
               t.Solicita_o_de_Pagamento__c = c.motivo_a__c;
               t.Subject = 'Solicitação de Pagamento - Malote';
               t.ActivityDate = Date.today();
               t.Ownerid = '005U0000000EtIH';
               lstNewTask.add(t);

           }
       }
    }
    insert lstNewTask;
}