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
Matt FieldMatt Field 

Need help with a trigger to update a field

Hi all.  I am looking for some help with what should be a simple trigger.  What I want to do is update the Billing_Date__c field in the Opportunity object with the value from the Projected_Live_Date from the Milestone1_Project__c object when the following conditions are met:  1. Milestone1_Project__c.Status = "Project on Target", 2. Milestone1_Project__c.Projected_Live_Date__c != null, and 3. Opportunity.Probability = 95%.  Here is what I have so far:

trigger UpdateBillDate on Milestone1_Project__c (before insert) {
   
    List<ID> OppIds = New List<ID>();
   
    for(Milestone1_Project__c o : Trigger.new){
        if(o.Status__c == 'Project on Target' && o.Projected_Live_Date__c != null){
            OppIds.add(o.Opportunity);
        }
    }
   
    List<Opportunity> oppList = [SELECT id, Billing_Date__c FROM Opportunity WHERE
                                    id in :OppIds];
    for(integer i = 0 ; i < oppList.size(); i++){
        oppList[i].Billing_Date__c = Milestone1_Project__r.Projected_Live_Date__c;
    }
   
    update oppList;
}

Any help will be GREATLY appreciated.

Thanks
justin_sfdcjustin_sfdc
Hi Matt,
Could you change your for loop like this and see if that works;
List<Opportunity> oppList = [SELECT id, Billing_Date__c FROM Opportunity WHERE
                                    id in :OppIds];
for(Opportunity opp:oppList) {
        opp.Billing_Date__c = Milestone1_Project__r..Projected_Live_Date__c;
    }
  
    update oppList;

Thanks!
Matt FieldMatt Field
Hi Justin,

Made the change, but I am getting an error that says "Variable does not exist: Milestone1_Project__r.Projected_Live_Date__c.
I'm not sure why I'm getting that error.  I have a lookup field in Opportunity titled "Project_Lookup" so I tried it both the way listed above and as Project_Lookup__r.Projected_Live_Date__c and I get the same error.  Any ideas?

Thanks,
Matt
justin_sfdcjustin_sfdc
Hey,
I had a hintch it wouldnt work. Well, even though you have the lookup to that object, you can retreive the value from the query.

List<ID> OppIds = New List<ID>();
    for(Milestone1_Project__c o : Trigger.new){
        if(o.Status__c == 'Project on Target' && o.Projected_Live_Date__c != null){
            OppIds.add(o.Opportunity);
        }
    }
  
    List<Opportunity> oppList = [SELECT id, Billing_Date__c FROM Opportunity WHERE
                                    id in :OppIds];
List<Milestone1_Project__c> mproj= [Select Projected_Live_Date__c from Milestone1_Project__c where opportunity in: OppIds];
    for(Opportunity opp:oppList) {
        oppList[i].Billing_Date__c = mproj.Projected_Live_Date__c;
    }
  
    update oppList;
}

You might have to tweak it similarly to assign the value to the billing date but it should work.
Matt FieldMatt Field
Thanks for all your help, Justin.  I really appreciate it.
I am now getting an error that says "Variable does not exist: i for line 15.  Here is what the trigger currently looks like:

trigger UpdateBillDate on Milestone1_Project__c (before insert) {
   
    List<ID> OppIds = New List<ID>();
   
    for(Milestone1_Project__c o : Trigger.new){
        if(o.Status__c == 'Project on Target' && o.Projected_Live_Date__c != null){
            OppIds.add(o.Opportunity);
        }
    }
   
    List<Opportunity> oppList = [SELECT id, Billing_Date__c FROM Opportunity WHERE
                                    id in :OppIds];
    List<Milestone1_Project__c> mproj = [SELECT OpportunityID__c, Projected_Live_Date__c FROM Milestone1_Project__c WHERE Opportunity in: OppIds];
    for(Opportunity opp:oppList){
        oppList[i].Billing_Date__c = mproj.Projected_Live_Date__c;
    }
   
    update oppList;
}
justin_sfdcjustin_sfdc
Could you try this instead:

List<ID> OppIds = New List<ID>();
  
    for(Milestone1_Project__c o : Trigger.new){
        if(o.Status__c == 'Project on Target' && o.Projected_Live_Date__c != null){
            OppIds.add(o.Opportunity);
        }
    }
  
    List<Opportunity> oppList = [SELECT id, Billing_Date__c FROM Opportunity WHERE
                                    id in :OppIds];
    List<Milestone1_Project__c> mproj =[SELECT OpportunityID__c, Projected_Live_Date__c FROM Milestone1_Project__c WHERE Opportunity in: OppIds];
    for (Milestone1_Project__c milestone: mproj) {
            for(Opportunity opp:oppList){
                    oppList[i].Billing_Date__c = milestone.Projected_Live_Date__c;
            }
      }
  
    update oppList;
}
Matt FieldMatt Field
Same error, this time at line 16.
justin_sfdcjustin_sfdc
Hi matt, Sorry, we both missed it! Line 16: * oppList[i].Billing_Date__c = milestone.Projected_Live_Date__c;* *Change it to:* * opp.Billing_Date__c = milestone.Projected_Live_Date__c;* *Thanks!*
Matt FieldMatt Field
That took care of that error, thanks!!

Another one popped up.  Line 7: Invalid field Opportunity for SObject Milestone1_Project__c.  The line of code is:
OppIds.add(o.Opportunity);
justin_sfdcjustin_sfdc
Hi Matt, for that you need to know the API name of the opportunity ID field in the Milestone Project Object. If you go to the Milestone Object, there should be a Lookup relationship field to Opportunity, check the API name of that field and this should take care of this. Thanks!
Matt FieldMatt Field
That did it Justin.  No errors.

Sadly, when I change the Projected Live Date in the project, it isn't changing the Billing Date on the opportunity.

This is the code I ended up with:

trigger UpdateBillDate on Milestone1_Project__c (before insert, before update) {

List<ID> OppIds = New List<ID>();
 
    for(Milestone1_Project__c o : Trigger.new){
        if(o.Status__c == 'Project on Target' && o.Projected_Live_Date__c != null){
            OppIds.add(o.OpportunityID__c);
        }
    }
 
    List<Opportunity> oppList = [SELECT id, Billing_Date__c FROM Opportunity WHERE
                                    id in :OppIds];
    List<Milestone1_Project__c> mproj =[SELECT OpportunityID__c, Projected_Live_Date__c FROM Milestone1_Project__c WHERE OpportunityID__c in: OppIds];
    for (Milestone1_Project__c milestone: mproj) {
            for(Opportunity opp:oppList){
                    opp.Billing_Date__c = milestone.Projected_Live_Date__c;
            }
      }
 
    update oppList;
}
justin_sfdcjustin_sfdc
Hi Matt, Please check the && or || condition based on your need. Currently with the code you have below, the trigger will only fire when Status equals to Project on Target AND Projected Live Date is not NULL AND PRojected_live_Date is not equal to its previous value; trigger UpdateBillDate on Milestone1_Project__c (before insert, before update) { List OppIds = New List(); for(Milestone1_Project__c o : Trigger.new){ if(o.Status__c == 'Project on Target' && o.Projected_Live_Date__c != null && Projected_Live_Date__c!=Trigger.oldMap.get(o.Projected_Live_Date__c){ OppIds.add(o.OpportunityID__c); } } List oppList = [SELECT id, Billing_Date__c FROM Opportunity WHERE id in :OppIds]; List mproj =[SELECT OpportunityID__c, Projected_Live_Date__c FROM Milestone1_Project__c WHERE OpportunityID__c in: OppIds]; for (Milestone1_Project__c milestone: mproj) { for(Opportunity opp:oppList){ opp.Billing_Date__c = milestone.Projected_Live_Date__c; } } update oppList; } Thanks! :)
Matt FieldMatt Field
Hi Justin,

I appreciate all of your help with this, especially on a Friday night!  I have gone in and removed each of the criteria one at a time and it never updated the Billing Date field.  I ran the debug logs and this is what I saw with the oppList and mproj lists:

17:03:40.270 (270048000)|VARIABLE_ASSIGNMENT|[11]|this.oppList|{"serId":1,"value":[{"serId":2,"value":{"Billing_Date__c":"2013-08-24T00:00:00.000Z","Id":"0064000000Rux8uAAB"}}]}|0x2313e018
17:03:40.270 (270061000)|STATEMENT_EXECUTE|[13]
17:03:40.270 (270067000)|HEAP_ALLOCATE|[13]|Bytes:109
17:03:40.270 (270075000)|HEAP_ALLOCATE|[13]|Bytes:4
17:03:40.270 (270247000)|SOQL_EXECUTE_BEGIN|[13]|Aggregations:0|select OpportunityID__c, Projected_Live_Date__c from Milestone1_Project__c where OpportunityID__c IN :tmpVar1
17:03:40.274 (274027000)|SOQL_EXECUTE_END|[13]|Rows:0
17:03:40.274 (274045000)|HEAP_ALLOCATE|[13]|Bytes:4
17:03:40.274 (274058000)|HEAP_ALLOCATE|[13]|Bytes:0
17:03:40.274 (274072000)|HEAP_ALLOCATE|[13]|Bytes:4
17:03:40.274 (274108000)|VARIABLE_ASSIGNMENT|[13]|this.mproj|{"serId":1,"value":[]}|0x2313e018

I don't know if it means anything, but I noticed that in oppList the Billing_Date__c field shows a date, but in mproj, no date shows.  Do you think that might mean anything?

Thanks again!!

Matt
justin_sfdcjustin_sfdc
Not a problem at all! This means that the list mproj is empty. Try this; instead of mproj, we can directly get to the project_live_date of the current object. for (Milestone1_Project__c milestone: Trigger.new) { for(Opportunity opp:oppList){ opp.Billing_Date__c = milestone.Projected_Live_Date__c; } } This should do it! Thanks!
Matt FieldMatt Field
You are a genius, my friend.  Thank you very much for all of your help with this.

One last question.  The criteria is currently only looking at the Project object.  If I wanted to add a critieria from the Opportunity object, would I add another For - If statement?  Would I change this:

for(Milestone1_Project__c o : Trigger.new){
        if(o.Status__c == 'Project on Target' && o.Projected_Live_Date__c != null){
            OppIds.add(o.OpportunityID__c);
        }
    }
To something like this:

for(Milestone1_Project__c o : Trigger.new){
        if(o.Status__c == 'Project on Target' && o.Projected_Live_Date__c != null){
            OppIds.add(o.OpportunityID__c);
        }
    }
for(Opportunity opp : Trigger.new){
        if(Probability == 95){
            OppIds.add(o.OpportunityID__c);
   }
}
justin_sfdcjustin_sfdc
Thanks! Trigger.new means that it is passing you list of new versions of sOjbect records when the trigger is firing. In your case, the trigger is on Project object therefore, setting for(Opportunity opp: trigger.new) would not work. When you say criteria for Opportunity object, what are you exactly referring to? If I understand your requirement correctly, you want to change the status on opportunity on all three conditions you have then you will be adding just the if condition in opportunity like this; for(Opportunity opp:oppList){ if(opp.Probability > '95' ) { opp.Billing_Date__c = milestone.Projected_Live_Date__c; } } Not sure if you have to put the quotes for 95 or not. Hope that helped! :)