2016-01-20 104 views
3

Azure費率卡API返回MeterRates字段(請參閱documentation)。 Azure UsageAggregate給出數量(請參閱documentation)。根據天藍色支持page。這是提問的論壇。費率計費計算

那麼,如何應用米率?

示例測量儀率:

{"0":20, "100":15, "200":10} 

如果我有175量是量100*20 + 75*15175*15

爲什麼指定包含的數量?

示例:rates:{"0":23}與包括quantitiy 10可以表示爲速率:

{"0":0, "10":23} 
+1

計費問題在這裏被認爲是關鍵問題,您可能會更好地詢問Serverfault。 –

+1

是什麼?這是一個關於如何使用從Usage and Rate Card api收到的信息進行計算的技術問題。 –

+0

@SteveBrownell這不是一個編程問題。其實我不確定你的實際問題是什麼。你在說什麼米?現在沒有圍繞它的上下文。 –

回答

5

例如米率:{ 「0」:20, 「100」:15, 「200」:10}

如果我有175的數量是金額100 * 20 + 75 * 15或175 * 15?

該定價是分層定價。因此,當你的利率它本質上是告訴你:

  • 0 - 99單位,單價爲20
  • 100 - 199單位,單價爲15
  • 200單位及以上,單位率10

基於這個邏輯,你的計算應該是:

99 * 20 + 75 * 15 = 3105

一兩件事混淆我雖然是上限。以上計算基於我從Azure Billing團隊收到的信息。我困惑的是,如果消費是99.5單位會發生什麼?對於第一個99單位它是好的,但我不知道如何計算額外的0.5單位。

+0

感謝您的回答。我想知道如果它不應該是 [99 * 20 + 76 * 15 = 3105] 或 [100 * 20 + 75 * 15 = 3105] –

2

Guarav成爲問題的核心,也是我將其標記爲答案的原因。基於此,我設計了以下代碼來實現邏輯。它屬於兩個部分:

  1. 創建從儀表率
  2. 處理的數量與遺願清單桶列表來確定

下面的函數創建桶的列表(每個量桶對象是具有最小值,最大值和速率屬性的簡單POCO)。該列表附加到具有來自價目表api的其他屬性的電錶對象。

 private Dictionary<int, RateBucket> ParseRateBuckets(string rates) 
    { 
     dynamic dRates = JsonConvert.DeserializeObject(rates); 
     var rateContainer = (JContainer)dRates; 

     var buckets = new Dictionary<int, RateBucket>(); 
     var bucketNumber = 0; 
     foreach (var jToken in rateContainer.Children()) 
     { 
      var jProperty = jToken as JProperty; 
      if (jProperty != null) 
      { 
       var bucket = new RateBucket 
       { 
        Min = Convert.ToDouble(jProperty.Name), 
        Rate = Convert.ToDouble(jProperty.Value.ToString()) 
       }; 

       if (bucketNumber > 0) 
        buckets[bucketNumber - 1].Max = bucket.Min; 

       buckets.Add(bucketNumber, bucket); 
      } 

      bucketNumber++; 
     } 

     return buckets; 
    } 

第二個函數使用具有兩個有用屬性的計量器對象:存儲桶列表和所包含的數量。根據價目表文檔(當我閱讀它時),在超過所包含的數量之前,您纔會開始計算可計費數量。我確信有一些重構可以在這裏完成,但是有序的處理是關鍵。

我想我已經通過認識到它是一個double而不是一個整數來解決數量問題。因此,與任何單個桶相關的數量是桶最大和桶最小值之間的差值(除非我們只填充了部分桶)。

 private double CalculateUsageCost(RateCardMeter meter, double quantity) 
    { 
     var amount = 0.0; 

     quantity -= meter.IncludedQuantity; 

     if (quantity > 0) 
     { 
      for (var i = 0; i < meter.RateBuckets.Count; i++) 
      { 
       var bucket = meter.RateBuckets[i]; 
       if (quantity > bucket.Min) 
       { 
        if (bucket.Max.HasValue && quantity > bucket.Max) 
         amount += (bucket.Max.Value - bucket.Min)*bucket.Rate; 
        else 
         amount += (quantity - bucket.Min)*bucket.Rate; 
       } 
      } 
     } 
     return amount; 
    } 

最後,關於層次的時間範圍的文檔不清楚。如果我根據數量獲得折扣價格,我會在什麼時間範圍內累計數量?使用api允許我每天或每小時拉取數據。我想每小時收集一次我的數據,這樣我就可以按照一天中的時間關聯我的成本。但是什麼時候實際計算賬單呢?似乎每小時都是錯誤的,每天都可能工作,但它可能只適合整個月。

+0

答案與記帳週期時間範圍的交易。我正在嘗試獲得一筆金額以分配給特定的使用情況。因此,特定使用量的數量與之前的數量相比是遞增的。 因此,根據最初的問題,我們假設我正在計算一個數量爲8.0的使用情況,並且在結算週期中所有以前使用情況的總和爲97.0。 (請記住,數量是雙倍不是整數。) –

+0

我的數量是97.0 + 8.0,所以我需要弄清楚我需要100.0 - 97.0從第一個桶和105.0 - 100.0從第二個桶。 或(100.0-97.0)* 20 +(105.0-100.0)* 15 = 135.00 –

0

最近我剛做了這個類似的任務。以下是我的例子(我認爲你可以使用正則表達式來刪除這些字符,而不是像我一樣使用替換)。第一個函數解析費率信息字符串以生成鍵值對集合,第二個函數用於計算總價格。

private Dictionary<float, double> GetRatesDetail(string r) 
{ 
    Dictionary<float, double> pairs = null; 
    if(string.IsNullOrEmpty(r) || r.Length <=2) 
    { 
     pairs = new Dictionary<float, double>(); 
     pairs.Add(0, 0); 
    } 
    else 
    { 
     pairs = r.Replace("{", "").Replace("}", "").Split(',') 
     .Select(value => value.Split(':')) 
     .ToDictionary(pair => float.Parse(pair[0].Replace("\"", "")), pair => double.Parse(pair[1])); 
    } 

    return pairs; 
} 

public decimal Process(Dictionary<float, double> rates, decimal quantity) 
{ 
    double ret = 0; 

    foreach (int key in rates.Keys.OrderByDescending(k => k)) 
    { 
     if (quantity >= key) 
     { 
      ret += ((double)quantity - key) * rates[key]; 
      quantity = key; 
     } 
    } 

    return (decimal)ret; 
}