+ Start a Discussion
Abhijeet Purohit01Abhijeet Purohit01 

Trigger inserting a record twice

HI. Can anyone help me what mistake am I doing here. The problem is the trigger is inserting the record for twice.

 

How to stop it? 

 

trigger SalesOrder on Sales_Order__c (after update){

//delete savepoint
    Savepoint sp = Database.setSavepoint();
    
    List <Sales_Order_Status_History__c> sosh = new List<Sales_Order_Status_History__c>();
   if(Trigger.isUpdate){
        for(Sales_Order__c  so : Trigger.new){
            if(so.Sales_Order_Status__c == 'Order Acknowledgement' ||
               so.Sales_Order_Status__c == 'Customer Inputs' ||
               so.Sales_Order_Status__c == 'Scheduling'  ||
               so.Sales_Order_Status__c == 'Order Acceptance' ||
               so.Sales_Order_Status__c == 'Design Queue' ||
               so.Sales_Order_Status__c == 'Design' ||
               so.Sales_Order_Status__c == 'Punching/Bending Queue' ||
               so.Sales_Order_Status__c == 'Punching/Bending' ||
               so.Sales_Order_Status__c == 'Fabrication Queue' ||
               so.Sales_Order_Status__c == 'Fabrication' ||
               so.Sales_Order_Status__c == 'Customer Inspection' ||
               so.Sales_Order_Status__c == 'Powder Coating Queue' ||
               so.Sales_Order_Status__c == 'Pre-Treatment & Powder Coating' ||
               so.Sales_Order_Status__c == 'Assembly Queue' ||
               so.Sales_Order_Status__c == 'Assembly' ||
               so.Sales_Order_Status__c == 'Finished Goods Queue' ||
               so.Sales_Order_Status__c == 'Finished Goods' ||
               so.Sales_Order_Status__c == 'Pending Closure' ||
               so.Sales_Order_Status__c == 'Closed' ||
               so.Sales_Order_Status__c == 'Cancelled' ){
               
                   sosh.add(new Sales_Order_Status_History__c(Status__c = so.Sales_Order_Status__c, SO_No__c = so.Name,Record_Created_Date__c=so.createdDate,Last_Modified_Date__c=so.systemModStamp,Record_User__c=userinfo.getUserName()));   
            }


     
        }

 

//delete try-catch
        try {

            insert sosh;

        } catch (DmlException e) {
              Database.rollback(sp);
          }              
 }

HariDineshHariDinesh

 

Hi,

 

By below statement you are clearly creating new set of records and trying to insert.

That’s y your trigger might inserting records twice.

 

sosh.add(new Sales_Order_Status_History__c(Status__c = so.Sales_Order_Status__c, SO_No__c = so.Name,Record_Created_Date__c=so.createdDate,Last_Modified_Date__c=so.systemModStamp,Record_User__c=userinfo.getUserName()));  

 

Here what you what to achieve through trigger?

Remove the above statements and write code accordingly.

 

OR

 

Explain what you are planning to do, if you face any difficulty, post it. someone can help you.

 

Abhijeet Purohit01Abhijeet Purohit01

I am trying to run a trigger which will insert the following:

Status__c,

SO_No__c,

Record_Created_Date__c, 

Last_Modified_Date__c,

Record_User__c 

 

in another object's record iff the condition is satisfied. But the problem is the records are getting inserted twice.  I want it to insert only for once. I don't know what mistake am doing and how to over come.....

HariDineshHariDinesh

Hi,

 

The problem is like,

your trigger is firing for every update operation, for every update operation it is firing and creating new reocrds in Sales_Order_Status_History__c object.

 

To solve this few questions here.

1) Is there any relation between 2 objects?

2) is there any problem if the trigger Event is changed to Before/After Insert

 

If Ans is "No" for both questions then below code will work for you and will create records only one time in Sales_Order_Status_History__c object.

 

Change the trigger event to After insert

 

trigger SalesOrder on Sales_Order__c (after insert)
{

//delete savepoint
    Savepoint sp = Database.setSavepoint();
    
    List <Sales_Order_Status_History__c> sosh = new List<Sales_Order_Status_History__c>();
   if(Trigger.isUpdate)
   
   {
        for(Sales_Order__c  so : Trigger.new)
		{
            if(so.Sales_Order_Status__c == 'Order Acknowledgement' ||
               so.Sales_Order_Status__c == 'Customer Inputs' ||
               so.Sales_Order_Status__c == 'Scheduling'  ||
               so.Sales_Order_Status__c == 'Order Acceptance' ||
               so.Sales_Order_Status__c == 'Design Queue' ||
               so.Sales_Order_Status__c == 'Design' ||
               so.Sales_Order_Status__c == 'Punching/Bending Queue' ||
               so.Sales_Order_Status__c == 'Punching/Bending' ||
               so.Sales_Order_Status__c == 'Fabrication Queue' ||
               so.Sales_Order_Status__c == 'Fabrication' ||
               so.Sales_Order_Status__c == 'Customer Inspection' ||
               so.Sales_Order_Status__c == 'Powder Coating Queue' ||
               so.Sales_Order_Status__c == 'Pre-Treatment & Powder Coating' ||
               so.Sales_Order_Status__c == 'Assembly Queue' ||
               so.Sales_Order_Status__c == 'Assembly' ||
               so.Sales_Order_Status__c == 'Finished Goods Queue' ||
               so.Sales_Order_Status__c == 'Finished Goods' ||
               so.Sales_Order_Status__c == 'Pending Closure' ||
               so.Sales_Order_Status__c == 'Closed' ||
               so.Sales_Order_Status__c == 'Cancelled' ){
               
                   sosh.add(new Sales_Order_Status_History__c(Status__c = so.Sales_Order_Status__c, SO_No__c = so.Name,Record_Created_Date__c=so.createdDate,Last_Modified_Date__c=so.systemModStamp,Record_User__c=userinfo.getUserName()));   
            }

     
        }
 
//delete try-catch
        try {
            insert sosh;
        } catch (DmlException e) {
              Database.rollback(sp);
          }              
 }

 

Abhijeet Purohit01Abhijeet Purohit01

Thanks for the reply. I will try to explain the requirement.. Its like this:

 There are 2 custom objects  Sales_Order__c and Sales_Order_Status_History__c. There is no relationship between the two objects.

There is a picklist field in Sales_Order__c called Sales_Order_Status__c. On change (update) in the value of

Sales_Order_Status__cfield a trigger should be fired which should store the values for the following fields:

Status__c, SO_No__c,Record_Created_Date__c,Last_Modified_Date__c,Record_User__c

as a record in the Sales_Order_Status_History__c object.

This should happen iff there is a change(update) in value of the picklist field Sales_Order_Status__c.

 

My problems:

1. Everytime the value of the picklist is being changed a record is getting inserted into the Sales_Order_Status_History__c for twice.

I am trying to make sure the record is inserted only for once.

2. How to calculate the time taken( i.e. duration) to change the value of Sales_Order_Status__c from its current value to some other value?

 

HariDineshHariDinesh

Hi,

 

It seems there is no problem with your code.

I have tested your code by creating objects in my org. It is working as expected.

 

In my org records are not getting created 2 times. 

Why it is happening in you org?

 

The reasons might be:

1)Check is there any workflows on Sales_Order__c object that cause of field update and causing trigger fire one more time.

 2) By mistake you might create 2 triggers with same code.

 

You can observe the debug logs also, how many times the trigger is firing.

And try to observe any work flows are firing in debug logs, and try add some debug statements and find what really happening in your  org.

 

For Que 2)

 

1) Do you want to calculate the time take for SF to change the pciklist value?

OR

2) Are you looking for time difference between Last updated and current update of that picklist?

 

Let me know your comments regarding both que..

 

TejTej

Probably the trigger is getting fired twice.

Are there any workflows on the first object updaing any field causing the trigger to run more than once?

 

if so, u can either write a trigger helper class to prevent the trigger from running more than once or bring the workflow logic in to before trigger and deactivate the workflow.

 

Refer to the below cook book recipe for Trigger helper

 

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

Abhijeet Purohit01Abhijeet Purohit01

1. Yes there are workflows related to the sales_Order__c object but the workflows are for some other purpose. But deactivating them is not  a solution. Right?

 

2. When any user changes the status value then the present timing of the status and the previous status timing should be recorded to find the duration. Something like this..

 

Duration = lastModifiedDatePresentStatus-lastModifiedDatePreviousStatus.

Abhijeet Purohit01Abhijeet Purohit01

1. Yes there are workflows related to the sales_Order__c object but the workflows are for some other purpose. But deactivating them is not  a solution. Right?

 

2. When any user changes the status value then the present timing of the status and the previous status timing should be recorded to find the duration. Something like this..

 

Duration = lastModifiedDatePresentStatus-lastModifiedDatePreviousStatus.

Abhijeet Purohit01Abhijeet Purohit01

Thanks for the help. My problem is solved. There was a workflow which was retriggering the code. But I don't know whether deactivating the workflow is the ultimate solution. 

TejTej

what i meant was, bring the work flow logic into the trigger and deactivate the work flow.

 

You can always look into trigger helper if thats not possible.

HariDineshHariDinesh

Hi,

 

Good to hear that your problem is solved.

 

Don't deactivate the workflow that is not the good solution.

But need to know complete scenario (WF rule criteria, etc) to handle this by keeping workflow Active.

 

 

If you are ok with to deactivate the workflow make sure the thing which are happening with that workflow were done with trigger and then make the workflow deactivate.

 

If solution/Suggestion resolves your problem make it as marked so that other might also benefits with the solution


HariDinesh.K