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!

6

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

The maximum value that can be held in an Integer type is therefore (2^31) - 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

  • 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 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 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 at 19:13
0

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;
}

}

  • 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 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 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 at 21:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.