VM暫存
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

262 řádky
10KB

  1. <?php
  2. require_once 'Altob.Payment.Core.php';
  3. abstract class PricePlanValueKey
  4. {
  5. const p0 = "p0"; // 費用 0
  6. const limit0 = "limit0"; // 上限 0
  7. const limit0_start_time = "limit0_start_time"; // 上限 0 開始時間
  8. const limit0_end_time = "limit0_end_time"; // 上限 0 結束時間
  9. const free0_min = "free0_min"; // 免費時間 (分)
  10. }
  11. /**
  12. * 明細拆算: 費用明細 key
  13. */
  14. abstract class PriceDeatilStatusValue
  15. {
  16. const TYPE_0 = 0; // 一般
  17. const TYPE_1 = 1; // 達上限
  18. }
  19. /**
  20. * 明細拆算: 費用明細 key
  21. */
  22. abstract class PriceDeatilKey
  23. {
  24. const r_no = "r_no"; // 明細拆算: 序號
  25. const day = "day"; // 明細拆算: 日期
  26. const hours = "h"; // 明細拆算: 時
  27. const mins = "i"; // 明細拆算: 分
  28. const price = "p"; // 明細拆算: 費用
  29. const meta = "meta"; // 明細拆算: 費用說明
  30. const status = "status"; // 明細拆算: 狀態
  31. const p0 = "p0"; // 費用 0
  32. const limit0 = "limit0"; // 上限 0
  33. const limit0_start_time = "limit0_start_time"; // 上限 0 開始時間
  34. const limit0_end_time = "limit0_end_time"; // 上限 0 結束時間
  35. const free0_min = "free0_min"; // 免費時間 (分)
  36. }
  37. /**
  38. * 適用: 臨停
  39. *
  40. * @version 1.0
  41. * @author mip
  42. */
  43. class AltobPayment extends AltobPaymentAbstractClass
  44. {
  45. // 取得帳單與明細
  46. public function getBill($inTime, $balanceTime, $stationNo)
  47. {
  48. $dateBegin = new DateTime($inTime);
  49. $dateEnd = new DateTime($balanceTime);
  50. $interval = $dateBegin->diff($dateEnd); // y, m, d, h, i, s
  51. // A. 取得費率設定
  52. $this->PricePlan = $this->getPricePlan($stationNo); // get price plan
  53. /*
  54. 規則:
  55. 1. 每小時20元,每日最高150元,前30分鐘免費
  56. 2. 另外停車1小時候未滿30分以10元計,超過30分以20元計
  57. ex. 15日18:00進場~16日20:30出場:15日金額120元 + 16日金額150元 =270
  58. ex. 15日12:00進場~15日16:25出場:80元+10元
  59. */
  60. $p0 = $this->PricePlan[PricePlanValueKey::p0]; // 費用 0 (10元 /半小時)
  61. $limit0 = $this->PricePlan[PricePlanValueKey::limit0]; // 上限 0 (150元 /D)
  62. $limit0_start_time = $this->PricePlan[PricePlanValueKey::limit0_start_time]; // 上限 0 開始時間 (00:00:00)
  63. $limit0_end_time = $this->PricePlan[PricePlanValueKey::limit0_end_time]; // 上限 0 結束時間 (23:59:59)
  64. $free0_min = $this->PricePlan[PricePlanValueKey::free0_min]; // 免費 0 (前 30 分)
  65. // B. 取得特殊日期
  66. //$this->PricePlanDate = $this->getPricePlanDate($inTime, $balanceTime);
  67. // C. 開始建立帳單明細 $this->PriceDetail
  68. $this->PriceDetail = array();
  69. // D. 取得帳單結算價錢
  70. // D.1 前 30 分鐘免費
  71. if($interval->y == 0 && $interval->m == 0 && $interval->d == 0 && $interval->h == 0 && $interval->i < $free0_min){
  72. $this->Price = 0;
  73. return $this->genBillResult($interval);
  74. }
  75. // D.2 依照費率將時間切割, 暫存 $day_array
  76. $day_array = array();
  77. $dateFront = $dateBegin;
  78. $dateTail = $dateEnd;
  79. $period_of_basic_repeat = new DatePeriod($dateFront, DateInterval::createFromDateString('30 minutes'), $dateTail);
  80. foreach ($period_of_basic_repeat as $basic_part){
  81. $today_key = $this->genLv1Key($basic_part);
  82. if(!array_key_exists($today_key, $this->PriceDetail)){
  83. $today_data = array();
  84. $today_data[PriceDeatilKey::p0] = $p0;
  85. $today_data[PriceDeatilKey::limit0] = $limit0;
  86. $today_data[PriceDeatilKey::limit0_start_time] = $limit0_start_time;
  87. $today_data[PriceDeatilKey::limit0_end_time] = $limit0_end_time;
  88. $today_data[PriceDeatilKey::free0_min] = $free0_min;
  89. $this->PriceDetail[$today_key] = $today_data;
  90. }
  91. $this->genLv2Value(0, $today_key, $basic_part, 0, "init");
  92. array_push($day_array, $basic_part);
  93. }
  94. $this->PriceDetail["day_array"] = $day_array;
  95. //return $this->genBillResult($interval);
  96. // 解析 $day_array 建立帳單明細於 $this->PriceDetail
  97. $total_price = 0;
  98. $today_limit0_amt = 0;
  99. $count_period = count($day_array);
  100. for($i = 0 ; $i < $count_period ; $i+=1){
  101. $price_this = 0;
  102. $day_this = $day_array[$i];
  103. $today_key = $this->genLv1Key($day_this);
  104. $today_lv2_key = $this->genLv2Key($day_this);
  105. $today_p0 = $this->PriceDetail[$today_key][PriceDeatilKey::p0];
  106. $today_limit0 = $this->PriceDetail[$today_key][PriceDeatilKey::limit0];
  107. $today_limit0_start_time = $this->PriceDetail[$today_key][PriceDeatilKey::limit0_start_time];
  108. $today_limit0_end_time = $this->PriceDetail[$today_key][PriceDeatilKey::limit0_end_time];
  109. $today_free0_min = $this->PriceDetail[$today_key][PriceDeatilKey::free0_min];
  110. // 重置每日收費上限
  111. $current_h = $day_this->format('H');
  112. if($current_h == substr($today_limit0_start_time, 0, 2)){
  113. $today_limit0_amt = 0;
  114. }
  115. // 記算金額
  116. $status = PriceDeatilStatusValue::TYPE_0;
  117. if($today_limit0_amt >= $today_limit0){
  118. // 已達上限值, 免費
  119. $price_this = 0;
  120. $memo = "B.4 ..FREE..";
  121. $status = PriceDeatilStatusValue::TYPE_1;
  122. }else{
  123. // 未達上限值, 取得時段費用
  124. $price_this = $this->getPrice($today_p0);
  125. if(array_key_exists($i - 1, $day_array)){
  126. if(array_key_exists($i + 1, $day_array)){
  127. if($today_limit0_amt + $price_this >= $today_limit0){
  128. // 未達上限值, 有上一筆, 有下一筆, 本次達上限
  129. $price_this = $today_limit0 - $today_limit0_amt;
  130. $today_limit0_amt = $today_limit0;
  131. $memo = "B.3 ..today limit : {$today_limit0}..";
  132. $status = PriceDeatilStatusValue::TYPE_1;
  133. }else{
  134. // 未達上限值, 有上一筆, 有下一筆, 本次未達上限
  135. $today_limit0_amt += $price_this;
  136. $memo = "B.2 ..next..";
  137. }
  138. }else{
  139. // 未達上限值, 有上一筆, 最後一筆
  140. if($today_limit0_amt + $price_this >= $today_limit0){
  141. // 未達上限值, 有上一筆, 最後一筆, 本次達上限
  142. $price_this = $today_limit0 - $today_limit0_amt;
  143. $today_limit0_amt = $today_limit0;
  144. $memo = "D.2 ..today limit : {$today_limit0}..";
  145. $status = PriceDeatilStatusValue::TYPE_1;
  146. }else{
  147. // 未達上限值, 有上一筆, 最後一筆, 本次未達上限
  148. $today_limit0_amt += $price_this;
  149. $memo = "D.1 ..next..";
  150. }
  151. }
  152. }else{
  153. if(array_key_exists($i + 1, $day_array)){
  154. // 未達上限值, 第一筆, 有下一筆
  155. $today_limit0_amt += $price_this;
  156. $memo = "B.1 ..START..a";
  157. }else{
  158. // 未達上限值, 第一筆, 最後一筆
  159. $memo = "C ..done..";
  160. }
  161. }
  162. }
  163. // 建立明細資料
  164. if(array_key_exists($i - 1, $day_array)){
  165. if(array_key_exists($i + 1, $day_array)){
  166. // 有上一筆, 有下一筆
  167. $this->setLv2Value($i, $today_key, $today_lv2_key, $price_this, $memo, $status);
  168. }else{
  169. // 有上一筆, 最後一筆
  170. $this->setLv2Value($i, $today_key, $today_lv2_key, $price_this, $memo, $status);
  171. $price_end = 0;
  172. $status = PriceDeatilStatusValue::TYPE_0;
  173. /*
  174. if($day_this->diff($dateEnd)->i < $today_free0_min){
  175. // 未滿 30 分, 不計
  176. $memo = "E.3 ..end..";
  177. }else{
  178. */
  179. $price_end = $this->getPrice($today_p0);;
  180. if($today_limit0_amt + $price_end >= $today_limit0){
  181. // 達上限
  182. $price_end = $today_limit0 - $today_limit0_amt;
  183. $memo = "E.2 ..today limit : {$today_limit0}..";
  184. $status = PriceDeatilStatusValue::TYPE_1;
  185. }else{
  186. $memo = "E.1 ..end..";
  187. }
  188. $this->genLv2Value($i + 1, $today_key, $dateEnd, $price_end, $memo, $status);
  189. }
  190. }else{
  191. if(array_key_exists($i + 1, $day_array)){
  192. // 第一筆, 有下一筆
  193. // do nothing
  194. }else{
  195. // 第一筆, 最後一筆
  196. $this->genLv2Value($i + 1, $today_key, $dateEnd, $price_this, $memo, $status);
  197. }
  198. }
  199. // 總結算
  200. $total_price += $price_this;
  201. }
  202. $this->Price = $total_price;
  203. return $this->genBillResult($interval);
  204. }
  205. // 取得目前時段價格
  206. private function getPrice($today_p0)
  207. {
  208. return $today_p0;
  209. }
  210. // 建立 lv2
  211. private function genLv2Info($r_no, $today_lv1_key, $today_lv2_key, $price, $price_type, $meta)
  212. {
  213. $lv1Key = $today_lv1_key;
  214. $lv2Key = $today_lv2_key;
  215. $this->PriceDetail[$lv1Key][$lv2Key][PriceDeatilKey::r_no] = $r_no;
  216. $this->PriceDetail[$lv1Key][$lv2Key][PriceDeatilKey::price] = $price;
  217. $this->PriceDetail[$lv1Key][$lv2Key][PriceDeatilKey::p_type] = $price_type;
  218. $this->PriceDetail[$lv1Key][$lv2Key][PriceDeatilKey::meta] = $meta;
  219. }
  220. // 建立 lv2 value
  221. private function genLv2Value($r_no, $lv1Key, $day, $price, $meta, $status=PriceDeatilStatusValue::TYPE_0)
  222. {
  223. $lv2Key = $this->genLv2Key($day);
  224. $this->PriceDetail[$lv1Key][$lv2Key][PriceDeatilKey::day] = $day->format('Y-m-d H:i:s');
  225. $this->setLv2Value($r_no, $lv1Key, $lv2Key, $price, $meta, $status);
  226. }
  227. // 設定 lv2 value
  228. private function setLv2Value($r_no, $lv1Key, $lv2Key, $price, $meta, $status=PriceDeatilStatusValue::TYPE_0)
  229. {
  230. $this->PriceDetail[$lv1Key][$lv2Key][PriceDeatilKey::r_no] = $r_no;
  231. $this->PriceDetail[$lv1Key][$lv2Key][PriceDeatilKey::price] = $price;
  232. $this->PriceDetail[$lv1Key][$lv2Key][PriceDeatilKey::meta] = $meta;
  233. $this->PriceDetail[$lv1Key][$lv2Key][PriceDeatilKey::status] = $status;
  234. }
  235. }