VM暫存
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

3042 рядки
115KB

  1. <?php
  2. /*
  3. file: Admins_station_model.php
  4. */
  5. class Admins_station_model extends CI_Model
  6. {
  7. var $vars = array();
  8. function __construct()
  9. {
  10. parent::__construct();
  11. $this->load->database();
  12. $this->now_str = date('Y-m-d H:i:s');
  13. $this->default_valid_time = date('Y-m-d H:i:s', strtotime("{$this->now_str} + 2 days")); // 2016/12/15 新增有效期限 (預設為兩天)
  14. }
  15. public function init($vars)
  16. {
  17. $this->vars = $vars;
  18. }
  19. // 付款
  20. public function login_verify($login_name, $login_pswd)
  21. {
  22. $rows = $this->db->select('count(*) as ok')
  23. ->from('staffs')
  24. ->where(array('login_name' => $login_name, 'pswd' => md5($login_pswd)))
  25. ->get()
  26. ->row_array();
  27. return $rows['ok'];
  28. }
  29. // 讀出各初始值至web
  30. public function get_init_vars()
  31. {
  32. $st_info = $this->vars['mcache']->get('st_info');
  33. // 路徑初始值
  34. $str = "var APP_URL = '". APP_URL . "';\n".
  35. "var WEB_LIB = '" . WEB_LIB . "';\n".
  36. "var BOOTSTRAPS = '" . BOOTSTRAPS . "';\n".
  37. "var WEB_SERVICE = '" . WEB_SERVICE . "';\n".
  38. "var station_no ={$st_info['station_no']};\n".
  39. "var company_no = {$st_info['company_no']};\n".
  40. "var xvars = new Array();\n".
  41. "xvars['ck'] = 'NOLOGIN';\n";
  42. // 讀出場站資訊
  43. $str .= "var st = new Array();\n";
  44. $str .= "st[" . STATION_NO . "]=\"" . STATION_NAME . "\";\n";
  45. /*
  46. $results = $this->db->select('station_no, short_name')
  47. ->from('stations')
  48. ->order_by('station_no', 'asc')
  49. ->get()
  50. ->result_array();
  51. $str .= "var st = new Array();\n";
  52. foreach($results as $rows)
  53. {
  54. $str .= "st[{$rows['station_no']}]=\"{$rows['short_name']}\";\n";
  55. }
  56. */
  57. // 讀出時段表資訊
  58. $str .= "var pt = new Array();\n"; // park_time
  59. foreach($this->vars['mcache']->get('pt') as $key => $rows)
  60. {
  61. $str .= "pt['{$key}']={'seqno':{$rows['seqno']},'remarks':'{$rows['remarks']}'};\n";
  62. }
  63. /*
  64. // 讀取繳期名稱
  65. $rows = $this->db->select('period_name')
  66. ->from('info')
  67. ->where('seqno', 1)
  68. ->get()
  69. ->row_array();
  70. $str .= "var period_name=Array();\nperiod_name={$rows['period_name']};\n";
  71. */
  72. // 篩選會員身份及繳期資訊
  73. $info = $this->vars['mcache']->get('info');
  74. $str .= "var period_name=Array();\n";
  75. foreach($info['period_name'] as $idx => $rows)
  76. {
  77. $str .= "period_name[{$idx}]=\"{$rows}\";\n";
  78. }
  79. $str .= "var mem_attr = new Array();\n";
  80. foreach($info['member_attr'] as $idx => $rows)
  81. {
  82. $str .= "mem_attr[{$idx}]=\"{$rows}\";\n";
  83. }
  84. return $str;
  85. }
  86. // 取得停車時段資訊
  87. public function get_parktime_str()
  88. {
  89. return $this->vars['mcache']->get('pt');
  90. }
  91. /*
  92. // 停車時段資訊
  93. public function park_time()
  94. {
  95. $data = array();
  96. $idx = 0;
  97. // $results = $this->db->select('time_id, seqno, park_type, week_start, week_end, daytime_start, daytime_end, remarks')
  98. $results = $this->db->select('time_id, seqno, timex, remarks')
  99. ->from('park_time')
  100. ->order_by('seqno', 'asc')
  101. ->get()
  102. ->result_array();
  103. foreach($results as $rows)
  104. {
  105. $data[$idx] = array
  106. (
  107. 'time_id' => $rows['time_id'],
  108. 'seqno' => $rows['time_id'],
  109. 'remarks' => $rows['remarks']
  110. );
  111. ++$idx;
  112. }
  113. return $results;
  114. }
  115. // 停車時段資訊單筆刪除
  116. public function park_time_delete($time_id)
  117. {
  118. $this->db->delete('park_time', array('time_id' => $time_id));
  119. return true;
  120. }
  121. */
  122. // 會員清單
  123. public function member_query_all()
  124. {
  125. $sql = "
  126. SELECT
  127. members.member_no,
  128. members.lpr,
  129. members.etag,
  130. members.member_name,
  131. members.mobile_no,
  132. members.start_date,
  133. members.end_date,
  134. members.fee_period,
  135. members.member_attr,
  136. members.suspended,
  137. members.contract_no,
  138. members.amt,
  139. COALESCE(members.valid_time, members.end_date) as valid_time
  140. FROM members
  141. ORDER BY members.member_no DESC
  142. ";
  143. $results = $this->db->query($sql)->result_array();
  144. return $results;
  145. }
  146. // 待審核清單
  147. public function member_tx_check_query()
  148. {
  149. $sql = "
  150. SELECT
  151. members.lpr as current_lpr,
  152. member_tx.lpr,
  153. member_tx.tx_no,
  154. member_tx.station_no,
  155. member_tx.member_no,
  156. member_tx.fee_period,
  157. member_tx.fee_period_last,
  158. member_tx.amt1,
  159. member_tx.amt,
  160. member_tx.amt_last,
  161. member_tx.deposit,
  162. date_format(member_tx.start_date,'%Y-%m-%d') as start_date,
  163. date_format(member_tx.end_date,'%Y-%m-%d') as end_date,
  164. date_format(member_tx.start_date_last,'%Y-%m-%d') as start_date_last,
  165. date_format(member_tx.end_date_last,'%Y-%m-%d') as end_date_last,
  166. member_tx.member_company_no,
  167. member_tx.company_no,
  168. member_tx.acc_date,
  169. member_tx.invoice_no,
  170. member_tx.invoice_amt,
  171. member_tx.invoice_track,
  172. member_tx.invoice_time,
  173. member_tx.invoice_type,
  174. member_tx.verify_state,
  175. member_tx.valid_time,
  176. member_tx.remarks,
  177. member_tx.tx_state
  178. FROM member_tx
  179. LEFT JOIN members ON (member_tx.member_no = members.member_no AND members.station_no = member_tx.station_no)
  180. WHERE
  181. member_tx.verify_state in (0, 99) and members.member_no is not null
  182. and member_tx.valid_time > 0 -- 20170131 added
  183. ORDER BY member_tx.valid_time ASC
  184. ";
  185. $results = $this->db->query($sql)->result_array();
  186. return $results;
  187. }
  188. // 已退租交易清單
  189. public function member_tx_refund_query($station_no, $q_item, $q_str)
  190. {
  191. $where_station = $station_no == 0 ? '' : " member_refund.station_no = {$station_no} and "; // 如為0, 則全部場站讀取
  192. switch($q_item)
  193. {
  194. case 'lpr':
  195. $items = "member_log.{$q_item} like ";
  196. $q_str = strtoupper($q_str).'%';
  197. break;
  198. default:
  199. $items = "member_log.{$q_item} like ";
  200. $q_str .= '%';
  201. break;
  202. }
  203. $sql = "
  204. SELECT
  205. member_refund.member_refund_id,
  206. member_refund.station_no,
  207. member_refund.member_no,
  208. member_log.lpr,
  209. member_log.member_name,
  210. member_log.company_no,
  211. member_log.member_company_no,
  212. member_refund.refund_amt,
  213. member_refund.refund_deposit,
  214. member_refund.refund_tot_amt,
  215. member_refund.refund_time,
  216. member_refund.refund_state,
  217. member_refund.create_time,
  218. member_refund.dismiss_state
  219. FROM member_refund
  220. LEFT JOIN member_log ON ( member_log.member_log_id = member_refund.member_log_id and member_log.station_no = member_refund.station_no )
  221. WHERE {$where_station} {$items} '{$q_str}'
  222. ORDER BY member_refund.create_time DESC
  223. ";
  224. //trigger_error("test: {$sql}");
  225. $results = $this->db->query($sql)->result_array();
  226. return $results;
  227. }
  228. // 取得轉租資訊
  229. public function member_refund_transfer_data_query($station_no, $member_no, $member_refund_id)
  230. {
  231. $rows = $this->db->select('
  232. member_log.member_id,
  233. member_log.member_no,
  234. member_log.member_name,
  235. member_log.member_nick_name,
  236. member_log.member_attr,
  237. member_log.fee_period,
  238. member_log.contract_no,
  239. member_log.lpr,
  240. member_log.etag,
  241. member_log.member_company_no,
  242. member_log.mobile_no,
  243. member_log.tel_o,
  244. member_log.tel_h,
  245. member_log.addr,
  246. member_log.park_time,
  247. member_refund.refund_deposit,
  248. member_refund.refund_amt,
  249. member_refund.refund_state,
  250. member_refund.dismiss_state,
  251. member_refund.refund_time
  252. ')
  253. ->from('member_refund')
  254. ->join('member_log', 'member_log.member_log_id = member_refund.member_log_id', 'left')
  255. ->where(array(
  256. 'member_refund.member_refund_id' => $member_refund_id,
  257. 'member_refund.station_no' => $station_no,
  258. 'member_refund.member_no' => $member_no
  259. ))
  260. ->get()
  261. ->row_array();
  262. $data = array();
  263. if(empty($rows) || empty($rows['member_no']))
  264. {
  265. $data['result_code'] = 'NOT_FOUND';
  266. }
  267. else
  268. {
  269. $data['result_code'] = 'OK';
  270. $data['result'] = $rows;
  271. }
  272. return $data;
  273. }
  274. // 會員查詢
  275. public function member_query($station_no, $q_item, $q_str)
  276. {
  277. $where_station = $station_no == 0 ? '' : " station_no = {$station_no} and "; // 如為0, 則全部場站讀取
  278. switch($q_item)
  279. {
  280. case 'end_date':
  281. $items = "{$q_item} <=";
  282. $q_str .= ' 23:59:59';
  283. break;
  284. case 'lpr':
  285. $items = "{$q_item} like ";
  286. $q_str = strtoupper($q_str).'%';
  287. break;
  288. default:
  289. $items = "{$q_item} like ";
  290. $q_str .= '%';
  291. break;
  292. }
  293. $sql = "select
  294. station_no,
  295. member_no,
  296. lpr,
  297. member_name,
  298. mobile_no,
  299. date_format(demonth_start_date,'%Y-%m-%d') as demonth_start_date,
  300. date_format(demonth_end_date,'%Y-%m-%d') as demonth_end_date,
  301. date_format(start_date,'%Y-%m-%d') as start_date,
  302. date_format(end_date,'%Y-%m-%d') as end_date,
  303. date_format(rent_start_date,'%Y-%m-%d') as rent_start_date,
  304. contract_no,
  305. coalesce(etag, '') as etag,
  306. fee_period1,
  307. fee_period,
  308. amt1,
  309. amt,
  310. if(member_company_no > 0, member_company_no, '') as member_company_no,
  311. if(company_no > 0, company_no, '') as company_no,
  312. coalesce(member_attr, 1) as member_attr,
  313. deposit,
  314. park_time,
  315. coalesce(member_id, '') as member_id,
  316. coalesce(tel_o, '') as tel_o,
  317. coalesce(tel_h, '') as tel_h,
  318. coalesce(addr, '') as addr,
  319. suspended
  320. from members
  321. where {$where_station} {$items} '{$q_str}'";
  322. $results = $this->db->query($sql)->result_array();
  323. return $results;
  324. }
  325. // 交易查詢
  326. public function member_tx_query($station_no, $member_no)
  327. {
  328. $sql = "select
  329. tx_no, station_no,
  330. member_no,
  331. lpr,
  332. fee_period,
  333. fee_period_last,
  334. amt1,
  335. amt,
  336. amt_last,
  337. deposit,
  338. date_format(start_date,'%Y-%m-%d') as start_date,
  339. date_format(end_date,'%Y-%m-%d') as end_date,
  340. date_format(start_date_last,'%Y-%m-%d') as start_date_last,
  341. date_format(end_date_last,'%Y-%m-%d') as end_date_last,
  342. member_company_no,
  343. company_no,
  344. acc_date,
  345. invoice_no,
  346. invoice_amt,
  347. invoice_track,
  348. invoice_time,
  349. invoice_type,
  350. verify_state,
  351. valid_time,
  352. remarks,
  353. tx_state
  354. from member_tx
  355. where station_no = {$station_no} and member_no = {$member_no}
  356. order by tx_no desc";
  357. // and tx_state = ".MEMBER_TX_TX_STATE_NONE."
  358. $results = $this->db->query($sql)->result_array();
  359. return $results;
  360. }
  361. // 發票查詢
  362. public function member_tx_bill_query($station_no, $tx_no=0, $verify_state_str='', $invoice_state_str='', $tx_state_str='', $tx_bill_no=0)
  363. {
  364. $tx_no_statement = !empty($tx_no) ? " and member_tx_bill.tx_no = {$tx_no} " : "";
  365. $tx_bill_no_statement = !empty($tx_bill_no) ? " and member_tx_bill.tx_bill_no = {$tx_no} " : "";
  366. // 審核狀態
  367. $verify_state_statement = !empty($verify_state_str) ? " and member_tx.verify_state in ( {$verify_state_str} )" : "";
  368. // 發票狀態
  369. $invoice_statement = '';
  370. if($invoice_state_str == '0') // 限定:未開立發票
  371. {
  372. $invoice_statement = " and member_tx_bill.invoice_no <= 0 ";
  373. }
  374. if($invoice_state_str == '1') // 限定:未開立發票, 或是 有餘額未開立 (且為 待補開發票)
  375. {
  376. $invoice_statement = " and member_tx_bill.invoice_state = 1 and ( member_tx_bill.invoice_no <= 0 OR member_tx_bill.remain_amt > 0 ) ";
  377. }
  378. else if($invoice_state_str == '2') // 限定:待折讓發票
  379. {
  380. $invoice_statement = " and member_tx_bill.invoice_state = 2";
  381. }
  382. else if($invoice_state_str == '100') // 限定:未開立發票, 或是 有餘額未開立
  383. {
  384. $invoice_statement = " and ( member_tx_bill.invoice_no <= 0 OR member_tx_bill.remain_amt > 0 ) ";
  385. }
  386. // 交易狀態
  387. $tx_state_statement = ($tx_state_str != '') ? " and member_tx.tx_state in ( {$tx_state_str} )" : " and member_tx.tx_state in (0,4,44) ";
  388. $sql = "select
  389. member_tx.tx_no,
  390. member_tx.station_no,
  391. member_tx.member_no,
  392. member_tx.lpr,
  393. member_tx.fee_period,
  394. member_tx.fee_period_last,
  395. member_tx.amt1,
  396. member_tx.amt,
  397. member_tx.amt_last,
  398. member_tx.deposit,
  399. date_format(member_tx.start_date,'%Y-%m-%d') as start_date,
  400. date_format(member_tx.end_date,'%Y-%m-%d') as end_date,
  401. date_format(member_tx.start_date_last,'%Y-%m-%d') as start_date_last,
  402. date_format(member_tx.end_date_last,'%Y-%m-%d') as end_date_last,
  403. member_tx_bill.tx_bill_no,
  404. member_tx_bill.member_company_no,
  405. member_tx_bill.company_no,
  406. member_tx_bill.acc_date,
  407. LPAD(member_tx_bill.invoice_no, 8, '0') as invoice_no, -- 發票號碼補零到8碼
  408. member_tx_bill.invoice_amt,
  409. member_tx_bill.invoice_track,
  410. member_tx_bill.invoice_time,
  411. member_tx_bill.invoice_type,
  412. member_tx_bill.remain_amt,
  413. member_tx_bill.invoice_state, -- 發票狀態
  414. member_tx_bill.refund_amt, -- 折讓金額
  415. member_tx.verify_state,
  416. member_tx.valid_time,
  417. member_tx.remarks,
  418. member_tx.tx_state
  419. from member_tx_bill
  420. left join member_tx on ( member_tx.tx_no = member_tx_bill.tx_no and member_tx.station_no = member_tx_bill.station_no )
  421. where member_tx_bill.station_no = {$station_no}
  422. {$tx_no_statement} {$tx_bill_no_statement}
  423. {$verify_state_statement} {$invoice_statement} {$tx_state_statement}
  424. order by member_tx_bill.tx_bill_no desc";
  425. //trigger_error("test: {$sql}");
  426. $results = $this->db->query($sql)->result_array();
  427. return $results;
  428. }
  429. // 發票查詢
  430. public function member_refund_bill_query($station_no, $tx_no=0, $verify_state_str='', $invoice_state_str='', $tx_state_str='',
  431. $tx_bill_no=0, $member_refund_id=0)
  432. {
  433. $tx_no_statement = !empty($tx_no) ? " and member_tx_bill.tx_no = {$tx_no} " : "";
  434. $tx_bill_no_statement = !empty($tx_bill_no) ? " and member_tx_bill.tx_bill_no = {$tx_no} " : "";
  435. $member_refund_id_statement = !empty($member_refund_id) ? " and member_refund.member_refund_id = {$member_refund_id} " : "";
  436. // 審核狀態
  437. $verify_state_statement = !empty($verify_state_str) ? " and member_tx.verify_state in ( {$verify_state_str} )" : "";
  438. // 發票狀態
  439. $invoice_statement = '';
  440. if($invoice_state_str == '0') // 限定:未開立發票
  441. {
  442. $invoice_statement = " and member_tx_bill.invoice_no <= 0 ";
  443. }
  444. if($invoice_state_str == '1') // 限定:未開立發票, 或是 有餘額未開立 (且為 待補開發票)
  445. {
  446. $invoice_statement = " and member_tx_bill.invoice_state = 1 and ( member_tx_bill.invoice_no <= 0 OR member_tx_bill.remain_amt > 0 ) ";
  447. }
  448. else if($invoice_state_str == '2') // 限定:待折讓發票
  449. {
  450. $invoice_statement = " and member_tx_bill.invoice_state = 2";
  451. }
  452. else if($invoice_state_str == '100') // 限定:未開立發票, 或是 有餘額未開立
  453. {
  454. $invoice_statement = " and ( member_tx_bill.invoice_no <= 0 OR member_tx_bill.remain_amt > 0 ) ";
  455. }
  456. // 交易狀態
  457. $tx_state_statement = !empty($tx_state_str) ? " and member_tx.tx_state in ( {$tx_state_str} )" : " and member_tx.tx_state = 0 ";
  458. $sql = "select
  459. member_tx.tx_no,
  460. member_tx.station_no,
  461. member_tx.member_no,
  462. member_tx.lpr,
  463. member_tx.fee_period,
  464. member_tx.fee_period_last,
  465. member_tx.amt1,
  466. member_tx.amt,
  467. member_tx.amt_last,
  468. member_tx.deposit,
  469. date_format(member_tx.start_date,'%Y-%m-%d') as start_date,
  470. date_format(member_tx.end_date,'%Y-%m-%d') as end_date,
  471. date_format(member_tx.start_date_last,'%Y-%m-%d') as start_date_last,
  472. date_format(member_tx.end_date_last,'%Y-%m-%d') as end_date_last,
  473. member_tx_bill.tx_bill_no,
  474. member_tx_bill.member_company_no,
  475. member_tx_bill.company_no,
  476. member_tx_bill.acc_date,
  477. LPAD(member_tx_bill.invoice_no, 8, '0') as invoice_no, -- 發票號碼補零到8碼
  478. member_tx_bill.invoice_amt,
  479. member_tx_bill.invoice_track,
  480. member_tx_bill.invoice_time,
  481. member_tx_bill.invoice_type,
  482. member_tx_bill.remain_amt,
  483. member_tx_bill.invoice_state, -- 發票狀態
  484. member_tx_bill.refund_amt, -- 折讓金額
  485. member_tx.verify_state,
  486. member_tx.valid_time,
  487. member_tx.remarks,
  488. member_tx.tx_state
  489. from member_tx_bill
  490. left join member_tx on ( member_tx.tx_no = member_tx_bill.tx_no and member_tx.station_no = member_tx_bill.station_no )
  491. left join member_refund on ( member_refund.member_no = member_tx_bill.member_no and member_refund.station_no = member_tx_bill.station_no )
  492. where member_tx_bill.station_no = {$station_no}
  493. {$tx_no_statement} {$tx_bill_no_statement} {$member_refund_id_statement}
  494. {$verify_state_statement} {$invoice_statement} {$tx_state_statement}
  495. order by member_tx_bill.tx_bill_no desc";
  496. //trigger_error("test: {$sql}");
  497. $results = $this->db->query($sql)->result_array();
  498. return $results;
  499. }
  500. // 臨停未結確認完成
  501. public function cario_temp_confirmed($parms)
  502. {
  503. $this->try_sync_batch($parms['station_no']); // 同步未同步記錄
  504. trigger_error(ADMIN_LOG_TITLE.'臨停未結確認完成:' . print_r($parms, true));
  505. // 取得交易資料
  506. $cario_info = $this->db->select('cario_no, in_time, out_time')
  507. ->from('cario')
  508. ->where(array('station_no' => $parms['station_no'], 'cario_no' => $parms['cario_no']))
  509. ->get()
  510. ->row_array();
  511. if(empty($cario_info))
  512. {
  513. trigger_error(__FUNCTION__ . '..cario not found..' . print_r($parms, true));
  514. return 'tx_error_not_found'; // 中斷
  515. }
  516. $data_cario = array('confirms' => 1, 'remarks' => $parms['remarks']);
  517. // [A.開始]
  518. $this->db->trans_start();
  519. $this->db->update('cario', $data_cario, array('station_no' => $parms['station_no'], 'cario_no' => $parms['cario_no'])); // t1. 更新 cario_no.confirms, cario.remarks
  520. // [B.建立同步檔] (略)
  521. // [C.完成]
  522. $this->db->trans_complete();
  523. if ($this->db->trans_status() === FALSE)
  524. {
  525. trigger_error(__FUNCTION__ . '..trans_error..data:' . print_r($data_cario, true). '| last_query: ' . $this->db->last_query());
  526. return 'fail'; // 中斷
  527. }
  528. return 'ok';
  529. }
  530. // 審核完成
  531. public function member_tx_confirmed($parms)
  532. {
  533. $this->try_sync_batch($parms['station_no']); // 同步未同步記錄
  534. trigger_error(ADMIN_LOG_TITLE.'審核完成:' . print_r($parms, true));
  535. $altob_admin_submit = $this->input->post('altob_admin_submit', true); // 取得 admin 參數
  536. //trigger_error(__FUNCTION__ . '..admin:' . print_r($altob_admin_submit, true));
  537. //trigger_error(__FUNCTION__ . '..check:' . print_r($this->gen_admin_ck($parms['station_no']), true));
  538. if($altob_admin_submit !== $this->gen_admin_ck($parms['station_no']))
  539. {
  540. trigger_error(__FUNCTION__ . '..altob_admin_submit error..' . print_r($parms, true));
  541. return 'admin_error'; // 中斷
  542. }
  543. // 取得交易資料
  544. $tx_info = $this->db->select('member_no, end_date')
  545. ->from('member_tx')
  546. ->where(array('station_no' => $parms['station_no'], 'tx_no' => $parms['tx_no']))
  547. ->get()
  548. ->row_array();
  549. if(empty($tx_info))
  550. {
  551. trigger_error(__FUNCTION__ . '..member_tx not found..' . print_r($parms, true));
  552. return 'tx_error_not_found'; // 中斷
  553. }
  554. $member_no = $tx_info['member_no'];
  555. // [ 可能的 BUG ] : 直接針對較新的交易審核過關, 會讓會員直接跳過較舊的交易有效期限
  556. $data_member = array(); // 若不為空會觸發同步 members
  557. $data_tx = array('verify_state' => $parms['verify_state'], 'remarks' => $parms['remarks']);
  558. // [A.開始]
  559. $this->db->trans_start();
  560. $this->db->update('member_tx', $data_tx, array('station_no' => $parms['station_no'], 'tx_no' => $parms['tx_no'])); // t1. 更新 member_tx.verify_state, member_tx.valid_time, member_tx.remarks
  561. $this->gen_member_tx_log($data_tx, $parms['station_no'], $parms['tx_no']); // t.log. 建立 member_tx_log
  562. if($data_tx['verify_state'] == MEMBER_TX_VERIFY_STATE_OK)
  563. {
  564. $next_valid_time = $tx_info['end_date']. ' 23:59:59'; // 交易若通過, 可取得的新有效期限
  565. // 取得會員資料
  566. $member_info = $this->db->select('valid_time')
  567. ->from('members')
  568. ->where(array('station_no' => $parms['station_no'], 'member_no' => $member_no))
  569. ->get()
  570. ->row_array();
  571. if(empty($member_info))
  572. {
  573. trigger_error(__FUNCTION__ . '..member not found..' . print_r($parms, true));
  574. }
  575. else
  576. {
  577. if(strtotime($member_info['valid_time']) >= strtotime($next_valid_time) )
  578. {
  579. trigger_error(__FUNCTION__ . '..member already got valid_time..' . print_r($parms, true));
  580. }
  581. else
  582. {
  583. $data_member = array('valid_time' => $next_valid_time);
  584. $this->db->update('members', $data_member, array('station_no' => $parms['station_no'], 'member_no' => $member_no)); // t2. 更新 members.valid_time
  585. $this->gen_member_log($data_member, $parms['station_no'], $member_no); // t.log. 建立 member_log
  586. }
  587. }
  588. // 若審核完成, 更新 members 有效期限
  589. }
  590. // [B.建立同步檔]
  591. $sync_seqnos = $this->prepare_sync2hq('U', $parms['station_no'], 'member_tx', $parms['tx_no'], $data_tx); // t3.a. 準備同步檔 (member_tx)
  592. if(!empty($data_member))
  593. {
  594. $sync_seqnos .= ',' . $this->prepare_sync2hq('U', $parms['station_no'], 'members', $member_no, $data_member); // t3.b. 準備同步檔 (members)
  595. }
  596. // [C.完成]
  597. $this->db->trans_complete();
  598. if ($this->db->trans_status() === FALSE)
  599. {
  600. trigger_error(__FUNCTION__ . '..trans_error..data:' . print_r($data_tx, true). '| last_query: ' . $this->db->last_query());
  601. return 'fail'; // 中斷
  602. }
  603. $this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
  604. return 'ok';
  605. }
  606. // 切換賣方統編
  607. public function switch_company_no($parms)
  608. {
  609. $this->try_sync_batch($parms['station_no']); // 同步未同步記錄
  610. trigger_error(ADMIN_LOG_TITLE.'切換賣方統編:' . print_r($parms, true));
  611. // 取得交易資料
  612. $tx_info = $this->db->select('company_no, invoice_no')
  613. ->from('member_tx_bill')
  614. ->where(array('station_no' => $parms['station_no'], 'tx_bill_no' => $parms['tx_bill_no']))
  615. ->get()
  616. ->row_array();
  617. if(empty($tx_info))
  618. {
  619. trigger_error(__FUNCTION__ . '..tx_error_not_found..' . print_r($parms, true));
  620. return 'tx_error_not_found'; // 中斷
  621. }
  622. if(!empty($tx_info['invoice_no']))
  623. {
  624. trigger_error(__FUNCTION__ . '..invoice_exist..' . print_r($parms, true));
  625. return 'invoice_exist'; // 中斷
  626. }
  627. $st_info = $this->vars['mcache']->get('st_info');
  628. $next_company_no = $st_info['company_no']; // 場站統編
  629. if($parms['company_no'] == $next_company_no)
  630. {
  631. $next_company_no = '80682490'; // 總公司統編
  632. }
  633. if($tx_info['company_no'] == $next_company_no)
  634. {
  635. trigger_error(__FUNCTION__ . '..not_changed..' . print_r($parms, true));
  636. return 'not_changed'; // 中斷
  637. }
  638. $data_tx_bill = array('company_no' => $next_company_no);
  639. // [A.開始]
  640. $this->db->trans_start();
  641. $this->db->update('member_tx_bill', $data_tx_bill, array('station_no' => $parms['station_no'], 'tx_bill_no' => $parms['tx_bill_no'])); // t1. 更新 member_tx_bill.company_no
  642. // [B.建立同步檔]
  643. $sync_seqnos = $this->prepare_sync2hq('U', $parms['station_no'], 'member_tx_bill', $parms['tx_bill_no'], $data_tx_bill); // t2. 準備同步檔 (member_tx_bill)
  644. // [C.完成]
  645. $this->db->trans_complete();
  646. if ($this->db->trans_status() === FALSE)
  647. {
  648. trigger_error(__FUNCTION__ . '..trans_error..data:' . print_r($data_tx_bill, true). '| last_query: ' . $this->db->last_query());
  649. return 'fail'; // 中斷
  650. }
  651. $this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
  652. return 'ok';
  653. }
  654. // 刪除月租會員
  655. /*
  656. public function member_delete($station_no, $member_no)
  657. {
  658. $this->try_sync_batch($station_no); // 同步未同步記錄
  659. // [A.開始]
  660. $this->db->trans_start();
  661. $this->db->delete('members', array('station_no' => $station_no, 'member_no' => $member_no, 'suspended' => 0)); // t1. 刪除 members
  662. $this->db->delete('member_car', array('station_no' => $station_no, 'member_no' => $member_no)); // t2. 刪除 member_car
  663. // [B.建立同步檔]
  664. $sync_seqnos = $this->prepare_sync2hq('D', $station_no, 'members', $member_no, array()); // t3. 準備同步檔 (members)
  665. // [C.完成]
  666. $this->db->trans_complete();
  667. if ($this->db->trans_status() === FALSE)
  668. {
  669. trigger_error(__FUNCTION__ . '..trans_error..data:' . "{$station_no}, {$member_no}". '| last_query: ' . $this->db->last_query());
  670. return 'trans_error';
  671. }
  672. // 同步至總管理處
  673. $this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
  674. return 'ok';
  675. }
  676. */
  677. // 月租會員加入
  678. public function member_add($data, $rents_arr)
  679. {
  680. $data['lpr'] = preg_replace('/\s+/', '', $data['lpr']); // 移除空白
  681. $check_member_no = $data['member_no'];
  682. $station_no = $data['station_no'];
  683. $tx_no = 0;
  684. $this->try_sync_batch($station_no); // 同步未同步記錄
  685. // 預設值 (修改會員時, 將直接填入)
  686. $tx_bill_no = 0;
  687. $invoice_amt = 0;
  688. $remain_amt = 0;
  689. $period_max_amt = 0;
  690. // 會員車輛基本資料檔
  691. $start_date = (empty($data['demonth_start_date']) ? $data['start_date'] : $data['demonth_start_date']);
  692. $data['rent_start_date'] = $data['start_date'];
  693. $data['rent_end_date'] = $data['end_date'];
  694. $data['start_date'] = "{$start_date} 00:00:00";
  695. $data['end_date'] = "{$data['end_date']} 23:59:59";
  696. $old_lpr = $data['old_lpr'];
  697. unset($data['old_lpr']);
  698. $data_car = array
  699. (
  700. 'lpr' => $data['lpr'],
  701. 'lpr_correct' => $data['lpr'],
  702. 'etag' => $data['etag'],
  703. 'station_no' => $station_no,
  704. 'start_time' => $data['start_date'],
  705. 'end_time' => $data['end_date']
  706. );
  707. // 取出會員轉租資訊
  708. $refund_transfer_id = empty($data['refund_transfer_id']) ? 0 : $data['refund_transfer_id'];
  709. $amt_discount = empty($data['refund_transfer_discount']) ? 0 : $data['refund_transfer_discount'];
  710. unset($data['refund_transfer_id']);
  711. unset($data['refund_transfer_discount']);
  712. if ($check_member_no == 0) // 新增一筆會員資料
  713. {
  714. unset($data['member_no']);
  715. $data['payed_date'] = substr($this->now_str, 0, 10);
  716. $data['login_id'] = $data['lpr'];
  717. $data['passwd'] = $data['lpr'];
  718. $data['valid_time']= $this->default_valid_time; // 有效期限 2017/01/15 added
  719. if($refund_transfer_id > 0)
  720. {
  721. $data['refund_transfer_id'] = $refund_transfer_id; // 轉租來源編號 2017/02/24 added
  722. }
  723. $action_code = 'A';
  724. // [A.開始]
  725. $this->db->trans_start();
  726. /*
  727. 2017/03/16 統一新增流程
  728. $this->db->insert('members', $data);
  729. $members_insert_id = $this->db->insert_id();
  730. $data_car['member_no'] = $members_insert_id;
  731. $this->db->insert('member_car', $data_car);
  732. */
  733. $members_insert_id = $this->gen_members($data); // t1 新增 members
  734. $data_car['member_no'] = $members_insert_id;
  735. $this->gen_member_car($data_car); // t2.a 新增 member_car
  736. $data['member_no'] = $members_insert_id;
  737. $this->gen_member_log($data); // t.log. 建立 member_log
  738. trigger_error(MEMBER_LOG_TITLE.'新增:' . print_r($data, true) . ", from: {$old_lpr}");
  739. $invoice_count = $this->gen_invoice_count($data['fee_period']); // 試算發票張數
  740. $data_tx = array(
  741. 'member_no' => $members_insert_id, // 會員編號
  742. 'station_no' => $station_no, // 場站編號
  743. 'sync_no' => 0, // 預設同步編號
  744. 'lpr' => $data['lpr'], // 車牌號碼
  745. 'member_attr' => $data['member_attr'], // 會員身份
  746. 'amt_accrued' => $data['amt_accrued'], // 應收租金
  747. 'amt_tot' => $data['amt_tot'], // 實收租金
  748. 'deposit' => $data['deposit'], // 押金
  749. 'amt' => $data['amt'], // 本期租金
  750. 'fee_period' => $data['fee_period'], // 本期繳期
  751. 'start_date' => $data['rent_start_date'], // 本期開始日
  752. 'end_date' => $data['rent_end_date'], // 本期結束日
  753. 'amt1' => $data['amt1'], // 首期租金
  754. 'amt_last' => $data['amt1'], // 上期租金
  755. 'fee_period_last' => $data['fee_period1'], // 上期繳期
  756. 'start_date_last' => $data['demonth_start_date'], // 上期開始日
  757. 'end_date_last' => $data['demonth_end_date'], // 上期結束日
  758. 'member_company_no' => $data['member_company_no'], // 買方統編
  759. 'company_no' => $data['company_no'], // 賣方統編
  760. 'invoice_count' => $invoice_count, // 預計發票張數
  761. 'acc_date' => $data['payed_date'], // 入帳日(暫定)
  762. 'acc_time' => $this->now_str, // 入帳時間 2017/02/15 added
  763. 'valid_time' => $data['valid_time'], // 有效期限
  764. 'amt_discount' => $amt_discount // 設定轉租折扺 2017/02/24 added
  765. );
  766. $this->db->insert('member_tx', $data_tx); // t3 新增 member_tx
  767. $tx_no = $this->db->insert_id(); // 訂單序號
  768. $data_tx['tx_no'] = $tx_no;
  769. $this->gen_member_tx_log($data_tx); // t.log. 建立 member_tx_log
  770. // 建立首期發票開立記錄 (公式 A: 首期租金 + 拆分第一期金額)
  771. $total_amt = $data['amt'] + $data['amt1'];
  772. $period_max_amt = $this->gen_invoice_count_amt($data['amt'], $invoice_count);
  773. $invoice_amt = $data['amt1'] + $period_max_amt;
  774. $remain_amt = ($total_amt - $invoice_amt > 0) ? $total_amt - $invoice_amt : 0;
  775. trigger_error(__FUNCTION__ . ', period_max_amt: ' . $period_max_amt . ', amt:'. $data['amt']. ', amt1:'. $data['amt1'] . ', invoice_amt:' .$invoice_amt . ', remain_amt:' . $remain_amt);
  776. /*
  777. // 建立首期發票開立記錄 (公式 B: 首期租金 + 最多一季金額) // 2017/01/11 更換
  778. $total_amt = $data['amt'] + $data['amt1'];
  779. $period_3_amt = $rents_arr[3][$data['member_attr']];
  780. $invoice_amt = ($data['amt'] > $period_3_amt) ? $period_3_amt + $data['amt1'] : $total_amt;
  781. $remain_amt = ($total_amt - $invoice_amt > 0) ? $total_amt - $invoice_amt : 0;
  782. trigger_error('period_3_amt: ' . $period_3_amt . ', amt:'. $data['amt']. ', amt1:'. $data['amt1'] . ', invoice_amt:' .$invoice_amt . ', remain_amt:' . $remain_amt);
  783. */
  784. $data_tx_bill = array(
  785. 'tx_no' => $tx_no, // 訂單序號
  786. 'member_no' => $members_insert_id, // 會員編號
  787. 'station_no' => $station_no, // 場站編號
  788. 'sync_no' => 0, // 預設同步編號
  789. 'lpr' => $data['lpr'], // 車牌號碼
  790. 'member_company_no' => $data['member_company_no'], // 買方統編
  791. 'company_no' => $data['company_no'], // 賣方統編
  792. 'acc_date' => $data['payed_date'], // 入帳日(暫定)
  793. 'invoice_amt' => $invoice_amt, // 本次發票金額
  794. 'remain_amt' => $remain_amt, // 剩餘未開立金額
  795. 'invoice_count' => $invoice_count // 預計發票張數
  796. );
  797. if($invoice_count > 1)
  798. {
  799. $data_tx_bill['invoice_next_date'] = $this->gen_invoice_next_date($data['rent_start_date']); // 預計下一張發票開立日
  800. }
  801. $this->db->insert('member_tx_bill', $data_tx_bill); // t4 新增 member_tx_bill
  802. $tx_bill_no = $this->db->insert_id(); // 帳單序號
  803. $data_tx_bill['tx_bill_no'] = $tx_bill_no;
  804. // [B.建立同步檔]
  805. $sync_seqnos = $this->prepare_sync2hq($action_code, $station_no, 'members', $members_insert_id, $data); // t5 準備同步檔 (members)
  806. $sync_seqnos .= ',' . $this->prepare_sync2hq($action_code, $station_no, 'member_tx', $tx_no, $data_tx); // t6 準備同步檔 (member_tx)
  807. $sync_seqnos .= ',' . $this->prepare_sync2hq($action_code, $station_no, 'member_tx_bill', $tx_bill_no, $data_tx_bill); // t7 準備同步檔 (member_tx_bill)
  808. if($refund_transfer_id > 0)
  809. {
  810. // 更新退租記錄
  811. $data_refund = array('dismiss_state' => MEMBER_REFUND_DISMISS_STATE_TRANSFERRED);
  812. $this->db->update('member_refund', $data_refund, array('station_no' => $station_no, 'member_refund_id' => $refund_transfer_id)); // t8.1 更新 member_refund
  813. $this->gen_member_refund_log($data_refund, $station_no, $refund_transfer_id); // t.log. 建立 member_refund_log
  814. $sync_seqnos .= ',' . $this->prepare_sync2hq('U', $station_no, 'member_refund', $refund_transfer_id, $data_refund); // t8. 準備同步檔 (member_refund)
  815. // 清除 etag 記錄
  816. if ($old_lpr !== $data['lpr'])
  817. {
  818. $this->db->delete('etag_lpr', array('lpr' => $old_lpr));
  819. trigger_error(MEMBER_LOG_TITLE."{$old_lpr} 清除 etag 記錄a");
  820. }
  821. }
  822. // [C.完成]
  823. $this->db->trans_complete();
  824. if ($this->db->trans_status() === FALSE)
  825. {
  826. trigger_error(MEMBER_LOG_TITLE.'..trans_error..last_query:' . $this->db->last_query());
  827. trigger_error(__FUNCTION__ . '..trans_error..data:' . print_r($data, true). ', data_tx:'. print_r($data_tx, true) .'| last_query: ' . $this->db->last_query());
  828. return 'trans_error';
  829. }
  830. // 同步至總管理處
  831. $this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
  832. }
  833. else
  834. {
  835. $altob_admin_submit = $this->input->post('altob_admin_submit', true); // 取得 admin 參數
  836. if($altob_admin_submit == $this->gen_admin_ck($station_no))
  837. {
  838. trigger_error("admin: " + $altob_admin_submit);
  839. //unset($data['contract_no']); // 合約號
  840. //unset($data['park_time']); // 停車時段
  841. unset($data['rent_start_date']);
  842. unset($data['rent_end_date']);
  843. unset($data['start_date']);
  844. unset($data['end_date']);
  845. unset($data['demonth_start_date']);
  846. unset($data['demonth_end_date']);
  847. //unset($data['member_attr']); // 會員身份
  848. unset($data['deposit']);
  849. unset($data['amt_tot']);
  850. unset($data['amt_accrued']);
  851. unset($data['fee_period1']);
  852. unset($data['amt1']);
  853. //unset($data['fee_period']); // 例行繳期
  854. //unset($data['amt']); // 例行租金
  855. trigger_error(MEMBER_LOG_TITLE.'修改 (admin):' . print_r($data, true). ", from: {$old_lpr}");
  856. }
  857. else
  858. {
  859. // 一般情況下, 時段與費率都不能在這個流程修改
  860. //unset($data['contract_no']); // 合約號
  861. unset($data['park_time']);
  862. unset($data['rent_start_date']);
  863. unset($data['rent_end_date']);
  864. unset($data['start_date']);
  865. unset($data['end_date']);
  866. unset($data['demonth_start_date']);
  867. unset($data['demonth_end_date']);
  868. unset($data['member_attr']);
  869. unset($data['deposit']);
  870. unset($data['amt_tot']);
  871. unset($data['amt_accrued']);
  872. unset($data['fee_period1']);
  873. unset($data['amt1']);
  874. unset($data['fee_period']);
  875. unset($data['amt']);
  876. trigger_error(MEMBER_LOG_TITLE.'修改 (normal):' . print_r($data, true). ", from: {$old_lpr}");
  877. }
  878. $action_code = 'U';
  879. // [A.開始]
  880. $this->db->trans_start();
  881. $this->db->update('members', $data, array('station_no' => $station_no, 'member_no' => $check_member_no)); // t1. 更新 members
  882. $this->gen_member_log($data, $station_no, $check_member_no); // t.log. 建立 member_log
  883. // 沒有異動到車牌, 使用update, 否則重建一筆
  884. if ($old_lpr == $data['lpr']) // t2.a 更新 member_car
  885. {
  886. unset($data_car['lpr']);
  887. unset($data_car['lpr_correct']);
  888. $this->db->update('member_car', $data_car, array('station_no' => $station_no, 'member_no' => $check_member_no));
  889. }
  890. else
  891. {
  892. /*
  893. 2017/03/16 更換為統一建立流程
  894. $this->db->delete('member_car', array('station_no' => $station_no, 'member_no' => $check_member_no));
  895. $data_car['member_no'] = $check_member_no;
  896. $this->db->insert('member_car', $data_car);
  897. */
  898. $data_car['member_no'] = $check_member_no;
  899. $this->gen_member_car($data_car);
  900. // 清除 etag 記錄
  901. $this->db->delete('etag_lpr', array('lpr' => $old_lpr));
  902. trigger_error(MEMBER_LOG_TITLE."{$old_lpr} 清除 etag 記錄b");
  903. }
  904. // [B.建立同步檔]
  905. $sync_seqnos = $this->prepare_sync2hq($action_code, $station_no, 'members', $check_member_no, $data); // t3. 準備同步檔 (members)
  906. // [C.完成]
  907. $this->db->trans_complete();
  908. if ($this->db->trans_status() === FALSE)
  909. {
  910. trigger_error(MEMBER_LOG_TITLE.'..trans_error..last_query:' . $this->db->last_query());
  911. trigger_error(__FUNCTION__ . '..trans_error..data:' . print_r($data, true). '| last_query: ' . $this->db->last_query());
  912. return 'trans_error';
  913. }
  914. // 同步至總管理處
  915. $this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
  916. }
  917. return array(
  918. 'station_no' => $station_no,
  919. 'company_no' => $data['company_no'],
  920. 'member_no' => $data['member_no'],
  921. 'start_date' => $start_date,
  922. 'msg' => 'ok',
  923. 'action_code' => $action_code,
  924. 'tx_no' => $tx_no,
  925. 'tx_bill_no' => $tx_bill_no,
  926. 'invoice_amt' => $invoice_amt,
  927. 'remain_amt' => $remain_amt,
  928. 'period_3_amt' => $period_max_amt,
  929. 'amt_discount' => $amt_discount
  930. );
  931. }
  932. // 查詢車牌是否重複 (查詢會員車牌)
  933. public function check_lpr($lpr)
  934. {
  935. $rows = $this->db->select('count(*) as counts')
  936. ->from('members')
  937. ->where(array('lpr' => $lpr))
  938. ->get()
  939. ->row_array();
  940. return $rows['counts'];
  941. }
  942. // 查詢車牌是否重複 (查詢尚未處理退租金額的退租車牌)
  943. public function check_refund_lpr($lpr)
  944. {
  945. $rows = $this->db->select('count(*) as counts')
  946. ->from('member_refund')
  947. ->join('member_log', 'member_refund.member_log_id = member_log.member_log_id', 'left')
  948. ->where(array('member_log.lpr' => $lpr))
  949. ->where_in('member_refund.dismiss_state', array(
  950. MEMBER_REFUND_DISMISS_STATE_NONE, // 0: 無 (尚未處理退租金額, 視為退租中)
  951. MEMBER_REFUND_DISMISS_STATE_KEEP_DEPOSIT // 10: 押金未退 (已處理退租金額, 但押金未退, 視為退租中)
  952. //MEMBER_REFUND_DISMISS_STATE_TRANSFERRED, // 1: 已轉租 (金額已結清, 視為新車牌, 忽略)
  953. //MEMBER_REFUND_DISMISS_STATE_DONE // 100: 已結清 (金額已結清, 視為新車牌, 忽略)
  954. ))
  955. ->get()
  956. ->row_array();
  957. return $rows['counts'];
  958. }
  959. // 查詢車牌是否重複 (查詢尚未處理退租金額的退租會員)
  960. public function check_refund_member_no($member_no)
  961. {
  962. $rows = $this->db->select('count(*) as counts')
  963. ->from('member_refund')
  964. ->join('member_log', 'member_refund.member_log_id = member_log.member_log_id', 'left')
  965. ->where(array('member_log.member_no' => $member_no))
  966. ->where_in('member_refund.dismiss_state', array(
  967. MEMBER_REFUND_DISMISS_STATE_NONE, // 0: 無 (尚未處理退租金額, 視為退租中)
  968. MEMBER_REFUND_DISMISS_STATE_KEEP_DEPOSIT // 10: 押金未退 (已處理退租金額, 但押金未退, 視為退租中)
  969. //MEMBER_REFUND_DISMISS_STATE_TRANSFERRED, // 1: 已轉租 (金額已結清, 視為新車牌, 忽略)
  970. //MEMBER_REFUND_DISMISS_STATE_DONE, // 100: 已結清 (金額已結清, 視為新車牌, 忽略)
  971. ))
  972. ->get()
  973. ->row_array();
  974. return $rows['counts'];
  975. }
  976. // 查詢車牌是否重複 (查詢已進行過退租的會員)
  977. public function check_refund_member_no_exist($member_no)
  978. {
  979. $rows = $this->db->select('count(*) as counts')
  980. ->from('member_refund')
  981. ->join('member_log', 'member_refund.member_log_id = member_log.member_log_id', 'left')
  982. ->where(array('member_log.member_no' => $member_no))
  983. ->get()
  984. ->row_array();
  985. return $rows['counts'];
  986. }
  987. // 取得交易發票
  988. public function get_tx_invoice_no($tx_no)
  989. {
  990. $rows = $this->db->select('invoice_no')
  991. ->from('member_tx')
  992. ->where(array('tx_no' => $tx_no))
  993. ->get()
  994. ->row_array();
  995. return $rows['invoice_no'];
  996. }
  997. // 更新月租發票記錄
  998. function set_tx_invoice_no($parms)
  999. {
  1000. $data = array
  1001. (
  1002. 'member_company_no' => $parms['member_company_no'],
  1003. 'company_no' => $parms['company_no'],
  1004. 'invoice_track' => $parms['invoice_track'],
  1005. 'invoice_no' => $parms['invoice_no'],
  1006. 'invoice_time' => $parms['invoice_time']
  1007. );
  1008. if(array_key_exists('invoice_type', $parms))
  1009. {
  1010. $data['invoice_type'] = $parms['invoice_type']; // 發票種類
  1011. }
  1012. // [A.開始]
  1013. $this->db->trans_start();
  1014. $this->db->update('member_tx_bill', $data, array('station_no' => $parms['station_no'], 'tx_bill_no' => $parms['tx_bill_no'])); // t1. 更新 member_tx_bill
  1015. trigger_error(TX_LOG_TITLE.'更新發票記錄:' . print_r($data, true). ', tx_bill_no: '. $tx_bill_no);
  1016. // [B.建立同步檔]
  1017. $sync_seqnos = $this->prepare_sync2hq('U', $parms['station_no'], 'member_tx_bill', $parms['tx_bill_no'], $data); // t2. 準備同步檔 (member_tx_bill)
  1018. // 判斷是否為補開發票
  1019. $sql = "select member_refund.member_refund_id, member_refund.member_no, member_refund.member_log_id
  1020. from member_tx_bill
  1021. LEFT JOIN member_refund ON ( member_refund.member_no = member_tx_bill.member_no and member_refund.station_no = member_tx_bill.station_no )
  1022. WHERE
  1023. member_tx_bill.station_no = {$parms['station_no']} and
  1024. member_tx_bill.tx_bill_no = {$parms['tx_bill_no']} and
  1025. member_tx_bill.invoice_count = 1 and
  1026. member_tx_bill.remain_amt = 0 and
  1027. member_tx_bill.invoice_state = ".MEMBER_TX_BILL_INVOICE_STATE_MORE
  1028. ;
  1029. $rows = $this->db->query($sql)->result_array();
  1030. //trigger_error('test xxx:'.$sql. ', member_refund_id: ' . $rows[0]['member_refund_id']);
  1031. if(!empty($rows[0]) && array_key_exists('member_refund_id', $rows[0]))
  1032. {
  1033. $data_refund = array('refund_state' => MEMBER_REFUND_STATE_DONE); // 完結
  1034. $this->db->update('member_refund', $data_refund,
  1035. array('station_no' => $parms['station_no'], 'member_refund_id' => $rows[0]['member_refund_id'])); // t3. 更新 member_refund.refund_state
  1036. $this->gen_member_refund_log($data_refund, $parms['station_no'], $rows[0]['member_refund_id']); // t.log. 建立 member_refund_log
  1037. $sync_seqnos .= ',' . $this->prepare_sync2hq('U', $parms['station_no'], 'member_refund', $rows[0]['member_refund_id'], $data_refund); // t4. 準備同步檔 (member_refund)
  1038. }
  1039. // [C.完成]
  1040. $this->db->trans_complete();
  1041. if ($this->db->trans_status() === FALSE)
  1042. {
  1043. trigger_error(TX_LOG_TITLE.'..trans_error..last_query:' . $this->db->last_query());
  1044. trigger_error(__FUNCTION__ . '..trans_error..data:' . print_r($data, true). '| last_query: ' . $this->db->last_query());
  1045. return 'fail'; // 中斷
  1046. }
  1047. // 同步至總管理處
  1048. $this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
  1049. return 'ok';
  1050. }
  1051. // 首期月租付款交易
  1052. public function first_rents_payment($parms)
  1053. {
  1054. $this->try_sync_batch($parms['station_no']); // 同步未同步記錄
  1055. trigger_error(TX_LOG_TITLE.'列印發票:' . print_r($parms, true));
  1056. // 確認交易記錄
  1057. $rows = $this->db->select('count(*) as counts, lpr')
  1058. ->from('member_tx_bill')
  1059. ->where(array(
  1060. 'tx_bill_no' => $parms['tx_bill_no'], 'tx_no' => $parms['tx_no'],
  1061. 'station_no' => $parms['station_no'], 'member_no' => $parms['member_no'],
  1062. 'invoice_amt' => $parms['invoice_amt'], 'invoice_no' => ''
  1063. ))
  1064. ->get()
  1065. ->row_array();
  1066. if(empty($rows) || $rows['counts'] != 1)
  1067. {
  1068. trigger_error(__FUNCTION__ . '..member_tx_bill not found..' . print_r($parms, true) . $this->db->last_query());
  1069. return 'tx_error'; // 中斷
  1070. }
  1071. // 印發票
  1072. if(array_key_exists('invoice_track', $parms) && array_key_exists('invoice_no', $parms))
  1073. {
  1074. $parms['invoice_time'] = $this->now_str; // 目前時間
  1075. }
  1076. else
  1077. {
  1078. $invoice_parms = array(
  1079. 'station_no' => $parms['station_no'],
  1080. 'tx_bill_no' => $parms['tx_bill_no'],
  1081. 'amt' => $parms['invoice_amt'],
  1082. 'member_company_no' => $parms['member_company_no'],
  1083. 'company_no' => $parms['company_no'],
  1084. 'email' => $parms['email'],
  1085. 'mobile' => $parms['mobile'],
  1086. 'lpr' => $rows['lpr']
  1087. );
  1088. $invoice_result = $this->print_invoice($invoice_parms);
  1089. if(!empty($invoice_result) && array_key_exists('einvoice_no', $invoice_result))
  1090. {
  1091. $parms['invoice_track'] = $invoice_result['einvoice_track']; // 發票字軌
  1092. $parms['invoice_no'] = $invoice_result['einvoice_no']; // 發票號碼
  1093. $parms['invoice_time'] = $this->now_str; // 目前時間
  1094. }
  1095. }
  1096. if(empty($parms['invoice_no']) || empty($parms['invoice_track']))
  1097. {
  1098. trigger_error(__FUNCTION__ . '..invoice gg..' . print_r($parms, true));
  1099. return 'invoice_fail'; // 中斷
  1100. }
  1101. // 更新月租發票記錄
  1102. echo $this->set_tx_invoice_no($parms);
  1103. }
  1104. // 新增月租付款交易
  1105. public function rents_payment($parms, $rents_arr)
  1106. {
  1107. $this->try_sync_batch($parms['station_no']); // 同步未同步記錄
  1108. trigger_error(TX_LOG_TITLE.'繳租:' . print_r($parms, true). print_r($rents_arr, true));
  1109. $invoice_count = $this->gen_invoice_count($parms['fee_period']); // 試算發票張數
  1110. // 先不印發票
  1111. $parms['sync_no'] = 0; // 預設同步編號
  1112. $parms['fee_period_last'] = $parms['fee_period']; // 上期繳期
  1113. $parms['start_date'] = date('Y-m-d', strtotime("{$parms['end_date_last']} first day of next month")); // 本期開始日:上期結束日之次月首日
  1114. $parms['acc_date'] = date('Y-m-d'); // 入帳日(暫定)
  1115. $parms['valid_time'] = $this->default_valid_time; // 有效期限
  1116. $parms['invoice_count'] = $invoice_count; // 預計發票張數
  1117. $parms['acc_time'] = $this->now_str; // 入帳時間 2017/02/15 added
  1118. // [A.開始]
  1119. $this->db->trans_start();
  1120. $data_tx = $parms;
  1121. $this->db->insert('member_tx', $data_tx); // t1 新增 member_tx
  1122. $tx_no = $this->db->insert_id(); // 交易序號
  1123. $data_tx['tx_no'] = $tx_no;
  1124. $this->gen_member_tx_log($data_tx); // t.log. 建立 member_tx_log
  1125. // 接續發票開立記錄 (公式: 拆分第一期金額)
  1126. $invoice_amt = $this->gen_invoice_count_amt($parms['amt'], $invoice_count);
  1127. $remain_amt = $parms['amt'] - $invoice_amt;
  1128. trigger_error(__FUNCTION__ . ', amt:'. $parms['amt']. ', invoice_amt:' .$invoice_amt . ', remain_amt:' . $remain_amt);
  1129. /*
  1130. // 接續發票開立記錄 (公式: 最多一季金額) // 2017/01/11 更換
  1131. $period_3_amt = ($rents_arr[3][$parms['member_attr']] > 2000) ? $rents_arr[3][$parms['member_attr']] : 2000; // 至少 $2000
  1132. $invoice_amt = ($parms['amt'] > $period_3_amt) ? $period_3_amt : $parms['amt'];
  1133. $remain_amt = $parms['amt'] - $invoice_amt;
  1134. trigger_error('period_3_amt: ' . $period_3_amt . ', amt:'. $parms['amt']. ', invoice_amt:' .$invoice_amt . ', remain_amt:' . $remain_amt);
  1135. */
  1136. $data_tx_bill = array(
  1137. 'tx_no' => $tx_no, // 交易編號
  1138. 'member_no' => $parms['member_no'], // 會員編號
  1139. 'station_no' => $parms['station_no'], // 場站編號
  1140. 'sync_no' => 0, // 預設同步編號
  1141. 'lpr' => $parms['lpr'], // 車牌號碼
  1142. 'member_company_no' => $parms['member_company_no'], // 買方統編
  1143. 'company_no' => $parms['company_no'], // 賣方統編
  1144. 'acc_date' => $parms['acc_date'], // 入帳日(延用)
  1145. 'invoice_amt' => $invoice_amt, // 本次發票金額
  1146. 'remain_amt' => $remain_amt, // 剩餘未開立金額
  1147. 'invoice_count' => $invoice_count // 預計發票張數
  1148. );
  1149. if($invoice_count > 1)
  1150. {
  1151. $data_tx_bill['invoice_next_date'] = $this->gen_invoice_next_date($parms['start_date']); // 預計下一張發票開立日
  1152. }
  1153. $this->db->insert('member_tx_bill', $data_tx_bill); // t2 新增 member_tx_bill
  1154. $tx_bill_no = $this->db->insert_id(); // 帳單序號
  1155. $data_tx_bill['tx_bill_no'] = $tx_bill_no;
  1156. $data_member = array(
  1157. 'fee_period' => $parms['fee_period'],
  1158. 'payed_date' => $parms['acc_date'], // 付款日
  1159. 'start_date' => "{$parms['start_date_last']} 00:00:00", // 開始日:由上期繼續延續下去
  1160. 'end_date' => "{$parms['end_date']} 23:59:59", // 結束日
  1161. 'valid_time' => $this->default_valid_time // 有效期限 (更新寬限期) // 2017/02/15 updated
  1162. );
  1163. $this->db->update('members', $data_member, array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no'])); // t3. 更新 members
  1164. $this->gen_member_log($data_member, $parms['station_no'], $parms['member_no']); // t.log. 建立 member_log
  1165. $this->db->update('member_car', // t4. 更新 member_car
  1166. array('start_time' => "{$data_member['start_date']} 00:00:00", 'end_time' => "{$data_member['end_date']} 23:59:59"),
  1167. array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no']));
  1168. // [B.準備同步檔]
  1169. $sync_seqnos = $this->prepare_sync2hq('A', $parms['station_no'], 'member_tx', $tx_no, $data_tx); // t5. 準備同步檔 (member_tx)
  1170. $sync_seqnos .= ',' . $this->prepare_sync2hq('A', $parms['station_no'], 'member_tx_bill', $tx_bill_no, $data_tx_bill); // t6. 準備同步檔 (member_tx_bill)
  1171. $sync_seqnos .= ',' . $this->prepare_sync2hq('U', $parms['station_no'], 'members', $parms['member_no'], $data_member); // t7. 準備同步檔 (members)
  1172. // [c.完成]
  1173. $this->db->trans_complete();
  1174. if ($this->db->trans_status() === FALSE)
  1175. {
  1176. trigger_error(__FUNCTION__ . '..trans_error..data:' . print_r($data_tx, true). '| last_query: ' . $this->db->last_query());
  1177. return 'fail'; // 中斷
  1178. }
  1179. // 同步至總管理處
  1180. $this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
  1181. return 'ok';
  1182. }
  1183. // 退租
  1184. public function stop_rents_payment($parms, $rents_arr)
  1185. {
  1186. $this->try_sync_batch($parms['station_no']); // 同步未同步記錄
  1187. trigger_error(MEMBER_LOG_TITLE.'開始退租流程:' . print_r($parms, true). print_r($rents_arr, true));
  1188. // 1. 取得退租資訊
  1189. $result = $this->calculate_stop_rents_amt($parms, $rents_arr);
  1190. // 2. 確認審核狀態
  1191. if(!$result['verify_state'])
  1192. {
  1193. $altob_admin_submit = $this->input->post('altob_admin_submit', true); // 取得 admin 參數
  1194. if($altob_admin_submit == $this->gen_admin_ck($parms['station_no']))
  1195. {
  1196. $parms['tot_amt'] = $result['return_amt'] + $result['return_deposit'];
  1197. trigger_error(ADMIN_LOG_TITLE.'強制退租:' . print_r($parms, true). print_r($rents_arr, true));
  1198. trigger_error("force refund by admin: " + $altob_admin_submit + " | set tot_amt: " + $parms['tot_amt']);
  1199. }
  1200. else
  1201. {
  1202. trigger_error(__FUNCTION__ . '..verify_state_error..' . print_r($parms, true). print_r($result, true));
  1203. return 'verify_state_error'; // 尚未審核完成
  1204. }
  1205. }
  1206. // 3. 確認金額正確性
  1207. $tot_amt = $result['return_amt'] + $result['return_deposit'];
  1208. if($tot_amt != $parms['tot_amt'])
  1209. {
  1210. trigger_error(__FUNCTION__ . '..tot_amt_error..' . print_r($parms, true). print_r($result, true));
  1211. return 'tot_amt_error'; // 金額有誤
  1212. }
  1213. // 4. 確認會員資料
  1214. $data_member = $this->db->select('*')->from('members')
  1215. ->where(array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no']))
  1216. ->get()
  1217. ->row_array();
  1218. if(empty($data_member))
  1219. {
  1220. trigger_error(__FUNCTION__ . '..member_not_found..' . print_r($parms, true));
  1221. return 'member_not_found'; // 中斷
  1222. }
  1223. // 5. 退租
  1224. // TODO: 審核流程?
  1225. $result['return_state'] = ($result['return_state'] == MEMBER_REFUND_STATE_NONE) ? MEMBER_REFUND_STATE_DONE : $result['return_state']; // 自動完成
  1226. // [A.開始]
  1227. $this->db->trans_start();
  1228. /*
  1229. 2017/03/16: 改成不刪除記錄, 但變更時間區間
  1230. $this->db->delete('members', array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no'])); // t1. 刪除 members
  1231. */
  1232. $data_member_end_date = array('end_date' => $parms['stop_date']. ' 23:59:59');
  1233. $this->db->update('members', $data_member_end_date, array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no'])); // t1.a 更新 members
  1234. $data_member['end_date'] = $data_member_end_date['end_date'];
  1235. $member_log_id = $this->gen_member_log($data_member, $parms['station_no'], $parms['member_no']); // t.log. 建立 member_log
  1236. $data_refund = array(
  1237. 'member_no' => $parms['member_no'],
  1238. 'station_no' => $parms['station_no'],
  1239. 'member_log_id' => $member_log_id,
  1240. 'refund_amt' => $result['return_amt'],
  1241. 'refund_deposit' => $result['return_deposit'],
  1242. 'refund_tot_amt' => $tot_amt,
  1243. 'refund_state' => $result['return_state'],
  1244. 'refund_time' => $data_member_end_date['end_date']
  1245. );
  1246. $this->db->insert('member_refund', $data_refund); // t1.b 建立 member_refund
  1247. $refund_id = $this->db->insert_id();
  1248. $data_refund['member_refund_id'] = $refund_id;
  1249. trigger_error(__FUNCTION__ . '..data_refund..' . print_r($data_refund, true));
  1250. $this->gen_member_refund_log($data_refund, $parms['station_no']); // t.log. 建立 member_refund_log
  1251. /*
  1252. 2017/03/16: 改成不刪除記錄, 但變更時間區間
  1253. $this->db->delete('member_car', array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no']));
  1254. */
  1255. $this->db->update('member_car', // t2. 更新 member_car
  1256. array('end_time' => "{$data_refund['refund_time']}"),
  1257. array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no']));
  1258. // [B.建立同步檔]
  1259. /*
  1260. 2017/03/16: 改成不刪除記錄, 但變更時間區間
  1261. $sync_seqnos = $this->prepare_sync2hq('D', $parms['station_no'], 'members', $parms['member_no'], array()); // t3. 準備同步檔 (members)
  1262. */
  1263. $sync_seqnos = $this->prepare_sync2hq('U', $parms['station_no'], 'members', $parms['member_no'], $data_member_end_date); // t3.a 準備同步檔 (members)
  1264. $sync_seqnos .= ',' . $this->prepare_sync2hq('A', $parms['station_no'], 'member_refund', $refund_id, $data_refund); // t3.b 準備同步檔 (member_refund)
  1265. foreach($result['results'] as $key => $val)
  1266. {
  1267. $tx_no = $key;
  1268. $data_tx = array('tx_state' => MEMBER_TX_TX_STATE_STOP); // 已退租
  1269. $this->db->update('member_tx', $data_tx,
  1270. array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no'], 'tx_no' => $tx_no)); // t4. 更新 member_tx.tx_state
  1271. $this->gen_member_tx_log($data_tx, $parms['station_no'], $tx_no); // t.log. 建立 member_tx_log
  1272. // [B.建立同步檔]
  1273. $sync_seqnos .= ',' . $this->prepare_sync2hq('U', $parms['station_no'], 'member_tx', $tx_no, $data_tx); // t5. 準備同步檔 (member_tx)
  1274. }
  1275. foreach($result['results_i'] as $key => $val)
  1276. {
  1277. $tx_bill_no = $key;
  1278. $data_tx_bill = array('invoice_state' => MEMBER_TX_BILL_INVOICE_STATE_ALLOWANCE, 'refund_amt' => $val['refund_amt']); // 待折讓
  1279. $this->db->update('member_tx_bill', $data_tx_bill,
  1280. array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no'], 'tx_bill_no' => $tx_bill_no)); // t6. 更新 member_tx_bill.invoice_state
  1281. // [B.建立同步檔]
  1282. $sync_seqnos .= ',' . $this->prepare_sync2hq('U', $parms['station_no'], 'member_tx_bill', $tx_bill_no, $data_tx_bill); // t7. 準備同步檔 (member_tx_bill)
  1283. }
  1284. if($result['return_state'] == MEMBER_REFUND_STATE_MORE_INVOICE)
  1285. {
  1286. // 補開
  1287. $invoice_tot_amt = -$tot_amt;
  1288. $invoice_count = $this->gen_invoice_count($data_member['fee_period']); // 試算發票張數
  1289. $invoice_amt = $this->gen_invoice_count_amt($invoice_tot_amt, $invoice_count);
  1290. $remain_amt = $invoice_tot_amt - $invoice_amt;
  1291. trigger_error(__FUNCTION__ . ', invoice_tot_amt:'. $invoice_tot_amt. ', invoice_amt:' .$invoice_amt . ', remain_amt:' . $remain_amt);
  1292. $parms['sync_no'] = 0; // 預設同步編號
  1293. $parms['acc_date'] = date('Y-m-d'); // 入帳日(暫定)
  1294. $parms['invoice_count'] = $invoice_count; // 預計發票張數
  1295. $data_tx = array(
  1296. 'member_no' => $parms['member_no'], // 會員編號
  1297. 'station_no' => $parms['station_no'], // 場站編號
  1298. 'sync_no' => 0, // 預設同步編號
  1299. 'lpr' => $data_member['lpr'], // 車牌號碼
  1300. 'end_date' => $data_refund['refund_time'], // 結束日
  1301. 'member_company_no' => $data_member['member_company_no'], // 買方統編
  1302. 'company_no' => $data_member['company_no'], // 賣方統編
  1303. 'acc_date' => $parms['acc_date'], // 入帳日(暫定)
  1304. 'amt' => $invoice_tot_amt, // 本次發票金額
  1305. 'invoice_count' => $invoice_count, // 預計發票張數
  1306. 'tx_state' => MEMBER_TX_TX_STATE_STOP // 已退租
  1307. );
  1308. $this->db->insert('member_tx', $data_tx); // t8. 新增 member_tx
  1309. $tx_no = $this->db->insert_id(); // 訂單序號
  1310. $data_tx['tx_no'] = $tx_no;
  1311. $this->gen_member_tx_log($data_tx); // t.log. 建立 member_tx_log
  1312. $data_tx_bill = array(
  1313. 'tx_no' => $tx_no, // 交易編號
  1314. 'member_no' => $parms['member_no'], // 會員編號
  1315. 'station_no' => $parms['station_no'], // 場站編號
  1316. 'sync_no' => 0, // 預設同步編號
  1317. 'lpr' => $data_member['lpr'], // 車牌號碼
  1318. 'member_company_no' => $data_member['member_company_no'], // 買方統編
  1319. 'company_no' => $data_member['company_no'], // 賣方統編
  1320. 'acc_date' => $parms['acc_date'], // 入帳日(延用)
  1321. 'invoice_amt' => $invoice_amt, // 本次發票金額
  1322. 'remain_amt' => $remain_amt, // 剩餘未開立金額
  1323. 'invoice_count' => $invoice_count, // 預計發票張數
  1324. 'invoice_state' => MEMBER_TX_BILL_INVOICE_STATE_MORE // 待補開
  1325. );
  1326. if($invoice_count > 1)
  1327. {
  1328. $data_tx_bill['invoice_next_date'] = $this->gen_invoice_next_date($parms['acc_date']); // 預計下一張發票開立日
  1329. }
  1330. $this->db->insert('member_tx_bill', $data_tx_bill); // t9. 新增 member_tx_bill
  1331. $tx_bill_no = $this->db->insert_id(); // 帳單序號
  1332. $data_tx_bill['tx_bill_no'] = $tx_bill_no;
  1333. $sync_seqnos .= ',' . $this->prepare_sync2hq('A', $parms['station_no'], 'member_tx', $tx_no, $data_tx); // t10. 準備同步檔 (member_tx)
  1334. $sync_seqnos .= ',' . $this->prepare_sync2hq('A', $parms['station_no'], 'member_tx_bill', $tx_bill_no, $data_tx_bill); // t11. 準備同步檔 (member_tx_bill)
  1335. }
  1336. // [c.完成]
  1337. $this->db->trans_complete();
  1338. if ($this->db->trans_status() === FALSE)
  1339. {
  1340. trigger_error(__FUNCTION__ . '..trans_error..data:' . print_r($parms, true). print_r($result, true). '| last_query: ' . $this->db->last_query());
  1341. return 'fail'; // 中斷
  1342. }
  1343. // 同步至總管理處
  1344. $this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
  1345. return 'ok';
  1346. }
  1347. // 計算退租金額
  1348. public function calculate_stop_rents_amt($parms, $rents_arr)
  1349. {
  1350. $result = array();
  1351. $result['results'] = array(); // 交易
  1352. $result['verify_state'] = true; // 審核
  1353. $result['results_i'] = array(); // 發票
  1354. // 取得所有已開立發票記錄
  1355. $result_tx = array(); // 發票記錄 A (tx_no)
  1356. $result_tx_bill = array(); // 發票記錄 B (tx_bill_no)
  1357. $sql = "select
  1358. member_tx_bill.tx_no, member_tx_bill.tx_bill_no,
  1359. member_tx_bill.invoice_amt, member_tx_bill.invoice_no, member_tx_bill.invoice_track, member_tx_bill.invoice_time
  1360. from member_tx_bill
  1361. left join member_tx on (member_tx.tx_no = member_tx_bill.tx_no and member_tx.station_no = member_tx_bill.station_no)
  1362. where
  1363. member_tx_bill.station_no = {$parms['station_no']} and
  1364. member_tx_bill.member_no = {$parms['member_no']} and
  1365. member_tx_bill.invoice_no != 0 and
  1366. member_tx.tx_state not in (". MEMBER_TX_TX_STATE_CANCEL .", ". MEMBER_TX_TX_STATE_STOP .")
  1367. order by member_tx_bill.invoice_time asc";
  1368. $invoice_results = $this->db->query($sql)->result_array();
  1369. if(!empty($invoice_results))
  1370. {
  1371. foreach($invoice_results as $rows)
  1372. {
  1373. $tx_no = $rows['tx_no'];
  1374. if(!array_key_exists($tx_no, $result_tx))
  1375. {
  1376. $result_tx[$tx_no] = array();
  1377. }
  1378. $result_tx[$tx_no][$rows['tx_bill_no']] = $rows; // 發票記錄 A (tx_no)
  1379. //array_push($result_tx[$tx_no], $rows); // 發票記錄 A (tx_no)
  1380. $result_tx_bill[$rows['tx_bill_no']] = $rows; // 發票記錄 B (tx_bill_no)
  1381. }
  1382. }
  1383. // TEST
  1384. //$result['test_rents_arr'] = json_encode($rents_arr, true);
  1385. //$result['results_A'] = $result_tx;
  1386. //$result['results_B'] = $result_tx_bill;
  1387. // 取得所有交易記錄
  1388. $sql = "select
  1389. tx_no, start_date, end_date, start_date_last, end_date_last,
  1390. member_attr, fee_period, fee_period_last, amt, amt1, amt_last, deposit, amt_tot, verify_state, remarks
  1391. from member_tx
  1392. where
  1393. member_tx.station_no = {$parms['station_no']} and
  1394. member_tx.member_no = {$parms['member_no']} and
  1395. member_tx.tx_state not in (". MEMBER_TX_TX_STATE_CANCEL .", ". MEMBER_TX_TX_STATE_STOP .")
  1396. order by tx_no asc";
  1397. $member_tx_results = $this->db->query($sql)->result_array();
  1398. if(!empty($member_tx_results))
  1399. {
  1400. // A. 取得待退金額與相關依據
  1401. $total_amt = 0;
  1402. $return_amt = 0;
  1403. $return_deposit = 0;
  1404. $last_end_date = $parms['stop_date'];
  1405. $stop_date_value = strtotime($parms['stop_date']);
  1406. $stop_date_time = new DateTime($parms['stop_date']);
  1407. foreach($member_tx_results as $rows)
  1408. {
  1409. $last_end_date = $rows['end_date']; // 暫存最後一筆結束時間
  1410. // 更新審核狀態
  1411. if($rows['verify_state'] != MEMBER_TX_VERIFY_STATE_OK)
  1412. {
  1413. $result['verify_state'] = false; // 任何一筆未審核就 gg
  1414. }
  1415. $start_date = $rows['start_date']; // 本期開始日
  1416. $end_date = $rows['end_date']; // 本期結束日
  1417. $member_attr = $rows['member_attr']; // 本期身份
  1418. $fee_period = $rows['fee_period']; // 本期繳期
  1419. $deposit = $rows['deposit']; // 首期押金
  1420. $amt1 = $rows['amt1']; // 首期租金
  1421. $amt = $rows['amt']; // 本期租金
  1422. $stop_used_days_last = 0; // f.1. 首期已使用天數
  1423. $stop_rents_period_amt_last = $amt1; // f.2. 首期繳期金額
  1424. $stop_rents_used_amt_last = 0; // f.3. 首期已消耗金額
  1425. $stop_rents_period = $fee_period; // a.0. 本期試算繳期
  1426. $stop_used_days = 0; // a.1. 本期已使用天數
  1427. $stop_rents_period_amt = $amt; // a.2. 本期繳期金額
  1428. $stop_rents_used_amt = 0; // a.3. 本期已消耗金額
  1429. // F. 首期金額
  1430. if($amt1 > 0)
  1431. {
  1432. $start_date_last = $rows['start_date_last']; // 上期開始日
  1433. $end_date_last = $rows['end_date_last']; // 上期結束日
  1434. $fee_period_last = $rows['fee_period_last']; // 上期繳期
  1435. $start_date_last_time = new DateTime($start_date_last);
  1436. if($start_date_last_time > $stop_date_time)
  1437. {
  1438. // F.1. 首期金額, 沒用過, 完全退費 (預設值)
  1439. }
  1440. else
  1441. {
  1442. // 首期開始日早於退租日
  1443. $stop_used_days_last = $stop_date_time->diff($start_date_last_time)->format("%a") + 1; // f.1. 首期已使用天數
  1444. $stop_rents_period_amt_last = $amt1; // f.2. 首期繳期金額
  1445. if(strtotime($end_date_last) < $stop_date_value)
  1446. {
  1447. // F.2. 首期金額, 完全用盡
  1448. $stop_rents_used_amt_last = $stop_rents_period_amt_last; // f.3. 首期已消耗金額
  1449. }
  1450. else
  1451. {
  1452. // F.3. 首期金額, 尚未用盡, 臨停金額換算
  1453. $in_time = $start_date_last.' 00:00:00';
  1454. $balance_time = $parms['stop_date']. ' 23:59:59';
  1455. $stop_rents_used_amt_last = $this->get_bill($in_time, $balance_time, $parms['station_no']);
  1456. }
  1457. }
  1458. }
  1459. // A. 本期金額
  1460. if(strtotime($start_date) > $stop_date_value)
  1461. {
  1462. // A.1. 本期金額, 沒用過, 完全退費 (預設值)
  1463. }
  1464. else if(strtotime($end_date) <= $stop_date_value)
  1465. {
  1466. // A.3. 本期金額, 完全用盡
  1467. $stop_used_days = $rents_arr[$stop_rents_period][0]; // a.1. 本期已使用天數
  1468. $stop_rents_period_amt = $amt; // a.2. 本期繳期金額
  1469. $stop_rents_used_amt = $stop_rents_period_amt; // a.3. 本期已消耗金額
  1470. }
  1471. else
  1472. {
  1473. // A.2. 本期金額, 用過一部份
  1474. $start_date_time = new DateTime($start_date);
  1475. $stop_used_days = $stop_date_time->diff($start_date_time)->format("%a") + 1; // a.1. 本期已使用天數
  1476. if($fee_period > 1)
  1477. {
  1478. // A.2.a. 使用上一階繳期
  1479. for(; $fee_period >= 1 ; $fee_period--)
  1480. {
  1481. if(array_key_exists($fee_period, $rents_arr) && $stop_used_days >= $rents_arr[$fee_period][0])
  1482. {
  1483. $stop_rents_period = $fee_period; // a.0. 本期試算繳期
  1484. $stop_rents_period_amt = $rents_arr[$stop_rents_period][$member_attr]; // a.2. 本期繳期金額 (根據上一階繳期)
  1485. $stop_rents_used_amt = round($stop_rents_period_amt * $stop_used_days / $rents_arr[$stop_rents_period][0]); // a.3. 本期已消耗金額 (根據上一階繳期)
  1486. break;
  1487. }
  1488. }
  1489. }
  1490. // A.2.b. 查無適用繳期, 改用臨停金額換算
  1491. if($stop_rents_used_amt == 0)
  1492. {
  1493. $stop_rents_period = 0; // a.0. 本期試算繳期 (臨停)
  1494. $in_time = $start_date.' 00:00:00';
  1495. $balance_time = $parms['stop_date']. ' 23:59:59';
  1496. $stop_rents_period_amt = $this->get_bill($in_time, $balance_time, $parms['station_no']); // a.2. 本期繳期金額 (臨停)
  1497. $stop_rents_used_amt = $stop_rents_period_amt; // a.3. 本期已消耗金額 (臨停)
  1498. }
  1499. }
  1500. $data = $rows;
  1501. $data['stop_rents_tot_amt'] = $amt + $amt1; // y. 交易總金額
  1502. $data['stop_rents_return_amt'] = $amt + $amt1 - $stop_rents_used_amt - $stop_rents_used_amt_last; // z. 可退還金額
  1503. $data['stop_used_days_last'] = $stop_used_days_last; // f.1. 首期已使用天數
  1504. $data['stop_rents_period_amt_last'] = $stop_rents_period_amt_last; // f.2. 首期繳期金額
  1505. $data['stop_rents_used_amt_last'] = $stop_rents_used_amt_last; // f.3. 首期已消耗金額
  1506. $data['stop_rents_period'] = $stop_rents_period; // a.0. 本期試算繳期
  1507. $data['stop_used_days'] = $stop_used_days; // a.1. 本期已使用天數
  1508. $data['stop_rents_period_amt'] = $stop_rents_period_amt; // a.2. 本期繳期金額
  1509. $data['stop_rents_used_amt'] = $stop_rents_used_amt; // a.3. 本期已消耗金額
  1510. // i.1.發票
  1511. $data['stop_rents_invoices'] = array_key_exists($data['tx_no'], $result_tx) ? $result_tx[$data['tx_no']] : array();
  1512. // R.1. 明細
  1513. $result['results'][$data['tx_no']] = $data;
  1514. $total_amt += $data['stop_rents_tot_amt'];
  1515. $return_amt += $data['stop_rents_return_amt'];
  1516. $return_deposit += $data['deposit'];
  1517. }
  1518. // B. 無待退金額, 補繳臨停金額
  1519. if($return_amt == 0)
  1520. {
  1521. $in_time = date('Y-m-d', strtotime("+1 days", strtotime($last_end_date))). ' 00:00:00'; // 最後一天開始算臨停
  1522. $balance_time = $parms['stop_date']. ' 23:59:59';
  1523. $return_amt = - $this->get_bill($in_time, $balance_time, $parms['station_no']);
  1524. }
  1525. $result['total_amt'] = $total_amt; // R.2. 累計交易總金額
  1526. $result['return_amt'] = $return_amt; // R.3. 累計可退還金額
  1527. // 2017/04/06 若無首期押金記錄, 由會員身份查詢押金
  1528. if($return_deposit == 0)
  1529. {
  1530. $member_info = $this->db->select('deposit')
  1531. ->from('members')
  1532. ->where(array('member_no' => $parms['member_no']))
  1533. ->get()
  1534. ->row_array();
  1535. if(!empty($member_info['deposit']))
  1536. {
  1537. trigger_error(__FUNCTION__ . '..get return_deposit 1..' . print_r($parms, true) . ' deposit: ' . $member_info['deposit']);
  1538. $return_deposit = $member_info['deposit'];
  1539. }
  1540. }
  1541. $result['return_deposit'] = $return_deposit; // R.4. 總押金
  1542. // C. 發票, 折讓或補印
  1543. $result['return_state'] = MEMBER_REFUND_STATE_NONE; // 預設 0
  1544. $result['return_tot_amt'] = $return_amt + $return_deposit; // 總金額
  1545. if($result['return_amt'] > 0)
  1546. {
  1547. $tmp_amt = $result['return_amt']; // 僅折讓非押金的部份
  1548. // C.1. 需退還金額 (折讓發票)
  1549. foreach($result_tx_bill as $tx_bill_no => $tx_invoice)
  1550. {
  1551. $refund_amt = 0;
  1552. if($tmp_amt > $tx_invoice['invoice_amt'])
  1553. {
  1554. // 尚有待折讓金額
  1555. $refund_amt = $tx_invoice['invoice_amt'];
  1556. $tmp_amt -= $tx_invoice['invoice_amt'];
  1557. }
  1558. else
  1559. {
  1560. // 已無待折讓金額
  1561. $refund_amt = $tmp_amt;
  1562. $tmp_amt = 0;
  1563. }
  1564. //trigger_error("{$tx_bill_no} : {$tmp_amt}, {$refund_amt}");
  1565. $result['results'][$tx_invoice['tx_no']]['stop_rents_invoices'][$tx_bill_no]['refund_amt'] = $refund_amt;
  1566. // 記錄發票折讓資訊
  1567. $result['results_i'][$tx_bill_no] = $result['results'][$tx_invoice['tx_no']]['stop_rents_invoices'][$tx_bill_no];
  1568. $result['return_state'] = MEMBER_REFUND_STATE_LESS_INVOICE; // 只要有就設為需要折讓
  1569. }
  1570. }
  1571. else if($result['return_tot_amt'] < 0)
  1572. {
  1573. // C.2. 需補繳金額 (補印發票)
  1574. $result['return_state'] = MEMBER_REFUND_STATE_MORE_INVOICE;
  1575. }
  1576. }
  1577. else
  1578. {
  1579. // Z. 異常
  1580. $result['return_state'] = MEMBER_REFUND_STATE_NONE; // 預設 0
  1581. $result['total_amt'] = 0; // R.2. 累計交易總金額
  1582. $result['return_amt'] = 0; // R.3. 累計可退還金額
  1583. //$result['return_deposit'] = 0; // R.4. 總押金
  1584. // 2017/04/06 若無首期押金記錄, 由會員身份查詢押金
  1585. $member_info = $this->db->select('deposit')
  1586. ->from('members')
  1587. ->where(array('member_no' => $parms['member_no']))
  1588. ->get()
  1589. ->row_array();
  1590. if(!empty($member_info['deposit']))
  1591. {
  1592. trigger_error(__FUNCTION__ . '..gen return_deposit 2..' . print_r($parms, true) . ' deposit: ' . $member_info['deposit']);
  1593. $result['return_deposit'] = $member_info['deposit']; // R.4. 總押金
  1594. $result['return_tot_amt'] = $result['return_deposit']; // 總金額
  1595. }
  1596. }
  1597. return $result;
  1598. }
  1599. // 押金保留,結清其它金額 (退租後)
  1600. public function member_refund_keep_deposit($parms)
  1601. {
  1602. trigger_error(TX_LOG_TITLE.'押金保留,結清其它金額:' . print_r($parms, true));
  1603. return $this->do_member_refund_dismiss($parms, MEMBER_REFUND_DISMISS_STATE_KEEP_DEPOSIT);
  1604. }
  1605. // 結清所有金額 (退租後)
  1606. public function member_refund_dismiss_all($parms)
  1607. {
  1608. trigger_error(TX_LOG_TITLE.'結清所有金額:' . print_r($parms, true));
  1609. return $this->do_member_refund_dismiss($parms, MEMBER_REFUND_DISMISS_STATE_DONE);
  1610. }
  1611. // [共用] 退租結清共用操作 (退租後)
  1612. function do_member_refund_dismiss($parms, $dismiss_state)
  1613. {
  1614. $this->try_sync_batch($parms['station_no']); // 同步未同步記錄
  1615. $data = array('dismiss_state' => $dismiss_state);
  1616. // [A.開始]
  1617. $this->db->trans_start();
  1618. $this->db->update('member_refund', $data, array('station_no' => $parms['station_no'], 'member_refund_id' => $parms['member_refund_id'])); // t1. 更新 member_refund
  1619. $this->gen_member_refund_log($data, $parms['station_no'], $parms['member_refund_id']); // t.log. 建立 member_refund_log
  1620. // [B.準備同步檔]
  1621. $sync_seqnos = $this->prepare_sync2hq('U', $parms['station_no'], 'member_refund', $parms['member_refund_id'], $data); // t2. 準備同步檔
  1622. // [C.完成]
  1623. $this->db->trans_complete();
  1624. if ($this->db->trans_status() === FALSE)
  1625. {
  1626. trigger_error(__FUNCTION__ . '..trans_error..data:' . print_r($data, true). '| last_query: ' . $this->db->last_query());
  1627. return 'fail'; // 中斷
  1628. }
  1629. // 同步至總管理處
  1630. $this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
  1631. return 'ok';
  1632. }
  1633. // 發票折讓 (退租後)
  1634. public function refund_invoice_allowance($parms)
  1635. {
  1636. $this->try_sync_batch($parms['station_no']); // 同步未同步記錄
  1637. trigger_error(TX_LOG_TITLE.'發票折讓:' . print_r($parms, true));
  1638. // 確認 member_tx_bill
  1639. $sql = "select
  1640. member_tx_bill.tx_bill_no,
  1641. member_tx_bill.invoice_track,
  1642. member_tx_bill.invoice_no,
  1643. member_tx_bill.lpr,
  1644. member_tx_bill.member_company_no,
  1645. member_tx_bill.company_no,
  1646. member_tx_bill.acc_date,
  1647. member_tx_bill.refund_amt as amt,
  1648. member_tx_bill.invoice_count,
  1649. member_tx_bill.invoice_next_date,
  1650. member_refund.member_refund_id
  1651. from member_tx_bill
  1652. LEFT JOIN member_refund ON ( member_refund.member_no = member_tx_bill.member_no and member_refund.station_no = member_tx_bill.station_no )
  1653. WHERE
  1654. member_tx_bill.station_no = {$parms['station_no']} and
  1655. member_tx_bill.member_no = {$parms['member_no']} and
  1656. member_tx_bill.invoice_state = ".MEMBER_TX_BILL_INVOICE_STATE_ALLOWANCE
  1657. ;
  1658. $results = $this->db->query($sql)->result_array();
  1659. //trigger_error('test: '. $sql);
  1660. $refund_info = array();
  1661. $count = 0;
  1662. foreach($results as $rows)
  1663. {
  1664. if($rows['tx_bill_no'] == $parms['tx_bill_no'])
  1665. {
  1666. $refund_info = $rows;
  1667. }
  1668. $count++;
  1669. }
  1670. if(empty($refund_info))
  1671. {
  1672. trigger_error(__FUNCTION__ . '..member_tx_bill not found..' . print_r($parms, true));
  1673. return 'tx_error_not_found'; // 中斷
  1674. }
  1675. if($refund_info['invoice_no'] <= 0)
  1676. {
  1677. trigger_error(__FUNCTION__ . '..member_tx_bill not ready..' . print_r($parms, true));
  1678. return 'tx_error_not_ready'; // 中斷(本期的還沒開立)
  1679. }
  1680. // 電子發票折讓介接
  1681. $allowance_parms = array(
  1682. 'station_no' => $parms['station_no'],
  1683. 'invoice_no' => $refund_info['invoice_track'].str_pad($refund_info['invoice_no'], 8, '0', STR_PAD_LEFT),
  1684. 'allowance_amt' => $refund_info['amt']
  1685. );
  1686. $allowance_result = $this->allowance_invoice($allowance_parms);
  1687. if($allowance_result['result_code'] == 'OK')
  1688. {
  1689. // [A.開始]
  1690. $this->db->trans_start();
  1691. $data_tx_bill = array('invoice_state' => MEMBER_TX_BILL_INVOICE_STATE_ALLOWANCE_DONE); // 折讓完成
  1692. $this->db->update('member_tx_bill', $data_tx_bill,
  1693. array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no'], 'tx_bill_no' => $parms['tx_bill_no'])); // t1. 更新 member_tx_bill.invoice_state
  1694. // [B.建立同步檔]
  1695. $sync_seqnos = $this->prepare_sync2hq('U', $parms['station_no'], 'member_tx_bill', $parms['tx_bill_no'], $data_tx_bill); // t2. 準備同步檔 (member_tx_bill)
  1696. if($count <= 1)
  1697. {
  1698. $data_refund = array('refund_state' => MEMBER_REFUND_STATE_DONE); // 完結退租
  1699. $this->db->update('member_refund', $data_refund,
  1700. array('station_no' => $parms['station_no'], 'member_refund_id' => $refund_info['member_refund_id'])); // t3. 更新 member_refund.refund_state
  1701. $this->gen_member_refund_log($data_refund, $parms['station_no'], $refund_info['member_refund_id']); // t.log. 建立 member_refund_log
  1702. $sync_seqnos .= ',' . $this->prepare_sync2hq('U', $parms['station_no'], 'member_refund', $refund_info['member_refund_id'], $data_refund); // t4. 準備同步檔 (member_refund)
  1703. }
  1704. // [c.完成]
  1705. $this->db->trans_complete();
  1706. if ($this->db->trans_status() === FALSE)
  1707. {
  1708. trigger_error(__FUNCTION__ . '..trans_error..data:' . print_r($data_tx_bill, true). '| last_query: ' . $this->db->last_query());
  1709. return 'fail'; // 中斷
  1710. }
  1711. // 同步至總管理處
  1712. $this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
  1713. return 'ok';
  1714. }
  1715. else if(!empty($allowance_result['result_msg']))
  1716. {
  1717. return $allowance_result['result_msg']; // 折讓發票失敗
  1718. }
  1719. else
  1720. {
  1721. return '未知的錯誤';
  1722. }
  1723. }
  1724. // 交易取消
  1725. public function member_tx_cancel($parms)
  1726. {
  1727. $this->try_sync_batch($parms['station_no']); // 同步未同步記錄
  1728. trigger_error(TX_LOG_TITLE.'交易取消:' . print_r($parms, true));
  1729. // A. 確認交易記錄
  1730. $sql = "select
  1731. tx_no, start_date, end_date, start_date_last, end_date_last, fee_period, verify_state, deposit
  1732. from member_tx
  1733. where station_no = {$parms['station_no']} and member_no = {$parms['member_no']} and tx_state = ".MEMBER_TX_TX_STATE_NONE."
  1734. order by tx_no DESC limit 2";
  1735. $member_tx_results = $this->db->query($sql)->result_array();
  1736. if(empty($member_tx_results))
  1737. {
  1738. trigger_error(__FUNCTION__ . '..tx_error_not_found..' . print_r($parms, true));
  1739. return 'tx_error_not_found'; // 查無記錄
  1740. }
  1741. $member_last_tx = $member_tx_results[0]; // 最後一筆交易
  1742. $member_restore_tx = $member_tx_results[1]; // 倒數一筆交易
  1743. if($member_last_tx['tx_no'] != $parms['tx_no'])
  1744. {
  1745. trigger_error(__FUNCTION__ . '..tx_error_not_last..' . print_r($parms, true) . print_r($member_last_tx, true));
  1746. return 'tx_error_not_last'; // 拒絕 (只能由最後一筆記錄開始取消)
  1747. }
  1748. $data_member = $this->db->select('*')->from('members')
  1749. ->where(array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no']))
  1750. ->get()
  1751. ->row_array();
  1752. if(empty($data_member))
  1753. {
  1754. trigger_error(__FUNCTION__ . '..member_not_found..' . print_r($parms, true));
  1755. return 'member_not_found'; // 中斷
  1756. }
  1757. // [A.開始]
  1758. $this->db->trans_start();
  1759. $sync_seqnos = "";
  1760. if(!empty($member_restore_tx))
  1761. {
  1762. // A. 一般取消流程
  1763. $data_member = array(
  1764. 'fee_period' => $member_restore_tx['fee_period'],
  1765. 'payed_date' => $member_restore_tx['acc_date'], // 付款日
  1766. 'start_date' => "{$member_restore_tx['start_date_last']} 00:00:00", // 開始日
  1767. 'end_date' => "{$member_restore_tx['end_date']} 23:59:59" // 結束日
  1768. );
  1769. $this->db->update('members', $data_member, array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no'])); // t.1a. 更新 members
  1770. $this->gen_member_log($data_member, $parms['station_no'], $parms['member_no']); // t.log. 建立 member_log
  1771. $this->db->update('member_car', // t.2a. 更新 member_car
  1772. array('start_time' => "{$data_member['start_date']} 00:00:00", 'end_time' => "{$data_member['end_date']} 23:59:59"),
  1773. array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no']));
  1774. // [B.建立同步檔]
  1775. $sync_seqnos = $this->prepare_sync2hq('U', $parms['station_no'], 'members', $parms['member_no'], $data_member); // t.3a. 準備同步檔 (members)
  1776. $data_tx = array('tx_state' => MEMBER_TX_TX_STATE_CANCEL); // 交易取消
  1777. $this->db->update('member_tx', $data_tx,
  1778. array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no'], 'tx_no' => $parms['tx_no'])); // t4. 更新 member_tx.tx_state
  1779. $this->gen_member_tx_log($data_tx, $parms['station_no'], $parms['tx_no']); // t.log. 建立 member_tx_log
  1780. $sync_seqnos .= ',' . $this->prepare_sync2hq('U', $parms['station_no'], 'member_tx', $parms['tx_no'], $data_tx); // t.5. 準備同步檔 (member_tx)
  1781. }
  1782. else
  1783. {
  1784. // 僅有一筆交易,且交易尚未審核
  1785. if($member_last_tx['verify_state'] == MEMBER_TX_VERIFY_STATE_NONE)
  1786. {
  1787. $data_tx = array('tx_state' => MEMBER_TX_TX_STATE_CANCEL); // 交易取消
  1788. $this->db->update('member_tx', $data_tx,
  1789. array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no'], 'tx_no' => $parms['tx_no'])); // t4. 更新 member_tx.tx_state
  1790. $this->gen_member_tx_log($data_tx, $parms['station_no'], $parms['tx_no']); // t.log. 建立 member_tx_log
  1791. $sync_seqnos = $this->prepare_sync2hq('U', $parms['station_no'], 'member_tx', $parms['tx_no'], $data_tx); // t.5. 準備同步檔 (member_tx)
  1792. // 若此交易有壓金,判定為取消新增會員,進入刪除會員流程 2017/04/16 added
  1793. if($member_last_tx['deposit'] > 0)
  1794. {
  1795. trigger_error(TX_LOG_TITLE.' DELETE members, member_car:' . print_r($parms, true));
  1796. // B. 第一筆交易, 金額尚未審核, 直接進行刪除流程
  1797. $this->db->delete('members', array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no'])); // t.1b. 刪除 members
  1798. $this->gen_member_log($data_member, $parms['station_no'], $parms['member_no']); // t.log. 建立 member_log
  1799. $this->db->delete('member_car', array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no'])); // t.2b. 刪除 member_car
  1800. // [B.建立同步檔]
  1801. $sync_seqnos.= ',' .$this->prepare_sync2hq('D', $parms['station_no'], 'members', $parms['member_no'], array()); // t.3b. 準備同步檔 (members)
  1802. }
  1803. // 若此交易為轉租,判定為取消會員轉租,還原原退租記錄 (TODO: 預設都是全額押金轉租,如果有變化就要改成還原上一個狀態)
  1804. if($data_member['refund_transfer_id'] > 0)
  1805. {
  1806. trigger_error(TX_LOG_TITLE.' RESTORE member_refund' . print_r($data_member, true));
  1807. $data_refund = array('dismiss_state' => MEMBER_REFUND_DISMISS_STATE_KEEP_DEPOSIT);
  1808. $station_no = $data_member['station_no'];
  1809. $refund_transfer_id = $data_member['refund_transfer_id'];
  1810. $this->db->update('member_refund', $data_refund, array('station_no' => $station_no, 'member_refund_id' => $refund_transfer_id)); // t8.1 更新 member_refund
  1811. $this->gen_member_refund_log($data_refund, $station_no, $refund_transfer_id); // t.log. 建立 member_refund_log
  1812. $sync_seqnos .= ',' . $this->prepare_sync2hq('U', $station_no, 'member_refund', $refund_transfer_id, $data_refund); // t8. 準備同步檔 (member_refund)
  1813. }
  1814. }
  1815. else
  1816. {
  1817. $this->db->trans_complete();
  1818. trigger_error(__FUNCTION__ . '..tx_error_refuse..' . print_r($parms, true));
  1819. return 'tx_error_refuse'; // 中斷
  1820. }
  1821. }
  1822. // [c.完成]
  1823. $this->db->trans_complete();
  1824. if ($this->db->trans_status() === FALSE)
  1825. {
  1826. trigger_error(__FUNCTION__ . '..trans_error..data:' . print_r($parms, true). '| last_query: ' . $this->db->last_query());
  1827. return 'fail'; // 中斷
  1828. }
  1829. // 同步至總管理處
  1830. $this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
  1831. return 'ok';
  1832. }
  1833. // 接續開立發票
  1834. public function next_tx_bill($parms, $rents_arr)
  1835. {
  1836. $this->try_sync_batch($parms['station_no']); // 同步未同步記錄
  1837. trigger_error(TX_LOG_TITLE.'接續開立發票:' . print_r($parms, true). print_r($rents_arr, true));
  1838. // 確認上一筆 member_tx_bill
  1839. $rows = $this->db->select('
  1840. member_tx_bill.tx_bill_no,
  1841. member_tx_bill.invoice_no,
  1842. member_tx_bill.lpr,
  1843. member_tx_bill.member_company_no,
  1844. member_tx_bill.company_no,
  1845. member_tx_bill.acc_date,
  1846. member_tx_bill.remain_amt as amt,
  1847. COALESCE(members.member_attr, 1) as member_attr,
  1848. member_tx_bill.invoice_count,
  1849. member_tx_bill.invoice_next_date,
  1850. member_tx_bill.invoice_state
  1851. ')
  1852. ->from('member_tx_bill')
  1853. ->join('members', 'members.member_no = member_tx_bill.member_no', 'left')
  1854. ->where(array(
  1855. 'member_tx_bill.tx_bill_no' => $parms['tx_bill_no'], 'member_tx_bill.tx_no' => $parms['tx_no'],
  1856. 'member_tx_bill.station_no' => $parms['station_no'], 'member_tx_bill.member_no' => $parms['member_no'],
  1857. 'member_tx_bill.remain_amt' => $parms['remain_amt']
  1858. ))
  1859. ->get()
  1860. ->row_array();
  1861. if(empty($rows))
  1862. {
  1863. trigger_error(__FUNCTION__ . '..member_tx_bill not found..' . print_r($parms, true));
  1864. return 'tx_error_not_found'; // 中斷
  1865. }
  1866. if($rows['invoice_no'] <= 0)
  1867. {
  1868. trigger_error(__FUNCTION__ . '..member_tx_bill not ready..' . print_r($parms, true));
  1869. return 'tx_error_not_ready'; // 中斷(本期的還沒開立)
  1870. }
  1871. if($rows['invoice_count'] <= 1 || empty($rows['invoice_next_date']))
  1872. {
  1873. trigger_error(__FUNCTION__ . '..member_tx_bill no next..' . print_r($parms, true));
  1874. return 'tx_error_next'; // 中斷(無下一張資訊)
  1875. }
  1876. if(strtotime($rows['invoice_next_date']) > time())
  1877. {
  1878. trigger_error(__FUNCTION__ . '..member_tx_bill not yet..' . "next_date:{$rows['invoice_next_date']}" . print_r($parms, true));
  1879. return $rows['invoice_next_date']; // 中斷(時間還沒到)
  1880. }
  1881. $next_invoice_count = ($rows['invoice_count'] > 1) ? $rows['invoice_count'] - 1 : 1;
  1882. // 接續發票開立記錄 (公式: 拆分第一期金額)
  1883. $invoice_amt = $this->gen_invoice_count_amt($rows['amt'], $next_invoice_count);
  1884. $remain_amt = $rows['amt'] - $invoice_amt;
  1885. trigger_error(__FUNCTION__ . ', amt:'. $rows['amt']. ', invoice_amt:' .$invoice_amt . ', remain_amt:' . $remain_amt);
  1886. /*
  1887. // 接續發票開立記錄 (公式 B: 最多一季金額)
  1888. $period_3_amt = ($rents_arr[3][$rows['member_attr']] > 2000) ? $rents_arr[3][$rows['member_attr']] : 2000; // 至少 $2000
  1889. $invoice_amt = ($rows['amt'] > $period_3_amt) ? $period_3_amt : $rows['amt'];
  1890. $remain_amt = $rows['amt'] - $invoice_amt;
  1891. trigger_error('period_3_amt: ' . $period_3_amt . ', amt:'. $rows['amt']. ', invoice_amt:' .$invoice_amt . ', remain_amt:' . $remain_amt);
  1892. */
  1893. // [A.開始]
  1894. $this->db->trans_start();
  1895. $data_tx_bill = array(
  1896. 'tx_no' => $parms['tx_no'], // 交易編號
  1897. 'member_no' => $parms['member_no'], // 會員編號
  1898. 'station_no' => $parms['station_no'], // 場站編號
  1899. 'sync_no' => 0, // 預設同步編號
  1900. 'lpr' => $rows['lpr'], // 車牌號碼
  1901. 'member_company_no' => $rows['member_company_no'], // 買方統編
  1902. 'company_no' => $rows['company_no'], // 賣方統編
  1903. 'acc_date' => $rows['acc_date'], // 入帳日(延用)
  1904. 'invoice_amt' => $invoice_amt, // 本次發票金額
  1905. 'remain_amt' => $remain_amt, // 剩餘未開立金額
  1906. 'invoice_count' => $next_invoice_count, // 預計發票張數
  1907. 'invoice_state' => $rows['invoice_state'] // 發票狀態
  1908. );
  1909. if($next_invoice_count > 1 && !empty($rows['invoice_next_date']))
  1910. {
  1911. $data_tx_bill['invoice_next_date'] = $this->gen_invoice_next_date($rows['invoice_next_date']); // 預計下一張發票開立日
  1912. }
  1913. $this->db->insert('member_tx_bill', $data_tx_bill); // t1 新增 member_tx_bill
  1914. $tx_bill_no = $this->db->insert_id(); // 帳單序號
  1915. $data_tx_bill['tx_bill_no'] = $tx_bill_no;
  1916. $tx_bill_no_reset = $rows['tx_bill_no'];
  1917. $data_tx_bill_reset = array('remain_amt' => 0, 'invoice_count' => 1);
  1918. $this->db->update('member_tx_bill', $data_tx_bill_reset,
  1919. array('station_no' => $parms['station_no'], 'tx_bill_no' => $tx_bill_no_reset)); // t1.a. 更新 member_tx_bill.remain_amt 為 0
  1920. // [B.準備同步檔]
  1921. $sync_seqnos = $this->prepare_sync2hq('A', $parms['station_no'], 'member_tx_bill', $tx_bill_no, $data_tx_bill); // t2 準備同步檔 (member_tx_bill)
  1922. $sync_seqnos .= ',' . $this->prepare_sync2hq('U', $parms['station_no'], 'member_tx_bill', $tx_bill_no_reset, $data_tx_bill_reset); // t2.a 準備同步檔 (member_tx_bill)
  1923. // [c.完成]
  1924. $this->db->trans_complete();
  1925. if ($this->db->trans_status() === FALSE)
  1926. {
  1927. trigger_error(__FUNCTION__ . '..trans_error..data:' . print_r($data_tx_bill, true). '| last_query: ' . $this->db->last_query());
  1928. return 'fail'; // 中斷
  1929. }
  1930. // 同步至總管理處
  1931. $this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
  1932. return 'ok';
  1933. }
  1934. // 停權或啟動
  1935. public function suspended($parms)
  1936. {
  1937. $this->try_sync_batch($parms['station_no']); // 同步未同步記錄
  1938. trigger_error(ADMIN_LOG_TITLE.'停權或啟動:' . print_r($parms, true));
  1939. $altob_admin_submit = $this->input->post('altob_admin_submit', true); // 取得 admin 參數
  1940. if($altob_admin_submit !== $this->gen_admin_ck($parms['station_no']))
  1941. {
  1942. trigger_error(__FUNCTION__ . '..altob_admin_submit error..' . print_r($parms, true));
  1943. return 'admin_error'; // 中斷
  1944. }
  1945. $data = array('suspended' => $parms['suspended']);
  1946. // [A.開始]
  1947. $this->db->trans_start();
  1948. $this->db->update('members', $data, array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no'])); // t1. 更新 member.suspended
  1949. $this->gen_member_log($data, $parms['station_no'], $parms['member_no']); // t.log. 建立 member_log
  1950. // [B.準備同步檔]
  1951. $sync_seqnos = $this->prepare_sync2hq('U', $parms['station_no'], 'members', $parms['member_no'], $data); // t2. 準備同步檔
  1952. // [C.完成]
  1953. $this->db->trans_complete();
  1954. if ($this->db->trans_status() === FALSE)
  1955. {
  1956. trigger_error(__FUNCTION__ . '..trans_error..data:' . print_r($data, true). '| last_query: ' . $this->db->last_query());
  1957. return 'fail'; // 中斷
  1958. }
  1959. // 同步至總管理處
  1960. $this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
  1961. return 'ok';
  1962. }
  1963. // 批次延時
  1964. public function member_tx_check_list_confirm_batch($parms)
  1965. {
  1966. $this->try_sync_batch($parms['station_no']); // 同步未同步記錄
  1967. trigger_error(ADMIN_LOG_TITLE.'批次延時:' . print_r($parms, true));
  1968. $altob_admin_submit = $this->input->post('altob_admin_submit', true); // 取得 admin 參數
  1969. if($altob_admin_submit !== $this->gen_admin_ck($parms['station_no']))
  1970. {
  1971. trigger_error(__FUNCTION__ . '..altob_admin_submit error..' . print_r($parms, true));
  1972. return 'admin_error'; // 中斷
  1973. }
  1974. // 建立延時資訊
  1975. if($parms['day'] > 0)
  1976. {
  1977. $new_valid_time = date('Y-m-d 23:59:59', strtotime("{$this->now_str} + {$parms['day']} days"));
  1978. }
  1979. else
  1980. {
  1981. $new_valid_time = date('Y-m-d 23:59:59', strtotime("{$this->now_str} + 1 days"));
  1982. }
  1983. trigger_error(__FUNCTION__ . '..start..' . print_r($parms, true) . ', new_valid_time: '. $new_valid_time);
  1984. // [A.開始]
  1985. $this->db->trans_start();
  1986. $sync_seqnos = '';
  1987. // 更新有效期限: 交易記錄
  1988. $tx_no_array = explode(',', $parms['tx_no_str']);
  1989. foreach($tx_no_array as $idx => $tx_no)
  1990. {
  1991. $data_tx = array('valid_time' => $new_valid_time);
  1992. $this->db->update('member_tx', $data_tx, array('station_no' => $parms['station_no'], 'tx_no' => $tx_no)); // t1. 更新 member_tx.valid_time
  1993. $this->gen_member_tx_log($data_tx, $parms['station_no'], $tx_no); // t.log. 建立 member_tx_log
  1994. if($idx > 0)
  1995. {
  1996. $sync_seqnos .= ',';
  1997. }
  1998. $sync_seqnos .= $this->prepare_sync2hq('U', $parms['station_no'], 'member_tx', $tx_no, $data_tx); // t2. 準備同步檔 (member_tx)
  1999. }
  2000. // 更新有效期限: 會員
  2001. $member_no_array = explode(',', $parms['member_no_str']);
  2002. foreach($member_no_array as $idx => $member_no)
  2003. {
  2004. // 取得會員資料
  2005. $member_info = $this->db->select('member_no, valid_time')
  2006. ->from('members')
  2007. ->where(array('station_no' => $parms['station_no'], 'member_no' => $member_no))
  2008. ->get()
  2009. ->row_array();
  2010. if(empty($member_info))
  2011. {
  2012. trigger_error(__FUNCTION__ . '..member not found..' . print_r($parms, true));
  2013. }
  2014. else
  2015. {
  2016. if(strtotime($member_info['valid_time']) >= strtotime($new_valid_time) )
  2017. {
  2018. trigger_error(__FUNCTION__ . '..member already got valid_time..' . print_r($member_info, true));
  2019. }
  2020. else
  2021. {
  2022. $data_member = array('valid_time' => $new_valid_time);
  2023. $this->db->update('members', $data_member, array('station_no' => $parms['station_no'], 'member_no' => $member_no)); // t3. 更新 members.valid_time
  2024. $this->gen_member_log($data_member, $parms['station_no'], $member_no); // t.log. 建立 member_log
  2025. $sync_seqnos .= ',' . $this->prepare_sync2hq('U', $parms['station_no'], 'members', $member_no, $data_member); // t4. 準備同步檔 (members)
  2026. }
  2027. }
  2028. }
  2029. // [C.完成]
  2030. $this->db->trans_complete();
  2031. if ($this->db->trans_status() === FALSE)
  2032. {
  2033. trigger_error(__FUNCTION__ . '..trans_error..data:' . print_r($data, true). '| last_query: ' . $this->db->last_query());
  2034. return 'fail'; // 中斷
  2035. }
  2036. // 同步至總管理處
  2037. $this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
  2038. return 'ok';
  2039. }
  2040. // 設定關帳時間點
  2041. public function set_check_point($parms)
  2042. {
  2043. $this->try_sync_batch($parms['station_no']); // 同步未同步記錄
  2044. trigger_error(TX_LOG_TITLE.'設定關帳時間點:' . print_r($parms, true));
  2045. // 取得上一關帳時間點
  2046. $check_time_last_result = $this->db->select('check_time as check_time_last, check_time_no as check_time_last_no')
  2047. ->from('check_points')
  2048. ->where(array('station_no' => $parms['station_no']))
  2049. ->order_by("check_time", "desc")
  2050. ->get()
  2051. ->row_array();
  2052. $check_time_last = !empty($check_time_last_result['check_time_last']) ? $check_time_last_result['check_time_last'] : '2017-01-01 00:00:00';
  2053. $check_time_last_no = !empty($check_time_last_result['check_time_last_no']) ? $check_time_last_result['check_time_last_no'] : 0;
  2054. // 取得本次關帳時間對應交易編號
  2055. $member_tx_last_result = $this->db->select('tx_no as check_time_no')
  2056. ->from('member_tx')
  2057. ->where(array(
  2058. 'acc_time <= ' => $parms['check_time'],
  2059. 'tx_no > ' => $check_time_last_no,
  2060. 'station_no' => $parms['station_no'],
  2061. 'tx_state' => MEMBER_TX_TX_STATE_NONE
  2062. ))
  2063. ->order_by("tx_no", "desc")
  2064. ->get()
  2065. ->row_array();
  2066. $check_time_no = !empty($member_tx_last_result['check_time_no']) ? $member_tx_last_result['check_time_no'] : 0;
  2067. // 取得上一關帳時間點至本次時間點,金額加總等資訊
  2068. $member_tx_result = $this->db->select('SUM(member_tx.amt) as amt, SUM(member_tx.amt1) as amt1, SUM(member_tx.deposit) as deposit')
  2069. ->from('member_tx')
  2070. ->where(array(
  2071. 'tx_no <= ' => $check_time_no,
  2072. 'tx_no > ' => $check_time_last_no,
  2073. 'station_no' => $parms['station_no'],
  2074. 'tx_state' => MEMBER_TX_TX_STATE_NONE
  2075. ))
  2076. ->get()
  2077. ->row_array();
  2078. $check_amt = $member_tx_result['amt'] + $member_tx_result['amt1'];
  2079. $check_deposit = $member_tx_result['deposit'];
  2080. // 確認金額是否異常
  2081. if(empty($check_amt) && empty($check_deposit))
  2082. {
  2083. trigger_error(__FUNCTION__ . '..error_amt..parms:' . print_r($parms, true). '| last_query: ' . $this->db->last_query());
  2084. return 'error_amt'; // 中斷
  2085. }
  2086. trigger_error(__FUNCTION__ . ', check_amt:'. $check_amt. ', check_deposit:' .$check_deposit .
  2087. ', check_time:' . $parms['check_time'] . ', check_time_last:' . $check_time_last .
  2088. ', check_time_no:' . $check_time_no . ', check_time_last_no:' . $check_time_last_no
  2089. );
  2090. $data_check_point = array(
  2091. 'station_no' => $parms['station_no'],
  2092. 'check_time' => $parms['check_time'],
  2093. 'check_time_no' => $check_time_no,
  2094. 'check_time_last' => $check_time_last,
  2095. 'check_time_last_no' => $check_time_last_no,
  2096. 'check_type' => 1, // 手動關帳
  2097. 'check_amt' => $check_amt, // 總金額
  2098. 'check_deposit' => $check_deposit, // 總押金
  2099. 'remarks' => $parms['remarks']
  2100. );
  2101. // [A.開始]
  2102. $this->db->trans_start();
  2103. $this->db->insert('check_points', $data_check_point); // t1. 新增 check_points
  2104. $check_no = $this->db->insert_id();
  2105. $data_check_point['check_no'] = $check_no;
  2106. // [B.準備同步檔]
  2107. $sync_seqnos = $this->prepare_sync2hq('A', $parms['station_no'], 'check_points', $data_check_point['check_no'], $data_check_point); // t2. 準備同步檔
  2108. // [C.完成]
  2109. $this->db->trans_complete();
  2110. if ($this->db->trans_status() === FALSE)
  2111. {
  2112. trigger_error(__FUNCTION__ . '..trans_error..data_check_point:' . print_r($data_check_point, true). '| last_query: ' . $this->db->last_query());
  2113. return 'fail'; // 中斷
  2114. }
  2115. // 同步至總管理處
  2116. $this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
  2117. return 'ok';
  2118. }
  2119. // 關帳查詢
  2120. public function check_point_query($parms)
  2121. {
  2122. $station_no = $parms['station_no'];
  2123. $check_point_time_from = $parms['check_point_time_from'];
  2124. $check_point_time_to = $parms['check_point_time_to'];
  2125. $sql = "select
  2126. check_no, station_no, check_time, check_time_no, check_time_last, check_time_last_no,
  2127. check_amt, check_deposit, check_type, remarks, create_time
  2128. from check_points
  2129. where
  2130. station_no = {$station_no} and
  2131. check_time >= '{$check_point_time_from}' and
  2132. check_time <= '{$check_point_time_to}'
  2133. order by check_no desc
  2134. ";
  2135. $results = $this->db->query($sql)->result_array();
  2136. return $results;
  2137. }
  2138. // 關帳查詢(明細)
  2139. public function check_point_detail_query($parms)
  2140. {
  2141. $station_no = $parms['station_no'];
  2142. $check_time_no = $parms['check_time_no'];
  2143. $check_time_last_no = $parms['check_time_last_no'];
  2144. $sql = "
  2145. SELECT
  2146. members.lpr as current_lpr,
  2147. member_tx.lpr,
  2148. member_tx.tx_no,
  2149. member_tx.station_no,
  2150. member_tx.member_no,
  2151. member_tx.fee_period,
  2152. member_tx.fee_period_last,
  2153. member_tx.amt1,
  2154. member_tx.amt,
  2155. member_tx.amt_last,
  2156. member_tx.deposit,
  2157. date_format(member_tx.start_date,'%Y-%m-%d') as start_date,
  2158. date_format(member_tx.end_date,'%Y-%m-%d') as end_date,
  2159. date_format(member_tx.start_date_last,'%Y-%m-%d') as start_date_last,
  2160. date_format(member_tx.end_date_last,'%Y-%m-%d') as end_date_last,
  2161. member_tx.member_company_no,
  2162. member_tx.company_no,
  2163. member_tx.acc_date,
  2164. member_tx.invoice_no,
  2165. member_tx.invoice_amt,
  2166. member_tx.invoice_track,
  2167. member_tx.invoice_time,
  2168. member_tx.invoice_type,
  2169. member_tx.verify_state,
  2170. member_tx.valid_time,
  2171. member_tx.remarks,
  2172. member_tx.tx_state
  2173. FROM member_tx
  2174. LEFT JOIN members ON (member_tx.member_no = members.member_no AND members.station_no = member_tx.station_no)
  2175. WHERE
  2176. member_tx.station_no = {$station_no} and
  2177. member_tx.tx_no <= {$check_time_no} and
  2178. member_tx.tx_no > {$check_time_last_no}
  2179. ORDER BY member_tx.valid_time ASC
  2180. ";
  2181. $results = $this->db->query($sql)->result_array();
  2182. return $results;
  2183. }
  2184. // 電子發票查詢
  2185. public function member_invoice_query($parms)
  2186. {
  2187. $station_no = $parms['station_no'];
  2188. $member_invoice_time_from = $parms['member_invoice_time_from'];
  2189. $member_invoice_time_to = $parms['member_invoice_time_to'];
  2190. $sql = "select
  2191. order_no, amt, station_no, tx_time, tx_type, email, mobile, invoice_no, invoice_remark, status, lpr
  2192. from tx_bill_ats
  2193. where
  2194. station_no = {$station_no} and
  2195. tx_time >= '{$member_invoice_time_from}' and
  2196. tx_time <= '{$member_invoice_time_to}' and
  2197. invoice_no is not NULL
  2198. order by tx_time desc
  2199. ";
  2200. $results = $this->db->query($sql)->result_array();
  2201. return $results;
  2202. }
  2203. // 電子發票作廢
  2204. public function member_invoice_void($parms)
  2205. {
  2206. $this->try_sync_batch($parms['station_no']); // 同步未同步記錄
  2207. trigger_error(TX_LOG_TITLE.'電子發票作廢:' . print_r($parms, true));
  2208. $void_result = $this->void_invoice($parms); // 作廢發票
  2209. if($void_result['result_code'] == 'OK')
  2210. {
  2211. $tx_bill_no = $void_result['tx_bill_no'];
  2212. $data = array
  2213. (
  2214. 'member_company_no' => 0,
  2215. 'invoice_track' => '',
  2216. 'invoice_no' => 0,
  2217. 'invoice_time' => NULL,
  2218. 'invoice_type' => 0
  2219. );
  2220. // [A.開始]
  2221. $this->db->trans_start();
  2222. $this->db->update('member_tx_bill', $data, array('station_no' => $parms['station_no'], 'tx_bill_no' => $tx_bill_no)); // t1. 更新 member_tx_bill
  2223. trigger_error(TX_LOG_TITLE.'更新發票記錄:' . print_r($data, true) . ', tx_bill_no: '. $tx_bill_no);
  2224. // [B.建立同步檔]
  2225. $sync_seqnos = $this->prepare_sync2hq('U', $parms['station_no'], 'member_tx_bill', $tx_bill_no, $data); // t2. 準備同步檔 (member_tx_bill)
  2226. // [C.完成]
  2227. $this->db->trans_complete();
  2228. if ($this->db->trans_status() === FALSE)
  2229. {
  2230. trigger_error(TX_LOG_TITLE.'..trans_error..last_query:' . $this->db->last_query());
  2231. trigger_error(__FUNCTION__ . '..trans_error..data:' . print_r($data, true). '| last_query: ' . $this->db->last_query());
  2232. return 'fail'; // 中斷
  2233. }
  2234. // 同步至總管理處
  2235. $this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
  2236. return 'ok';
  2237. }
  2238. else if(!empty($void_result['result_msg']))
  2239. {
  2240. return $void_result['result_msg']; // 作廢發票失敗
  2241. }
  2242. else
  2243. {
  2244. return '未知的錯誤';
  2245. }
  2246. }
  2247. // 取得未同步資料筆數
  2248. public function get_un_synced_count($station_no)
  2249. {
  2250. $sql = "select COUNT(*) as count from syncs where synced = 0 and erred = 0 and station_no = {$station_no}";
  2251. $result = $this->db->query($sql)->result_array();
  2252. if(!empty($result[0]))
  2253. return $result[0];
  2254. else
  2255. return 0;
  2256. }
  2257. // 同步未同步記錄
  2258. public function try_sync_batch($station_no, $limit=5)
  2259. {
  2260. $sql = "select st_sync_no
  2261. from syncs
  2262. where synced = 0 and erred = 0 and station_no = {$station_no}
  2263. order by st_sync_no ASC
  2264. limit {$limit}";
  2265. $results = $this->db->query($sql)->result_array();
  2266. if(empty($results)) return false; // do nothing
  2267. $sync_seqnos = '';
  2268. foreach($results as $rows)
  2269. {
  2270. $sync_seqnos .= ',' . $rows['st_sync_no'];
  2271. }
  2272. $sync_seqnos = ltrim($sync_seqnos, ',');
  2273. trigger_error(__FUNCTION__ . '|' . $sync_seqnos);
  2274. // 同步至總管理處
  2275. $this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
  2276. }
  2277. // 取得 : 預計下一張發票開立日
  2278. function gen_invoice_next_date($this_date)
  2279. {
  2280. return date('Y-m-d', strtotime("+3 months", strtotime($this_date)));
  2281. }
  2282. // 取得 : 發票拆分金額
  2283. function gen_invoice_count_amt($amt, $count)
  2284. {
  2285. return round($amt / $count); // 四捨五入
  2286. }
  2287. // 取得 : 預計發票張數
  2288. function gen_invoice_count($fee_period)
  2289. {
  2290. return ceil($fee_period / 3);
  2291. }
  2292. // 產生會員記錄
  2293. function gen_members($data)
  2294. {
  2295. $this->db->delete('members', array('station_no' => $data['station_no'], 'lpr' => $data['lpr']));
  2296. trigger_error(__FUNCTION__ . ', remove members by lpr: ' . $data['lpr']);
  2297. $this->db->insert('members', $data);
  2298. trigger_error(__FUNCTION__ . ', new members: ' . print_r($data, true));
  2299. return $this->db->insert_id();
  2300. }
  2301. // 產生會員車記錄
  2302. function gen_member_car($data)
  2303. {
  2304. $this->db->delete('member_car', array('station_no' => $data['station_no'], 'lpr' => $data['lpr']));
  2305. trigger_error(__FUNCTION__ . ', remove member_car by lpr: ' . $data['lpr']);
  2306. $this->db->delete('member_car', array('station_no' => $data['station_no'], 'member_no' => $data['member_no']));
  2307. trigger_error(__FUNCTION__ . ', remove member_car by member_no: ' . $data['member_no']);
  2308. $this->db->insert('member_car', $data);
  2309. trigger_error(__FUNCTION__ . ', new member_car: ' . print_r($data, true));
  2310. return $this->db->insert_id();
  2311. }
  2312. // 產生會員檔記錄
  2313. function gen_member_log($data, $station_no=0, $member_no=0)
  2314. {
  2315. $data_log = $data;
  2316. if(!empty($station_no))
  2317. $data_log['station_no'] = $station_no;
  2318. if(!empty($member_no))
  2319. $data_log['member_no'] = $member_no;
  2320. $this->db->insert('member_log', $data_log);
  2321. return $this->db->insert_id();
  2322. }
  2323. // 產生交易檔記錄
  2324. function gen_member_tx_log($data, $station_no=0, $tx_no=0)
  2325. {
  2326. $data_log = $data;
  2327. if(!empty($station_no))
  2328. $data_log['station_no'] = $station_no;
  2329. if(!empty($tx_no))
  2330. $data_log['tx_no'] = $tx_no;
  2331. $this->db->insert('member_tx_log', $data_log);
  2332. return $this->db->insert_id();
  2333. }
  2334. // 產生退租檔記錄
  2335. function gen_member_refund_log($data, $station_no=0, $member_refund_id=0)
  2336. {
  2337. $data_log = $data;
  2338. if(!empty($station_no))
  2339. $data_log['station_no'] = $station_no;
  2340. if(!empty($member_refund_id))
  2341. $data_log['member_refund_id'] = $member_refund_id;
  2342. $this->db->insert('member_refund_log', $data_log);
  2343. return $this->db->insert_id();
  2344. }
  2345. // 同步至總公司
  2346. function prepare_sync2hq($act, $station_no, $st_tname, $st_seqno, $data)
  2347. {
  2348. $data_syncs = array
  2349. (
  2350. 'station_no' => $station_no,
  2351. 'synced' => 0, // 尚未同步
  2352. 'erred' => 0,
  2353. 'act' => $act, // A:新增, U:修改, D:刪除
  2354. 'hq_tname' => 'hq_'.$st_tname,
  2355. 'st_tname' => $st_tname, // 場站資料表
  2356. 'st_seqno' => $st_seqno, // 場站交易序號
  2357. 'sync_data' => json_encode($data, JSON_UNESCAPED_UNICODE)
  2358. );
  2359. $this->db->insert('syncs', $data_syncs);
  2360. return $this->db->insert_id();
  2361. }
  2362. // curl送收資料
  2363. function worker_tx($cmd, $data)
  2364. {
  2365. try
  2366. {
  2367. $ch = curl_init();
  2368. $curl_options = array
  2369. (
  2370. CURLOPT_URL => "http://localhost:60133/?cmd={$cmd}",
  2371. CURLOPT_HEADER => 0,
  2372. CURLOPT_RETURNTRANSFER => 1, // 返回值不顯示, 只做變數用
  2373. CURLOPT_POST => 1,
  2374. CURLOPT_POSTFIELDS => $data
  2375. );
  2376. curl_setopt_array($ch, $curl_options);
  2377. curl_exec($ch);
  2378. curl_close($ch);
  2379. }
  2380. catch (Exception $e)
  2381. {
  2382. trigger_error("{$cmd} error: ".$e->getMessage());
  2383. }
  2384. }
  2385. // 管理員參數
  2386. function gen_admin_ck($station_no)
  2387. {
  2388. return md5(date("m \a\l\t\o\b d").$station_no.date("i \z\z\z H"));
  2389. }
  2390. // 試算臨停費用
  2391. function get_bill($in_time, $balance_time, $station_no)
  2392. {
  2393. require_once(ALTOB_BILL_FILE); // 臨停費率
  2394. $oPayment = new AltobPayment();
  2395. $oPayment->ServiceURL = ALTOB_PAYMENT_TXDATA_URL;
  2396. $bill = $oPayment->getBill($in_time, $balance_time, $station_no);
  2397. $price = $bill[BillResultKey::price];
  2398. trigger_error(__FUNCTION__ . "|{$station_no}|{$in_time}|{$balance_time}|price:{$price}");
  2399. return $price;
  2400. }
  2401. // 印發票
  2402. function print_invoice($parms)
  2403. {
  2404. try{
  2405. $ch = curl_init();
  2406. curl_setopt($ch, CURLOPT_URL, 'http://localhost/allpay_invoice.html/create_member_tx_bill_invoice');
  2407. curl_setopt($ch, CURLOPT_HEADER, FALSE);
  2408. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  2409. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  2410. curl_setopt($ch, CURLOPT_POST, TRUE);
  2411. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,30);
  2412. curl_setopt($ch, CURLOPT_TIMEOUT, 30); //timeout in seconds
  2413. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($parms));
  2414. $data = curl_exec($ch);
  2415. if(curl_errno($ch))
  2416. {
  2417. trigger_error(__FUNCTION__ . ', curl error: '. curl_error($ch));
  2418. }
  2419. curl_close($ch);
  2420. if(!empty($data))
  2421. {
  2422. $data_decode = json_decode($data, true);
  2423. if($data_decode['result_code'] == 'OK')
  2424. {
  2425. $result = array();
  2426. $result['einvoice_track'] = substr($data_decode['invoice_no'], 0, 2); // 發票字軌
  2427. $result['einvoice_no'] = substr($data_decode['invoice_no'], 2, 8); // 發票號碼
  2428. return $result;
  2429. }
  2430. }
  2431. }catch (Exception $e){
  2432. trigger_error(__FUNCTION__ . 'error:'.$e->getMessage());
  2433. }
  2434. $result = array();
  2435. $result['einvoice_track'] = ''; // 發票字軌
  2436. $result['einvoice_no'] = ''; // 發票號碼
  2437. return $result;
  2438. }
  2439. // 作廢發票
  2440. function void_invoice($parms)
  2441. {
  2442. try{
  2443. $ch = curl_init();
  2444. curl_setopt($ch, CURLOPT_URL, 'http://localhost/allpay_invoice.html/void_member_tx_bill_invoice');
  2445. curl_setopt($ch, CURLOPT_HEADER, FALSE);
  2446. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  2447. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  2448. curl_setopt($ch, CURLOPT_POST, TRUE);
  2449. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,30);
  2450. curl_setopt($ch, CURLOPT_TIMEOUT, 30); //timeout in seconds
  2451. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($parms));
  2452. $data = curl_exec($ch);
  2453. if(curl_errno($ch))
  2454. {
  2455. trigger_error(__FUNCTION__ . ', curl error: '. curl_error($ch));
  2456. }
  2457. curl_close($ch);
  2458. if(!empty($data))
  2459. {
  2460. $data_decode = json_decode($data, true);
  2461. return $data_decode;
  2462. }
  2463. }catch (Exception $e){
  2464. trigger_error(__FUNCTION__ . 'error:'.$e->getMessage());
  2465. }
  2466. return 0;
  2467. }
  2468. // 折讓發票
  2469. function allowance_invoice($parms)
  2470. {
  2471. try{
  2472. $ch = curl_init();
  2473. curl_setopt($ch, CURLOPT_URL, 'http://localhost/allpay_invoice.html/allowance_member_tx_bill_invoice');
  2474. curl_setopt($ch, CURLOPT_HEADER, FALSE);
  2475. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  2476. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  2477. curl_setopt($ch, CURLOPT_POST, TRUE);
  2478. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,30);
  2479. curl_setopt($ch, CURLOPT_TIMEOUT, 30); //timeout in seconds
  2480. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($parms));
  2481. $data = curl_exec($ch);
  2482. if(curl_errno($ch))
  2483. {
  2484. trigger_error(__FUNCTION__ . ', curl error: '. curl_error($ch));
  2485. }
  2486. curl_close($ch);
  2487. if(!empty($data))
  2488. {
  2489. $data_decode = json_decode($data, true);
  2490. return $data_decode;
  2491. }
  2492. }catch (Exception $e){
  2493. trigger_error(__FUNCTION__ . 'error:'.$e->getMessage());
  2494. }
  2495. return 0;
  2496. }
  2497. /*
  2498. // 印發票
  2499. public function print_invoice($parms)
  2500. {
  2501. $result = array();
  2502. try
  2503. {
  2504. // 印發票
  2505. $ch = curl_init();
  2506. $curl_options = array
  2507. (
  2508. CURLOPT_URL => "http://localhost:60134/",
  2509. CURLOPT_HEADER => 0,
  2510. CURLOPT_RETURNTRANSFER => 1,
  2511. CURLOPT_CONNECTTIMEOUT => 2,
  2512. CURLOPT_TIMEOUT => 2,
  2513. CURLOPT_POST => 1,
  2514. CURLOPT_POSTFIELDS => array(
  2515. 'cmd' => 'printInvoice',
  2516. 'company_no' => $parms['company_no'],
  2517. 'vCUS_COMP_CODE'=> $parms['member_company_no'],
  2518. 'vAmount' => $parms['invoice_amt'],
  2519. 'vPLU_MEMO' => 'parking:50:3',
  2520. 'vTAIL_MESSAGE' => 'Rental'
  2521. )
  2522. );
  2523. curl_setopt_array($ch, $curl_options);
  2524. $ch_response = curl_exec($ch);
  2525. trigger_error(__FUNCTION__ . '|' . print_r($ch_response, true));
  2526. curl_close($ch);
  2527. $result = json_decode($ch_response, true);
  2528. }
  2529. catch (Exception $e)
  2530. {
  2531. trigger_error(__FUNCTION__ .$e->getMessage());
  2532. }
  2533. //測試用
  2534. //$result['einvoice_track'] = 'AB'; // 發票字軌
  2535. //$result['einvoice_no'] = '12345678'; // 發票號碼
  2536. return $result;
  2537. }
  2538. */
  2539. }