You need to sign in to do that
Don't have an account?
DaNae Peterson 1
How to update an original record after cloning itself in a trigger
Hi all,
I am trying to write a trigger that is 2-fold in purpose. The context is we have 2 different types of opportunity record types (for existing business): Renewal and Retention. Renewal is informal when we are proactively trying to extend a contract and Retention is more formal when the client has issued a Request for Proposal from multiple vendors. It is possible that we have a renewal that will change to retention. In that case, what I am trying to do is:
1 - Clone the record (when stage = '6 Going to Bid') but change the record type to Retention and set stage = '3 Analysis'
2 - Update the original record (the one whose stage = '6 Going to Bid') with a link to the new record (I have created a custom lookup field labeled 'Related Retention Opportunity').
I have written a trigger and can get the first part to work but am getting stuck on the second requirement. I think it is because of the criteria when to run the trigger (before update, after insert, etc.). I have copied my trigger below but commented out where it is not working at the end. Any help would be greatly appreciated. THANK YOU!!
trigger CloneOpportunity on Opportunity (before update, after insert) {
for(Opportunity o : trigger.new){
if(o.StageName == '6 Going to Bid'){
Opportunity opp = [SELECT Id, Name, Related_Retention_Opportunity__c, AccountId, CloseDate, Type, No_of_Buses__c, Current_Contractor__c, NEC_Company__c, LeadSource, NEC_Contract__c, No_Bid_Decision_Made__c, OwnerId, CampaignId, Up_or_Out__c, Total_Routes_out_for_bid__c, Market_Cap__c, Description, Contract_Start_Date__c, Contract_End_Date__c, Contract_Extension_Date__c, Reason_Win_Loss_NoBid_Note__c, Account_Management__c, Priority__c, Business_Analysts__c, Bid_Coordinator__c, Comments_Update__c, Budgeted_Increase__c, Approved_Increase__c, Actual_Increase__c, Budgeted_Bus_Count__c, Approved_Bus_Count__c, Awarded_Bus_Count__c, Amount, X5_YR_OM__c, YR_1_Capex__c, New_Bus_CapEx_Yr1__c, District_Fleet_CapEx_Yr1__c, Cascade_Fleet_Value_Yr1__c, Other_Equip_CapEx_Yr1__c, ROCE__c, IRR__c, NPV__c, Final_Model_Detail__c, Op_Lease_Purchase__c, of_Op_Leases__c, Avg_Annual_Op_Lease_Cost__c, Winning_Contractor__c, No_Bid_Reason__c, Difference_from_low_bidder__c, Competitor_Pricing_Not_Available__c, Other_Bidding_Companies__c, Pricing__c, Reason_Win_Loss__c, STA_price_change_Yr_1__c, Difference_from_First_Student__c, Illinois_Central_s_price_change_Yr_1__c, Cook_IL_price_change_Yr_1__c, Regional_Co_price_change_Yr_1__c, Regional_Co_2_price_change_Yr_1__c
FROM Opportunity WHERE Id = :o.Id];
Opportunity OClone = new Opportunity();
OClone.Name = 'Going to Bid - ' + opp.Name;
OClone.RecordTypeId = '012A0000000VkfM';
OClone.AccountId = opp.AccountId;
OClone.CloseDate = opp.CloseDate;
OClone.StageName = '3 Analysis';
OClone.Type = opp.Type;
OClone.No_of_Buses__c = opp.No_of_Buses__c;
OClone.Current_Contractor__c = opp.Current_Contractor__c;
OClone.NEC_Company__c = opp.NEC_Company__c;
OClone.LeadSource = opp.LeadSource;
OClone.NEC_Contract__c = opp.NEC_Contract__c;
OClone.No_Bid_Decision_Made__c = opp.No_Bid_Decision_Made__c;
OClone.OwnerId = opp.OwnerId;
OClone.CampaignId = opp.CampaignId;
OClone.Up_or_Out__c = opp.Up_or_Out__c;
OClone.Total_Routes_out_for_bid__c = opp.Total_Routes_out_for_bid__c;
OClone.Market_Cap__c = opp.Market_Cap__c;
OClone.Description = opp.Description;
OClone.Contract_Start_Date__c = opp.Contract_Start_Date__c;
OClone.Contract_End_Date__c = opp.Contract_End_Date__c;
OClone.Contract_Extension_Date__c = opp.Contract_Extension_Date__c;
OClone.Priority__c = opp.Priority__c;
OClone.Business_Analysts__c = opp.Business_Analysts__c;
OClone.Bid_Coordinator__c = opp.Bid_Coordinator__c;
OClone.Comments_Update__c = opp.Comments_Update__c;
OClone.Budgeted_Increase__c = opp.Budgeted_Increase__c;
OClone.Approved_Increase__c = opp.Approved_Increase__c;
OClone.Actual_Increase__c = opp.Actual_Increase__c;
OClone.Budgeted_Bus_Count__c = opp.Budgeted_Bus_Count__c;
OClone.Approved_Bus_Count__c = opp.Approved_Bus_Count__c;
OClone.Awarded_Bus_Count__c = opp.Awarded_Bus_Count__c;
OClone.Amount = opp.Amount;
OClone.Reason_Win_Loss_NoBid_Note__c = opp.Reason_Win_Loss_NoBid_Note__c;
OClone.X5_YR_OM__c = opp.X5_YR_OM__c;
OClone.YR_1_Capex__c = opp.YR_1_Capex__c;
OClone.New_Bus_CapEx_Yr1__c = opp.New_Bus_CapEx_Yr1__c;
OClone.District_Fleet_CapEx_Yr1__c = opp.District_Fleet_CapEx_Yr1__c;
OClone.Cascade_Fleet_Value_Yr1__c = opp.Cascade_Fleet_Value_Yr1__c;
OClone.Other_Equip_CapEx_Yr1__c = opp.Other_Equip_CapEx_Yr1__c;
OClone.ROCE__c = opp.ROCE__c;
OClone.IRR__c = opp.IRR__c;
OClone.NPV__c = opp.NPV__c;
OClone.Final_Model_Detail__c = opp.Final_Model_Detail__c;
OClone.Op_Lease_Purchase__c = opp.Op_Lease_Purchase__c;
OClone.of_Op_Leases__c = opp.of_Op_Leases__c;
OClone.Avg_Annual_Op_Lease_Cost__c = opp.Avg_Annual_Op_Lease_Cost__c;
OClone.Winning_Contractor__c = opp.Winning_Contractor__c;
OClone.Reason_Win_Loss__c = opp.Reason_Win_Loss__c;
OClone.No_Bid_Reason__c = opp.No_Bid_Reason__c;
OClone.Difference_from_low_bidder__c = opp.Difference_from_low_bidder__c;
OClone.Competitor_Pricing_Not_Available__c = opp.Competitor_Pricing_Not_Available__c;
OClone.Other_Bidding_Companies__c = opp.Other_Bidding_Companies__c;
OClone.Pricing__c = opp.Pricing__c;
OClone.Reason_Win_Loss__c = opp.Reason_Win_Loss__c;
OClone.STA_price_change_Yr_1__c = opp.STA_price_change_Yr_1__c;
OClone.Difference_from_First_Student__c = opp.Difference_from_First_Student__c;
OClone.Illinois_Central_s_price_change_Yr_1__c = opp.Illinois_Central_s_price_change_Yr_1__c;
OClone.Cook_IL_price_change_Yr_1__c = opp.Cook_IL_price_change_Yr_1__c;
OClone.Regional_Co_price_change_Yr_1__c = opp.Regional_Co_price_change_Yr_1__c;
OClone.Regional_Co_2_price_change_Yr_1__c = opp.Regional_Co_2_price_change_Yr_1__c;
OClone.Account_Management__c = opp.Account_Management__c;
insert OClone;
/* IF(trigger.isafter){
opp.Related_Retention_Opportunity__c = OClone.Id;
update opp;
}
*/
}
}
}
I am trying to write a trigger that is 2-fold in purpose. The context is we have 2 different types of opportunity record types (for existing business): Renewal and Retention. Renewal is informal when we are proactively trying to extend a contract and Retention is more formal when the client has issued a Request for Proposal from multiple vendors. It is possible that we have a renewal that will change to retention. In that case, what I am trying to do is:
1 - Clone the record (when stage = '6 Going to Bid') but change the record type to Retention and set stage = '3 Analysis'
2 - Update the original record (the one whose stage = '6 Going to Bid') with a link to the new record (I have created a custom lookup field labeled 'Related Retention Opportunity').
I have written a trigger and can get the first part to work but am getting stuck on the second requirement. I think it is because of the criteria when to run the trigger (before update, after insert, etc.). I have copied my trigger below but commented out where it is not working at the end. Any help would be greatly appreciated. THANK YOU!!
trigger CloneOpportunity on Opportunity (before update, after insert) {
for(Opportunity o : trigger.new){
if(o.StageName == '6 Going to Bid'){
Opportunity opp = [SELECT Id, Name, Related_Retention_Opportunity__c, AccountId, CloseDate, Type, No_of_Buses__c, Current_Contractor__c, NEC_Company__c, LeadSource, NEC_Contract__c, No_Bid_Decision_Made__c, OwnerId, CampaignId, Up_or_Out__c, Total_Routes_out_for_bid__c, Market_Cap__c, Description, Contract_Start_Date__c, Contract_End_Date__c, Contract_Extension_Date__c, Reason_Win_Loss_NoBid_Note__c, Account_Management__c, Priority__c, Business_Analysts__c, Bid_Coordinator__c, Comments_Update__c, Budgeted_Increase__c, Approved_Increase__c, Actual_Increase__c, Budgeted_Bus_Count__c, Approved_Bus_Count__c, Awarded_Bus_Count__c, Amount, X5_YR_OM__c, YR_1_Capex__c, New_Bus_CapEx_Yr1__c, District_Fleet_CapEx_Yr1__c, Cascade_Fleet_Value_Yr1__c, Other_Equip_CapEx_Yr1__c, ROCE__c, IRR__c, NPV__c, Final_Model_Detail__c, Op_Lease_Purchase__c, of_Op_Leases__c, Avg_Annual_Op_Lease_Cost__c, Winning_Contractor__c, No_Bid_Reason__c, Difference_from_low_bidder__c, Competitor_Pricing_Not_Available__c, Other_Bidding_Companies__c, Pricing__c, Reason_Win_Loss__c, STA_price_change_Yr_1__c, Difference_from_First_Student__c, Illinois_Central_s_price_change_Yr_1__c, Cook_IL_price_change_Yr_1__c, Regional_Co_price_change_Yr_1__c, Regional_Co_2_price_change_Yr_1__c
FROM Opportunity WHERE Id = :o.Id];
Opportunity OClone = new Opportunity();
OClone.Name = 'Going to Bid - ' + opp.Name;
OClone.RecordTypeId = '012A0000000VkfM';
OClone.AccountId = opp.AccountId;
OClone.CloseDate = opp.CloseDate;
OClone.StageName = '3 Analysis';
OClone.Type = opp.Type;
OClone.No_of_Buses__c = opp.No_of_Buses__c;
OClone.Current_Contractor__c = opp.Current_Contractor__c;
OClone.NEC_Company__c = opp.NEC_Company__c;
OClone.LeadSource = opp.LeadSource;
OClone.NEC_Contract__c = opp.NEC_Contract__c;
OClone.No_Bid_Decision_Made__c = opp.No_Bid_Decision_Made__c;
OClone.OwnerId = opp.OwnerId;
OClone.CampaignId = opp.CampaignId;
OClone.Up_or_Out__c = opp.Up_or_Out__c;
OClone.Total_Routes_out_for_bid__c = opp.Total_Routes_out_for_bid__c;
OClone.Market_Cap__c = opp.Market_Cap__c;
OClone.Description = opp.Description;
OClone.Contract_Start_Date__c = opp.Contract_Start_Date__c;
OClone.Contract_End_Date__c = opp.Contract_End_Date__c;
OClone.Contract_Extension_Date__c = opp.Contract_Extension_Date__c;
OClone.Priority__c = opp.Priority__c;
OClone.Business_Analysts__c = opp.Business_Analysts__c;
OClone.Bid_Coordinator__c = opp.Bid_Coordinator__c;
OClone.Comments_Update__c = opp.Comments_Update__c;
OClone.Budgeted_Increase__c = opp.Budgeted_Increase__c;
OClone.Approved_Increase__c = opp.Approved_Increase__c;
OClone.Actual_Increase__c = opp.Actual_Increase__c;
OClone.Budgeted_Bus_Count__c = opp.Budgeted_Bus_Count__c;
OClone.Approved_Bus_Count__c = opp.Approved_Bus_Count__c;
OClone.Awarded_Bus_Count__c = opp.Awarded_Bus_Count__c;
OClone.Amount = opp.Amount;
OClone.Reason_Win_Loss_NoBid_Note__c = opp.Reason_Win_Loss_NoBid_Note__c;
OClone.X5_YR_OM__c = opp.X5_YR_OM__c;
OClone.YR_1_Capex__c = opp.YR_1_Capex__c;
OClone.New_Bus_CapEx_Yr1__c = opp.New_Bus_CapEx_Yr1__c;
OClone.District_Fleet_CapEx_Yr1__c = opp.District_Fleet_CapEx_Yr1__c;
OClone.Cascade_Fleet_Value_Yr1__c = opp.Cascade_Fleet_Value_Yr1__c;
OClone.Other_Equip_CapEx_Yr1__c = opp.Other_Equip_CapEx_Yr1__c;
OClone.ROCE__c = opp.ROCE__c;
OClone.IRR__c = opp.IRR__c;
OClone.NPV__c = opp.NPV__c;
OClone.Final_Model_Detail__c = opp.Final_Model_Detail__c;
OClone.Op_Lease_Purchase__c = opp.Op_Lease_Purchase__c;
OClone.of_Op_Leases__c = opp.of_Op_Leases__c;
OClone.Avg_Annual_Op_Lease_Cost__c = opp.Avg_Annual_Op_Lease_Cost__c;
OClone.Winning_Contractor__c = opp.Winning_Contractor__c;
OClone.Reason_Win_Loss__c = opp.Reason_Win_Loss__c;
OClone.No_Bid_Reason__c = opp.No_Bid_Reason__c;
OClone.Difference_from_low_bidder__c = opp.Difference_from_low_bidder__c;
OClone.Competitor_Pricing_Not_Available__c = opp.Competitor_Pricing_Not_Available__c;
OClone.Other_Bidding_Companies__c = opp.Other_Bidding_Companies__c;
OClone.Pricing__c = opp.Pricing__c;
OClone.Reason_Win_Loss__c = opp.Reason_Win_Loss__c;
OClone.STA_price_change_Yr_1__c = opp.STA_price_change_Yr_1__c;
OClone.Difference_from_First_Student__c = opp.Difference_from_First_Student__c;
OClone.Illinois_Central_s_price_change_Yr_1__c = opp.Illinois_Central_s_price_change_Yr_1__c;
OClone.Cook_IL_price_change_Yr_1__c = opp.Cook_IL_price_change_Yr_1__c;
OClone.Regional_Co_price_change_Yr_1__c = opp.Regional_Co_price_change_Yr_1__c;
OClone.Regional_Co_2_price_change_Yr_1__c = opp.Regional_Co_2_price_change_Yr_1__c;
OClone.Account_Management__c = opp.Account_Management__c;
insert OClone;
/* IF(trigger.isafter){
opp.Related_Retention_Opportunity__c = OClone.Id;
update opp;
}
*/
}
}
}
1. You can check trigger.old and trigger.new values to avoid recursion.
2. I saw you are copping each and every field manually. You can use object.clone(false) method.
3. It will be easy to understand if you can write Trigger Handler and push your code to methods.
Please check the below code which will solve your first requirement.
To implement the second requirement, we have to identify a way to match the created cloned record vs existing record because this trigger may execute for 1 record / 10 records or 100 records in the same way.
Regards,
Mahesh
Regards,
Mahesh
cloneOpp.Name = 'Going to Bid - ' + opp.Name;
Do you have any suggestions how to meet the second requirement? A couple of ways to help match the record is both have the same account IDs, due dates, and the names will be very similar with the exception of the cloned record will contain 'Going to Bid - ' in the front of the name.
-DaNae