How to insert records in an object only when there are no records present in it before... the following trigger inserts records in payment_schedule object(child to opportunity) when a checkbox is true.

The problem is,it keeps on inserting whenever i update something!! :(.Only once record should be inserted

trigger generatePS on Opportunity (after insert,after update) {
List<Id> projectIds = new List<Id>();
id Oid;
for(opportunity opp :Trigger.new) {
    if(opp.Generate_Payment_Schedule__c == true )
        oid = opp.id;
system.debug('Project ID'+ projectIds);  
List<Payment_Schedule__c> ps = new List<Payment_Schedule__c>();
List<Payment_Schedule_Template__c> pst = [select name,Project__c,Due_Date__c,Amount_Percentage_Made__c from Payment_Schedule_Template__c where Project__c in :projectIds ];
system.debug('PST'+ pst);

    for(Payment_Schedule_Template__c psinsert:pst)

        Payment_Schedule__c payshcedule = new Payment_Schedule__c();
        payshcedule.name = psinsert.name;
        payshcedule.Amount_Percentage_Made__c = psinsert.Amount_Percentage_Made__c;
        payshcedule.Due_Date__c = psinsert.Due_Date__c;
        payshcedule.Opportunity__c = Oid;


    system.debug('Payment Schedule to insert'+PS);

     insert ps;

What am I doing wrong ?


Ok, first of all, do you want your code to run both on insert or also on update?

If you would let the code run only on insert, when checking your box Generate_Payment_Schedule__c after the record was inserted, the code wouldn't run.

If your code should run only on insert, remove the "after update" from your trigger. (first line)

If your code should run on both insert and update, you will need to check if the Generate_Payment_Schedule__c checkbox was changed from false to true.

@Phil Hawthorn posted the following samplecode on how to compare the "old" to the "new" values (Just update when a specific field changes):

for( Account accountId : Trigger.newMap.keySet() )
  if( Trigger.oldMap.get( accountId ).Antecipado__c != Trigger.newMap.get( accountId ).Antecipado__c )
     // do something here because your field has changed

You should use such code to check for which opportunities it needs to generate the child records.


From the looks of the way you are working in your code your trigger is not bulkified to handle the update / insertion of many Opportunities in one go. All Payment_Schedule__c objects you create will be related to a single Opportunity inserted instead of 1 per Opportunity as you mentioned in your question.

To get around this I would look into using the Map container to store the project related to each opportunity and a similar map to store the Payment_Schedule_Template__c related to each project. (it might be benificial have a bit of a practice in a dev org to get the hang of using maps)

As KoenVM mentioned you will need to implement a check to look for the difference between the old field value and the new field value, this can be done as follows.

for(Opportunity opp : trigger.new)
    //If the record is being inserted and the Generate option is selected add the Project Id to the map
    if(trigger.isInsert && opp.Generate_Payment_Schedule__c == true)
        //Add the opp.project_name__c to a map or a list which can then be used later to query the Templates

    } //if the flag has been changed from false to true on update add the project Id to the map
    else if (trigger.isUpdate && (trigger.oldMap.get(opp.Id)Generate_Payment_Schedule__c == false && opp.Generate_Payment_Schedule__c == true ))
        //Add the opp.project_name__c to a map or a list which can then be used later to query the Templates


I have made a change to the solution provided by KoenVM to handle inserts as well as updates.

With the use of Maps to store the templates related to each project you can then create the Payment_Schedule__c objects and relate them to the correct Opportunity.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.