RateMoney.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: stanley-king
  5. * Date: 2018/8/24
  6. * Time: 下午6:35
  7. */
  8. namespace bonus;
  9. class RateMoney implements IMoneyCalc
  10. {
  11. const ASC = 1;
  12. const DESC = 2;
  13. const PRED_RATE = 30;
  14. private $mRates;
  15. private $mDirty;
  16. public function __construct($rates)
  17. {
  18. $this->mDirty = false;
  19. $this->mRates = [];
  20. foreach ($rates as $key => $val) {
  21. $val = intval(100 * $val + 0.5);
  22. if ($val > 0) {
  23. $this->mRates[$key] = $val / 100;
  24. }
  25. }
  26. krsort($this->mRates);
  27. }
  28. public function add_bonuses($items)
  29. {
  30. foreach ($items as $item) {
  31. $bonus = user_bonus::create_by_param($item);
  32. $rate = $bonus->bonus_rate();
  33. $amount = intval($bonus->remain_amount() * 100 + 0.5);
  34. if ($amount <= 0) continue;
  35. $this->mDirty = true;
  36. if (isset($this->mRates[$rate]) == false) {
  37. $this->mRates[$rate] = 0.00;
  38. }
  39. $this->mRates[$rate] += $bonus->remain_amount();
  40. }
  41. krsort($this->mRates);
  42. }
  43. public function resort()
  44. {
  45. krsort($this->mRates);
  46. }
  47. public function is_enough(&$rate, $amount)
  48. {
  49. $amount = intval($amount * 100 + 0.5);
  50. foreach ($this->mRates as $key => $val)
  51. {
  52. $val = intval($val * 100 + 0.5);
  53. if ($rate == -1) {
  54. if ($val >= $amount) {
  55. $rate = $key;
  56. return true;
  57. }
  58. }
  59. elseif ($rate == $key)
  60. {
  61. $rate = $key;
  62. if ($val >= $amount) {
  63. return true;
  64. } else {
  65. return false;
  66. }
  67. }
  68. }
  69. return false;
  70. }
  71. public function with_hold($rate, $amount)
  72. {
  73. if (isset($this->mRates[$rate])) {
  74. $this->mDirty = true;
  75. $this->mRates[$rate] = $this->mRates[$rate] - $amount;
  76. }
  77. }
  78. public function find_rate($amount)
  79. {
  80. if (empty($this->mRates)) return false;
  81. $rates = $this->mRates;
  82. ksort($rates);
  83. foreach ($rates as $rate => $money) {
  84. $money = intval($money * 100 + 0.5);
  85. $amount = intval($amount * 100 + 0.5);
  86. if ($amount >= $money) {
  87. return ['rate' => $rate, 'amount' => $money / 100];
  88. } else {
  89. return ['rate' => $rate, 'amount' => $amount / 100];
  90. }
  91. }
  92. return false;
  93. }
  94. public function format()
  95. {
  96. $result = [];
  97. foreach ($this->mRates as $key => $val) {
  98. $val = intval($val * 100 + 0.5);
  99. if ($val > 0) {
  100. $result[$key] = $val / 100;
  101. }
  102. }
  103. return $result;
  104. }
  105. public function total()
  106. {
  107. $total = 0.00;
  108. foreach ($this->mRates as $key => $amount) {
  109. $total += $amount;
  110. }
  111. return $total;
  112. }
  113. public function dirty()
  114. {
  115. return $this->mDirty;
  116. }
  117. public function clean()
  118. {
  119. $this->mDirty = false;
  120. }
  121. public function calc_rates($amount)
  122. {
  123. $rates = [];
  124. $left = intval($amount * 100 + 0.5);
  125. foreach ($this->mRates as $rate => $total) {
  126. if ($left <= 0) break;
  127. if ($rate > 100) continue;
  128. $total = intval($total * 100 + 0.5);
  129. if ($total <= 0) {
  130. continue;
  131. } else {
  132. if ($total >= $left) {
  133. $rates[$rate] = $left / 100;
  134. $left = 0;
  135. } else {
  136. $rates[$rate] = $total / 100;
  137. $left -= $total;
  138. }
  139. }
  140. }
  141. return $rates;
  142. }
  143. public function calc_money($price, &$rates)
  144. {
  145. $rates = [];
  146. $disc = 0;
  147. $left = intval($price * 100 + 0.5);
  148. foreach ($this->mRates as $rate => $total) {
  149. if ($left <= 0) break;
  150. if ($rate > 100) continue;
  151. $total = intval($total * 100 + 0.5);
  152. if ($total <= 0) {
  153. continue;
  154. } else {
  155. $max_rate = intval($left * $rate / 100 + 0.5);
  156. if ($total >= $max_rate) {
  157. $disc += $max_rate;
  158. $left = 0;
  159. $rates[$rate] = $max_rate / 100;
  160. } else {
  161. $disc += $total;
  162. $left -= intval($total * 100 / $rate + 0.5);
  163. $rates[$rate] = $total / 100;
  164. }
  165. }
  166. }
  167. $cur_price = intval($price * 100 + 0.5) - $disc;
  168. return $cur_price / 100;
  169. }
  170. public function calc_price($price, &$rates)
  171. {
  172. $cur_price = intval($this->calc_money($price, $rates) * 100 + 0.5);
  173. return $cur_price / 100;
  174. }
  175. static function scale()
  176. {
  177. return (100 - self::PRED_RATE) / 100;
  178. }
  179. }