+ Start a Discussion
travis.truetttravis.truett 

Opportunity Product Trigger not Working

I wrote a trigger that edits the schedule of an opportunity product once it's created. Here's the trigger:

trigger editSchedule on OpportunityLineItem (after insert) {

if(Trigger.isInsert){

List<OpportunityLineItemSchedule> listOLIS = new List<OpportunityLineItemSchedule>();

for (OpportunityLineItem oli: Trigger.new){

Date myDate = Date.today();

for(Integer duration = (Integer)oli.Duration__c; duration == 0; duration--){

listOLIS.add(new OpportunityLineItemSchedule(OpportunityLineItemId = oli.Id, Quantity = 1, ScheduleDate = myDate));
myDate.addMonths(1);

}//end of inner for loop

}//end of for loop

insert listOLIS;

}//end of isInsert

}//end of trigger

Basically, it pulls in a custom field that I created called Duration, which is an integer representing how many months the client will be using the particular product. I want to add a schedule entry once a month based on the size of duration. For some reason though, when I add a product to an opportunity, my trigger doesn't change the schedule at all. 
surasura
try below code 
 
trigger editSchedule on OpportunityLineItem (after insert) {

if(Trigger.isInsert){

List<OpportunityLineItemSchedule> listOLIS = new List<OpportunityLineItemSchedule>();

for (OpportunityLineItem oli: Trigger.new){

Date myDate = Date.today();

for(Integer duration = (Integer)oli.Duration__c; duration == 0; duration--){

listOLIS.add(new OpportunityLineItemSchedule(OpportunityLineItemId = oli.Id, Quantity = 1, ScheduleDate = myDate));
 myDate =myDate.addMonths(1);

}//end of inner for loop

}//end of for loop

insert listOLIS;

}//end of isInsert

}//end of trigger

addmonths method do not update the original  date varaiable reference it returns the updated date , you should assign it to the varaible
travis.truetttravis.truett
Thanks for your help. I made that correction. I think that there's another problem, though, and I might know what it is. When a product is added to an opportunity, our system is automatically adding a schedule for that product, and I think my trigger isn't working because when it runs, there's already a schedule associated with that product. Is there a way to override the other schedule or delete it before running my code?
surasura
if it is possible try to stop automatically adding a schedule  for product , otherwise it created a lot of dml operation which may ultimately result in exceeding salesforce governor limits
travis.truetttravis.truett
I created a test product that has revenue scheduling enabled, but does not have a default schedule. When I add that product to an opportunity and give a value for the duration, my trigger still doesn't add any schedule items to the opportunity product. I'm not sure why.
travis.truetttravis.truett
trigger setMonthlyAmountAndDuration on OpportunityLineItem (after insert, after update) {
    if(!SetMonthlyAmountHelper.hasAlreadySetMonthlyAmount()) {
        for (OpportunityLineItem LI : trigger.new) {
            PricebookEntry pbentry = [select Product2Id from PricebookEntry where Id = :LI.PriceBookEntryId];
            Product2 prod = [select CanUseRevenueSchedule, NumberOfRevenueInstallments from Product2 where Id = :pbentry.Product2Id];

            if (prod.CanUseRevenueSchedule==true && prod.NumberofRevenueInstallments>0) {
                OpportunityLineItem opp_prod = [select Monthly_amount__c, Contract_duration__c from OpportunityLineItem where Id = :LI.Id];
                List<OpportunityLineItemSchedule> schedule = [select ScheduleDate from OpportunityLineItemSchedule where OpportunityLineItemId = :LI.Id];

                if (schedule.size()==0) 
                    opp_prod.Monthly_amount__c = LI.UnitPrice;
                else 
                    opp_prod.Monthly_amount__c = LI.UnitPrice / schedule.size();
                
                opp_prod.Contract_duration__c = schedule.size();
                
                SetMonthlyAmountHelper.setAlreadySetMonthlyAmount();
                Update opp_prod;
            }
        }
    }
}

I also found this code in another forum post. I'm not sure what some of these functions are, but would any of this be helpful in my case?
surasura
i think problem lies in your for loop becuase below given loop 
 
for(Integer duration = (Integer)oli.Duration__c; duration == 0; duration--){

only runs if Oli.duration__c value is equal to zero  . if the line item duration__c field value is not equal to zero it never enters the loop
travis.truetttravis.truett
You're absolutely right. I corrected that. Now when I go to add a product, it's throwing an apex error...

Apex trigger editSchedule caused an unexpected exception, contact your administrator: editSchedule: execution of AfterInsert caused by: System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Type]: [Type]: Trigger.editSchedule: line 20, column 1 
surasura
when creating the OpportunityLineItemSchedule records specify the value for Type field .I think it will solve your issue ,

eg:
 
listOLIS.add(new OpportunityLineItemSchedule(OpportunityLineItemId = oli.Id, Quantity = 1, ScheduleDate = myDate ,Type='Quantity'));

for more info refer https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_opportunitylineitemschedule.htm
please mark this best answere if it helped to resolve your issue
travis.truetttravis.truett
Yeah I actually noticed I was missing that right after I commented. Unfortunately, now it is throwing a FIELD_INTEGRITY_ERROR
surasura
post the full error message
travis.truetttravis.truett
Apex trigger editSchedule caused an unexpected exception, contact your administrator: editSchedule: execution of AfterInsert caused by: System.DmlException: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, field integrity exception: Type, Quantity, unknown (invalid quantity/revenue for given type): [Type, Quantity, unknown]: Trigger.editSchedule: line 20, column 1