VM暫存
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

273 line
7.8KB

  1. <?php
  2. /*
  3. file: Shop_model.php 購物
  4. */
  5. class Shop_model extends CI_Model
  6. {
  7. var $vars = array();
  8. function __construct()
  9. {
  10. parent::__construct();
  11. $this->load->database();
  12. // product code
  13. define('PRODUCT_CODE_COFFEE_SHOP', 'coffee_shop'); // 咖啡產品包
  14. define('PRODUCT_CODE_COFFEE', 'coffee'); // 咖啡
  15. }
  16. public function init($vars)
  17. {
  18. $this->vars = $vars;
  19. }
  20. // 取得發票待兌換訂單
  21. public function q_invoice_ready_bill($invoice_no)
  22. {
  23. $where_arr['invoice_no'] = $invoice_no;
  24. $where_arr['status'] = 1;
  25. $data = array();
  26. $result = $this->db->select('product_id, product_code, product_name, invoice_remark, product_plan')
  27. ->from('product_bill')
  28. ->where($where_arr)->order_by("create_time", "desc")
  29. ->get()
  30. ->row_array();
  31. return $result;
  32. }
  33. // 取得產品資訊
  34. public function q_product($product_id=0, $product_code=PRODUCT_CODE_COFFEE_SHOP)
  35. {
  36. $now = date('Y/m/d H:i:s');
  37. $where_arr = array('start_time <= ' => $now, 'valid_time > ' => $now);
  38. // 指定產品流水號
  39. if($product_id != 0)
  40. $where_arr['product_id'] = $product_id;
  41. // 指定產品包
  42. $where_arr['product_code'] = $product_code;
  43. $data = array();
  44. $result = $this->db->select('product_id, product_code, product_name, product_desc, amt, remarks, product_plan')
  45. ->from('products')
  46. ->where($where_arr)->order_by("create_time", "desc")
  47. ->limit(1)
  48. ->get()
  49. ->row_array();
  50. return $result;
  51. }
  52. // 產生交易序號
  53. private function gen_trx_no()
  54. {
  55. return time().rand(10000,99999);
  56. }
  57. // S.1. 建立產品訂單
  58. public function create_product_bill($product_id, $product_code)
  59. {
  60. // 取得商品資訊
  61. $product_info = $this->q_product($product_id, $product_code);
  62. if(!isset($product_info['product_plan']))
  63. {
  64. return 'unknown_product'; // 中斷
  65. }
  66. $data = array();
  67. $data['order_no'] = $this->gen_trx_no();
  68. $data['product_id'] = $product_info["product_id"];
  69. $data['product_code'] = $product_info["product_code"];
  70. $data['product_plan'] = $product_info["product_plan"];
  71. $data['invoice_remark'] = $product_info["product_name"];
  72. $data['amt'] = $product_info["amt"];
  73. $data['valid_time'] = date('Y-m-d H:i:s', strtotime(" + 15 minutes")); // 15 min 內有效
  74. $this->db->insert('product_bill', $data);
  75. $affect_rows = $this->db->affected_rows();
  76. if ($affect_rows <= 0)
  77. return 'fail';
  78. trigger_error(__FUNCTION__ . '..' . print_r($data, true));
  79. return $data;
  80. }
  81. // S.2. 處理產品訂單
  82. public function proceed_product_bill($parms, $tx_type=0)
  83. {
  84. $order_no = $parms['order_no'];
  85. $invoice_receiver = $parms['invoice_receiver'];
  86. $company_no = $parms['company_no'];
  87. $email = $parms['email'];
  88. $mobile = $parms['mobile'];
  89. $product_info = $this->db->select('valid_time, product_plan')
  90. ->from('product_bill')
  91. ->where(array('order_no' => $order_no))
  92. ->limit(1)
  93. ->get()
  94. ->row_array();
  95. if(!isset($product_info['product_plan']))
  96. {
  97. trigger_error(__FUNCTION__ . "|{$order_no}|unknown_order");
  98. return 'unknown_order'; // 中斷
  99. }
  100. if(!isset($product_info['valid_time']))
  101. {
  102. trigger_error(__FUNCTION__ . "|{$order_no}|valid_time_not_found");
  103. return 'valid_time_not_found'; // 中斷
  104. }
  105. $data = array();
  106. $data['tx_type'] = $tx_type; // 交易種類: 0:未定義, 1:現金, 40:博辰人工模組, 41:博辰自動繳費機, 50:歐付寶轉址刷卡, 51:歐付寶APP, 52:歐付寶轉址WebATM, 60:中國信託刷卡轉址
  107. if(strlen($company_no) >= 8)
  108. {
  109. $data['company_no'] = $company_no; // 電子發票:公司統編
  110. $data['company_receiver'] = "公司名稱"; // 電子發票:公司名稱
  111. $data['company_address'] = "公司地址"; // 電子發票:公司地址
  112. }
  113. $data['invoice_receiver'] = (strlen($invoice_receiver) >= 7) ? $invoice_receiver : ''; // 電子發票:載具編號
  114. $data['email'] = (strlen($email) >= 5) ? $email : ''; // 電子發票:email
  115. $data['mobile'] = (strlen($mobile) >= 10) ? $mobile : ''; // 電子發票:手機
  116. // 交易時間
  117. $tx_time = time();
  118. $data['tx_time'] = date('Y/m/d H:i:s', $tx_time);
  119. if(strtotime($product_info['valid_time']) < $tx_time)
  120. {
  121. $data['status'] = 99; //狀態: 99:訂單逾期作廢
  122. $this->db->update('product_bill', $data, array('order_no' => $order_no));
  123. trigger_error(__FUNCTION__ . "|{$order_no}| 99 gg");
  124. return 'gg';
  125. }
  126. // 完成
  127. $data['status'] = 100; // 狀態: 100:交易進行中
  128. $this->db->update('product_bill', $data, array('order_no' => $order_no));
  129. $affect_rows = $this->db->affected_rows();
  130. if ($affect_rows <= 0)
  131. return 'fail';
  132. $data['order_no'] = $order_no;
  133. trigger_error(__FUNCTION__ . ".." . print_r($data, true));
  134. return $data;
  135. }
  136. // S.3. 更新產品訂單
  137. public function reload_product_bill($order_no, $invoice_no, $product_plan)
  138. {
  139. // 更新為已結帳
  140. $this->db->update('product_bill',
  141. array('status' => 1, 'invoice_no' => $invoice_no, 'product_plan' => $product_plan),
  142. array('status' => 100, 'order_no' => $order_no)
  143. );
  144. $affect_rows = $this->db->affected_rows();
  145. if ($affect_rows <= 0)
  146. return 'fail';
  147. // 兌換
  148. return $this->redeem_product_bill($order_no);
  149. }
  150. // S.4. 兌換訂單商品
  151. public function redeem_product_bill($order_no)
  152. {
  153. $product_info = $this->db->select('invoice_no, product_plan')
  154. ->from('product_bill')
  155. ->where(array('order_no' => $order_no))
  156. ->limit(1)
  157. ->get()
  158. ->row_array();
  159. $invoice_no = $product_info['invoice_no'];
  160. $product_plan = $product_info['product_plan'];
  161. // 取得訂單內容
  162. $data = json_decode($product_plan, true);
  163. if(!isset($data['product_code']))
  164. {
  165. trigger_error(__FUNCTION__ . "|$order_no|not_found");
  166. return 'not_found';
  167. }
  168. $product_code = $data['product_code'];
  169. // 咖啡
  170. if($product_code == PRODUCT_CODE_COFFEE)
  171. {
  172. // 取得產品包資訊
  173. $station_no = $data['station_no'];
  174. $amount = $data['amount'];
  175. $memo = $data['memo'];
  176. $product = $this->q_product(0, $product_code);
  177. if(!isset($product['product_id']))
  178. {
  179. trigger_error(__FUNCTION__ . "|$order_no|$station_no, $product_code, $amount, $memo|product_not_found");
  180. return 'product_contain_not_found';
  181. }
  182. trigger_error(__FUNCTION__ . "|$order_no|$station_no, $product_code, $amount, $memo|兌換|" . print_r($product, true));
  183. // 兌換產品
  184. return $this->redeem_product($order_no, $invoice_no, $product, $amount);
  185. }
  186. trigger_error(__FUNCTION__ . "|$order_no|undefined_product|" . print_r($data, true));
  187. return 'undefined_product';
  188. }
  189. // 兌換產品
  190. function redeem_product($order_no, $invoice_no, $product, $amount=1)
  191. {
  192. // [A.開始]
  193. $this->db->trans_start();
  194. // 兌換時間
  195. $tx_time = date('Y/m/d H:i:s');
  196. for($i = 0; $i < $amount; $i++)
  197. {
  198. $item = array();
  199. $item['order_no'] = $this->gen_trx_no();
  200. $item['tx_time'] = $tx_time;
  201. $item['invoice_no'] = $invoice_no;
  202. $item['product_id'] = $product["product_id"];
  203. $item['product_code'] = $product["product_code"];
  204. $item['product_plan'] = $product["product_plan"];
  205. $item['invoice_remark'] = $product["product_name"];
  206. $item['amt'] = $product["amt"];
  207. $item['status'] = 1;
  208. $this->db->insert('product_bill', $item);
  209. }
  210. // 更新為已領取
  211. $this->db->update('product_bill', array('status' => 111), array('status' => 1, 'order_no' => $order_no));
  212. // [C.完成]
  213. $this->db->trans_complete();
  214. if ($this->db->trans_status() === FALSE)
  215. {
  216. trigger_error(__FUNCTION__ . "..$order_no, $invoice_no..trans error..". '| last_query: ' . $this->db->last_query());
  217. return 'fail'; // 中斷
  218. }
  219. return 'ok';
  220. }
  221. }