123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- <?php
- /**
- * Created by PhpStorm.
- * User: stanley-king
- * Date: 2018/8/24
- * Time: 下午6:35
- */
- namespace bonus;
- class RateMoney implements IMoneyCalc
- {
- const ASC = 1;
- const DESC = 2;
- const PRED_RATE = 30;
- private $mRates;
- private $mDirty;
- public function __construct($rates)
- {
- $this->mDirty = false;
- $this->mRates = [];
- foreach ($rates as $key => $val) {
- $val = intval(100 * $val + 0.5);
- if ($val > 0) {
- $this->mRates[$key] = $val / 100;
- }
- }
- krsort($this->mRates);
- }
- public function add_bonuses($items)
- {
- foreach ($items as $item) {
- $bonus = \bonus\user_bonus::create_by_param($item);
- $rate = $bonus->bonus_rate();
- $amount = intval($bonus->remain_amount() * 100 + 0.5);
- if ($amount <= 0) continue;
- $this->mDirty = true;
- if (isset($this->mRates[$rate]) == false) {
- $this->mRates[$rate] = 0.00;
- }
- $this->mRates[$rate] += $bonus->remain_amount();
- }
- krsort($this->mRates);
- }
- public function resort()
- {
- krsort($this->mRates);
- }
- public function is_enough(&$rate, $amount)
- {
- $amount = intval($amount * 100 + 0.5);
- foreach ($this->mRates as $key => $val) {
- $val = intval($val * 100 + 0.5);
- if ($rate == -1) {
- if ($val >= $amount) {
- $rate = $key;
- return true;
- }
- } else {
- if ($rate == $key) {
- $rate = $key;
- if ($val >= $amount) {
- return true;
- } else {
- return false;
- }
- }
- }
- }
- return false;
- }
- public function with_hold($rate, $amount)
- {
- if (isset($this->mRates[$rate])) {
- $this->mDirty = true;
- $this->mRates[$rate] = $this->mRates[$rate] - $amount;
- }
- }
- public function find_rate($amount)
- {
- if (empty($this->mRates)) return false;
- $rates = $this->mRates;
- ksort($rates);
- foreach ($rates as $rate => $money) {
- $money = intval($money * 100 + 0.5);
- $amount = intval($amount * 100 + 0.5);
- if ($amount >= $money) {
- return ['rate' => $rate, 'amount' => $money / 100];
- } else {
- return ['rate' => $rate, 'amount' => $amount / 100];
- }
- }
- return false;
- }
- public function format()
- {
- $result = [];
- foreach ($this->mRates as $key => $val) {
- $val = intval($val * 100 + 0.5);
- if ($val > 0) {
- $result[$key] = $val / 100;
- }
- }
- return $result;
- }
- public function total()
- {
- $total = 0.00;
- foreach ($this->mRates as $key => $amount) {
- $total += $amount;
- }
- return $total;
- }
- public function dirty()
- {
- return $this->mDirty;
- }
- public function clean()
- {
- $this->mDirty = false;
- }
- public function calc_rates($amount)
- {
- $rates = [];
- $left = intval($amount * 100 + 0.5);
- foreach ($this->mRates as $rate => $total) {
- if ($left <= 0) break;
- if ($rate > 100) continue;
- $total = intval($total * 100 + 0.5);
- if ($total <= 0) {
- continue;
- } else {
- if ($total >= $left) {
- $rates[$rate] = $left / 100;
- $left = 0;
- } else {
- $rates[$rate] = $total / 100;
- $left -= $total;
- }
- }
- }
- return $rates;
- }
- public function calc_money($price, &$rates)
- {
- $rates = [];
- $disc = 0;
- $left = intval($price * 100 + 0.5);
- foreach ($this->mRates as $rate => $total) {
- if ($left <= 0) break;
- if ($rate > 100) continue;
- $total = intval($total * 100 + 0.5);
- if ($total <= 0) {
- continue;
- } else {
- $max_rate = intval($left * $rate / 100 + 0.5);
- if ($total >= $max_rate) {
- $disc += $max_rate;
- $left = 0;
- $rates[$rate] = $max_rate / 100;
- } else {
- $disc += $total;
- $left -= intval($total * 100 / $rate + 0.5);
- $rates[$rate] = $total / 100;
- }
- }
- }
- $cur_price = intval($price * 100 + 0.5) - $disc;
- return $cur_price / 100;
- }
- public function calc_price($price, &$rates)
- {
- $cur_price = intval($this->calc_money($price, $rates) * 100 + 0.5);
- return $cur_price / 100;
- }
- static function scale()
- {
- return (100 - self::PRED_RATE) / 100;
- }
- }
|