+ Start a Discussion
anyioneta1.3025054394678596E12anyioneta1.3025054394678596E12 

Bulk Update Trigger

A trigger that executed when updating a record,

It update all the other records in the database that have dates greater than the actual record bean updated in descending order.

 

 

I need help Pls!!!

 

 

=========================================CLARIFY=============================================

 

SALES TABLE

 

Action

Date

Supplies

Stock

Qty Sold

Bal Stock

Sold Price

Total Price

Customer

Edit |Del

11/21/2011 2:57 PM

60

67

14

53

$990.00

$13860.00

Oka

Edit |Del

11/21/2011 2:54 PM

0

10

3

7

$1000.00

$3000.00

Woko

Edit |Del

11/21/2011 2:52 PM

0

35

25

10

$980.00

$24500.00

Jude

Edit |Del

11/21/2011 2:51 PM

0

45

10

35

$1000.00

$10000.00

Mike

Edit |Del

11/21/2011 2:50 PM

100

100

55

45

$920.00

$50600.00

Paul

 

 

WHAT I WANT TO ACHIEVE

 

If Stock Keeper updates Oty Sold in Row three from 25 to 23

I want both Stock and Bal Stock of Row Two then Row One be updated in that order

after Row Three has updated.

 

 

Action

Date

Supplies

Stock

Qty Sold

Bal Stock

Sold Price

Total Price

Customer

Edit |Del

11/21/2011 2:57 PM

60

69

14

55

$990.00

$13860.00

Oka

Edit |Del

11/21/2011 2:54 PM

0

12

3

9

$1000.00

$3000.00

Woko

Edit |Del

11/21/2011 2:52 PM

0

35

23

12

$980.00

$24500.00

Jude

Edit |Del

11/21/2011 2:51 PM

0

45

10

35

$1000.00

$10000.00

Mike

Edit |Del

11/21/2011 2:50 PM

100

100

55

45

$920.00

$50600.00

Paul

 

NOTE: A separate before update  trigger is already handling the update of Bal Stock in Row three from 10 to 12

 

 

 

 

MY CODE

 

trigger stockKeepingUpdate on Sales__c (before update) {

List<Sales__c> sales = [SELECT Id, Name, Supplies__c, Stock__c, Qty_Sold__c, Bal_Stock__c, Sold_Price__c,   Total_Price__c, Date__c  FROM Sales__c ORDER BY Date__c DESC];
                            
    for(Sales__c s1:System.Trigger.new){
        for(Sales__c s2: sales){
            Integer val = 0;
            
            if(s1.Date__c == s2.Date__c){
                val = Integer.valueOf(s2.Qty_Sold__c - s1.Qty_Sold__c);      // 12 - 10 = 2
            }
            
            if(s1.Date__c > s2.Date__c){                
                s2.Stock__c = s2.Stock__c + val;                    //  (1st pass) 10 + 2 = 12     (2nd pass) 67 + 2 = 69
                s2.Bal_Stock__c = s2.Bal_Stock__c + val;   //  (1st pass) 7 + 2 = 8         (2nd pass)  53 + 2 = 55
            }
        }
    }
    
    update sales;  //line 21, column 5
}

 

 

ERROR MSG

 

System.DmlException: Update failed. First exception on row 2 with id a02U0000001K0TJIA0; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = a02U0000001K0TJ) is currently in trigger stockKeepingUpdate, therefore it cannot recursively update itself: []: Trigger.stockKeepingUpdate: line 21, column 5

 

Saravanan @CreationSaravanan @Creation

try to implement like this ,If you want to campare the previous value you must use Trigger.old then only you can able to compare previous value with new value.

 

trigger Value on location__c (before update) {
   if(Trigger.isUpdate && Trigger.isBefore){
       Map<Id,location__c> i=new Map<Id,location__c>();
     Map<Id,location__c> j=new Map<Id,location__c>();
    
     for(location__c l:Trigger.old)
     {
      i.put(l.id,l);
     
     }
        
     for(location__c ll:Trigger.new){
          j.put(ll.id,ll);
           if(i.get(ll.id).Pincode__c!=j.get(ll.id).Pincode__c){
                 ll.Pincode__c=1;
             }
     }
        
}


}

 

 

are u got it!

 

Starz26Starz26

You cannot UPDATE the sales object during a before update trigger using dml as the record is not committed yet....

 

Try this:

 

trigger stockKeepingUpdate on Sales__c (before update) {

List<Sales__c> sales = [SELECT Id, Name, Supplies__c, Stock__c, Qty_Sold__c, Bal_Stock__c, Sold_Price__c,   Total_Price__c, Date__c  FROM Sales__c WHERE ID NOT IN :trigger.new ORDER BY Date__c DESC];
                            
    for(Sales__c s1:System.Trigger.new){
        
       for(Sales__c s2: sales){
            Integer val = 0;
            
            if(s1.Date__c == s2.Date__c){
                val = Integer.valueOf(s2.Qty_Sold__c - s1.Qty_Sold__c);                
            }
            
            if(s1.Date__c > s2.Date__c){                
                s2.Stock__c = s2.Stock__c + val;
                s2.Bal_Stock__c = s2.Bal_Stock__c + val;
            }
        }
    }
    
    update sales;
}

 All I did was exclude the records that are in the trigger from the List of sales.

 

Now, if you want to update the values for the records that are actually in the trigger, process them at the start of the for trigger.new loop. If there is a potential that any record in the trigger (bulk) would need to be updated based on a value of another record in the trigger, then your original trigger would work and would have to be implemented in an AFTER UPDATE trigger...

 

One thing to keep in mind is that you are NOT filtering out any records and you will potentally hit governor limits based on the number of records returned, script statements, etc. It seems that this process should really be ran as a batch apex job fired from the trigger and not actually processed in the trigger itself

 

 

anyioneta1.3025054394678596E12anyioneta1.3025054394678596E12

This is the error I get:

 

System.DmlException: Update failed. First exception on row 0 with id a02U0000001K0TrIAK; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, stockKeepingUpdate: execution of BeforeUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id a02U0000001K0TJIA0; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = a02U0000001K0TJ) is currently in trigger stockKeepingUpdate, therefore it cannot recursively update itself: [] Trigger.stockKeepingUpdate: line 21, column 5: []: Trigger.stockKeepingUpdate: line 21, column 5

 

Starz26Starz26

Check to make sure there are no workflows or roll up summaries that are causing the updated records to update themselves again...

anyioneta1.3025054394678596E12anyioneta1.3025054394678596E12

This is what I have

 

SALES TABLE

 

Action

Date

Supplies

Stock

Qty Sold

Bal Stock

Sold Price

Total Price

Customer

Edit |Del

11/21/2011 2:57 PM

60

67

14

53

$990.00

$13860.00

Oka

Edit |Del

11/21/2011 2:54 PM

0

10

3

7

$1000.00

$3000.00

Woko

Edit |Del

11/21/2011 2:52 PM

0

35

25

10

$980.00

$24500.00

Jude

Edit |Del

11/21/2011 2:51 PM

0

45

10

35

$1000.00

$10000.00

Mike

Edit |Del

11/21/2011 2:50 PM

100

100

55

45

$920.00

$50600.00

Paul

 

 

WHAT I WANT TO ACHIEVE

 

If Stock Keeper updates Oty Sold in Row three from 25 to 23

I want both Stock and Bal Stock of Row Two then Row One be updated in that order

after Row Three has updated.

 

 

Action

Date

Supplies

Stock

Qty Sold

Bal Stock

Sold Price

Total Price

Customer

Edit |Del

11/21/2011 2:57 PM

60

69

14

55

$990.00

$13860.00

Oka

Edit |Del

11/21/2011 2:54 PM

0

12

3

9

$1000.00

$3000.00

Woko

Edit |Del

11/21/2011 2:52 PM

0

35

23

12

$980.00

$24500.00

Jude

Edit |Del

11/21/2011 2:51 PM

0

45

10

35

$1000.00

$10000.00

Mike

Edit |Del

11/21/2011 2:50 PM

100

100

55

45

$920.00

$50600.00

Paul

 

NOTE: A separate before update  trigger is already handling the update of Bal Stock in Row three from 10 to 12

Starz26Starz26

"NOTE: A separate before update  trigger is already handling the update of Bal Stock in Row three from 10 to 12"

 

You CANNOT have two before update triggers operating on the same record. If you have multiple before update trigers on the same object, one can be used to update the records in the trigger using trigger.new and the other can update other objects but they BOTH CANNOT update the same object....

 

I may not be following you with your objects but please take this into consideration and review your code:  Once a record is in a before update trigger, NO OTHER trigger, workflow, or roll up summary can update the record until the context of the first trigger (before update) is completed.

 

 

Also, I do not believe that you can control the order in which records are updated. The only way to do this is to gather the records, sort them, update them in memory, and then perform the DML on the final list.

anyioneta1.3025054394678596E12anyioneta1.3025054394678596E12

BASED ON YOUR ADVICE I TRIED TO PUT EVERYTHING IN ONE TRIGGER

 

NOTE: The block marked Red is where I need you to look at which is where the error is coming from.

 

 

CODE:

trigger stockKeeping on Sales__c (before insert, before update, after update) {
    
    if(Trigger.isInsert && Trigger.isBefore){
        
        List<Product__c> productList = [SELECT Id, Name, Stock__c, Bal_Stock__c FROM Product__c];
    
        for(Sales__c sales: Trigger.new){
            sales.Stock__c = sales.A__c;
            sales.Bal_Stock__c = sales.B__c;
            sales.Supplies__c = sales.C__c;  
            sales.Purchased_Price__c = sales.D__c;
            
            for (Product__c prod: productList){               
               if( prod.Id ==  sales.Product__c){
                   prod.Stock__c = sales.Stock__c;
                   prod.Bal_Stock__c = sales.Bal_Stock__c;                       
                   break;
               }
            }           
        }
        
        update productList;
    }
    
        
     Decimal val = 0;
     
     if(Trigger.isUpdate && Trigger.isBefore){
       
        Map<Id,Sales__c> salesO = new Map<Id,Sales__c>();
        Map<Id,Sales__c> salesN = new Map<Id,Sales__c>();
        
        for(Sales__c salesOld: Trigger.old){
             SalesO.put(salesOld.Id,salesOld);
        }
         
        for(Sales__c salesNew: Trigger.new){  
                  
            //Decimal val = 0;
            
            SalesN.put(salesNew.Id,salesNew);
                      
            if(SalesN.get(salesNew.Id).Name == SalesO.get(salesNew.Id).Name){                     
                 val = salesNew.U__c = SalesO.get(salesNew.Id).Qty_Sold__c - SalesN.get(salesNew.Id).Qty_Sold__c;
                 salesNew.Bal_Stock__c += salesNew.U__c;
                 salesNew.Date__c = SalesO.get(salesNew.Id).Date__c; //Old Date must be retained
             }                                                          
        }                                
    }    
    
    if(Trigger.isUpdate && Trigger.isAfter){
    
        List<Sales__c> salesList = [SELECT Id, Name, Supplies__c, Stock__c, Qty_Sold__c, Bal_Stock__c, U__c,
                                    Sold_Price__c, Total_Price__c, Date__c  FROM Sales__c                                   
                                    WHERE ID NOT IN :trigger.new ORDER BY Date__c DESC];
                                    
        for(Sales__c sales : Trigger.old){                       
          
            for(Sales__c sl : salesList){                
                if( (sales.Name != sl.Name) && (sales.Date__c >= sl.Date__c)){
                    sl.Stock__c += val;
                    sl.Bal_Stock__c += val;
                }
            }
        }
        update salesList;
    }  
}

 

 

ERROR:

 

Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger stockKeeping caused an unexpected exception, contact your administrator: stockKeeping: execution of AfterUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id a02U0000001K0TrIAK; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, stockKeeping: maximum trigger depth exceeded Sales trigger event AfterUpdate for [a02U0000001K0TJ] Sales trigger event AfterUpdate for [a02U0000001K0Sp, a02U0000001K0Sz, a02U0000001K0T4, a02U0000001K0T9, a02U0000001K0TE, a02U0000001K0Tm, a02U0000001K0Tr] Sales trigger event AfterUpdate for [a02U0000001K0TJ] Sales trigger event AfterUpdate for [a02U0000001K0Sp, a02U0000001K0Sz, a02U0000001K0T4, a02U0000001K0T9, a02U0000001K0TE, a02U0000001K0Tm, a02U0000001K0Tr] Sales trigger event AfterUpdate for [a02U0000001K0TJ] Sales trigger event AfterUpdate for [a02U0000001K0Sp, a02U0000001K0Sz, a02U0000001K0T4, a02U0000001K0T9, a02U0000001K0TE, a02U0000001K0Tm, a02U0000001K0Tr] Sales trigger event AfterUpdate for [a02U0000001K0TJ] Sales trigger event AfterUpdate for [a02U0000001K0Sp, a02U0000001K0Sz, a02U0000001K0T4, a02U0000001K0T9, a02U0000001K0TE, a02U0000001K0Tm, a02U0000001K0Tr] Sales trigger event AfterUpdate for [a02U0000001K0TJ] Sales trigger event AfterUpdate for [a02U0000001K0Sp, a02U0000001K0Sz, a02U0000001K0T4, a02U0000001K0T9, a02U0000001K0TE, a02U0000001K0Tm, a02U0000001K0Tr] Sales trigger event AfterUpdate for [a02U0000001K0TJ] Sales trigger event AfterUpdate for [a02U0000001K0Sp, a02U0000001K0Sz, a02U0000001K0T4, a02U0000001K0T9, a02U0000001K0TE, a02U0000001K0Tm, a02U0000001K0Tr] Sales trigger event AfterUpdate for [a02U0000001K0TJ] Sales trigger event AfterUpdate for [a02U0000001K0Sp, a02U0000001K0Sz, a02U0000001K0T4, a02U0000001K0T9, a02U0000001K0TE, a02U0000001K0Tm, a02U0000001K0Tr] Sales trigger event AfterUpdate for [a02U0000001K0TJ] Sales trigger event AfterUpdate for [a02U0000001K0Sp, a02U0000001K0Sz, a02U0000001K0T4, a02U0000001K0T9, a02U0000001K0TE, a02U0000001K0Tm, a02U0000001K0Tr]: []: Trigger.stockKeeping: line 84, column 9
 

 

Pls Any Hint Anybody!!!

 

Starz26Starz26

So here is what is happenning:

 

1. Record A causes the trigger to fire

2. The after update grabs all records BUT record A, updates the values and then updates the records

3. This causes the after update to fire again which pulls in record A since it was not in the list that just fired the trigger

4. This causes all records BUT A to be grabbed again

5. the cycle continues.

 

You will need to set up a global variable to prevent recursion. Take a look at this topic to assist you in solving:

 

http://www.salesforce.com/docs/developer/cookbook/Content/apex_controlling_recursive_triggers.htm

 

You need to set this up to set during the after update trigger and check the value before running the after update trigger. If the value is set, skip the trigger. This will allow it to run the one time and not on the subsequent passes