3

We are deploying a tiered schedule for pricing related to products based on a firms assets under management. The tiers have breakpoints based on these aum fields (currency).

In apex I have a method for building tier schedules, which works fine until I hit the $3B entry breakpoint. When I run the method at this breakpoint, I get a message in the developer console about an 'Illegal Integer'.

The Apex Method that I have accepts the following parameters and then processes the new tier schedules:

public static List<rbTier__c> createTiers(Id productFamilyId, Integer batchSize, Decimal beginningAUM, decimal aumIncrement, Decimal beginningBasePrice, Decimal basePriceIncrement)
{
    List<rbTier__c> tierList = new List<rbTier__c>();
    List<rbTierFamily__c> familyList = [Select Id, Name, RB_Product__c From rbTierFamily__c WHere Id = :productFamilyId];
    List<rbTier__c> existingTiers = getTiersForFamilies(familyList);
    Integer sequence = 0;
    INteger plusOne = 1;
    Integer minusOne = -1;
    Decimal aumFloor = beginningAUM;
    Decimal aumCeiling = aumFloor + aumIncrement + minusOne;
    if(existingTiers.size() > 0)
    {
        sequence = existingTiers.size() + plusOne;
    }
    else
    {
        sequence = 1;
    }
    for(Integer i = 0;i < batchSize; i++)
    {
        if(sequence == 1)
        {
            rbTier__c t = new rbTier__c();
            t.AUM_Floor__c = aumFloor;
            t.AUM_Ceiling__c = beginningAUM + aumIncrement;
            t.Sequence__c = sequence + (1 * i);
            t.Name = 'Tier '+ String.valueOf(sequence + (1 * i));
            t.Base_Amount__c = beginningBasePrice + (basePriceIncrement * i);
            t.RB_Tier_Family__c = productFamilyId;
            tierList.add(t);
            aumFloor = aumCeiling + plusOne;
            aumCeiling = aumFloor + aumIncrement + minusOne;
        }
        else
        {
            System.debug('aum floor entering loop is '+aumFloor+ ' and aum ceiling entering is '+ aumCeiling);
            rbTier__c t = new rbTier__c();
            t.AUM_Floor__c = aumFloor;
            t.AUM_Ceiling__c = aumCeiling;
            t.Sequence__c = sequence + (1 * i);
            t.Name = 'Tier '+ String.valueOf(sequence + (1 * i));
            t.Base_Amount__c = beginningBasePrice + (basePriceIncrement * i);
            t.RB_Tier_Family__c = productFamilyId;
            tierList.add(t);
            aumFloor = aumCeiling + plusOne;
            aumCeiling = aumFloor + aumIncrement + minusOne;
            System.debug('aum floor exiting loop is '+aumFloor+ ' and aum ceiling exiting is '+ aumCeiling + ' and AUM increment is '+ aumIncrement);

        }
    }
    if(tierList.size() > 0)
    {
        try 
        {
            RBS_GlobalDMLHandler.insertObjectList(tierList);    
        } 
        catch(Exception ex) 
        {
            System.debug('Problem encountered inserting the tier batch | '+ex.getMessage());
        }
    }
    return tierList;
}

I ran this in from the developer console in stages as outlined here: (note the Id is hardcoded only for the purposes of testing)

RBS_TierHelper.createTiers('a184B000000xdd9QAA', 1, 0, 99999999, 10000, 0);
RBS_TierHelper.createTiers('a184B000000xdd9QAA', 8, 100000000, 50000000, 11250, 1250);
RBS_TierHelper.createTiers('a184B000000xdd9QAA', 5, 500000000, 100000000, 22500, 2500);
RBS_TierHelper.createTiers('a184B000000xdd9QAA', 8, 1000000000, 250000000, 35000, 2500);
RBS_TierHelper.createTiers('a184B000000xdd9QAA', 4, 3000000000, 500000000, 55000, 5000);

The outputs for the first four traunches generate results as expected. The fifth traunch, beginning at $3,000,000,000 returns an error from the dev console; 'Line 7, Column 53 Illegal Integer'.

Does anyone know what is going wrong here?

Thanks in advance for any insight you can provide!

2 Answers 2

8

Integers in Salesforce are signed, 32-bit (and 2's complement, I assume)

The maximum value that can be held in an Integer type is therefore 231 - 1 = 2,147,483,647

If you need to work with values larger than that, then you'll need to use the Long type instead of Integer

3
  • Thanks for the quick reply Derek! I'm new to this development thing and only starting to get into using math in my methods. The only place I am using an integer is in the sequencing of tiers. The aumFloor and aumCeiling fields are decimal fields. Does your explanation also apply to decimal?
    – Kevin
    Feb 18, 2019 at 19:07
  • @Kevin I'm less sure about how a Decimal is stored, but I know that a Double is the equivalent to the Long type (i.e. a 64-bit representation). The documentation can be found in Primitive Data Types
    – Derek F
    Feb 18, 2019 at 19:11
  • Thanks for the resource link Derek. I'll take a look into it and post back with the working code once I figure it out :)
    – Kevin
    Feb 18, 2019 at 19:13
1

Kudos to Derek F. for pointing me in the right direction.

Before I post the code that works, let me explain what I tried:

  • Changed parameters for aumFloor and aumCeiling to both Long and Double but still received the same error about invalid integers.
    • changed all references to integers entirely throughout the method, using Long type in its place AND still received the same error (how is that even possible? :))

Eventually I settled on setting the parameters in the method to Strings then converting those strings to Long types in the method. I now have the ability to go as far as I want (or at least into the hundreds of billions from my tests) on this tier schedule.

Working code is as follows:

public static List<rbTier__c> createTiers(Id productFamilyId, Integer batchSize, String beginningAUM, String aumIncrement, Decimal beginningBasePrice, Decimal basePriceIncrement)
{
    List<rbTier__c> tierList = new List<rbTier__c>();
    List<rbTierFamily__c> familyList = [Select Id, Name, RB_Product__c From rbTierFamily__c WHere Id = :productFamilyId];
    List<rbTier__c> existingTiers = getTiersForFamilies(familyList);
    Integer sequence = 0;
    Integer plusOne = 1;
    Integer minusOne = -1;
    Long aumFloor = Long.valueof(beginningAUM);
    Decimal floorCalc;
    Decimal ceilingCalc = aumFloor + Long.valueOf(aumIncrement) + minusOne;
    Long aumCeiling = Long.valueOf(String.valueOf(ceilingCalc));
    if(existingTiers.size() > 0)
    {
        sequence = existingTiers.size() + plusOne;
    }
    else
    {
        sequence = 1;
    }
    for(Integer i = 0;i < batchSize; i++)
    {
        if(sequence == 1)
        {
            rbTier__c t = new rbTier__c();
            t.AUM_Floor__c = aumFloor;
            t.AUM_Ceiling__c = Long.valueOf(beginningAUM + aumIncrement);
            t.Sequence__c = sequence + (1 * i);
            t.Name = 'Tier '+ String.valueOf(sequence + (1 * i));
            t.Base_Amount__c = beginningBasePrice + (basePriceIncrement * i);
            t.RB_Tier_Family__c = productFamilyId;
            tierList.add(t);
            floorCalc = aumCeiling + plusOne;
            aumFloor = Long.valueOf(String.valueOf(floorCalc));
            ceilingCalc = aumFloor + Long.valueOf(aumIncrement) + minusOne;
            aumCeiling = Long.valueOf(String.valueOf(ceilingCalc));
        }
        else
        {
            rbTier__c t = new rbTier__c();
            t.AUM_Floor__c = aumFloor;
            t.AUM_Ceiling__c = aumCeiling;
            t.Sequence__c = sequence + (1 * i);
            t.Name = 'Tier '+ String.valueOf(sequence + (1 * i));
            t.Base_Amount__c = beginningBasePrice + (basePriceIncrement * i);
            t.RB_Tier_Family__c = productFamilyId;
            tierList.add(t);
            floorCalc = aumCeiling + plusOne;
            aumFloor = Long.valueOf(String.valueOf(floorCalc));
            ceilingCalc = aumFloor + Long.valueOf(aumIncrement) + minusOne;
            aumCeiling = Long.valueOf(String.valueOf(ceilingCalc));
        }
    }
    if(tierList.size() > 0)
    {
        try 
        {
            RBS_GlobalDMLHandler.insertObjectList(tierList);    
        } 
        catch(Exception ex) 
        {
            System.debug('Problem encountered inserting the tier batch | '+ex.getMessage());
        }
    }
    return tierList;
}

}

3
  • Were you adding "L" onto the end of your number literals? Long testLong = 3000000000; would still give you an error. Integers can be (automatically) coerced into being Longs (e.g. Long testLong = 100; would compile and work just fine), but if you're beyond the range of integers, appending "L" is required (e.g. Long testLong = 3000000000L;)
    – Derek F
    Feb 18, 2019 at 21:15
  • I did not know about the 'L' option. I should re-write this entire block as that would get rid of all of the string methods I used to capture the results that were beyond the range of integers. For the parameters to call the method, I iimagine I can change them back to decimal or integer then create variables to convert to Long types with the 'L' option?
    – Kevin
    Feb 18, 2019 at 21:24
  • never mind. I find myself going down the same rabbit hole to get the 'L' added to the end of the value. It works as it is so moving on :)
    – Kevin
    Feb 18, 2019 at 21:40

You must log in to answer this question.

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