選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 
 

884 行
34 KiB

  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: 501810442
  5. * Date: 2017/8/9
  6. * Time: 13:36
  7. */
  8. namespace backend\modules\api\logic;
  9. use backend\modules\zzcs\models\BaseSupplier;
  10. use backend\modules\api\models\OrderMain;
  11. use backend\modules\zzcs\models\ChannelBalanceHis;
  12. use backend\modules\zzcs\models\OperaBalanceHis;
  13. use backend\modules\zzcs\models\OperaBalanceHisSearch;
  14. use common\models\Msg;
  15. use Yii;
  16. use backend\modules\zzcs\models\TailorCustomerReplyMessage;
  17. use yii\base\Model;
  18. class BaseBalance extends Model
  19. {
  20. // 扣款类型
  21. const STATUS_REDUCE = 1; // 扣款
  22. const STATUS_ADD = 2; // 充值
  23. const BUS_TYPE = 81;
  24. //待扣款
  25. const PAY_STATUS_DKK = 1;
  26. //已扣款
  27. const PAY_STATUS_YKK = 2;
  28. //已取消
  29. const PAY_STATUS_YQX = 3;
  30. private $time;
  31. private $order_id;
  32. public $pay_type;
  33. public $memo;
  34. private $order_model;
  35. //入住口径和离店口径,扣款时间
  36. private $short_time;
  37. public function rules()
  38. {
  39. return [
  40. [['order_id', 'pay_type', 'memo', 'order_model'], 'required'],
  41. [['pay_type'], 'mustInArray'],
  42. ];
  43. }
  44. public function attributeLabels()
  45. {
  46. return [
  47. 'order_id' => '订单ID',
  48. 'pay_type' => '支付类型',
  49. 'memo' => '扣款说明',
  50. 'order_model' => '订单信息',
  51. ];
  52. }
  53. public function load($data, $formName = null)
  54. {
  55. $scope = $formName === null ? $this->formName() : $formName;
  56. if ($scope === '' && !empty($data)) {
  57. $this->setAttributes($data, false);
  58. $this->order_model = OrderMain::findOne(['ORDER_ID' => $this->order_id, 'CANCEL_FLAG' => 0]);
  59. if (!$this->order_model) {
  60. $this->addError('order_model', '找不到对应订单');
  61. }
  62. return true;
  63. } elseif (isset($data[$scope])) {
  64. $this->setAttributes($data[$scope]);
  65. return true;
  66. } else {
  67. return false;
  68. }
  69. }
  70. function __construct($order_id, $pay_type, $memo)
  71. {
  72. $this->time = date('Y-m-d H:i:s');
  73. $this->short_time = ' 18:00:00';
  74. $this->user = 1;
  75. $this->order_id = $order_id;
  76. $this->pay_type = $pay_type;
  77. $this->memo = $memo;
  78. parent::__construct();
  79. }
  80. function __get($name)
  81. {
  82. return $this->$name;
  83. }
  84. function __set($name, $value)
  85. {
  86. $this->$name = $value;
  87. }
  88. /**
  89. * Function Description:预付主流程(供应商)
  90. * Function Name: insertBalanceMain
  91. *
  92. *
  93. * @author LUOCJ
  94. */
  95. public function insertBalanceMain($price = 0)
  96. {
  97. $data = ['code' => '0', 'info' => '插入成功'];
  98. // 读取供应商扣款旧记录
  99. $load_data = array('order_id' => $this->order_id, 'pay_type' => $this->pay_type, 'memo' => $this->memo);
  100. if (!$this->load($load_data, '') || !$this->validate()) {
  101. return array('code' => '-1', 'info' => implode(',', array_column($this->getErrors(), 0)));
  102. }
  103. //创建需要插入和修改的对象
  104. $update_res = self::updateBalanceModel($price);
  105. if (!$update_res) {
  106. $data['code'] = '2';
  107. $data['info'] = '创建或插入失败';
  108. return $data;
  109. }
  110. return $data;
  111. }
  112. /*
  113. * 插入渠道商预付记录
  114. */
  115. public function insertChannelBalanceMain($price = 0, $channel_id = 0)
  116. {
  117. $data = ['code' => '0', 'info' => '插入成功'];
  118. $load_data = array('order_id' => $this->order_id, 'pay_type' => $this->pay_type, 'memo' => $this->memo);
  119. if (!$this->load($load_data, '') || !$this->validate()) {
  120. return array('code' => '-1', 'info' => implode(',', array_column($this->getErrors(), 0)));
  121. }
  122. //创建需要插入和修改的对象, 执行操作
  123. $update_res = self::updateChannelBalanceModel($price, $channel_id);
  124. if (!$update_res) {
  125. $data['code'] = '2';
  126. $data['info'] = '创建或插入失败';
  127. return $data;
  128. }
  129. return $data;
  130. }
  131. /**
  132. * Function Description:获取订单对象
  133. * Function Name: getOrderMainModel
  134. *
  135. * @return static
  136. *
  137. * @author LUOCJ
  138. */
  139. protected function getOrderMainModel()
  140. {
  141. $this->order_model = OrderMain::findOne(['ORDER_ID' => $this->order_id, 'CANCEL_FLAG' => 0]);
  142. if (!$this->order_model) {
  143. return false;
  144. } else {
  145. return true;
  146. }
  147. }
  148. /**
  149. * @Author wanglg
  150. * @Desc 供应商余额变化记录
  151. * @param $price用于订单修改时订单修改变化之前的订单成本金额
  152. * @return bool
  153. */
  154. protected function updateBalanceModel($price)
  155. {
  156. //供应商预付款对象
  157. $balance_his_model = new OperaBalanceHis();
  158. // 查找供应商信息
  159. $base_supplier_model = BaseSupplier::findOne(['ID' => $this->order_model->PROD_TOP_ORG_ID, 'CANCEL_FLAG' => 0, 'SUPPLIER_TYPE' => 187]);
  160. if (!$base_supplier_model) {
  161. return false;
  162. }
  163. // 供应商余额变动及供应商信息变化值
  164. //赋个值渠道商修改变化,余额改变为订单的基础价,即就是采购价,如果是下单调用接口,变动金额为
  165. $balance_his_model->order_id = $this->order_id;
  166. $balance_his_model->create_time = $balance_his_model->update_time = $this->time;
  167. $balance_his_model->supplier_id = $this->order_model->PROD_TOP_ORG_ID;
  168. $balance_his_model->pay_reason = $this->memo;
  169. $balance_his_model->pay_type = $this->pay_type;
  170. if ($this->order_model->BASE_PRICE < 0 || !empty($price))
  171. $balance_his_model->change_value = $price;
  172. else
  173. $balance_his_model->change_value = $this->order_model->BASE_PRICE;
  174. $balance_his_model->create_user_id = $balance_his_model->update_user_id = $this->user;
  175. /**
  176. * 扣款口径 区分预订口径,入住口径,离店口径
  177. * 预订口径直接扣款,巴士直接扣款
  178. */
  179. if ($base_supplier_model->DEDUCT_TYPE == OperaBalanceHisSearch::DEDUCT_TYPE_YD || $this->order_model->ORDER_PROD_TYPE == self::BUS_TYPE) {
  180. $balance_his_model->expect_time = $balance_his_model->pay_time = $this->time;
  181. $balance_his_model->pay_status = self::PAY_STATUS_YKK;
  182. $balance_his_model->balance_before = $base_supplier_model->ACCOUNT_BALANCE;
  183. if ($this->pay_type == self::STATUS_ADD) // 余额变动类型:充值,账户余额+变动金额
  184. $balance_his_model->balance_after = ((float)$balance_his_model->balance_before) + ((float)$balance_his_model->change_value);
  185. else if ($this->pay_type == self::STATUS_REDUCE) // 余额变动类型:扣款,账户余额 - 变动金额
  186. $balance_his_model->balance_after = $balance_his_model->balance_before - (float)$balance_his_model->change_value;
  187. } elseif ($base_supplier_model->DEDUCT_TYPE == OperaBalanceHisSearch::DEDUCT_TYPE_RZ) { // 入住口径执行扣款时间是订单入住时间
  188. $balance_his_model->expect_time = $this->order_model->PROD_START_STATION_DATE . $this->short_time;
  189. $balance_his_model->pay_status = self::PAY_STATUS_DKK;
  190. } elseif ($base_supplier_model->DEDUCT_TYPE == OperaBalanceHisSearch::DEDUCT_TYPE_LD) {// 离店口径执行扣款时间是订单完成时间,即客人离店时间
  191. $balance_his_model->expect_time = $this->order_model->PROD_END_STATION_DATE . $this->short_time;
  192. $balance_his_model->pay_status = self::PAY_STATUS_DKK;
  193. } else {
  194. return false;
  195. }
  196. // 供应商列表余额修改为变动后的金额
  197. $base_supplier_model->ACCOUNT_BALANCE = $balance_his_model->balance_after;
  198. $base_supplier_model->UPDATE_USER_ID = $this->user;
  199. $bt = Yii::$app->db->beginTransaction();
  200. if ($balance_his_model->save()) {
  201. if ($base_supplier_model->DEDUCT_TYPE == OperaBalanceHisSearch::DEDUCT_TYPE_YD || $this->order_model->ORDER_PROD_TYPE == self::BUS_TYPE) {
  202. $base_supplier_model->save(false);
  203. }
  204. $bt->commit();
  205. } else {
  206. $bt->rollBack();
  207. return false;
  208. }
  209. return true;
  210. }
  211. /**
  212. * @Author wanglg
  213. * @Desc 渠道商对应的扣款操作
  214. * @return bool
  215. */
  216. protected function updateChannelBalanceModel($price = 0, $channel_id = 0)
  217. {
  218. //找出渠道对象
  219. $balance_his_model = new ChannelBalanceHis();
  220. $channel_info = empty($channel_id) ? $this->order_model->OUTSIDE_SALE_ORG_ID : $channel_id;
  221. $base_supplier_model = BaseSupplier::findOne(['ID' => $channel_info, 'CANCEL_FLAG' => 0, 'SUPPLIER_TYPE' => 301]);
  222. if (!$base_supplier_model) {
  223. return false;
  224. }
  225. // 变动记录赋值用于保存
  226. $balance_his_model->order_id = $this->order_id;
  227. $balance_his_model->create_time = $balance_his_model->update_time = $this->time;
  228. $balance_his_model->supplier_id = $channel_info;
  229. $balance_his_model->pay_reason = $this->memo;
  230. $balance_his_model->pay_type = $this->pay_type;
  231. if ($this->order_model->ORDER_PRICE < 0 || !empty($price))
  232. $balance_his_model->change_value = $price;
  233. else
  234. $balance_his_model->change_value = $this->order_model->ORDER_PRICE;
  235. $balance_his_model->create_user_id = $balance_his_model->update_user_id = $this->user;
  236. /**
  237. * 扣款口径 区分预订口径,入住口径,离店口径, 根据口径判断扣款时间及支付状态
  238. */
  239. // 预订口径,直接执行扣款操作 巴士订单直接进行扣款操作!
  240. if ($base_supplier_model->DEDUCT_TYPE == OperaBalanceHisSearch::DEDUCT_TYPE_YD || $this->order_model->ORDER_PROD_TYPE == self::BUS_TYPE) {
  241. $balance_his_model->expect_time = $balance_his_model->pay_time = $this->time;
  242. $balance_his_model->pay_status = self::PAY_STATUS_YKK;
  243. $balance_his_model->balance_before = $base_supplier_model->ACCOUNT_BALANCE;
  244. if ($this->pay_type == self::STATUS_ADD) // 充值或金额回退,计算渠道商变动后账户余额
  245. $balance_his_model->balance_after = (float)$balance_his_model->balance_before + (float)$balance_his_model->change_value;
  246. else if ($this->pay_type == self::STATUS_REDUCE)// 下单扣款,计算渠道商变动后账户余额
  247. $balance_his_model->balance_after = $balance_his_model->balance_before - (float)$balance_his_model->change_value;
  248. } elseif ($base_supplier_model->DEDUCT_TYPE == OperaBalanceHisSearch::DEDUCT_TYPE_RZ) { // 入住口径,根据订单入住时间扣款
  249. $balance_his_model->expect_time = $this->order_model->PROD_START_STATION_DATE . $this->short_time;
  250. $balance_his_model->pay_status = self::PAY_STATUS_DKK;
  251. } elseif ($base_supplier_model->DEDUCT_TYPE == OperaBalanceHisSearch::DEDUCT_TYPE_LD) { // 离店口径,根据订单离店时间执行扣款操作
  252. $balance_his_model->expect_time = $this->order_model->PROD_END_STATION_DATE . $this->short_time;
  253. $balance_his_model->pay_status = self::PAY_STATUS_DKK;
  254. } else {
  255. return false;
  256. }
  257. $base_supplier_model->ACCOUNT_BALANCE = $balance_his_model->balance_after;
  258. $base_supplier_model->UPDATE_USER_ID = $this->user;
  259. $bt = Yii::$app->db->beginTransaction();
  260. $result = $balance_his_model->save();
  261. if ($result) {
  262. if ($base_supplier_model->DEDUCT_TYPE == OperaBalanceHisSearch::DEDUCT_TYPE_YD || $this->order_model->ORDER_PROD_TYPE == self::BUS_TYPE) {
  263. $base_supplier_model->save(false);
  264. }
  265. $bt->commit();
  266. } else {
  267. $bt->rollBack();
  268. return false;
  269. }
  270. return true;
  271. }
  272. /**
  273. * Function Description: 取消订单流程
  274. * Function Name: cancelBalanceMain
  275. * @param $price下单
  276. * @return array
  277. *
  278. * @author LUOCJ
  279. *
  280. * 有扣款 -》 插入新纪录,读取最新的订单相关扣款记录
  281. */
  282. public function cancelBalanceMain()
  283. {
  284. $data = ['code' => '0', 'info' => '取消成功'];
  285. $his_model = OperaBalanceHis::find()->where(['order_id' => $this->order_id])->orderBy('create_time desc')->one();
  286. if (!$his_model) {
  287. $data['code'] = '1';
  288. $data['info'] = '无该记录';
  289. return $data;
  290. }
  291. if ($his_model->pay_status == self::PAY_STATUS_DKK) {
  292. $his_model->pay_status = self::PAY_STATUS_YQX;
  293. $his_model->update_user_id = $this->user;
  294. $his_model->update_time = $this->time;
  295. if (!$his_model->save()) {
  296. $data['code'] = '3';
  297. $data['info'] = '修改失败';
  298. return $data;
  299. }
  300. } elseif ($his_model->pay_status == self::PAY_STATUS_YKK) {
  301. $data = $this->insertBalanceMain($his_model->change_value);
  302. } else {
  303. $data['code'] = '2';
  304. $data['info'] = '该记录为已取消,不进行操作';
  305. return $data;
  306. }
  307. return $data;
  308. }
  309. /**
  310. * @Author wanglg
  311. * @Desc 取消操作渠道商记录对应的操作流程
  312. * @return array
  313. */
  314. public function cancelChannelBalanceMain()
  315. {
  316. $data = ['code' => '0', 'info' => '取消成功'];
  317. $his_model = ChannelBalanceHis::find()->where(['order_id' => $this->order_id])->orderBy('create_time desc')->one();
  318. if (!$his_model) {
  319. $data['code'] = '1';
  320. $data['info'] = '无该记录';
  321. return $data;
  322. }
  323. // 扣款状态:待扣款,直接操作该记录,将扣款状态修改为取消;如果是已扣款,则新增一条记录,将扣款金额返还给渠道商;取消状态不做操作
  324. if ($his_model->pay_status == self::PAY_STATUS_DKK) {
  325. $his_model->pay_status = self::PAY_STATUS_YQX;
  326. $his_model->update_user_id = $this->user;
  327. $his_model->update_time = $this->time;
  328. if (!$his_model->save()) {
  329. $data['code'] = '3';
  330. $data['info'] = '修改失败';
  331. return $data;
  332. }
  333. } elseif ($his_model->pay_status == self::PAY_STATUS_YKK) {
  334. $data = $this->insertChannelBalanceMain($his_model->change_value, $his_model->supplier_id);
  335. } else {
  336. $data['code'] = '2';
  337. $data['info'] = '该记录为已取消,不进行操作';
  338. return $data;
  339. }
  340. return $data;
  341. }
  342. /**
  343. * Function Description:定时任务更新his表
  344. * Function Name: timingBalanceMain
  345. *
  346. * @author LUOCJ
  347. */
  348. public static function timingUpdateBalanceMain($user_id)
  349. {
  350. //刷新失败列表
  351. $failures = [];
  352. $data = ['code' => '0', 'info' => '全部更新成功'];
  353. $end_time = date('Y-m-d 18:00:01');
  354. $models = OperaBalanceHis::find()->where(['and', ['<', 'expect_time', $end_time], ['=', 'pay_status', self::PAY_STATUS_DKK]])->all();
  355. foreach ($models as $k => $his_model) {
  356. $order_model = OrderMain::findOne(['order_id' => $his_model->order_id, 'cancel_flag' => 0]);
  357. if (!$order_model) {
  358. $failures = $his_model->order_id;
  359. continue;
  360. }
  361. $supplier_model = BaseSupplier::findOne(['ID' => $order_model->PROD_TOP_ORG_ID]);
  362. if (!$supplier_model)
  363. continue;
  364. $bt = Yii::$app->db->beginTransaction();
  365. //状态置为已扣款
  366. $his_model->pay_status = self::PAY_STATUS_YKK;
  367. //变动之前账户余额
  368. $his_model->balance_before = $supplier_model->ACCOUNT_BALANCE;
  369. //变动之后账户余额
  370. if ($his_model->pay_type == self::STATUS_ADD)
  371. $his_model->balance_after = $his_model->balance_before + (float)$his_model->change_value;
  372. else if ($his_model->pay_type == self::STATUS_REDUCE)
  373. $his_model->balance_after = $his_model->balance_before - (float)$his_model->change_value;
  374. //供应商余额变动
  375. $supplier_model->ACCOUNT_BALANCE = $his_model->balance_after;
  376. //修改时间
  377. $his_model->update_time = $his_model->pay_time = date('Y-m-d H:i:s');
  378. $his_model->update_user_id = $user_id;
  379. if ($his_model->save() && $supplier_model->save()) {
  380. $bt->commit();
  381. } else {
  382. $failures = $his_model->order_id;
  383. $bt->rollBack();
  384. }
  385. }
  386. if (count($failures) == 0) {
  387. return $data;
  388. } else {
  389. $data['code'] = '1';
  390. $data['info'] = '部分订单更新失败';
  391. $data['data'] = $failures;
  392. return $data;
  393. }
  394. }
  395. /**
  396. * @Author wanglg
  397. * @Desc 定时任务更新渠道订单记录表
  398. * @param $user_id
  399. * @return array
  400. */
  401. public static function timingUpdateChannelBalanceMain($user_id)
  402. {
  403. //刷新失败列表
  404. $failures = [];
  405. $data = ['code' => '0', 'info' => '全部更新成功'];
  406. $end_time = date('Y-m-d 18:00:01');
  407. $models = ChannelBalanceHis::find()->where(['and', ['<', 'expect_time', $end_time], ['=', 'pay_status', self::PAY_STATUS_DKK]])->all();
  408. foreach ($models as $k => $his_model) {
  409. $order_model = OrderMain::findOne(['order_id' => $his_model->order_id, 'cancel_flag' => 0]);
  410. if (!$order_model) {
  411. $failures = $his_model->order_id;
  412. continue;
  413. }
  414. $supplier_model = BaseSupplier::findOne(['ID' => $his_model->supplier_id]);
  415. if (!$supplier_model)
  416. continue;
  417. $bt = Yii::$app->db->beginTransaction();
  418. //状态置为已扣款
  419. $his_model->pay_status = self::PAY_STATUS_YKK;
  420. //变动之前账户余额
  421. $his_model->balance_before = $supplier_model->ACCOUNT_BALANCE;
  422. //变动之后账户余额
  423. if ($his_model->pay_type == self::STATUS_ADD)
  424. $his_model->balance_after = $his_model->balance_before + (float)$his_model->change_value;
  425. else if ($his_model->pay_type == self::STATUS_REDUCE)
  426. $his_model->balance_after = $his_model->balance_before - (float)$his_model->change_value;
  427. //供应商余额变动
  428. $supplier_model->ACCOUNT_BALANCE = $his_model->balance_after;
  429. //修改时间
  430. $his_model->update_time = $his_model->pay_time = date('Y-m-d H:i:s');
  431. $his_model->update_user_id = $user_id;
  432. if ($his_model->save() && $supplier_model->save()) {
  433. $bt->commit();
  434. } else {
  435. $failures = $his_model->order_id;
  436. $bt->rollBack();
  437. }
  438. }
  439. if (count($failures) == 0) {
  440. return $data;
  441. } else {
  442. $data['code'] = '1';
  443. $data['info'] = '部分订单更新失败';
  444. $data['data'] = $failures;
  445. return $data;
  446. }
  447. }
  448. /**
  449. * Function Description:检查数据
  450. * Function Name: checkData
  451. *
  452. * @return bool
  453. *
  454. * @author LUOCJ
  455. */
  456. protected function checkData()
  457. {
  458. if ($this->order_id == '' || $this->order_id == 0 || $this->pay_type == '' || $this->memo == '' || !in_array($this->pay_type, [self::STATUS_ADD, self::STATUS_REDUCE])) {
  459. return false;
  460. } else {
  461. return true;
  462. }
  463. }
  464. public function addLog($data, $memo = '')
  465. {
  466. if (!file_exists(__DIR__ . '/../log/balance')) {
  467. mkdir(__DIR__ . '/../log/balance');
  468. }
  469. //获取调用行数;
  470. $debug_model = debug_backtrace();
  471. $debug = $debug_model[0];
  472. $lines = '文件:' . $debug['file'] . '行数' . $debug['line'];
  473. file_put_contents(__DIR__ . '/../log/balance/' . date("Y-m-d") . '.log', date("Y-m-d H:i:s") . '供应商相关信息::' . '调用行数:' . $lines . 'order_id:' . $this->order_id . ' 返回值:' . json_encode($data, JSON_UNESCAPED_UNICODE) . '其他:' . $memo . PHP_EOL, FILE_APPEND);
  474. }
  475. /**
  476. * @Author wanglg
  477. * @Desc 创建渠道商预支付记录日志记录
  478. * @param $data
  479. * @param string $memo
  480. */
  481. public function createChannelLog($data, $memo = '')
  482. {
  483. if (!file_exists(__DIR__ . '/../log/channel')) {
  484. mkdir(__DIR__ . '/../log/channel');
  485. }
  486. //获取调用行数;
  487. $debug_model = debug_backtrace();
  488. $debug = $debug_model[0];
  489. $lines = '文件:' . $debug['file'] . '行数' . $debug['line'];
  490. file_put_contents(__DIR__ . '/../log/channel/' . date("Y-m-d") . '.log', date("Y-m-d H:i:s") . '渠道商相关信息::' . '调用行数:' . $lines . 'order_id:' . $this->order_id . ' 返回值:' . json_encode($data, JSON_UNESCAPED_UNICODE) . '其他:' . $memo . PHP_EOL, FILE_APPEND);
  491. }
  492. /**
  493. * Function Description:余额主流程批量修改
  494. * Function Name: insertBalanceMain
  495. *
  496. *
  497. * @author LUOCJ
  498. */
  499. public function insertBalanceMainBatch()
  500. {
  501. $data = ['code' => '0', 'info' => '插入成功'];
  502. $flag = $this->checkData();
  503. if (!$flag)
  504. return ['code' => '-1', 'info' => '参数不对,请检查'];
  505. //获取订单对象
  506. $order_model = self::getOrderMainModel();
  507. if (!$order_model) {
  508. $data['code'] = '1';
  509. $data['info'] = '找不到对应订单';
  510. return $data;
  511. }
  512. //创建需要插入和修改的对象
  513. $update_res = self::updateBalanceModelBatch();
  514. if (!$update_res) {
  515. $data['code'] = '2';
  516. $data['info'] = '创建或插入失败';
  517. return $data;
  518. }
  519. return $data;
  520. }
  521. /**
  522. * Function Description:批量导入进行修改
  523. * Function Name: updateBalanceModel
  524. *
  525. * @return bool
  526. *
  527. * @author LUOCJ
  528. */
  529. protected function updateBalanceModelBatch()
  530. {
  531. //找个对象
  532. $balance_his_model = new OperaBalanceHis();
  533. $base_supplier_model = BaseSupplier::findOne(['ID' => $this->order_model->PROD_TOP_ORG_ID, 'CANCEL_FLAG' => 0]);
  534. if (!$base_supplier_model) {
  535. return false;
  536. }
  537. //如果重复 即最后创建的记录为扣款则不进行插入
  538. $his_model = OperaBalanceHis::find()->where(['and', ['=', 'order_id', $this->order_id]])->orderBy('create_time desc')->one();
  539. if ($his_model) {
  540. return false;
  541. }
  542. //赋个值
  543. $balance_his_model->order_id = $this->order_id;
  544. //时间修改为订单创建的时间
  545. $balance_his_model->create_time = $this->order_model->CREATE_TIME;
  546. $balance_his_model->update_time = $this->order_model->UPDATE_TIME;
  547. $balance_his_model->supplier_id = $this->order_model->PROD_TOP_ORG_ID;
  548. $balance_his_model->pay_reason = $this->memo;
  549. $balance_his_model->pay_type = $this->pay_type;
  550. if ($this->order_model->BASE_PRICE < 0)
  551. $balance_his_model->change_value = 0;
  552. else
  553. $balance_his_model->change_value = $this->order_model->BASE_PRICE;
  554. $balance_his_model->create_user_id = $balance_his_model->update_user_id = $this->user;
  555. /**
  556. * 扣款口径 区分预订口径,入住口径,离店口径
  557. */
  558. if ($base_supplier_model->DEDUCT_TYPE == OperaBalanceHisSearch::DEDUCT_TYPE_YD) {
  559. $balance_his_model->expect_time = $balance_his_model->pay_time = $this->order_model->UPDATE_TIME;
  560. $balance_his_model->pay_status = 2;
  561. $balance_his_model->balance_before = $base_supplier_model->ACCOUNT_BALANCE;
  562. if ($this->pay_type == self::STATUS_ADD)
  563. $balance_his_model->balance_after = $balance_his_model->balance_before + (float)$this->order_model->BASE_PRICE;
  564. else if ($this->pay_type == self::STATUS_REDUCE)
  565. $balance_his_model->balance_after = $balance_his_model->balance_before - (float)$this->order_model->BASE_PRICE;
  566. } elseif ($base_supplier_model->DEDUCT_TYPE == OperaBalanceHisSearch::DEDUCT_TYPE_RZ) {
  567. $balance_his_model->expect_time = $this->order_model->PROD_START_STATION_DATE . $this->short_time;
  568. $balance_his_model->pay_status = 1;
  569. } elseif ($base_supplier_model->DEDUCT_TYPE == OperaBalanceHisSearch::DEDUCT_TYPE_LD) {
  570. $balance_his_model->expect_time = $this->order_model->PROD_END_STATION_DATE . $this->short_time;
  571. $balance_his_model->pay_status = 1;
  572. } else {
  573. return false;
  574. }
  575. $base_supplier_model->ACCOUNT_BALANCE = $balance_his_model->balance_after;
  576. $base_supplier_model->UPDATE_USER_ID = $this->user;
  577. $bt = Yii::$app->db->beginTransaction();
  578. if ($balance_his_model->save()) {
  579. if ($base_supplier_model->DEDUCT_TYPE == OperaBalanceHisSearch::DEDUCT_TYPE_YD) {
  580. $base_supplier_model->save(false);
  581. }
  582. $bt->commit();
  583. } else {
  584. $bt->rollBack();
  585. return false;
  586. }
  587. return true;
  588. }
  589. /**
  590. * Function Description:获取短信 插入或修改tailormessage表
  591. * Function Name: actionGetMessage
  592. *
  593. * @return array|string
  594. *
  595. * @author LUOCJ
  596. */
  597. static function getMessage()
  598. {
  599. //获取短信
  600. $flag = Msg::getMessage();
  601. $json = ['code' => '0', 'info' => '获取成功', 'data' => $flag, 'order_main_failure' => []];
  602. //$flag = [200,"{\"result\":\"0\",\"desc\":\"\u6210\u529f\",\"delivers\":[{\"phone\":\"15201998183\",\"content\":\"\u54c8\u54c8\u54c8\u54c8\u4e0a\u8f66\u5730\u5740#\u6d4b\u8bd5\u7684\u4e0a\u8f66\u5730\u6ca1\u9519\u554a\u554a\u554a\u725b\u903c\u554a##\u5740#6464376\u5475\u5475\u7edd\u5bf9\u7edd\u5bf9\u7edd\u5bf9\u5bb6\",\"subcode\":\"78301\",\"delivertime\":\"2017-08-23 16:03:36\"}]}"];
  603. if (!$flag) {
  604. $json['code'] = '1';
  605. $json['info'] = '无短信数据';
  606. return $json;
  607. }
  608. // $tp_data = json_decode($flag);
  609. $data = json_decode($flag[1]);
  610. if ($data->result !== "0" || !isset($data->delivers)) {
  611. $json['code'] = '2';
  612. $json['info'] = 'result为0或者无数据';
  613. return $json;
  614. }
  615. //有数据则对数据进行遍历
  616. if (count($data->delivers) > 0) {
  617. foreach ($data->delivers as $k => $v) {
  618. //有则更新,无则新建
  619. $model = TailorCustomerReplyMessage::findOne(['tel' => $v->phone, 'reply_time' => $v->delivertime]);
  620. if (!$model) {
  621. $model = new TailorCustomerReplyMessage();
  622. }
  623. $model->tel = $v->phone;
  624. $model->reply_info = $v->content;
  625. $model->reply_time = $v->delivertime;
  626. $model->sub_code = $v->subcode;
  627. if (!$model->save()) {
  628. $json['code'] = '2';
  629. $json['info'] = $model->tel . ',' . $model->reply_time . ',' . '保存失败';
  630. return $json;
  631. }
  632. //进行订单返写,失败的订单号记入数组写入log
  633. $order_res = self::updateMessageToOrderMain($model);
  634. $json['order_main_failure'] = $order_res;
  635. }
  636. }
  637. return $json;
  638. }
  639. /**
  640. * Function Description:返写入order_main
  641. * Function Name: updateMessageToOrderMain
  642. * @param TailorCustomerReplyMessage $model
  643. *
  644. * @return array
  645. *
  646. * @author LUOCJ
  647. */
  648. static function updateMessageToOrderMain(TailorCustomerReplyMessage $model)
  649. {
  650. $json = ['code' => '0', 'info' => '写入成功', 'data' => []];
  651. $tomorrow = date("Y-m-d", strtotime("+1 day"));
  652. $today = date("Y-m-d");
  653. //邱哥说 9-1 10:48
  654. //比如说 一个人定了10/1 和 11/1的
  655. //今天回复地址,两条都更新
  656. //10/2日回复地址,只更新11/1的那单
  657. $order_main_models = OrderMain::find()
  658. ->joinWith('operaLine')
  659. ->where(
  660. ['and',
  661. ['like', 'order_main.CUSTOMER_MOBILE', $model->tel],
  662. ['=', 'order_main.CANCEL_FLAG', 0],
  663. ['=', 'order_main.ORDER_VALID_STATUS', 1],
  664. ['=', 'order_main.ORDER_PROD_TYPE', 82],
  665. ['>=', 'order_main.RUN_DATE', $today],
  666. ['=', 'opera_line.TAILOR_FLAG', 1],
  667. ])->all();
  668. if (!$order_main_models) {
  669. $json['code'] = '1';
  670. $json['info'] = '找不到对应订单';
  671. return $json;
  672. }
  673. //处理短信数据 获取地址
  674. $address = self::getAddressInMessage($model->reply_info, '#', '#');
  675. foreach ($order_main_models as $k => $order_main_model) {
  676. if ($address === false) {
  677. $order_main_model->CUSTOMER_MEMO = $order_main_model->CUSTOMER_MEMO . '|' . $model->reply_info;
  678. } else {
  679. $order_main_model->CUSTOMER_ADDRESS = $address;
  680. }
  681. if (!$order_main_model->save(false)) {
  682. $json['code'] = '2';
  683. $json['info'] = '保存失败';
  684. $json['data'][] = $order_main_model->order_id;
  685. return $json;
  686. }
  687. }
  688. return $json;
  689. }
  690. /**
  691. * Function Description:获取指定字符间的文字
  692. * Function Name: getAddressInMessage
  693. * @param $message
  694. * @param $start
  695. * @param $end
  696. *
  697. * @return bool|string
  698. *
  699. * @author LUOCJ
  700. */
  701. static function getAddressInMessage($message, $start, $end)
  702. {
  703. $start_pos = mb_stripos($message, $start);
  704. $end_pos = mb_strripos($message, $end);
  705. if ($start_pos == $end_pos) {
  706. return false;
  707. }
  708. $result = mb_substr($message, $start_pos + 1, $end_pos - $start_pos - 1);
  709. return $result;
  710. }
  711. /**
  712. * Function Description:定时任务,每隔一段时间对未回复短信的用户 发送短信提醒
  713. * Function Name: sendNoAddressMessage
  714. *
  715. *
  716. * @author LUOCJ
  717. */
  718. static function sendNoAddressMessage()
  719. {
  720. //■每天晚上19点 针对第二天9点前出发的还未设置地址的上门接订单发送最终提醒短信
  721. //■每天早上10点 针对当天9点后出发的还未设置地址的上门接订单发送最终提醒短信
  722. $time = date('H');
  723. // $time = 10;
  724. $flag_time = '09:00';
  725. if ($time == 19) {
  726. $run_time_arr = [date('Y-m-d', strtotime("+1 day"))];
  727. $flag_compare = '<=';
  728. } elseif ($time == 10) {
  729. $run_time_arr = [date('Y-m-d')];
  730. $flag_compare = '>';
  731. } else {
  732. $json['code'] = '4';
  733. $json['info'] = '时间不对,不发送短信';
  734. return $json;
  735. }
  736. $json = ['code' => '0', 'info' => '发送成功'];
  737. $models = OrderMain::find()
  738. ->joinWith('operaLine')
  739. ->where(
  740. ['and',
  741. ['=', 'order_main.ORDER_VALID_STATUS', 1],
  742. ['=', 'order_main.CANCEL_FLAG', 0],
  743. ['=', 'order_main.ORDER_PROD_TYPE', 82],
  744. ['=', 'order_main.CUSTOMER_ADDRESS', ''],
  745. ['!=', 'order_main.CUSTOMER_MOBILE', ''],
  746. ['in', 'order_main.RUN_DATE', $run_time_arr],
  747. [$flag_compare, 'order_main.RUN_TIME', $flag_time],
  748. ['=', 'opera_line.TAILOR_FLAG', 1],
  749. ]
  750. )
  751. ->groupBy('PARENT_ORDER_ID')
  752. ->all();
  753. if (!$models) {
  754. $json['code'] = '1';
  755. $json['info'] = '找不到需要发送的订单';
  756. return $json;
  757. }
  758. $content = "您购买的旅游产品包含免费上门接至集合点的服务,请您按照\"#上车地址#\"的格式回复短信 ,填写您的上车地址,我们将安排车辆上门接您。如您选择自行前往,也请务必短信回复\"#不需要#\"。20点前如还未收到您的回复,将视为您自动放弃本项服务,感谢您的理解和支持。";
  759. $tels_arr = [];
  760. $msg_web_name = \Yii::$app->params['msg_web_name'];
  761. foreach ($models as $k => $model) {
  762. if (isset($msg_web_name[$model->MAIN_CORP_ID])) {//有设置的用设置的 没有设置的用默认的1
  763. $tels_arr[$model->MAIN_CORP_ID][] = $model->CUSTOMER_MOBILE;
  764. } else {
  765. $tels_arr[1][] = $model->CUSTOMER_MOBILE;
  766. }
  767. }
  768. if (count($tels_arr) <= 0) {
  769. $json['code'] = '2';
  770. $json['info'] = '没有需要发送短信的号码';
  771. return $json;
  772. }
  773. $sendFlag = true;
  774. foreach ($tels_arr as $key => $tels) {
  775. $tels_str = implode(',', $tels);
  776. $res = Msg::sendTelMsg($tels_str, $content, $key);//区分不同的主体发送不通短信
  777. if ($res !== 0) {
  778. if (!file_exists(__DIR__ . '/../log/tailor')) {
  779. mkdir(__DIR__ . '/../log/tailor');
  780. }
  781. file_put_contents(__DIR__ . '/../log/tailor/' . date("Y-m-d") . '.log', date("Y-m-d H:i:s") . '发送用户详细地址短信提醒 短信发送失败 电话号码为' . $tels_str . PHP_EOL, FILE_APPEND);
  782. $sendFlag = false;
  783. }
  784. }
  785. if ($sendFlag == false) {
  786. $json['code'] = '3';
  787. $json['info'] = '短信发送失败';
  788. }
  789. return $json;
  790. }
  791. public function validatePrimary($attribute, $params)
  792. {
  793. if ($this->Spider_room == 0 || $this->RoomID == 0) {
  794. $this->addError($attribute, $params['message']);
  795. }
  796. }
  797. /**
  798. * @Author wanglg
  799. * @Desc验证扣款类型是否正确
  800. */
  801. public function mustInArray($attribute)
  802. {
  803. if (!in_array($this->$attribute, [self::STATUS_ADD, self::STATUS_REDUCE])) {
  804. $this->addError($attribute, '扣款类型不正确');
  805. }
  806. }
  807. }