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

438 lines
18 KiB

  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: luocj
  5. * Date: 2017/6/19
  6. * Time: 9:52
  7. */
  8. namespace backend\modules\api\logic;
  9. use backend\modules\api\models\BaseSupplier;
  10. use backend\modules\api\models\OperaHotelLog;
  11. use backend\modules\api\models\OrderHtStatusLog;
  12. use backend\modules\api\models\OrderMain;
  13. use backend\modules\api\models\RunHotel;
  14. use backend\modules\api\models\RunHotelDistrib;
  15. use Codeception\Module\Memcache;
  16. use common\models\CheckData;
  17. use yii\db\Query;
  18. use backend\modules\zzcs\models\BaseUser;
  19. use backend\modules\zzcs\models\DictType;
  20. use Yii;
  21. use yii\data\ActiveDataProvider;
  22. use yii\db\ActiveRecord;
  23. use backend\modules\api\util\Util;
  24. use common\models\Msg;
  25. use yii\base\Exception;
  26. use yii\db\Expression;
  27. class HotelCancelOrder extends Query
  28. {
  29. public $ctrip_url = "http://cs1.zhizhuchuxing.com/"; //需要向携程对接控制器发送请求的URL
  30. /**
  31. * @inheritdoc
  32. */
  33. public static function tableName()
  34. {
  35. return 'order_main';
  36. }
  37. /*
  38. * User:luocj
  39. *
  40. * 取消酒店订单,获取订单信息
  41. */
  42. public function getOrderInfo($order_id)
  43. {
  44. // select order_id,order_title_id,order_status,order_level,docking_type,
  45. // gathering_status,outside_sale_org_id,prod_id as room_type,parent_prod_id as hotel_id,
  46. //(select parent_room_type from opera_hotel_room where opera_hotel_room.hotel_id = order_main.parent_prod_id and opera_hotel_room.room_type=order_main.prod_id and opera_hotel_room.cancel_flag=0 limit 1) as base_room_type
  47. // from order_main where order_id =1010737 and cancel_flag = 0
  48. $data = OrderMain::find()->select([
  49. 'order_id',
  50. 'order_title_id', //组合订单id
  51. 'order_status', //订单状态
  52. 'order_level', //显示取消单,确认单,修改单
  53. 'docking_type', //直连标识
  54. 'gathering_status', //关帐标识
  55. 'outside_sale_org_id', //渠道订单号
  56. 'prod_id as room_type', //订单子房型,
  57. 'parent_prod_id as hotel_id', //酒店id
  58. 'base_room_type' => new Expression('(select parent_room_type from opera_hotel_room where opera_hotel_room.hotel_id = order_main.parent_prod_id and opera_hotel_room.room_type=order_main.prod_id and opera_hotel_room.cancel_flag=0 limit 1)'),
  59. 'channel_order_status',
  60. ])->where(['and', ['=', 'ORDER_ID', $order_id], ['=', 'CANCEL_FLAG', 0]])->asArray()->one();
  61. //子订单库存
  62. // select run_date,stock_type,count(1) as saled_count from order_main where parent_order_id = 1010737 and cancel_flag=0 group by run_date,stock_type
  63. $son_data = OrderMain::find()->select(['run_date', 'stock_type', 'count(1) as saled_count'])
  64. ->where(['and', ['=', 'parent_order_id', $order_id], ['=', 'cancel_flag', 0]])
  65. ->groupBy('run_date,stock_type')
  66. ->asArray()
  67. ->all();
  68. //渠道超卖数据
  69. // " select * from order_ht_consume_stock where order_id = 1010737 and cancel_flag= 0"
  70. $channel_data = OrderMain::find()->select(['order_id', 'distrib_id', 'run_date', 'consume_stock_count'])
  71. ->from('order_ht_consume_stock')
  72. ->where(['and', ['=', 'order_id', $order_id], ['=', 'cancel_flag', 0]])
  73. ->asArray()
  74. ->all();
  75. //处理数据
  76. foreach ($son_data as $k => $v) {
  77. $data['run_date'][$v['run_date'] . '|' . $v['stock_type']]['run_date'] = $v['run_date'];
  78. $data['run_date'][$v['run_date'] . '|' . $v['stock_type']]['stock_type'] = $v['stock_type'];
  79. $data['run_date'][$v['run_date'] . '|' . $v['stock_type']]['saled_count'] = $v['saled_count'];
  80. $data['run_date'][$v['run_date'] . '|' . $v['stock_type']]['distrib_id'] = 0;
  81. $data['run_date'][$v['run_date'] . '|' . $v['stock_type']]['consume_stock_count'] = 0;
  82. }
  83. if (count($channel_data) > 0) {
  84. foreach ($channel_data as $k => $v) {
  85. $tp = isset($data['run_date'][$v['run_date'] . '|' . 228]) ? $v['run_date'] . '|' . 228 :
  86. (isset($data['run_date'][$v['run_date'] . '|' . 229]) ? $v['run_date'] . '|' . 229 :
  87. (isset($data['run_date'][$v['run_date'] . '|' . 230]) ? $v['run_date'] . '|' . 230 : ''));
  88. $data['run_date'][$tp]['distrib_id'] = $v['distrib_id'];
  89. $data['run_date'][$tp]['consume_stock_count'] = $v['consume_stock_count'];
  90. }
  91. }
  92. return $data;
  93. }
  94. /*
  95. * User:luocj
  96. *
  97. * 可取消检查
  98. */
  99. public function checkIfCancel($data)
  100. {
  101. //订单需在 198待确认,313待发单,564带退单确认 情况下可以取消 且未关账可以取消
  102. if (!in_array($data['order_status'], [198, 313, 564]) || !in_array($data['gathering_status'], [0, 1])) {
  103. return false;
  104. } else {
  105. return true;
  106. }
  107. }
  108. /**
  109. * @param $data
  110. *
  111. * @return mixed
  112. * @throws Exception
  113. */
  114. public function cancelOrder($data,$user_id)
  115. {
  116. $transaction = Yii::$app->db->beginTransaction();
  117. try {
  118. foreach ($data['run_date'] as $k => $v) {
  119. #region 1.更新run_hotel 库存
  120. //订单状态为 564 &库存为230 则 不返还库存 其余则返回库存
  121. if ($data['order_status'] == 564 && $v['stock_type'] == 230) {
  122. $update_info =
  123. [
  124. 'saled_count' => new Expression("saled_count-{$v['saled_count']}"),
  125. 'update_user_id' => $user_id,
  126. ];
  127. $update_where =
  128. [
  129. 'hotel_id' => $data['hotel_id'],
  130. 'base_room_type' => $data['base_room_type'],
  131. 'run_date' => $v['run_date'],
  132. 'stock_type' => $v['stock_type'],
  133. ];
  134. RunHotel::updateAll($update_info, $update_where);
  135. } else {
  136. $update_info = [
  137. 'saled_count' => new Expression("saled_count-{$v['saled_count']}"),
  138. 'update_user_id' => $user_id,
  139. 'remaining_count' => new Expression("remaining_count + {$v['saled_count']}"),
  140. ];
  141. RunHotel::updateAll($update_info,
  142. [
  143. 'hotel_id' => $data['hotel_id'],
  144. 'base_room_type' => $data['base_room_type'],
  145. 'run_date' => $v['run_date'],
  146. 'stock_type' => $v['stock_type'],
  147. ]
  148. );
  149. }
  150. #endregion
  151. #region 2.更新run_hotel_distrib 库存
  152. //正常取消 状态为198和313 还渠道库存,还已售 异常取消 只还已售
  153. if (in_array($data['order_status'], [198, 313])) {
  154. //归还本渠道库存 和已售
  155. $update_info = [
  156. 'remaining_count' => new Expression("remaining_count + {$v['saled_count']}-{$v['consume_stock_count']}"),
  157. 'saled_count' => new Expression("saled_count - {$v['saled_count']}"),
  158. 'update_user_id' => $user_id,
  159. ];
  160. $update_where = [
  161. 'hotel_id' => $data['hotel_id'],
  162. 'distrib_id' => $data['outside_sale_org_id'],
  163. 'base_room_type' => $data['base_room_type'],
  164. 'room_type' => $data['room_type'],
  165. 'run_date' => $v['run_date']
  166. ];
  167. //归还借用渠道的库存
  168. $update_other_info = [
  169. 'remaining_count' => new Expression("remaining_count + {$v['consume_stock_count']}"),
  170. 'update_user_id' => $user_id,
  171. ];
  172. $update_other_where = [
  173. 'hotel_id' => $data['hotel_id'],
  174. 'distrib_id' => $v['distrib_id'],
  175. 'base_room_type' => $data['base_room_type'],
  176. 'room_type' => $data['room_type'],
  177. 'run_date' => $v['run_date']
  178. ];
  179. RunHotelDistrib::updateAll($update_info, $update_where);
  180. RunHotelDistrib::updateAll($update_other_info, $update_other_where);
  181. //借条 cancel_flag 置1
  182. Yii::$app->db
  183. ->createCommand("update order_ht_consume_stock set cancel_flag=1 where order_id = :order_id")
  184. ->bindValues(array(':order_id' => $data['order_id']))
  185. ->execute();
  186. } else {
  187. //异常取消 只还已售
  188. $update_info = [
  189. 'saled_count' => new Expression("saled_count - {$v['saled_count']}"),
  190. 'update_user_id' => $user_id,
  191. ];
  192. $update_where = [
  193. 'hotel_id' => $data['hotel_id'],
  194. 'distrib_id' => $data['outside_sale_org_id'],
  195. 'base_room_type' => $data['base_room_type'],
  196. 'room_type' => $data['room_type'],
  197. 'run_date' => $v['run_date']
  198. ];
  199. RunHotelDistrib::updateAll($update_info, $update_where);
  200. }
  201. #endregion
  202. }
  203. #region 更新order_main 状态
  204. #更新父订单 1:正常取消 2:正常修改 3:异常修改 4:异常取消
  205. $update_info = [
  206. 'order_status' => 148,
  207. 'order_valid_status' => 0,
  208. 'order_disable_user_id' => $user_id,
  209. 'update_user_id' => $user_id,
  210. 'order_disable_time' => date('Y-m-d H:i:s'),
  211. 'update_time' => date('Y-m-d H:i:s'),
  212. 'order_level' => 2
  213. ];
  214. //如果为直连订单需要修改 channel_order_status =563
  215. if ($data['docking_type'] == 556 && (($data['channel_order_status']==553 && $data['order_status'] == 198) || ($data['channel_order_status']==553 && $data['order_status'] == 198)) ) {
  216. $update_info = array_merge($update_info, ['channel_order_status' => 563]);
  217. }
  218. $update_where = [
  219. 'and', ['or', ['=', 'order_id', $data['order_id']], ['=', 'parent_order_id', $data['order_id']]], ['=', 'cancel_flag', 0]
  220. ];
  221. OrderMain::updateAll($update_info, $update_where);
  222. #endregion
  223. #region 推送携程
  224. // if (!empty($data)) {
  225. // $this->pushRoomInfo($data['hotel_id'], $data['base_room_type'], $data['room_type'], $data['run_date']);
  226. // }
  227. #endregion
  228. #region 更新LOG
  229. if ($this->hotelLog($data['order_id'], 3, '取消订单', $user_id) == false || $this->hotelStatusLog($data['order_id'], 148, $data['order_status'], $user_id) == false)
  230. throw new Exception('备注LOG数据错误');
  231. #endregion
  232. $transaction->commit();
  233. $json['code'] = '0';
  234. $json['info'] = '取消成功';
  235. $json['order_id'] = $data['order_id'];
  236. //TODO:: 非异常取消直接去掉该order_id memcache 异常则修改memcache订单的状态
  237. //memcache 去掉该取消订单memcache
  238. self::resetMemcache($data['order_id']);
  239. //供应商余额
  240. $model = new BaseBalance($data['order_id'], 2, '组合订单部分:取消还款');
  241. $sup_data = $model->cancelBalanceMain();
  242. $model->addLog($sup_data);
  243. return $json;
  244. } catch (\yii\db\Exception $exception) {
  245. $transaction->rollBack();
  246. $json['code'] = '1';
  247. $json['info'] = '取消失败';
  248. return $json;
  249. }
  250. }
  251. /**
  252. * User: wangxj
  253. *
  254. * 清除memcache
  255. *
  256. * @order_id integer 订单号
  257. *
  258. */
  259. function resetMemcache($order_id)
  260. {
  261. $newOrder = Yii::$app->cacheCS->get('hotel_newOrder');
  262. if ($newOrder && $this->count($newOrder) > 0) {
  263. foreach ($newOrder as &$vs) {
  264. if (count($vs) > 0) {
  265. foreach ($vs as $k => &$v) {
  266. if ($v['order_id'] == $order_id) {
  267. unset($vs[$k]);
  268. Yii::$app->cacheCS->set('hotel_newOrder', $newOrder);
  269. }
  270. }
  271. }
  272. }
  273. }
  274. }
  275. /**
  276. * User: wangxj
  277. *
  278. * 添加订单到memcache
  279. *
  280. * @supplier_id string 供应商ID
  281. * @order_id string 订单号
  282. * @status integer 订单状态, 313待发单、382异常处理待发单,383异常处理已取消,148正常已取消,147已完成,198待确认,314已安排。
  283. * @room_name string 房型
  284. * @expire string 默认为0,memcache时效
  285. *
  286. */
  287. function setMemcache($order_id, $type, $prod_top_org_id, $prod_name, $expire = 0)
  288. {
  289. $this->resetMemcache($order_id);
  290. $newOrder = Yii::$app->cacheCS->get('hotel_newOrder');
  291. $tmp = array();
  292. if ($order_id) {
  293. if ($newOrder && count($newOrder) > 0) {
  294. //按天为单位读取缓存
  295. // if(isset($newOrder[date('Y-m-d')])){
  296. // $tmp = $newOrder[date('Y-m-d')];
  297. // }
  298. if (isset($newOrder[$prod_top_org_id])) {
  299. array_push($newOrder[$prod_top_org_id], array('order_id' => $order_id, 'type' => $type, 'room_name' => $prod_name, 'status' => 0));
  300. } else {
  301. $newOrder[$prod_top_org_id] = array(array('order_id' => $order_id, 'type' => $type, 'room_name' => $prod_name, 'status' => 0));
  302. }
  303. $tmp = $newOrder;
  304. } else {
  305. $tmp[$prod_top_org_id] = array(array('order_id' => $order_id, 'type' => $type, 'room_name' => $prod_name, 'status' => 0));
  306. }
  307. Yii::$app->cacheCS->set('hotel_newOrder', $tmp, 0, $expire);
  308. }
  309. }
  310. /**
  311. * User:luocj
  312. * 酒店订单各状态实时变化表log
  313. *
  314. * @param $order_id //订单号
  315. * @param $order_status //订单修改成的状态
  316. * @param $before_status // 订单修改前的状态
  317. *
  318. * @return bool
  319. */
  320. public
  321. function hotelStatusLog($order_id, $order_status, $before_status, $user_id)
  322. {
  323. $update_info = ['cancel_flag' => 1];
  324. $update_where = ['order_id' => $order_id];
  325. OrderHtStatusLog::updateAll($update_info, $update_where);
  326. $obj = new OrderHtStatusLog();
  327. $obj->ORDER_ID = $order_id;
  328. $obj->ORDER_STATUS = $order_status;
  329. $obj->BEFORE_STATUS = $before_status;
  330. $obj->CANCEL_FLAG = 0;
  331. $obj->CREATE_USER_ID = $user_id;
  332. $obj->UPDATE_USER_ID = $user_id;
  333. $obj->UPDATE_TIME = date('Y-m-d H:i:s');
  334. $obj->CREATE_TIME = date('Y-m-d H:i:s');
  335. if ($obj->save() > 0)
  336. return true;
  337. else
  338. return false;
  339. }
  340. /**
  341. * @param $order_id //酒店订单id
  342. * @param $log_type //日志类型 1:酒店 2:房态 3:订单
  343. * @param $log_desc //日志描述
  344. *
  345. * @return bool
  346. */
  347. public
  348. function hotelLog($order_id, $log_type, $log_desc, $user_id)
  349. {
  350. $tmp_data = $this->getOrderInfo($order_id);
  351. $obj = new OperaHotelLog();
  352. $obj->CREATE_USER_ID = $user_id;
  353. $obj->CREATE_TIME = date('Y-m-d H:i:s');
  354. $obj->LOG_TYPE = $log_type;
  355. $obj->HOTEL_ID = $tmp_data['hotel_id'];
  356. $obj->ORDER_ID = $order_id;
  357. $obj->PARENT_ROOM_TYPE = $tmp_data['base_room_type'];
  358. $obj->ROOM_TYPE = $tmp_data['room_type'];
  359. $obj->LOG_DESC = $log_desc;
  360. if ($obj->save() > 0)
  361. return true;
  362. else
  363. return false;
  364. }
  365. /**
  366. * User: wangxj
  367. *
  368. * 推送对接的渠道商房态
  369. *
  370. * @param $hotel_id
  371. * @param $parent_room_type
  372. * @param $room_type
  373. * @param string $startDate
  374. * @param string $endDate
  375. * @param string $loop 循环次数
  376. */
  377. function pushRoomInfo($hotel_id, $parent_room_type, $room_type, $startDate = '', $endDate = '', $loop = 1)
  378. {
  379. // 26: 上海浦东星河湾 104:杭州千岛湖龙庭开元大酒店 取消MAPPING
  380. // 36:上海东郊宾馆 108:朱家尖慈航大酒店 125 上海浦西万怡 128 昆山皇冠假日酒店 106:义乌三鼎开元名都大酒店
  381. //99:上海茂业华美达广场酒店 37 外滩茂悦 19 嘉兴景澜月河客栈 23:上海花园饭店
  382. $sql = "select hotel_str from hotel_mapping where channel_id=669";
  383. $hotel = Yii::$app->db->createCommand($sql)->queryAll();
  384. $hotel_str = isset($hotel[0]['hotel_str']) ? $hotel[0]['hotel_str'] : '';
  385. $hotel_arr = explode(',', $hotel_str);
  386. if (in_array($hotel_id, $hotel_arr)) {
  387. //推送对接房态
  388. if ($startDate !== '' && $endDate === '') {
  389. $endDate = $startDate;
  390. }
  391. $startDate = $startDate != '' ? $startDate : date('Y-m-d');
  392. $endDate = $endDate != '' ? $endDate : date('Y-m-d', strtotime('+90 days'));
  393. $data['StartDate'] = $startDate;
  394. $data['EndDate'] = $endDate;
  395. $data['hotel_id'] = $hotel_id;
  396. $data['parent_room_type'] = $parent_room_type;
  397. $data['room_type'] = $room_type;
  398. $data['loop'] = $loop;
  399. $data['user_id'] = Yii::$app->user->id;
  400. // $res = Msg::httpRequest($this->ctrip_url . 'hotel/ctrip/set-room-info', $data);
  401. //
  402. // //SetRoomPrice(设置房型价格)向渠道商推送房型价格
  403. // $res = Msg::httpRequest($this->ctrip_url . 'hotel/ctrip/set-room-price', $data);
  404. //
  405. // //更新保留房数量
  406. // $res = Msg::httpRequest($this->ctrip_url . 'hotel/ctrip/update-room-quantity', $data);
  407. }
  408. }
  409. }