RateMoney.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  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 = \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. $val = intval($val * 100 + 0.5);
  52. if ($rate == -1) {
  53. if ($val >= $amount) {
  54. $rate = $key;
  55. return true;
  56. }
  57. } else {
  58. if ($rate == $key) {
  59. $rate = $key;
  60. if ($val >= $amount) {
  61. return true;
  62. } else {
  63. return false;
  64. }
  65. }
  66. }
  67. }
  68. return false;
  69. }
  70. public function with_hold($rate, $amount)
  71. {
  72. if (isset($this->mRates[$rate])) {
  73. $this->mDirty = true;
  74. $this->mRates[$rate] = $this->mRates[$rate] - $amount;
  75. }
  76. }
  77. public function find_rate($amount)
  78. {
  79. if (empty($this->mRates)) return false;
  80. $rates = $this->mRates;
  81. ksort($rates);
  82. foreach ($rates as $rate => $money) {
  83. $money = intval($money * 100 + 0.5);
  84. $amount = intval($amount * 100 + 0.5);
  85. if ($amount >= $money) {
  86. return ['rate' => $rate, 'amount' => $money / 100];
  87. } else {
  88. return ['rate' => $rate, 'amount' => $amount / 100];
  89. }
  90. }
  91. return false;
  92. }
  93. public function format()
  94. {
  95. $result = [];
  96. foreach ($this->mRates as $key => $val) {
  97. $val = intval($val * 100 + 0.5);
  98. if ($val > 0) {
  99. $result[$key] = $val / 100;
  100. }
  101. }
  102. return $result;
  103. }
  104. public function total()
  105. {
  106. $total = 0.00;
  107. foreach ($this->mRates as $key => $amount) {
  108. $total += $amount;
  109. }
  110. return $total;
  111. }
  112. public function dirty()
  113. {
  114. return $this->mDirty;
  115. }
  116. public function clean()
  117. {
  118. $this->mDirty = false;
  119. }
  120. public function calc_rates($amount)
  121. {
  122. $rates = [];
  123. $left = intval($amount * 100 + 0.5);
  124. foreach ($this->mRates as $rate => $total) {
  125. if ($left <= 0) break;
  126. if ($rate > 100) continue;
  127. $total = intval($total * 100 + 0.5);
  128. if ($total <= 0) {
  129. continue;
  130. } else {
  131. if ($total >= $left) {
  132. $rates[$rate] = $left / 100;
  133. $left = 0;
  134. } else {
  135. $rates[$rate] = $total / 100;
  136. $left -= $total;
  137. }
  138. }
  139. }
  140. return $rates;
  141. }
  142. public function calc_money($price, &$rates)
  143. {
  144. $rates = [];
  145. $disc = 0;
  146. $left = intval($price * 100 + 0.5);
  147. foreach ($this->mRates as $rate => $total) {
  148. if ($left <= 0) break;
  149. if ($rate > 100) continue;
  150. $total = intval($total * 100 + 0.5);
  151. if ($total <= 0) {
  152. continue;
  153. } else {
  154. $max_rate = intval($left * $rate / 100 + 0.5);
  155. if ($total >= $max_rate) {
  156. $disc += $max_rate;
  157. $left = 0;
  158. $rates[$rate] = $max_rate / 100;
  159. } else {
  160. $disc += $total;
  161. $left -= intval($total * 100 / $rate + 0.5);
  162. $rates[$rate] = $total / 100;
  163. }
  164. }
  165. }
  166. $cur_price = intval($price * 100 + 0.5) - $disc;
  167. return $cur_price / 100;
  168. }
  169. public function calc_price($price, &$rates)
  170. {
  171. $cur_price = intval($this->calc_money($price, $rates) * 100 + 0.5);
  172. return $cur_price / 100;
  173. }
  174. static function scale()
  175. {
  176. return (100 - self::PRED_RATE) / 100;
  177. }
  178. }