The tutorial below shows how you can use Salesforce Triggers to update the CloseDate of an opportunity and the associated Product Schedule.
First thing is we must create a product Trigger, below is the code for the product trigger:
trigger OpportunityScheduleUpdate on Opportunity (after update) { for (Opportunity o: Trigger.new) { Opportunity oldCloseDate = Trigger.oldMap.get(o.ID); if (o.CloseDate != oldCloseDate.CloseDate) { Integer dateval = oldCloseDate.CloseDate.daysBetween(o.CloseDate); OppScheduleUpdate.ScheduleDateUpdate(o.id, dateval); } } }
The trigger class updates all the Product ScheduleDate by the amount of the days the Opportunity Close Date has changed:
public class OppScheduleUpdate { public static void ScheduleDateUpdate(String oppid, Integer dateval) { List idval = [SELECT id FROM OpportunityLineItem WHERE OpportunityId=:oppid]; List datelist; for (Integer i = 0; i < idval.size(); i++) { datelist = [SELECT ScheduleDate FROM OpportunityLineItemSchedule WHERE OpportunityLineItemId =:idval[i].id]; for (Integer k = 0; k < datelist.size(); k++) { System.debug('DateList = ' + datelist[k]); Date mydate=Date.newInstance(datelist[k].ScheduleDate.Year(),datelist[k].ScheduleDate.Month(),datelist[k].ScheduleDate.Day()); mydate=mydate.addDays(dateval); datelist[k].ScheduleDate = mydate; update datelist; //date datediff = date.parse(datelist[k]); } } } }
Do you have test coverage for this?
Hi Edson, yes I tested multiple opportunities and made sure my schedule updates worked. It was successful in all cases.
yes thanks very much sir, Can you send me the test coverage or unit test for this? Thanks again very helpful.
yes thanks very much sir, Can you send me the test coverage or unit test for this? very much appreciated, Thanks again very helpful.
michael? the test coverage for this or unit test is hard to make, do you have your own test coverage for this?
I don’t have test coverage for it atm.
Could anyone publish the test code for this?
I added an opportunity line item using custom apex code. The product which I added in the opportunity line item has a default schedule settings. But OpportunityLineItem schedule records are not created for this opportunity line item. what might be the reason?
Hi,
I need to write test case in which when opportunity product inserted then opportunity product schedule must be inserted.
Thanks,
Khillan
Trigger:
Trigger OpportunityScheduling on Opportunity (after update) {
if(!Validator_cls.hasAlreadyDone())
{
for (Opportunity o: Trigger.new)
{
Opportunity oldCloseDate = Trigger.oldMap.get(o.ID);
if (o.CloseDate != oldCloseDate.CloseDate)
{
Integer dateval = oldCloseDate.CloseDate.daysBetween(o.CloseDate);
OpportunitySchedulingHandler.ScheduleDateUpdate(o.id, dateval);
}
}
}
}
Class:
public with sharing class OpportunitySchedulingHandler {
public static void ScheduleDateUpdate(String oppid, Integer dateval)
{
List idval = [SELECT id FROM OpportunityLineItem WHERE OpportunityId=:oppid];
List datelist = new List();
for (Integer i = 0; i < idval.size(); i++)
{
datelist = [SELECT ScheduleDate FROM OpportunityLineItemSchedule WHERE OpportunityLineItemId =:idval[i].id];
for (Integer k = 0; k < datelist.size(); k++)
{
Date mydate=Date.newInstance(datelist[k].ScheduleDate.Year(),datelist[k].ScheduleDate.Month(),datelist[k].ScheduleDate.Day());
mydate=mydate.addDays(dateval);
datelist[k].ScheduleDate = mydate;
update datelist;
}
}
}
}
Do you have by any chance the test class for this class and trigger as well? Thank you very much
To new developer: please don’t just copy-paste this code as it is actually not well written.
One of the most important rule in Apex triggers is to bulkify them to avoid hitting the limits, it means not put SOQL queries or DML operation (save, update, delete) in loops. Here, there is a SOQL query in a double triple and an update operation in a triple loop.
I work as a Salesforce developer consultant and I am now working on correcting the code of someone who just copy-pasted this one and it’s not even that difficult to bulkify it: use Trigger.newMap and Trigger.OldMap to get the old and new values of the opportunities, put the records to update in lists and actually do the update at the end of the class and never write a trigger in a loop “for(trigger.new)”.
I can’t share my rectified code because it is for one of our client (so I don’t have the right to make it public), but please stop spreading badly written triggers.