Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 
 
 

682 rader
32 KiB

  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: Steven
  5. * Date: 2017/10/10
  6. * Time: 14:42
  7. *
  8. * 阿里-飞猪(酒店)对接
  9. */
  10. namespace backend\modules\hotel\controllers;
  11. use backend\common\Utils;
  12. use backend\modules\hotel\models\Ali\XhotelRatesIncrementRequest;
  13. use backend\modules\hotel\models\Ali\XhotelRoomtypeUpdateRequest;
  14. use backend\modules\hotel\models\Ali\XhotelUpdateRequest;
  15. use backend\modules\hotel\models\HotelRelation;
  16. use backend\modules\hotel\models\OperaHotel;
  17. use backend\modules\hotel\models\OperaHotelBaseRoom;
  18. use backend\modules\hotel\models\OperaHotelRoom;
  19. use backend\modules\hotel\models\RoomRelation;
  20. use backend\modules\hotel\models\Ali\XhotelRateplanUpdateRequest;
  21. use backend\modules\hotel\models\Ali\XhotelRateUpdateRequest;
  22. use backend\modules\hotel\models\Ali\XhotelRatesUpdateRequest;
  23. use backend\modules\hotel\models\Ali\XhotelRateRelationshipwithroomGetRequest;
  24. use backend\modules\hotel\models\Ali\AliExecute;
  25. use backend\modules\hotel\models\Ali\TopLogger;
  26. use backend\modules\hotel\models\RunHotelDistrib;
  27. use common\models\Msg;
  28. use Yii;
  29. use yii\filters\AccessControl;
  30. use backend\modules\hotel\models\Ali\XhotelOrderUpdateRequest;
  31. class AliController extends BaseController
  32. {
  33. public $enableCsrfValidation = false;
  34. public $agent_id = self::AGENT_ALI_HOTEL_ID;
  35. /*public function behaviors()
  36. {
  37. return [
  38. 'access' => [
  39. 'class' => AccessControl::className(),
  40. 'rules' => [
  41. [
  42. 'ips' => ['101.226.248.76' //阿里IP访问白名单
  43. ,'127.0.0.1', '106.14.56.77', '180.168.4.58', '139.224.30.29'
  44. ],
  45. 'allow' => true,
  46. ],
  47. ],
  48. ],
  49. ];
  50. }*/
  51. /**
  52. * Author:Steven
  53. * Desc:添加酒店或更新酒店
  54. * taobao.xhotel.add (酒店新增接口(ID重复自动更新))
  55. */
  56. public function actionAddHotel($hotel_id = 0)
  57. {
  58. $id = empty($hotel_id) ? Yii::$app->request->get('hotel_id') : $hotel_id;
  59. $hotel = new OperaHotel();
  60. $hotel_info = $hotel->getPushHotelInfo($id);
  61. //判断该酒店的直连渠道有没有阿里
  62. $channel_arr = explode(',', $hotel_info['DRIECT_CONNNECT_CHANNEL']);
  63. if (!in_array(Yii::$app->params['ali']['relation_supplier_id'], $channel_arr)) {
  64. return json_encode(['code' => 203, 'msg' => '该酒店的直连渠道中不包含阿里飞猪,请确认', 'data' => '']);
  65. }
  66. // 转换星级表示
  67. $star = $this->hotelStarConversions($hotel_info['STAR_LEVEL']);
  68. // 酒店直连信息查询
  69. $already_connenct = HotelRelation::findOne(['HotelId' => $id, 'ChannelId' => Yii::$app->params['ali']['relation_supplier_id']]);
  70. $param = ['outer_id' => "{$hotel_info['HOTEL_ID']}", 'name' => "{$hotel_info['HOTEL_NAME']}", 'city' => "{$hotel_info['POSTCODE']}", 'address' => "{$hotel_info['HOTEL_ADDRESS']}", 'tel' => '021-33280550', 'star' => "$star"];
  71. if ($already_connenct) {
  72. $param['status'] = $hotel_info['HOTEL_STATUS'] == 0 ? -2 : 0;
  73. $req = new XhotelUpdateRequest(['scenario' => 'update_hotel']);
  74. } else {
  75. $req = new XhotelUpdateRequest();
  76. $already_connenct = new HotelRelation();
  77. }
  78. if ($req->load($param, '') && $req->validate()) {
  79. $rs = new AliExecute();
  80. $res = $rs->execute($req, true);
  81. if (!$res->xhotel) {
  82. return json_encode(['code' => $res->code, 'msg' => XhotelUpdateRequest::ERROR_MSG[$res->code], 'data' => '']);
  83. }
  84. // 阿里直连成功,本地建立关联关系
  85. $params = array('ChannelHotelId' => (string)$res->xhotel->hid, 'HotelId' => $id, 'ChannelId' => Yii::$app->params['ali']['relation_supplier_id']);
  86. if ($already_connenct->load($params, '') && $already_connenct->validate()) {
  87. if ($already_connenct->save()) {
  88. $logger = new TopLogger;
  89. $logger->log(array(
  90. date("Y-m-d H:i:s"),
  91. '阿里渠道新增直连酒店:' . __FUNCTION__ . json_encode($res)
  92. ));
  93. $result = ['code' => 0, 'msg' => '推送酒店成功', 'data' => $res];
  94. } else {
  95. $result = ['code' => 204, 'msg' => 'mapping失败', 'data' => $res];
  96. }
  97. return json_encode($result);
  98. }
  99. } else {
  100. $logger = new TopLogger;
  101. $msg = '';
  102. if (!empty($req->getFirstErrors())) {
  103. $msg = $req->getErrorMsg();
  104. }
  105. $logger->log(array(
  106. date("Y-m-d H:i:s"),
  107. '参数验证失败:' . __FUNCTION__ . $msg
  108. ));
  109. }
  110. }
  111. /**
  112. * @Author wanglg
  113. * @Desc 房型添加、修改接口(新房型添加,重复房型修改)
  114. * @param hotel_id // 酒店ID
  115. * @param PARENT_ROOM_TYPE // 基础房型房型ID
  116. * @param room_type // 子房型ID
  117. */
  118. public function actionRoomUpdate(array $params = [])
  119. {
  120. $request = empty($params) ? Yii::$app->request->post() : $params;
  121. // 通过渠道基础房型和子房型type查询房型,将子房型信息推送( 推送前判断是否直连,直连则解除关联,未直连则推送)
  122. $hotel_is_mapping = HotelRelation::findOne(['HotelId' => $request['hotel_id'], 'ChannelId' => Yii::$app->params['ali']['relation_supplier_id']]);
  123. // 首先判断酒店是否直连
  124. if (!$hotel_is_mapping) {
  125. return json_encode(array('code' => 207, 'msg' => '该房型所属酒店还未直连', 'data' => ''));
  126. }
  127. //推送基础房型
  128. $room_info = OperaHotelBaseRoom::find()
  129. ->select(['a.MAIN_ID', 'a.HOTEL_ID', 'a.BASE_ROOM_NAME', 'a.BED_TYPE', 'b.ChannelRoomId', 'c.HOTEL_NAME'])
  130. ->leftJoin('channel_room_relation as b', 'a.MAIN_ID=b.RoomId and b.ChannelId=' . Yii::$app->params['ali']['relation_supplier_id'])
  131. ->leftJoin('opera_hotel c', 'a.HOTEL_ID=c.HOTEL_ID and a.cancel_flag=0')
  132. ->where(['a.MAIN_ID' => $request['parent_room_type'], 'a.HOTEL_ID' => $request['hotel_id']])
  133. ->from('opera_hotel_base_room as a')
  134. // -> createCommand() -> getRawSql();
  135. ->asArray()->one();
  136. $bed_name = $this->getBedTypeName($room_info['BED_TYPE']);
  137. $param = array('outer_id' => (string)$room_info['MAIN_ID'], 'hotel_code' => (string)$room_info['HOTEL_ID'], 'name' => $room_info['BASE_ROOM_NAME'], 'bed_type' => $bed_name);
  138. if ($room_info['ChannelRoomId']) {
  139. $param['status'] = $room_info['IS_ONSALE'] == 1 ? 0 : -2;
  140. $scenario = 'update_room';
  141. } else {
  142. $scenario = 'add_room';
  143. }
  144. $room = new XhotelRoomtypeUpdateRequest(['scenario' => $scenario]);
  145. if ($room->load($param, '') && $room->validate()) {
  146. $rs = new AliExecute();
  147. $res = $rs->execute($room, true);
  148. if ($res->code != 0) {
  149. return json_encode(['code' => 1, 'msg' => XhotelRoomtypeUpdateRequest::ERROR_MSG[$res->code], 'data' => '']);
  150. }
  151. $logger = new TopLogger;
  152. if (!$room_info['ChannelRoomId']) // 推送成功且未直连添加本地记录
  153. {
  154. $channel_room_relation = new RoomRelation();
  155. $save_arr = array('channelRoomId' => (string)$res->xroomtype->rid, 'channelId' => Yii::$app->params['ali']['relation_supplier_id'], 'roomId' => $room_info['MAIN_ID']);
  156. $room_res = $channel_room_relation->mapping($save_arr);
  157. if ($room_res) {
  158. $logger->log(array(
  159. date("Y-m-d H:i:s"),
  160. '阿里渠道直连房型成功:' . __FUNCTION__ . json_encode($res)
  161. ));
  162. return json_encode(['code' => 0, 'msg' => 'success', 'data' => $res]);
  163. } else {
  164. $this->sendAliMsgToRtx('【阿里直连】阿里渠道直连房型成功,建立本地关联关系失败,渠道房型id:',
  165. "酒店名称:" . $room_info['HOTEL_NAME'] . "\n房型名称:" . $room_info['BASE_ROOM_NAME'] . "\n渠道房型ID:" . $res->xroomtype->rid, 2);
  166. $logger->log(array(
  167. date("Y-m-d H:i:s"),
  168. '阿里渠道直连房型失败:' . __FUNCTION__ . json_encode($res)
  169. ));
  170. return json_encode(['code' => 0, 'msg' => 'success', 'data' => $res]);
  171. }
  172. } /*else {
  173. if ($is_connect->delete()) {
  174. $logger->log(array(
  175. date("Y-m-d H:i:s"),
  176. '阿里渠道解除直连房型成功:' . __FUNCTION__ . json_encode($res)
  177. ));
  178. return json_encode(['code' => 200, 'msg' => '阿里渠道解除直连房型成功', 'data' => $res]);
  179. } else {
  180. $logger->log(array(
  181. date("Y-m-d H:i:s"),
  182. '阿里渠道解除直连房型失败, 本地记录删除失败:' . __FUNCTION__ . json_encode($res)
  183. ));
  184. return json_encode(['code' => 205, 'msg' => '阿里渠道解除直连房型失败', 'data' => $res]);
  185. }
  186. }*/
  187. } else {
  188. $logger = new TopLogger;
  189. $msg = '';
  190. if (!empty($room->getFirstErrors())) {
  191. $msg = $room->getErrorMsg();
  192. }
  193. $logger->log(array(
  194. date("Y-m-d H:i:s"),
  195. '参数验证失败:' . __FUNCTION__ . $msg
  196. ));
  197. return json_encode(['code' => 1, 'msg' => $msg]);
  198. }
  199. }
  200. /**
  201. * Author:Steven
  202. * @Desc 产品库接口 支持房价信息的新增和修改
  203. * taobao.xhotel.rateplan.add
  204. * 接口返回值 rpid
  205. * @param hotel_id //酒店ID
  206. * @param parent_room_type //基础房型ID
  207. * @param room_type //子房型ID
  208. * @return bool
  209. */
  210. public function actionUpdateRateplan()
  211. {
  212. //当修改子房型、变更子房型的直连开关的时候需要调用该接口
  213. $request = Yii::$app->request->post();
  214. if (!isset($request['hotel_id']) || !isset($request['parent_room_type']) || !isset($request['room_type'])) {
  215. return json_encode(['code' => 207, 'msg' => '参数错误', 'data' => '']);
  216. }
  217. $user_id = empty(Yii::$app->user->id) ? $request['user_id'] : Yii::$app->user->id;
  218. //先判断酒店是否与渠道直连,房型是否直连
  219. $diret = OperaHotelRoom::find()->select(['a.ID', 'a.HOTEL_ID', 'a.PARENT_ROOM_TYPE', 'c.ChannelHotelId', 'b.ChannelRoomId', 'a.RP_ID'])
  220. ->leftJoin('channel_room_relation b', 'a.PARENT_ROOM_TYPE=RoomId and b.ChannelId=' . Yii::$app->params['ali']['relation_supplier_id'])
  221. ->leftJoin('channel_hotel_relation c', 'a.HOTEL_ID=c.HotelId and c.ChannelId=' . Yii::$app->params['ali']['relation_supplier_id'])
  222. ->from('opera_hotel_room a')
  223. ->where([
  224. 'a.HOTEL_ID' => $request['hotel_id'],
  225. 'a.PARENT_ROOM_TYPE' => $request['parent_room_type'],
  226. 'a.ROOM_TYPE' => $request['room_type'],
  227. 'a.CANCEL_FLAG' => 0
  228. ])->asArray()->one();
  229. if (is_null($diret['ChannelHotelId']) || is_null($diret['ChannelRoomId'])) {
  230. $msg = is_null($diret['ChannelHotelId']) ? '【阿里】该酒店未直连' : (is_null($diret['ChannelRoomId']) ? '【阿里】该房型未直连' : '');
  231. return json_encode(['code' => 1, 'msg' => $msg, 'data' => '']);
  232. }
  233. //构造RP接口需要的数据 // 1 为 开启,2为关闭//借助参数修改rp,不能根据RP是否存在判断打开或关闭RP,存在修改的情况
  234. $status = empty($request['status']) || is_null($request['status']) ? 1 : $request['status'];
  235. $ohr = OperaHotelRoom::find()->select(['a.ID', 'a.HOTEL_ID', 'a.PARENT_ROOM_TYPE', 'a.ROOM_TYPE', 'a.ROOM_NAME', 'a.OCCUPANCY_LIMIT', 'a.BREAKFAST_INCLUDE', 'a.IS_ONSALE',
  236. 'a.LASTEST_BOOK_TIME', 'a.LASTEST_CANCEL_DAY', 'a.INNER_IDENTIFY', 'c.EARLIEST_CHECKIN_TIME', 'c.LASTEST_BOOK_TIME as REMAIN_TIME', 'c.HOTEL_NAME', 'a.INNER_IDENTIFY', 'd.DISTRIB_ROOM_NAME'])
  237. ->leftJoin('opera_hotel c', 'a.HOTEL_ID=c.HOTEL_ID and c.cancel_flag=0')
  238. ->leftJoin('opera_room_distrib d', 'a.ID=d.ROOM_ID and d.CANCEL_FLAG=0 and d.DISTRIB_ID=' . Yii::$app->params['ali']['relation_supplier_id'])
  239. ->where(['a.HOTEL_ID' => $request['hotel_id'],
  240. 'a.PARENT_ROOM_TYPE' => $request['parent_room_type'],
  241. 'a.ROOM_TYPE' => $request['room_type'],
  242. 'a.CANCEL_FLAG' => 0])->from('opera_hotel_room a')->asArray()->one();
  243. $rp_name = '';
  244. // 判断如果有渠道房型名称RP名称就不使用酒店内部标识
  245. if (empty($ohr['DISTRIB_ROOM_NAME'])) {
  246. $ohr['INNER_IDENTIFY'] = str_replace(')', ')', str_replace('(', '(', $ohr['INNER_IDENTIFY']));
  247. preg_match_all("#\((.*?)\)#us", $ohr['INNER_IDENTIFY'], $inner_identify);
  248. foreach ($inner_identify[1] as $item) {
  249. $rp_name .= $item . ' ';
  250. }
  251. } else {
  252. $rp_name = $ohr['DISTRIB_ROOM_NAME'];
  253. }
  254. $min_adv_hours = Utils::timeHour($ohr['LASTEST_BOOK_TIME']);
  255. $param = array(
  256. 'rateplan_code' => "{$ohr['ID']}",
  257. 'name' => $rp_name == '' ? $ohr['INNER_IDENTIFY'] : $rp_name,
  258. 'payment_type' => '1', //只支持:1:预付5:现付6: 信用住7:预付在线预约8:信用住在线预约。其中5,6,7,8四种类型需要申请权限
  259. 'breakfast_count' => $ohr['BREAKFAST_INCLUDE'],
  260. 'min_adv_hours' => "{$min_adv_hours}",//最小提前预定小时数,从入住当天的24点往前计算。例如如果这个字段设置了48,代表必须至少提前两天预定,那么如果想预定24号入住,,必须在23号零点前下单。
  261. 'end_time' => '', //产品每日结束销售时间
  262. 'cancel_policy' => '{"cancelPolicyType":2}',
  263. 'status' => "{$status}", //1:开启(默认)2:关闭。如果没传值那么默认默认值为1
  264. 'breakfast_cal' => '{"date": null,"startDate": "' . date('Y-m-d', time()) . '","endDate": "' . date('Y-m-d', strtotime('+3 month')) . '","breakfast_count":' . $ohr['BREAKFAST_INCLUDE'] . '}',
  265. 'guarantee_type' => '0', // 担保类型,只支持: 0 无担保 1 峰时首晚担保 2峰时全额担保 3全天首晚担保 4全天全额担保
  266. 'out_rid' => "{$ohr['PARENT_ROOM_TYPE']}", //外部房型id 基础房型ID
  267. 'out_hid' => "{$ohr['HOTEL_ID']}", // 外部酒店id
  268. 'operator' => Yii::$app->params['ali']['operator'],
  269. 'common_allot_release_time' => Utils::timeHour($ohr['REMAIN_TIME'])
  270. );
  271. $rateplan = new XhotelRateplanUpdateRequest(['scenario' => 'create']);
  272. if ($rateplan->load($param, '') && $rateplan->validate()) {
  273. $rs = new AliExecute();
  274. $res = $rs->execute($rateplan, true);
  275. if ($res->code != 0) {
  276. return json_encode(['code' => 0, 'msg' => XhotelRateplanUpdateRequest::ERROR_MSG[$res->code], 'data' => '']);
  277. }
  278. return json_encode(['code' => 0, 'msg' => 'success', 'data' => $res->rpid]);
  279. } else {
  280. $logger = new TopLogger;
  281. $msg = '';
  282. if (!empty($rateplan->getFirstErrors())) {
  283. $msg = $rateplan->getErrorMsg();
  284. }
  285. $logger->log(array(
  286. date("Y-m-d H:i:s"),
  287. '参数验证失败:' . __FUNCTION__ . $msg . '--' . $user_id
  288. ));
  289. }
  290. }
  291. /**
  292. * Author:Steven
  293. * Desc:单个房型和房价的全量价格更新接口 第一次设置RP的时候会推送
  294. */
  295. public function actionRateUpdate()
  296. {
  297. $request = Yii::$app->request->post();
  298. if (!isset($request['hotel_id']) || !isset($request['parent_room_type']) || !isset($request['room_type'])) {
  299. return json_encode(['code' => 207, 'msg' => '参数错误', 'data' => '']);
  300. }
  301. $user_id = empty(Yii::$app->user->id) ? $request['user_id'] : Yii::$app->user->id;
  302. //先判断酒店是否与渠道直连,房型是否直连
  303. $res = OperaHotelRoom::find()->select(['a.ID', 'a.HOTEL_ID', 'a.PARENT_ROOM_TYPE', 'c.ChannelHotelId', 'b.ChannelRoomId', 'a.RP_ID', 'd.HOTEL_NAME', 'a.ROOM_NAME', 'a.INNER_IDENTIFY'])
  304. ->leftJoin('channel_room_relation b', 'a.PARENT_ROOM_TYPE=RoomId and b.ChannelId=' . Yii::$app->params['ali']['relation_supplier_id'])
  305. ->leftJoin('channel_hotel_relation c', 'a.HOTEL_ID=c.HotelId and c.ChannelId=' . Yii::$app->params['ali']['relation_supplier_id'])
  306. ->leftJoin('opera_hotel d', 'a.HOTEL_ID=d.HOTEL_ID and d.cancel_flag=0')
  307. ->from('opera_hotel_room a')
  308. ->where([
  309. 'a.HOTEL_ID' => $request['hotel_id'],
  310. 'a.PARENT_ROOM_TYPE' => $request['parent_room_type'],
  311. 'a.ROOM_TYPE' => $request['room_type'],
  312. 'a.CANCEL_FLAG' => 0
  313. ])
  314. // -> createCommand() -> getRawSql();
  315. ->asArray()->one();
  316. if (is_null($res['ChannelHotelId']) || is_null($res['ChannelRoomId']) || empty($res['RP_ID'])) {
  317. //酒店或者房型未直连
  318. $msg = is_null($res['ChannelHotelId']) ? '【阿里】该酒店未直连' : (is_null($res['ChannelRoomId']) ? '【阿里】该房型未直连' : '');
  319. return json_encode(['code' => 1, 'msg' => $msg, 'data' => '']);
  320. }
  321. $begin_date = date('Y-m-d', time());
  322. $end_date = date('Y-m-d', strtotime('+3month'));
  323. // 查出该子房型的信息及渠道房型信息
  324. $model = new RunHotelDistrib();
  325. $data = $model->getAvailProduct($res['ID'], $begin_date, $end_date);
  326. if (empty($data)) {
  327. return false;
  328. }
  329. //构造接口需要的数据
  330. foreach ($data as $item) {
  331. $inventory_price[] = array(
  332. 'date' => $item['RUN_DATE'], //日期必须为 T---T+180 日内的日期(T为当天),且不能重复
  333. 'quota' => $item['REMAINING_COUNT'],//库存 int 类型 取值范围 0-999(数量库存)60000(状态库存关) 61000(状态库存开)
  334. 'price' => $item['PROD_PRICE'] * 100,//价格 int类型 取值范围1-99999999 单位为分
  335. );
  336. if ($item['IS_ONSALE'] == 0 || $item['RUN_STATUS'] == 329 || $item['AUTHORITY_STATUS'] == 0 || $item['ROOM_IS_ONSALE'] == 0
  337. || $item['ROOM_RUN_STATUS'] == 0) {// 当子房型下线|渠道关房|渠道未授权|子房型关房,关闭价格
  338. $rate_status = 0;
  339. } else {
  340. $rate_status = 1;
  341. }
  342. $rate_switch_cal[] = array(
  343. "date" => $item['RUN_DATE'], //开关状态控制的那一天
  344. "rate_status" => $rate_status, //开关状态(0,关闭;1,打开)
  345. );
  346. }
  347. if (!isset($inventory_price)) {
  348. return false;
  349. }
  350. $inventory_price = array( //每日价格和房价专有库存信息
  351. 'use_room_inventory' => false, //是否使用房型共享库存 ,false时:使用房价专有库存 此时要求价格和库存必填
  352. 'inventory_price' => $inventory_price
  353. );
  354. $param = array(
  355. 'out_rid' => "{$res['PARENT_ROOM_TYPE']}", //卖家房型ID
  356. 'rateplan_code' => "{$res['ID']}", //商家价格计划编码
  357. 'inventory_price' => json_encode($inventory_price),
  358. 'rate_switch_cal' => json_encode($rate_switch_cal)
  359. );
  360. $model = new XhotelRateUpdateRequest();
  361. if ($model->load($param, '') && $model->validate()) {
  362. $rs = new AliExecute();
  363. $exec_res = $rs->execute($model, true);
  364. if ($exec_res->code != 0) {
  365. return json_encode(['code' => 1, 'msg' => XhotelRateUpdateRequest::ERROR_MSG[$exec_res->code], 'data' => '']);
  366. }
  367. return json_encode(['code' => 0, 'msg' => 'success', 'data' => '']);
  368. } else {
  369. $logger = new TopLogger;
  370. $msg = '';
  371. if (!empty($model->getFirstErrors())) {
  372. $msg = $model->getErrorMsg();
  373. }
  374. $logger->log(array(
  375. date("Y-m-d H:i:s"),
  376. '参数验证失败:' . __FUNCTION__ . $msg
  377. ));
  378. }
  379. }
  380. /**
  381. * Author:Steven
  382. * Desc:多个房型和房价的价格更新接口
  383. * @param $flag 当flag为true的时候,全量更新,当flag=false时,增量更新
  384. * @return bool
  385. */
  386. public function actionRatesUpdate(array $param = [], $flag = false)
  387. {
  388. $request = empty(Yii::$app->request->post()) ? $param : Yii::$app->request->post();
  389. if (!isset($request['room_info'])) {
  390. return json_encode(['code' => 207, 'msg' => '参数错误', 'data' => '']);
  391. }
  392. $room_info = json_decode($request['room_info'], true);
  393. /*$room_info = [
  394. 0 => [
  395. 'hotel_id' => '81',
  396. 'parent_room_type' => '100076',
  397. 'room_type' => '82',
  398. 'begin_date' => '2017-11-22',
  399. 'end_date' => '2017-11-25'
  400. ],
  401. 1 => [
  402. 'hotel_id' => '197',
  403. 'parent_room_type' => '150246',
  404. 'room_type' => '9',
  405. 'begin_date' => '2017-10-30',
  406. 'end_date' => '2017-11-11'
  407. ]
  408. ];*/
  409. //先判断酒店是否与渠道直连,房型是否直连
  410. $res = OperaHotelRoom::find()->select(['a.ID', 'a.HOTEL_ID', 'a.PARENT_ROOM_TYPE', 'a.ROOM_TYPE', 'c.ChannelHotelId', 'b.ChannelRoomId', 'a.RP_ID', 'd.HOTEL_NAME', 'a.ROOM_NAME', 'a.INNER_IDENTIFY'])
  411. ->leftJoin('channel_room_relation b', 'a.PARENT_ROOM_TYPE=RoomId and b.ChannelId=' . Yii::$app->params['ali']['relation_supplier_id'])
  412. ->leftJoin('channel_hotel_relation c', 'a.HOTEL_ID=c.HotelId and c.ChannelId=' . Yii::$app->params['ali']['relation_supplier_id'])
  413. ->leftJoin('opera_hotel d', 'a.HOTEL_ID=d.HOTEL_ID and d.cancel_flag=0')
  414. ->from('opera_hotel_room a');
  415. // ->andFilterWhere(['in', 'a.ID', [1897, 2284]]);
  416. foreach ($room_info as $item) {
  417. $res->orFilterWhere(['a.HOTEL_ID' => $item['hotel_id'], 'a.PARENT_ROOM_TYPE' => $item['parent_room_type'], 'a.ROOM_TYPE' => $item['room_type'], 'a.CANCEL_FLAG' => 0]);
  418. }
  419. $user_id = empty(Yii::$app->user->id) ? $room_info[0]['user_id'] : Yii::$app->user->id;
  420. $res = $res->asArray()->all();
  421. $diret_hid = [];
  422. foreach ($res as $item) {
  423. if (!is_null($item['ChannelHotelId']) && !is_null($item['ChannelRoomId']) && !empty($item['RP_ID'])) { //酒店和房型都直连
  424. foreach ($room_info as $v) {
  425. if ($item['HOTEL_ID'] == $v['hotel_id'] && $item['PARENT_ROOM_TYPE'] == $v['parent_room_type'] && $item['ROOM_TYPE'] == $v['room_type']) {
  426. $diret_hid[] = array(
  427. 'ID' => $item['ID'],
  428. 'BEGIN_DATE' => $v['begin_date'],
  429. 'END_DATE' => $v['end_date']
  430. );
  431. }
  432. }
  433. }
  434. }
  435. if (empty($diret_hid)) {
  436. return json_encode(['code' => 1, 'msg' => '暂无可推送数据', 'data' => '']);
  437. }
  438. $run_hotel_distrib = new RunHotelDistrib();
  439. foreach ($diret_hid as $room) {
  440. // 查询该房型在某日期段房态信息
  441. $data = $run_hotel_distrib->getAvailProduct($room['ID'], $room['BEGIN_DATE'], $room['END_DATE']);
  442. foreach ($data as $value) {
  443. $rs['rateplan_code'] = $value['RP_CODE'];
  444. $rs['vendor'] = "";
  445. $rs['lock_start_time'] = "";
  446. $rs['lock_end_time'] = "";
  447. $data = [
  448. "date" => $value['RUN_DATE'], //:date 日期必须为 T---T+180 日内的日期(T为当天),不能重复
  449. "quota" => $value['REMAINING_COUNT'], //房价专有库存 int 类型 取值范围 0-999(数量库存) 60000(状态库存关) 61000(状态库存开)
  450. "price" => $value['PROD_PRICE'] * 100, //价格 int类型 取值范围1-99999999 单位为分
  451. "status" => ($value['IS_ONSALE'] == 0 || $value['RUN_STATUS'] == 329 || $value['AUTHORITY_STATUS'] == 0 || $value['ROOM_IS_ONSALE'] == 0 || $value['ROOM_RUN_STATUS'] == 0) ? 0 : 1//status 价格开关,0为关,1为开
  452. ];
  453. $rs['out_rid'] = $value['PARENT_ROOM_TYPE'];
  454. $rs['data']['inventory_price'][] = $data;
  455. $rs['data']['use_room_inventory'] = false;
  456. }
  457. if (empty($rs['data']['inventory_price'])) {
  458. continue;
  459. }
  460. $req[] = $rs;
  461. }
  462. if (empty($req[0]['data']['inventory_price'])) {
  463. return json_encode(['code' => 2, 'msg' => '子房型:' . $req[0]['rateplan_code'] . '推送失败', 'data' => json_encode($req)]);
  464. }
  465. $param['rate_inventory_price_map'] = json_encode($req);
  466. $model = $flag ? new XhotelRatesUpdateRequest() : new XhotelRatesIncrementRequest;
  467. if ($model->load($param, '') && $model->validate()) {
  468. $rs = new AliExecute();
  469. $exec_res = $rs->execute($model, true);
  470. if ($exec_res->code != 0) {
  471. return json_encode(['code' => $exec_res->code, 'msg' => XhotelRatesIncrementRequest::ERROR_MSG[$exec_res->code], 'data' => '']);
  472. }
  473. return json_encode(['code' => 0, 'msg' => 'success', 'data' => '']);
  474. } else {
  475. $logger = new TopLogger;
  476. $msg = '';
  477. if (!empty($model->getFirstErrors())) {
  478. $msg = $model->getErrorMsg();
  479. }
  480. $logger->log(array(
  481. date("Y-m-d H:i:s"),
  482. '参数验证失败:' . __FUNCTION__ . $msg
  483. ));
  484. }
  485. }
  486. /**
  487. * @Author wanglg
  488. * @Desc获取阿里后台的Rpid
  489. */
  490. public function actionGetRpid($request)
  491. {
  492. $xmotel = new XhotelRateRelationshipwithroomGetRequest();
  493. if ($xmotel->load($request, '') && $xmotel->validate()) {
  494. $rs = new AliExecute();
  495. $exec_res = $rs->execute($xmotel, true);
  496. if ($exec_res->code != 0 || $exec_res->total_results == 0) {
  497. return false;
  498. }
  499. return true;
  500. } else {
  501. return false;
  502. }
  503. }
  504. /**
  505. * Author:Steven
  506. * Desc:酒店订单发货接口 即确认订单或者拒绝订单
  507. * @param $tid
  508. * @param $opt_type
  509. * @return string
  510. */
  511. public function actionConfirmOrder($tid, $opt_type)
  512. {
  513. $model = new XhotelOrderUpdateRequest();
  514. $logger = new TopLogger;
  515. //操作的类型:1.确认无房(取消预订,710发送短信提醒买家申请退款),2.确认预订 这里的订单号是指淘宝订单号
  516. $param = ['tid' => "{$tid}", 'opt_type' => $opt_type];
  517. $logger->log([date("Y-m-d H:i:s"), '酒店确认,未通过参数验证,渠道订单号:' . $tid . "\n" . PHP_EOL], 'ali/error');
  518. if ($model->load($param, '') && $model->validate()) {
  519. $logger->log([date("Y-m-d H:i:s"), '酒店确认,通过参数验证,渠道订单号:' . $tid . "\n" . PHP_EOL], 'ali/error');
  520. $exec = new AliExecute();
  521. $res = $exec->execute($model, true);
  522. if ($res->code != 0) {
  523. //失败消息提醒开发人员的企业微信
  524. $this->sendAliMsgToRtx('【阿里直连】确认订单失败:', $res->sub_msg . "\n" . '渠道单号:' . $tid, 4);
  525. return json_encode(['code' => 0, 'msg' => $res->sub_msg . $tid, 'data' => '']);
  526. }
  527. $logger->log([date("Y-m-d H:i:s"), '酒店确认, 确认阿里订单成功:' . $tid . "\n" . PHP_EOL], 'ali/error');
  528. //确认成功
  529. return json_encode(['code' => 0, 'msg' => 'success', 'data' => $res->rpid]);
  530. } else {
  531. $this->sendAliMsgToRtx('【阿里直连】确认订单失败:', '参数验证失败,渠道单号:' . $tid);
  532. $logger = new TopLogger;
  533. $msg = '';
  534. if (!empty($model->getFirstErrors())) {
  535. $msg = $model->getErrorMsg();
  536. }
  537. $logger->log(array(date("Y-m-d H:i:s"), '参数验证失败:' . __FUNCTION__ . $msg));
  538. return json_encode(['code' => 0, 'msg' => 'fail']);
  539. }
  540. }
  541. /**
  542. * @Author wanglg
  543. * @Desc 酒店星级转化
  544. * @param $star
  545. * @return int|string
  546. */
  547. public function hotelStarConversions($star)
  548. {
  549. switch ($star) {
  550. case 33:
  551. $star_level = 1;
  552. break;
  553. case 35:
  554. $star_level = 2;
  555. break;
  556. case 37:
  557. $star_level = 3;
  558. break;
  559. case 38:
  560. $star_level = 4;
  561. break;
  562. case 39:
  563. $star_level = 5;
  564. break;
  565. case 40:
  566. $star_level = 6;
  567. break;
  568. case 41:
  569. $star_level = 7;
  570. break;
  571. case 34:
  572. $star_level = 1.5;
  573. break;
  574. case 36:
  575. $star_level = 2.5;
  576. break;
  577. default:
  578. $star_level = 1;
  579. }
  580. return $star_level;
  581. }
  582. /**
  583. * @Author wanglg
  584. * @Desc获取床型名称
  585. * @param $str床型id拼接的字符串
  586. * @return string 床型名称字符串
  587. */
  588. public function getBedTypeName($str)
  589. {
  590. $bed_name = '';
  591. $bed_types = explode(',', $str);
  592. $bed_name .= in_array(1, $bed_types) ? '大床' : '';
  593. $bed_name .= in_array(2, $bed_types) ? '双床' : '';
  594. $bed_name .= in_array(10, $bed_types) ? '多床' : '';
  595. return $bed_name;
  596. }
  597. /**
  598. * Author:Steven
  599. * Desc:阿里酒店直连回调地址
  600. */
  601. public function actionCallback()
  602. {
  603. $url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . '?' . $_SERVER['QUERY_STRING'];
  604. $logger = new TopLogger;
  605. $logger->conf["log_file"] = dirname(dirname(dirname(__DIR__))) . "/runtime/logs/Ali/callback.log";
  606. $logger->log(array(
  607. date("Y-m-d H:i:s"),
  608. $url
  609. ));
  610. }
  611. /**
  612. * Author:Steven
  613. * Desc:阿里控制台创建的应用,未上线sessionKey有效期为1天,上线后为三个月,
  614. */
  615. public function actionCheckExpireTime()
  616. {
  617. $exec = new AliExecute();
  618. $res = $exec->checkExpireTime();
  619. if ($res > 85) {
  620. $this->sendAliMsgToRtx('【阿里直连】sessionKey过期通知::', "sessionKey即将过期,请及时获取最新的sesionKey;\nhttps://open.alitrip.com/docs/doc.htm?spm=a21tt.7629140.0.0.mhPqhk&treeId=164&articleId=104995&docType=1", '');
  621. $send_txt = "【蜘蛛出行】SessionKey过期通知:sessionKey即将过期,请及时获取最新的sesionKey;\nhttps://open.alitrip.com/docs/doc.htm?spm=a21tt.7629140.0.0.mhPqhk&treeId=164&articleId=104995&docType=1";
  622. // $send_mobile = "17602134075,18691077519,18257110363,18667946782,18855970997";
  623. // Msg::sendTelMsg($send_mobile, $send_txt);
  624. }
  625. return $res;
  626. }
  627. }
  628. ?>