Search code examples
azurescalebillingrate

Azure Usage Scaled Rates Pricing


I try to calculate the price for a meterID that has scaled rates . I use this as guide for the algorithm ( public static double computeRatedUsagePerMeter(Dictionary rates, double usage) ) https://github.com/PartnerCenterSamples/Commerce-API-DotNet/blob/master/Usage.cs

Comparing with the price from azure pricing calculator if i ask the price for quantity X in calculator it is equal to the price that i calculate from the above method but for quantity X - 1.

So i am confused if the method provided from Microsoft is complete or not , or maybe just a hint for the right direction.


 private static decimal computeRatedUsagePerMeter(Dictionary<decimal, decimal> rates, decimal usage)
        {
            decimal total = Decimal.Zero;

            if (rates.Count == 0)
                return Decimal.Zero;
            else if (rates.Count == 1)
                return (usage * rates.Values.FirstOrDefault());

            var remainingUsage = usage;

            while (rates.Count > 0)
            {
                decimal LastKey = rates.Keys.Last();

                if (remainingUsage > LastKey)
                {
                    decimal LastKeyValue = Decimal.Zero;
                    if (rates.TryGetValue(LastKey, out LastKeyValue))
                    {
                        total = total + ((remainingUsage - LastKey + 1) * LastKeyValue); // remainingUsage - LastKey +1  because tiered pricing is exclusive
                        remainingUsage = LastKey - 1;
                    }
                    rates.Remove(LastKey);
                }
                else if (remainingUsage <= LastKey)
                {
                    rates.Remove(LastKey);
                }
            }
            return total;
        }

{
      "MeterId": "d23a5753-ff85-4ddf-af28-8cc5cf2d3882",
      "MeterName": "Standard IO - Page Blob/Disk (GB)",
      "MeterCategory": "Storage",
      "MeterSubCategory": "Locally Redundant",
      "Unit": "GB",
      "MeterTags": [],
      "MeterRegion": "",
      "MeterRates": {
        "0": 0.042165,
        "1024": 0.0421650,
        "51200": 0.0421650,
        "512000": 0.0421650,
        "1024000": 0.0379485,
        "5120000": 0.0312021
      },
      "EffectiveDate": "2014-02-01T00:00:00Z",
      "IncludedQuantity": 0.0
    }

According to the method provided by the link above the price for quantity 1 = 0.084330 while azure pricing calculator gives 0.04 ( the prices are in EUR )

And another example : les say 100 quantity.

method: 4.258665 EUR

Azure Calculator = 4.22 EUR

method for 99 quantity = 4.216500 which rounded is 4.22 EUR. azure calculator Also cannot check the prices < 1.00 lets say 0.5 quantity ( in this case its measured in GB so 0,5 GB is perfectly reasonable quantity ) cause pricing calculator doesn't allow decimal .


Solution

  • According to the method provided by the link above the price for quantity 1 = 0.084330 while azure pricing calculator gives 0.04 ( the prices are in EUR )

    Looking at the code above, I believe there's an issue in the code itself. Essentially you're trying to find the price for 1 GB of storage which would fall under 0 - 1023 range or in other words the value of LastKey is 0. So when the following code executes:

    total = total + ((remainingUsage - LastKey + 1) * LastKeyValue);
    

    it gives you a total of 0.084330 (0 + (1 - 0 + 1) * 0.042165).

    Also cannot check the prices < 1.00 lets say 0.5 quantity ( in this case its measured in GB so 0,5 GB is perfectly reasonable quantity ) cause pricing calculator doesn't allow decimal.

    I am sure someone from Microsoft would provide a proper answer as to why they designed the calculator the way it is designed.