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
iKnowSFDCiKnowSFDC 

Test code for Product Schedules not working

Hi, I have a trigger in place that updates the product schedule dates if the Opportunity close date changes.  The trigger works exactly as expected, however, I'm unable to test it adequately. The test logic does not insert the default product schedules automatically, so I'm trying to insert them manually so I can generate adequate coverage. However, the code fails on insert when I try to insert the OpportunityProductSchedule record, the error is: 

System.DmlException: Insert failed. First exception on row 0; first error: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, insufficient access rights on cross-reference id: []

When I looked up the Object reference for OpportunityLineItemSchedule, it shows as createable so I'm not sure what the issue is - anyone been able to test product schedules? All of the posts I found it looks like other people are having the same issues and am not finding any resolutions posted. 

APEX Trigger and Class: 
trigger updateProdScheduleTrigger on Opportunity (after update) {
   
    Set<id> olisIds = new Set<id>();
    Set<id> opptyIds = new Set<id>();
   
    for(Opportunity o : trigger.new){
        if(o.CloseDate != trigger.oldMap.get(o.id).CloseDate){
     opptyIds.add(o.id);
        }
    }
    if(!opptyIds.isEmpty()){
    List<OpportunityLineItem> oli = [SELECT id FROM OpportunityLineItem WHERE OpportunityId IN :opptyIds AND HasRevenueSchedule = TRUE];
        if(!oli.isEmpty()){
            for(OpportunityLineItem olis : oli){
                olisIds.add(olis.id);
            }
        }
        updateProductSchedule.updateSchedule(olisIds);
    }

}

public class updateProductSchedule{
   
   
    public static void updateSchedule(Set<id> olisIds){
       
        List<OpportunityLineItem> olis = [SELECT id, OpportunityId, Opportunity.CloseDate, UnitPrice
                                          FROM OpportunityLineItem
                                          WHERE Id IN :olisIds];
        Map<String, Date> lineCloseDate = new Map<String, Date>();
        for(OpportunityLineItem o : olis){
            lineCloseDate.put(o.id, o.Opportunity.CloseDate);
        }
       
        List<OpportunityLineItemSchedule> oliSchedules = new List<OpportunityLineItemSchedule>();
       
  oliSchedules = [SELECT id, ScheduleDate, OpportunityLineItemId, Quantity, Revenue, Type, OpportunityLineItem.UnitPrice,
                        OpportunityLineItem.OpportunityId, OpportunityLineItem.Opportunity.CloseDate
                        FROM OpportunityLineItemSchedule
                        WHERE OpportunityLineItemId IN :olisIds ORDER BY ScheduleDate ASC];
      
        for(OpportunityLineItemSchedule os : oliSchedules){
            system.debug('current os schedule date>>>'+os.ScheduleDate +  ' and revenue>>>'+os.Revenue);
        }
   List<OpportunityLineItemSchedule> olischedToUpdate = new List<OpportunityLineItemSchedule>();       
       
       
        Date newStartSchedDate = oliSchedules[0].OpportunityLineItem.Opportunity.CloseDate;
        Decimal newREvScheduleAmt = oliSchedules[0].OpportunityLineItem.UnitPrice / 12;
        for(Integer i = 0; i<oliSchedules.size(); i++){
            oliSchedules[i].Revenue = newRevScheduleAmt;
            oliSchedules[i].ScheduleDate = newStartSchedDate.addMonths(i);
            olischedToUpdate.add(oliSchedules[i]);
            system.debug('current os schedule date>>>'+oliSchedules[i].ScheduleDate +  ' and revenue>>>'+oliSchedules[i].Revenue);
        }
        update olischedToUpdate;
      
    }

}

TEST Code: 

@istest (seeAlldata=True)
public class testUpdateProdSchedule{
    private testmethod static void testUpdateSched(){
       
        List<Account> accts = new List<Account>();
        for(integer i=0; i<200; i++){           
            Account a = new Account(Name='test'+i);
            accts.add(a);
        }
        insert accts;
       
        List<Opportunity> opptys = new List<Opportunity>();
        for(integer i=0; i<200; i++){
            Opportunity o = new Opportunity(Name='test'+i, AccountId = accts[i].id, CloseDate=date.today().addMonths(12),
                                            Amount=0, StageName='Proposed');
            opptys.add(o);
        }
        insert Opptys;
        Set<id> opptyIds = new Set<Id>();
        for(Opportunity o : opptys){
            opptyIds.add(o.id);
        }
        PricebookEntry pbe = [SELECT id, UnitPrice, Product2.NumberOfRevenueInstallments FROM PriceBookEntry
                              WHERE isActive=True
                              AND Product2.NumberOfRevenueInstallments = 12 LIMIT 1];
       
        system.debug('number of rev installments for pbe>>>'+pbe.Product2.NumberOfRevenueInstallments);
       
        List<OpportunityLineItem> olis = new List<OpportunityLineItem>();
        for(integer i=0; i<200; i++){
         OpportunityLineItem oli = new OpportunityLineItem();
            oli.OpportunityId=opptys[i].id;
            oli.PricebookEntryId=pbe.id;
            oli.Quantity=1;
            oli.UnitPrice=1200000;
            olis.add(oli);
        }
        insert olis;
        OpportunityLineItem line = [SELECT id FROM OpportunityLineItem WHERE PriceBookEntryId=:pbe.id LIMIT 1];
        List<OpportunityLineItemSchedule> oliSchedToInsert = new List<OpportunityLineItemSchedule>();
        for(integer i=0; i<12; i++){
            OpportunityLineItemSchedule s = new OpportunityLineItemSchedule();
            s.Revenue = 100000;
            s.ScheduleDate = date.today().addMonths(i);
            s.OpportunityLineItemId = line.id;
            s.type = 'Both';
            s.Quantity = 1;
           
            oliSchedToInsert.add(s);
        }
        insert oliSchedToInsert;
       
        List<OpportunityLineItemSchedule> oliSched = [SELECT id, Revenue, ScheduleDate,OpportunityLineItemId,
                                                      OpportunityLineItem.OpportunityId FROM OpportunityLineItemSchedule
                                                      WHERE OpportunityLineItem.OpportunityId IN : opptyIds];
       
        system.debug('size of schedule list>>>'+oliSched.size());
        //system.assertEquals(oliSched.size()>0, true);
        opptys[0].closeDate = date.today().addMonths(13);
        update opptys[0];
       
        List<Opportunity> opptysToUpdate = new List<Opportunity>();
       /* for(integer i=0;i<200; i++){
            opptys[i].CloseDate = date.today().addMonths(14);
            opptysToUpdate.add(opptys[i]);
        }
        update opptysToUpdate;*/
       
    }
}
Best Answer chosen by iKnowSFDC
Nirmal ChristopherNirmal Christopher
Hi JoAnn ,

         I looked into the Issue. The code works perfectly in my developer org without any hindrances. The Error “system.DmlException: Insert failed. First exception on row 0; first error: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, insufficient access rights on cross-reference id: []” 
From the error I understand the issue is caused by access given to running user or might be due to the permissions give to the object which you are trying to Insert or do any kind of DML operation.

Things to check on this case
1. Please check the object permissions given for the record you are trying to Insert.
2. This issue is also caused due to the object permission given to the related records of a master object. For example if you try to Insert opportunity record and if this error occurs check the permissions an sharing settings of its master object Account.
3. Try running this code as a system Admin using Runas() method. It doesn’t mean that  running as system admin will solve the issue rather if the system admin  have access to all the records it might solve the issue.

Try and let me know if it helps

Please check the references below it might help you
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_tools_runas.htm

                                             
                                                                                                                   Thanks and Regards,
                                                                                                                     Nirmal Christopher
                                                                                                                     Technical Consultant
                                                                                                                     GTR|www.gtr.net

All Answers

Nirmal ChristopherNirmal Christopher
Hi JoAnn ,

         I looked into the Issue. The code works perfectly in my developer org without any hindrances. The Error “system.DmlException: Insert failed. First exception on row 0; first error: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, insufficient access rights on cross-reference id: []” 
From the error I understand the issue is caused by access given to running user or might be due to the permissions give to the object which you are trying to Insert or do any kind of DML operation.

Things to check on this case
1. Please check the object permissions given for the record you are trying to Insert.
2. This issue is also caused due to the object permission given to the related records of a master object. For example if you try to Insert opportunity record and if this error occurs check the permissions an sharing settings of its master object Account.
3. Try running this code as a system Admin using Runas() method. It doesn’t mean that  running as system admin will solve the issue rather if the system admin  have access to all the records it might solve the issue.

Try and let me know if it helps

Please check the references below it might help you
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_tools_runas.htm

                                             
                                                                                                                   Thanks and Regards,
                                                                                                                     Nirmal Christopher
                                                                                                                     Technical Consultant
                                                                                                                     GTR|www.gtr.net
This was selected as the best answer
iKnowSFDCiKnowSFDC
Hi Nirmal - Thank you so much for your advice. The issue was the object permissions. I was specifying "Both" as the LineItemSchedule type, and should have only been specifying "Revenue". Was able to get this working with 100% coverage. 

Again - thanks for your help!
JoAnn