You need to sign in to do that
Don't have an account?
Better way to write this Trigger?
Hello All,
I have got a custom Object 'Customer Project' in the related list of an opportunity with the picklist field Status (Active, Inactive). Whenever a record on this object is inserted or updated wit status = Active-->a custom field 'Activate Customer Project' checkbox field on Opportunity must be set to True.
Moreover, as soon as the Record with status= Active in inserted for custom object ''Customer Project'' , the other records with the Active status must become inactive for the opportunity i.e only one customer project can exist with an Active status for an opportunity.
I have written the following code(bulkified) which is working but any suggestions if there is a better way to do this :
(Note : I have used If(Trigger.Isupdate && trigger.isAfter) and used this List insted of string List<Id> setcp = new List<Id>();
for testing only)
Many Thanks!!
----------------------------
trigger updateOpportunityStatus on Customer_Project__c (after insert, after update) {
List<opportunity> opps = new List<opportunity>();
List<Id> setcp = new List<Id>();
List<Customer_Project__c> cps = new List<Customer_Project__c>();
List<Customer_Project__c> cpps = new List<Customer_Project__c>();
opportunity opp;
If(Trigger.Isinsert && trigger.isAfter){
for(Customer_Project__c cp : trigger.new){
If(cp.status__c=='Active' && setcp.size()==0 ){
setcp.add(cp.Id);
opp = [Select Id, name,Active_Cust_Project__c from Opportunity where Id= :cp.Opportunity__c];
If(opp != null){
opp.Active_Cust_Project__c = True;
opps.add(opp); }
}
cps = [select Id,status__c from Customer_Project__c where Opportunity__c=:opp.id];
for(Customer_Project__c c:cps){
//Using the List because there is no get or a similar method for set
If(c.Id != setcp.get(0)){
c.status__c = 'Inactive';
cpps.add(c);}
}
}
update cpps;
}
If(Trigger.Isupdate && trigger.isAfter){
for(Customer_Project__c cp : trigger.new){
If(cp.status__c=='Active' ){
opp = [Select Id, name,Active_Cust_Project__c from Opportunity where Id= :cp.Opportunity__c];
If(opp != null && opp.Active_Cust_Project__c != True){
opp.Active_Cust_Project__c = True;
opps.add(opp); }
}
cps = [select Id,status__c from Customer_Project__c where Opportunity__c=:opp.id];
for(Customer_Project__c c:cps){
//Using the List because there is no get or a similar method for set
If(c.Id != setcp.get(0)){
c.status__c = 'Inactive';
cpps.add(c);}
}
}
}
update opps;
}
------------------------------------------------------------------------------------------------------------------------------------------
Try out the below. Also you can get rid of the If(Trigger.Isinsert && trigger.isAfter) and If(Trigger.Isupdate && trigger.isAfter) statements and just have one block of code.
All Answers
You'll definitely want to move your SOQL queries outside your loops..
Hey Thanks!! I would like to but how can i move the query out of the loop in case it is using the cp variable which gets populated in the loop itself? Clue please
for(Customer_Project__c cp : trigger.new
Try out the below. Also you can get rid of the If(Trigger.Isinsert && trigger.isAfter) and If(Trigger.Isupdate && trigger.isAfter) statements and just have one block of code.
Thanks mate : Excellent style of coding...there were couple of mistakes as u see in red...Thanks again
for(Customer_Project__c cp : trigger.new){
If(cp.status__c=='Active' )
setcp.add(cp.Id);
setcpOpp.add(cp.opportunity__c);
}
if(!setcp.isEmpty()){
// List<Opportunity> oppList = [Select Id, name,Active_Cust_Project__c from Opportunity where Id IN :setcp];
List<Opportunity> oppList = [Select Id, name,Active_Cust_Project__c from Opportunity where Id IN :setcpOpp];
List<Id> oppIds = new List <Id>();
for(Opportunity o; oppList){
o.Active_Cust_Project__c = True;
opps.add(o);
oppIds.add(o.Id);
}
List<Customer_Project__c> cps = [select Id,status__c from Customer_Project__c where Opportunity__c IN :oppIds AND Id NOT IN :setcp];
for(Customer_Project__c cs: cps){
cs.status__c = 'Inactive';
cpps.add(cs);
}
update opps;
update cpps;
}