3

Azure Rate Card API は MeterRates フィールドを返します (ドキュメントを参照してください)。Azure UsageAggregate は数量を示します (ドキュメントを参照してください)。

紺碧のサポートページによると。質問する掲示板です。

では、メーター料金はどのように適用されるのでしょうか。

メーター料金の例:

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

数量が 175 の場合、金額100*20 + 75*15または175*15?

含まれる数量を指定する理由は何ですか?

例:rates:{"0":23}含まれる数量 10 は、レートとして表すことができます。

{"0":0, "10":23}
4

3 に答える 3

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

私を混乱させる1つのことは、上限です。上記の計算は、Azure Billing チームから受け取った情報に基づいています。99.5私を混乱させたのは、消費が単位であるとしたらどうなるでしょうか? 最初の99ユニットは問題ありませんが、追加の0.5ユニットがどのように計算されるかわかりません。

于 2016-01-21T02:49:29.730 に答える
2

Guarav は問題の核心に到達し、それが私がそれを回答としてマークした理由です。それに基づいて、ロジックを実装するために次のコードを考案しました。次の 2 つの部分に分かれます。

  1. 従量料金からのバケット リストの作成
  2. バケット リストを使用して数量を処理し、金額を決定する

次の関数は、バケットのリストを作成します (各バケット オブジェクトは、Min、Max、および Rate プロパティを持つ単純な 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;
    }

2 番目の関数は、バケット リストと含まれる数量という 2 つの便利なプロパティを持つ meter オブジェクトを使用します。レートカードのドキュメント(私が読んだとき)によると、含まれている数量を超えるまで、請求可能な数量のカウントを開始しません。ここで実行できるリファクタリングがあると確信していますが、バケットの順序付けされた処理が重要なポイントです。

整数ではなく倍精度であることを認識することで、数量に関する問題に対処したと思います。したがって、1 つのバケットに関連付けられた数量は、バケットの最大値とバケットの最小値の差です (部分的なバケットしか満たしていない場合を除く)。

        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 を使用すると、毎日または毎時間データを取得できます。1 時間ごとにコストを関連付けるために、1 時間ごとにデータを取得したいと考えています。しかし、請求額を実際に計算するのはいつが適切なのでしょうか? 毎時は間違っているようです。

于 2016-01-21T12:42:22.340 に答える
0

最近、私はこの同様のタスクを実行しました。以下は私の例です(置換を使用するのではなく、正規表現を使用してこれらの文字を削除できると思います)。最初の関数はレート情報文字列を解析してキーと値のペアのコレクションを生成し、2 番目の関数は合計価格を計算するために使用されます。

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;
}
于 2016-03-11T04:57:16.763 に答える