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
Rafael.Martins.SantosRafael.Martins.Santos 

how update fields using trigger and APEX class?

Hi,
I need update the fields when I create a new register and when I update the same.
I created a trigger that execute a method that make this update.

When I create a new register This method works, and when I try update occurs a error.

Can you evaluate my code and see if I did the right way, and what is wrong?

Trigger code:
Trigger INSERT
trigger CalcularTudoTrigger on Item_de_oportunidade__c (after insert) {
    
    Item_de_oportunidade__c item = new Item_de_oportunidade__c();
    item = [SELECT Id, Name, Margin__c, Sales_Type__c, nome_oportunidade__c, Category__c, Extra_Expenses__c
            FROM Item_de_oportunidade__c
               WHERE Id IN : Trigger.newMap.keyset() limit 1];
    
    Opportunity op = new Opportunity();
    op = [SELECT Id FROM Opportunity WHERE Id = : item.nome_oportunidade__c];

    if(trigger.isAfter){
         if(trigger.isInsert){
            AutomatizaCalculos.inserirCalculoMVS(item.Id, op.Id, item.Sales_Type__c, item.Category__c, item.Margin__c, item.Extra_Expenses__c);
         }
    }
}

Trigger UPDATE
trigger CalcularAtualizacao on Item_de_oportunidade__c (before update) {
    
    Item_de_oportunidade__c item = new Item_de_oportunidade__c();
    item = [SELECT Id, Name, Margin__c, Sales_Type__c, nome_oportunidade__c, Category__c, Extra_Expenses__c
            FROM Item_de_oportunidade__c
               WHERE Id IN : Trigger.newMap.keyset() limit 1];
    
    Opportunity op = new Opportunity();
    op = [SELECT Id FROM Opportunity WHERE Id = : item.nome_oportunidade__c];

    if(trigger.isBefore){
         if(trigger.isUpdate){
            AutomatizaCalculos.inserirCalculoMVS(item.Id, op.Id, item.Sales_Type__c, item.Category__c, item.Margin__c, item.Extra_Expenses__c);
         }
    }

}

APEX CODE:

global class AutomatizaCalculos {
    
    public static void inserirCalculoMVS(String id_item, String regional, String tipoVenda, String categoria, Decimal margem, Decimal gastos){
        Item_de_oportunidade__c item = new Item_de_oportunidade__c();
        item = [SELECT Id, Name, Sales_Type__c, Category__c, Margin__c, Extra_Expenses__c FROM Item_de_oportunidade__c WHERE Id = : id_item];
        
        if(regional == 'AR'){
            if(tipoVenda == 'FEE'){
                item.MVS__c = (margem * 0.956) - gastos;
                inserirCalculoComissao(item.MVS__c, item.Id, categoria);
            }else{
                item.MVS__c = margem - gastos;
                inserirCalculoComissao(item.MVS__c, item.Id, categoria);
            }
            
        }else if(regional == 'CL' || regional == 'US'){
                item.MVS__c = margem - gastos;
            inserirCalculoComissao(item.MVS__c, item.Id, categoria);
        }else{
            if(tipoVenda == 'FEE'){
                item.MVS__c = (margem * 0.8725)-gastos;
                inserirCalculoComissao(item.MVS__c, item.Id, categoria);
            }else{
                item.MVS__c = margem - gastos;
                inserirCalculoComissao(item.MVS__c, item.Id, categoria);
            }  
        }
    update item;
    }
    public static void inserirCalculoComissao(Decimal mvs, String item_id, String categoria){
        Item_de_oportunidade__c item = new Item_de_oportunidade__c();
        item = [SELECT Id, Name, Margin__c, MVS__c, MS_Customer__c, Category__c FROM Item_de_oportunidade__c WHERE Id = : item_id];
        if(categoria == 'IT SERVICES' || categoria == 'MANAGED SERVICES'){
            if(item.MS_Customer__c == true){
                item.Fee_Pre_Sales__c = mvs *0.015;
                item.Fee_Pre_Manager__c = mvs * 0.075;
                item.Fee_Pre_Rep__c = mvs * 0.03;
            }else{
                item.Fee_Pre_Sales__c = mvs *0.03;
                item.Fee_Pre_Manager__c = mvs * 0.015;
                item.Fee_Pre_Rep__c = mvs * 0.06;
            }
            
        }else{
            if(item.MS_Customer__c == true){
                item.Fee_Pre_Sales__c = mvs *0.015;
                item.Fee_Pre_Manager__c = mvs * 0.075;
                item.Fee_Pre_Rep__c = mvs * 0.03;
            }else{
                item.Fee_Pre_Sales__c = mvs *0.02;
                item.Fee_Pre_Manager__c = mvs * 0.01;
                item.Fee_Pre_Rep__c = mvs * 0.04;
            } 
        }
        
        update item;
    }
}

Thanks
Rafael
Best Answer chosen by Rafael.Martins.Santos
karthikeyan perumalkarthikeyan perumal
Hello Rafael, 

which means your trigger fall in recurcive calls. 

make sure your trigger run only once at time. 

Just follow the point : 

You can create a class which holds a static boolean variable. You've to check the value of variable before entering the trigger. And after the trigger has updated the record, you can set that variable. It will cause the trigger to run only once for one DML operation.

Ex: 

Class:
 
public Class checkRecursive{
    private static boolean run = true;
    public static boolean runOnce(){
    if(run){
     run=false;
     return true;
    }else{
        return run;
    }
    }
}

Trigger :
 
trigger updateTrigger on anyObject(after update) {

    if(checkRecursive.runOnce())
    {
    //write your code here            
    }

}

Hope this will help you to solve the issue. 

Referece from : 

https://help.salesforce.com/articleView?id=000133752&language=en_US&type=1


Thanks
karthik
 

All Answers

karthikeyan perumalkarthikeyan perumal
Hello Rafael, 

i have updated your  updated your update trigger with System.Debug statement let me know how many  log messgae you are getting based on that we will work on the code. 
 
trigger CalcularAtualizacao on Item_de_oportunidade__c (before update) {
    
    Item_de_oportunidade__c item = new Item_de_oportunidade__c();
    item = [SELECT Id, Name, Margin__c, Sales_Type__c, nome_oportunidade__c, Category__c, Extra_Expenses__c
            FROM Item_de_oportunidade__c
               WHERE Id IN : Trigger.newMap.keyset() limit 1];
    
    Opportunity op = new Opportunity();
    op = [SELECT Id FROM Opportunity WHERE Id = : item.nome_oportunidade__c];

    if(trigger.isBefore){
	     System.Debug("Before Statement Executed");
         if(trigger.isUpdate){
		 System.Debug("Before Updated Statement Executed");
         AutomatizaCalculos.inserirCalculoMVS(item.Id, op.Id, item.Sales_Type__c, item.Category__c, item.Margin__c, item.Extra_Expenses__c);
         System.Debug("Before Updated Statement Executed-Successfully");
         }
    }

}

Hope this will help you. 

Thanks
karthik
 
Rafael.Martins.SantosRafael.Martins.Santos
Hi karthik,
Thanks for your help
follow the messages

12:04:14:126 USER_DEBUG [17]|DEBUG|Before Statement Executed
12:04:14:126 USER_DEBUG [21]|DEBUG|Before Updated Statement Executed

The error I'm getting is:
Line: 5, Column: 1
System.DmlException: Update failed. First exception on row 0 with id a0641000005DEyjAAG; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, CalcularAtualizacao: execution of BeforeUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id a0641000005DEyjAAG; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = a0641000005DEyj) is currently in trigger CalcularAtualizacao, therefore it cannot recursively update itself: [] Class.AutomatizaCalculos.inserirCalculoComissao: line 56, column 1 Class.AutomatizaCalculos.inserirCalculoMVS: line 25, column 1 Trigger.CalcularAtualizacao: line 23, column 1: []
karthikeyan perumalkarthikeyan perumal
Hello Rafael, 

which means your trigger fall in recurcive calls. 

make sure your trigger run only once at time. 

Just follow the point : 

You can create a class which holds a static boolean variable. You've to check the value of variable before entering the trigger. And after the trigger has updated the record, you can set that variable. It will cause the trigger to run only once for one DML operation.

Ex: 

Class:
 
public Class checkRecursive{
    private static boolean run = true;
    public static boolean runOnce(){
    if(run){
     run=false;
     return true;
    }else{
        return run;
    }
    }
}

Trigger :
 
trigger updateTrigger on anyObject(after update) {

    if(checkRecursive.runOnce())
    {
    //write your code here            
    }

}

Hope this will help you to solve the issue. 

Referece from : 

https://help.salesforce.com/articleView?id=000133752&language=en_US&type=1


Thanks
karthik
 
This was selected as the best answer
Rafael.Martins.SantosRafael.Martins.Santos
Hi karthik,

Thank you very much, now the update is working, thanks for your help.