0

I am trying to insert opportunity line item schedule record in test class for test coverage. I am unable to create a record.

Can some one help me in the fields and criteria required for inserting a record for schedule (revenue).

Here is test class I tried

        Product2 Prod =  new Product2();
    Prod.Name='NewProd';
    // Prod.CanUseQuantitySchedule = false;
    Prod.CanUseRevenueSchedule  = true;
    Prod.NumberOfRevenueInstallments = 10;
    Prod.RevenueScheduleType = 'Divide';
    Prod.RevenueInstallmentPeriod = 'Monthly';
    Prod.IsActive=True;
    insert Prod;

    PricebookEntry pbe = new PricebookEntry();
    pbe.Product2Id=Prod.Id;
    pbe.IsActive=True;
    pbe.UnitPrice=70;
    pbe.Pricebook2Id = Test.getStandardPricebookId();
    pbe.UseStandardPrice=false;

    insert pbe;


    OpportunityLineItem opli = new OpportunityLineItem();
    opli.UnitPrice = 57;
    opli.Quantity = 12;
    opli.OpportunityId=opp.Id;
    opli.PricebookEntryId=pbe.id;

    insert opli;

    opp.Date__c = opp.CloseDate.addDays(20);
    update opp;

  List<OpportunityLineItemSchedule> schedules = [select Id,ScheduleDate from OpportunityLineItemSchedule where OpportunityLineItemId =: opli.Id];
    System.assert(!schedules.isEmpty()); 

Handler class:

public with sharing class OpportunitySchedulingHandler {

     //Update LineItemSchedule dates for all scheduling dates

    public static void ScheduleDateUpdate(String oppid, Integer DayDiff) 
    {
       List<OpportunityLineItem> idval = [SELECT id FROM OpportunityLineItem WHERE OpportunityId=:oppid];

       List<OpportunityLineItemSchedule> datelist = new List<OpportunityLineItemSchedule>();
       for (Integer i = 0; i < idval.size(); i++)
       {
           datelist = [SELECT ScheduleDate FROM OpportunityLineItemSchedule WHERE OpportunityLineItemId =:idval[i].id];

           if(datelist.size() > 0){
           Date firstDate = datelist[0].ScheduleDate.addDays(DayDiff);
           datelist[0].ScheduleDate = firstDate;

           Integer day = firstDate.day();
           Integer month = firstDate.month();
           Integer year = firstDate.year();

           for (Integer k = 1; k < datelist.size(); k++)
           {
               Integer nYear = year;
               Integer nMonth = month + k;
               Integer nDay = day;

               if (nMonth > 12) {
                   nMonth = nMonth - 12;
                   nYear = nYear + 1;
               }

               Set<Integer> longMonths = new Set<Integer> {1,3,5,7,8,10,12};

               if (nDay == 31 && ! longMonths.contains(nMonth)) {
                   nDay = 30;
               }

               if (nDay > 28 && nMonth == 2) {
                   nDay = 28;
               }

               Date mydate = date.newInstance(nYear,nMonth,nDay);
               datelist[k].ScheduleDate = mydate;
           }
           if(!datelist.isEmpty())
           {
                update datelist;
           }
        }
       }
    }    
}

Trigger:

trigger OpportunityReScheduling on Opportunity (after update, before update, after insert) 
    {
        for (Opportunity o: Trigger.new)
        {
            if (Trigger.isBefore)
            {
                if(o.Category__c == 'Test'){
                Opportunity prevOpportunity = Trigger.oldMap.get(o.ID);
                    if(o.Date__c <> null){
                if (o.Date__c != prevOpportunity.Date__c) 
                {
                    Integer DayDiff = prevOpportunity.Date__c.daysBetween(o.Date__c);

       SchedulingHandler.ScheduleDateUpdate(o.id, DayDiff);
                }
            }
            }
            }
        }
    }

Error I am receiving is that the assertion is failing. I tried inserting the Schedule record, but getting multiple errors. I am trying to increase code coverage, since lines from datelist.size() are not covered and code coverage is now at 24%

1
  • 2
    What have you tried? What error are you receiving? You may want to take a moment to read through How to Ask to imprive your chances of getting an answer.
    – David Reed
    Commented May 20, 2018 at 22:01

1 Answer 1

1

UPDATE

At this stage the only way I can get this to work in a test context is to use @IsTest(SeeAlldata=true).

Note that it is not necessary to use an actual live Pricebook2 record instead of Test.getStandardPricebookId();.

There must be something in that the isolated testing data can't access to create the OpportunityLineItemSchedule records automatically.


I ran the following as anonymous Apex in an Org with revenue scheduling enabled. It ran through to completion at the expected final assertion to roll the transaction back.

Product2 Prod =  new Product2();
Prod.Name='NewProd';
Prod.CanUseRevenueSchedule  = true;
Prod.NumberOfRevenueInstallments = 10;
Prod.RevenueScheduleType = 'Divide';
Prod.RevenueInstallmentPeriod = 'Monthly';
Prod.IsActive=True;
insert Prod;

PricebookEntry pbe = new PricebookEntry();
pbe.Product2Id=Prod.Id;
pbe.IsActive=True;
pbe.UnitPrice=70;
pbe.Pricebook2Id = [Select Id from Pricebook2 where IsStandard=true].Id;//;Test.getStandardPricebookId();
pbe.UseStandardPrice=false;
insert pbe;

Opportunity opp = new Opportunity();
opp.Name = 'Test';
opp.StageName = 'ClosedWon';
opp.CloseDate = DateTime.now().Date();
insert opp;

OpportunityLineItem opli = new OpportunityLineItem();
opli.UnitPrice = 57;
opli.Quantity = 12;
opli.OpportunityId=opp.Id;
opli.PricebookEntryId=pbe.id;
insert opli;

List<OpportunityLineItemSchedule> schedules = [select Id,ScheduleDate from OpportunityLineItemSchedule where OpportunityLineItemId = :opli.Id];
System.assert(!schedules.isEmpty()); 
System.assertEquals(Prod.NumberOfRevenueInstallments, schedules.size());

Id oppId = opp.Id;
Integer DayDiff = 1;

List<OpportunityLineItem> idval = [SELECT id FROM OpportunityLineItem WHERE OpportunityId=:oppid];

List<OpportunityLineItemSchedule> datelist = new List<OpportunityLineItemSchedule>();
for (Integer i = 0; i < idval.size(); i++) {
    datelist = [SELECT ScheduleDate FROM OpportunityLineItemSchedule WHERE OpportunityLineItemId =:idval[i].id];

    if(datelist.size() > 0){
        Date firstDate = datelist[0].ScheduleDate.addDays(DayDiff);
        datelist[0].ScheduleDate = firstDate;

        Integer day = firstDate.day();
        Integer month = firstDate.month();
        Integer year = firstDate.year();

        for (Integer k = 1; k < datelist.size(); k++) {
            Integer nYear = year;
            Integer nMonth = month + k;
            Integer nDay = day;

            if (nMonth > 12) {
                nMonth = nMonth - 12;
                nYear = nYear + 1;
            }

            Set<Integer> longMonths = new Set<Integer> {1,3,5,7,8,10,12};

            if (nDay == 31 && ! longMonths.contains(nMonth)) {
                nDay = 30;
            }

            if (nDay > 28 && nMonth == 2) {
                nDay = 28;
            }

            Date mydate = date.newInstance(nYear,nMonth,nDay);
            datelist[k].ScheduleDate = mydate;
        }
        if(!datelist.isEmpty()) {
            update datelist;
        }
    }
}

System.assert(false, 'Force rollback');

You will need to add the details from the specific exception you are encountering. The code works generally. So any exception will probably be in how it is applied via triggers.

If you can, a debug log would also help to isolate the issue.

7
  • I just received error saying the assertion failed for the assert statement. When I remove that there is no error, but the code coverage for handler is around 23%. Any ideas for increasing coverage? Also the actual size of schedule is coming as 0 instead of 10
    – user43146
    Commented May 21, 2018 at 4:24
  • @user43146 I've confirmed that the same code in a test context fails to create the OpportunityLineItemSchedule records. I'll keep investigating for the underlying cause. Commented May 21, 2018 at 8:22
  • @user43146 I can get the test class to work with by using @IsTest(SeeAlldata=true). Not exactly sure why yet. Commented May 24, 2018 at 1:19
  • 2
    this is where the UnitOfWork and Selector patterns come in handy coupled with apexMocks so one can unit test without resorting to seeAllData=true; admittedly a big ask for the OP
    – cropredy
    Commented May 24, 2018 at 3:47
  • 1
    @Arthlete - best ref by far is Force.com Enterprise Architecture Chapters 5-7 and 12. Buy it. Money well worth it. You can also look at the ApexMocks readme and my own blog
    – cropredy
    Commented Apr 22, 2019 at 18:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .