база данных / алгоритм для структуры тарифов - PullRequest
4 голосов
/ 21 января 2010

Я должен рассчитать цену на основе структуры тарифов по следующим направлениям:

$303.00 fixed price up to 500 units
$0.023 additional per unit from 501-10,000 units
$0.022 additional per unit from 10,001-25,000 units
$0.021 additional per unit from 25,001-50,000 units

Я немного растерялся при настройке структуры базы данных и алгоритма (большая точка соприкосновения) для расчета этого. Кто-нибудь делал это? Есть ли хороший, элегантный способ расчета такого рода вещей?

edit: Например, 25 100 пробежек за единицу будут стоить 303,00 долл. США за первые 500 единиц, 218,50 долл. США за следующие 9500 единиц, 330,00 долл. США за следующие 15 000 единиц и 2,10 долл. США за следующие 100 единиц, на общую сумму 853,60 долл. США

Это не будет простым вычислением 25,100 * $ 0,021 - я хорошо знаю, как его выбрать и рассчитать.

Аналогично тому, как исчисляется подоходный налог - на маржинальной основе.

Ответы [ 5 ]

3 голосов
/ 21 января 2010

Полагаю, вы хотите что-то гибкое, иначе было бы просто жестко закодировать его.

Вы можете использовать таблицу цен:

ID MAX    FIX    UNIT
1  500    303    0
2  9500   0      .23
3  15000  0      .22
4  25000  0      .21

Тогда вы можете рассчитать следующим образом:

$items = ?;
$cost = 0;
$rows = get_rows("select max, fix, unit from pricing order by id asc");
foreach ($rows as $r)
{
    if ($items <= 0)
        break;
    $cost += $r['fix'] + min($r['max'], $items) * $r['unit'];
    $items -= $r['max'];
}

Я предположил, что вам нужен алгоритм на PHP.

2 голосов
/ 21 января 2010

Python

from collections import namedtuple

RateRule= namedtuple( 'RateRule', ['qty_band','fixed','per_unit'] )    

rate_table = [
    RateRule(500, 303, None),
    RateRule(9500, None, 0.023),
    RateRule(15000, None, 0.022),
    RateRule(25000, None, 0.021)
]

def total_price( units, rate_table ):
    # Base
    total = rate_table[0].fixed
    units_purchased_so_far = rate_table[0].qty_band
    # Whole Price Bands
    rule = 1
    while units > units_purchased_so_far + rate_table[rule].qty_band:
        total += rate_table[rule].qty_band * rate_table[rule].per_unit
        units_purchased_so_far += rate_table[rule].qty_band
        rule += 1
    # Units within the top Price Band
    if units > units_purchased_so_far:
        total += (units - units_purchased_so_far) * rate_table[rule].per_unit
    return total
0 голосов
/ 21 января 2010

Что я в итоге делаю:

size  units     fixed     per
1       500   303.000   0.000
1     10000     0.000   0.023
1     25000     0.000   0.022
1     50000     0.000   0.021



function calculate_price($size, $quantity) {
  global $db;

  $price = 0;
  $count = 0;

  // fetch rates from the database
  // note: $size is already sanitised by the calling function
  $query = "SELECT units, flat, per FROM rates WHERE size={$size} ORDER BY units ASC";
  $result = $db->query($query);

  // step through the rates
  while($rate = $result->fetch_object()) {
    // figure out how many of our units fall within this tier
    $tier_count = max(0, min($quantity - $count, $rate->units - $count));

    // calculate the price for this tier, including any flat rate
    $tier_price = $rate->flat + ($rate->per * $tier_count);

    // add tier price and count to the totals
    $price += $tier_price;
    $count += $tier_count;

    // store the last, largest number of units rate for any leftovers outside our tiers
    $last_rate = $rate;
  }

  // if some of our units fall outside our defined tiers, use the last tier's values for them
  if($count < $quantity) {
    $tier_count = $quantity - $count;
    $tier_price = $last_rate->flat + ($last_rate->per * $tier_count);
    $price += $tier_price;
    $count += $tier_count;
  }

  return $price;
}
0 голосов
/ 21 января 2010
SELECT 
 CASE is_fixed_price
  WHEN 1
   THEN unit_price / ?  
  ELSE
   unit_price
  END
FROM rate_structure
WHERE ? BETWEEN min_qty AND max_qty

Где? это количество, которое ваш клиент хочет заказать. Синтаксис с моей головы, для MySQL 5.x. Побочным эффектом является потенциальное накопление ошибок округления.

0 голосов
/ 21 января 2010

Примерно так:

Product
-------
[PK] ProductID


Price
-----
[PK] PriceID
[FK] ProductID
Price
QtyMin
QtyMax

Таким образом, эффективно соотношение между продуктом и ценой. Вы можете использовать максимальное значение для дозорного, если вам требуется фиксированная ставка независимо от количества.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...