You need to sign in to do that
Don't have an account?
iKnowSFDC
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;*/
}
}
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;*/
}
}
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
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
Again - thanks for your help!
JoAnn