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.
 
 
 
 
 
 

718 lines
34 KiB

  1. <?php
  2. namespace backend\modules\hotel\models;
  3. use common\components\zHttp;
  4. use Yii;
  5. use backend\common\Utils;
  6. use common\models\BaseSupplierSale;
  7. use yii\db\ActiveRecord;
  8. use common\models\BaseSupplier as HotelSupplier;
  9. use yii\db\Expression;
  10. use yii\db\Exception;
  11. /**
  12. * This is the model class for table "run_hotel_distrib".
  13. * 渠道固定数量
  14. *
  15. * @property integer $ID
  16. * @property integer $CREATE_USER_ID
  17. * @property string $CREATE_TIME
  18. * @property integer $UPDATE_USER_ID
  19. * @property string $UPDATE_TIME
  20. * @property integer $DISTRIB_ID
  21. * @property integer $HOTEL_ID
  22. * @property integer $BASE_ROOM_TYPE
  23. * @property integer $ROOM_TYPE
  24. * @property string $RUN_DATE
  25. * @property integer $REMAINING_COUNT
  26. * @property integer $SALED_COUNT
  27. * @property string $PROD_PRICE
  28. * @property string $CUS_PRICE
  29. * @property integer $RUN_STATUS
  30. * @property integer $OVERSELL_FLAG
  31. * @property string $CONSUME_STOCK_TYPE
  32. * @property integer $AUTHORITY_STATUS
  33. */
  34. class RunHotelDistrib extends ActiveRecord
  35. {
  36. const ROOM_STATUS_CLOSE = 329; //关房
  37. const ROOM_STATUS_SALE = 326; //固定数量
  38. const OVERSELL_ON = 1; //超卖开
  39. const OVERSELL_OFF = 0; //
  40. const AUTHORITY_STATUS_ON = 1;
  41. const AUTHORITY_STATUS_OFF = 0;
  42. /**
  43. * @inheritdoc
  44. */
  45. public static function tableName()
  46. {
  47. return 'run_hotel_distrib';
  48. }
  49. /**
  50. * @inheritdoc
  51. */
  52. public function rules()
  53. {
  54. return [
  55. [['CREATE_USER_ID', 'UPDATE_USER_ID', 'DISTRIB_ID', 'HOTEL_ID', 'BASE_ROOM_TYPE', 'ROOM_TYPE', 'REMAINING_COUNT', 'SALED_COUNT', 'RUN_STATUS', 'OVERSELL_FLAG'], 'integer'],
  56. [['CREATE_TIME'], 'required'],
  57. [['UPDATE_TIME'], 'safe'],
  58. [['PROD_PRICE', 'CUS_PRICE'], 'number'],
  59. [['CREATE_TIME'], 'string', 'max' => 20],
  60. [['RUN_DATE'], 'string', 'max' => 10],
  61. [['CONSUME_STOCK_TYPE'], 'string', 'max' => 100],
  62. ];
  63. }
  64. /**
  65. * @inheritdoc
  66. */
  67. public function attributeLabels()
  68. {
  69. return [
  70. 'ID' => 'ID',
  71. 'CREATE_USER_ID' => 'Create User ID',
  72. 'CREATE_TIME' => 'Create Time',
  73. 'UPDATE_USER_ID' => 'Update User ID',
  74. 'UPDATE_TIME' => 'Update Time',
  75. 'DISTRIB_ID' => 'Distrib ID',
  76. 'HOTEL_ID' => 'Hotel ID',
  77. 'BASE_ROOM_TYPE' => 'Base Room Type',
  78. 'ROOM_TYPE' => 'Room Type',
  79. 'RUN_DATE' => 'Run Date',
  80. 'REMAINING_COUNT' => 'Remaining Count',
  81. 'SALED_COUNT' => 'Saled Count',
  82. 'PROD_PRICE' => 'Prod Price',
  83. 'CUS_PRICE' => 'Cus Price',
  84. 'RUN_STATUS' => 'Run Status',
  85. 'OVERSELL_FLAG' => 'Oversell Flag',
  86. 'CONSUME_STOCK_TYPE' => 'Consume Stock Type',
  87. ];
  88. }
  89. public function getBaseSupplier()
  90. {
  91. return $this->hasOne(HotelSupplier::className(), ['ID' => 'DISTRIB_ID']);
  92. }
  93. public function getBaseSupplierSale()
  94. {
  95. return $this->hasMany(BaseSupplierSale::className(), ['SUPPLIER_ID' => 'DISTRIB_ID']);
  96. }
  97. /**
  98. * @return \yii\db\ActiveQuery 酒店
  99. */
  100. public function getOperaHotel()
  101. {
  102. return $this->hasOne(OperaHotel::className(), ['HOTEL_ID' => 'HOTEL_ID']);
  103. }
  104. public function getOperaHotelRoom()
  105. {
  106. return $this->hasOne(OperaHotelRoom::className(), ['HOTEL_ID' => 'HOTEL_ID', 'PARENT_ROOM_TYPE' => 'BASE_ROOM_TYPE', 'ROOM_TYPE' => 'ROOM_TYPE']);
  107. }
  108. public function getRunHotelSubRoom()
  109. {
  110. return $this->hasOne(RunHotelSubRoom::className(), ['HOTEL_ID' => 'HOTEL_ID', 'BASE_ROOM_TYPE' => 'BASE_ROOM_TYPE', 'ROOM_TYPE' => 'ROOM_TYPE', 'RUN_DATE' => 'RUN_DATE']);
  111. }
  112. public function getRoomStock()
  113. {
  114. return $this->hasMany(RunHotel::className(), ['HOTEL_ID' => 'HOTEL_ID', 'BASE_ROOM_TYPE' => 'BASE_ROOM_TYPE', 'RUN_DATE' => 'RUN_DATE']);
  115. }
  116. public function getRunHotel()
  117. {
  118. return $this->hasOne(RunHotel::className(), ['HOTEL_ID' => 'HOTEL_ID', 'BASE_ROOM_TYPE' => 'BASE_ROOM_TYPE', 'RUN_DATE' => 'RUN_DATE']);
  119. }
  120. /**
  121. * Author:Steven
  122. * Desc:获取可用的酒店、房型产品数据
  123. * @param $room_id
  124. * @param $begin_date
  125. * @param $end_date
  126. * @return array|ActiveRecord[]
  127. */
  128. public static function getAvailProduct($room_id, $begin_date, $end_date)
  129. {
  130. $model = RunHotelDistrib::find()
  131. ->select([
  132. 'a.RUN_DATE',
  133. 'a.REMAINING_COUNT',
  134. 'a.PROD_PRICE',
  135. 'a.RUN_STATUS',
  136. 'a.OVERSELL_FLAG',
  137. 'a.CUS_PRICE',
  138. 'b.RUN_STATUS AS ROOM_RUN_STATUS',
  139. 'b.IS_ONSALE AS ROOM_IS_ONSALE',
  140. 'c.ID AS RP_CODE',
  141. 'c.HOTEL_ID',
  142. 'c.PARENT_ROOM_TYPE',
  143. 'c.IS_ONSALE',
  144. 'c.ROOM_NAME',
  145. 'c.INNER_IDENTIFY',
  146. 'd.HOTEL_NAME',
  147. 'e.AUTHORITY_STATUS',
  148. ])
  149. ->leftJoin('run_hotel_sub_room b', 'a.HOTEL_ID=b.HOTEL_ID and a.BASE_ROOM_TYPE=b.BASE_ROOM_TYPE and a.ROOM_TYPE=b.ROOM_TYPE AND a.RUN_DATE=b.RUN_DATE')
  150. ->leftJoin('opera_hotel_room c', 'a.HOTEL_ID = c.HOTEL_ID AND a.BASE_ROOM_TYPE = c.PARENT_ROOM_TYPE AND a.ROOM_TYPE = c.ROOM_TYPE AND c.CANCEL_FLAG=0')
  151. ->leftJoin('opera_hotel d', 'a.HOTEL_ID=d.HOTEL_ID')
  152. ->leftJoin('opera_room_distrib e', 'a.DISTRIB_ID=e.DISTRIB_ID and e.ROOM_ID=c.ID')
  153. ->from('run_hotel_distrib a')
  154. ->where([
  155. 'c.ID' => $room_id,
  156. 'a.DISTRIB_ID' => Yii::$app->params['ali']['relation_supplier_id']
  157. ]);
  158. $model->andFilterWhere(['between', 'a.RUN_DATE', $begin_date, $end_date]);
  159. $data = $model->andFilterWhere(['between', 'b.RUN_DATE', $begin_date, $end_date])
  160. // -> createCommand() -> getRawSql();
  161. ->asArray()->all();
  162. return $data;
  163. }
  164. /**
  165. * User:Steven
  166. * Desc:可定检查
  167. * @param $roomInfo
  168. * @return array|\yii\db\ActiveRecord[]
  169. */
  170. public function CheckRoomAvail($roomInfo)
  171. {
  172. /*$hotel = $roomInfo['Hotel']; //酒店编号
  173. $Arrival = Utils::formatDataTime($roomInfo['Arrival'], 1); //到店日期
  174. $Departure = Utils::formatDataTime($roomInfo['Departure'], 1); //离店日期
  175. $Room = $roomInfo['Room']; //房型编号
  176. $CurrencyCode = $roomInfo['Currency']; //币种(可空)
  177. $RoomNumber = $roomInfo['RoomNumber']; //预定间数
  178. $Person = $roomInfo['Person']; //入住人数
  179. $BalanceType = $roomInfo['BalanceType']; //价格类型
  180. $IsHoldRoom = $roomInfo['IsHoldRoom']; //-是否保留房(F或空-否,R-是)*/
  181. $date_list = array();
  182. $roomData = isset($roomInfo['room_prices']['RoomPrice']['EffectDate']) ? $roomInfo['room_prices'] : $roomInfo['room_prices']['RoomPrice'];
  183. if (empty($roomInfo['room_prices'])) { //可订检查补偿
  184. $date_list = Utils::createDateRangeArray($roomInfo['Arrival'], $roomInfo['Departure']);
  185. } else {
  186. foreach ($roomData as $item) {
  187. $EffectDate = Utils::formatDataTime($item['EffectDate'], 1); //入住日期
  188. $EffectDate = date('Y-m-d', strtotime($EffectDate));
  189. // $date_list .= $date_list == '' ? '\'' . $EffectDate . '\'' : "," . '\'' . $EffectDate . '\'';
  190. $date_list[] = $EffectDate;
  191. /*
  192. $Cost = $item['Cost']; //底价
  193. $CNYCost = $item['CNYCost']; //汇率后的底价(可空)
  194. $BreakFast = $item['BreakFast']; //含早餐数*/
  195. }
  196. }
  197. $query = RunHotelDistrib::find()
  198. ->joinWith('operaHotel b')
  199. ->joinWith('operaHotelRoom c')
  200. ->joinWith('runHotel d')
  201. ->leftJoin('opera_room_distrib e', 'e.DISTRIB_ID=a.DISTRIB_ID and e.ROOM_ID=c.ID')
  202. ->from('run_hotel_distrib a');
  203. $query->select([
  204. 'a.HOTEL_ID',
  205. 'a.BASE_ROOM_TYPE',
  206. 'a.ROOM_TYPE',
  207. 'a.SALED_COUNT',
  208. 'a.PROD_PRICE',
  209. 'a.CUS_PRICE',
  210. 'c.BREAKFAST_INCLUDE',
  211. 'c.IS_ONSALE',
  212. 'b.CANCEL_FLAG as CANCEL_FLAG_B',
  213. 'c.CANCEL_FLAG as CANCEL_FLAG_C',
  214. 'a.RUN_STATUS',
  215. 'a.OVERSELL_FLAG',
  216. 'a.REMAINING_COUNT',
  217. 'a.RUN_DATE',
  218. 'e.AUTHORITY_STATUS',
  219. 'SUM(case d.stock_type when 228 then d.remaining_count else 0 end) as buyout',
  220. 'SUM(case d.stock_type when 229 then d.remaining_count else 0 end) as inquiry',
  221. 'sum(case d.stock_type when 230 then d.remaining_count else 0 end) as retain'
  222. ]);
  223. //228 买断 229 现询 230 保留
  224. $query->where([
  225. 'a.DISTRIB_ID' => Yii::$app->params['ctrip']['supplier_id'],
  226. 'a.HOTEL_ID' => $roomInfo['hotel_id'],
  227. 'c.ID' => $roomInfo['room_id'],
  228. 'd.IS_ONSALE' => 1
  229. ]);
  230. $query->andFilterWhere([
  231. 'in', 'a.RUN_DATE', $date_list
  232. ]);
  233. $query->groupBy('a.run_date');
  234. $res = $query->asArray()->all();
  235. // $sql = $query->createCommand()->getRawSql();
  236. return $res;
  237. /* $sql = "select a.hotel_id,a.base_room_type,a.room_type,a.saled_count,a.prod_price,a.cus_price,c.breakfast_include
  238. from run_hotel_distrib a
  239. left join opera_hotel b on a.hotel_id=b.hotel_id
  240. left join opera_hotel_room c on a.hotel_id=c.hotel_id and a.base_room_type=c.parent_room_type and a.room_type=c.room_type
  241. where b.cancel_flag=0 and c.is_onsale=1 and a.distrib_id=669 and a.hotel_id=107 and a.base_room_type=100078 and a.room_type=3 $sql_str
  242. and a.run_date='2017-04-10' and a.authority_status=1 and a.run_status<>329 limit 1";*/
  243. }
  244. /**
  245. * User:Steven
  246. * Desc:获取渠携程渠道房价
  247. * @param $param array
  248. * param StartDate
  249. * param EndDate
  250. * param hotel_id
  251. * param parent_room_type
  252. * param room_type
  253. * @return array|bool|\yii\db\ActiveRecord[]
  254. */
  255. public function getRoomPrice($param)
  256. {
  257. $begin_date = isset($param['StartDate']) ? $param['StartDate'] : false;
  258. $end_date = isset($param['EndDate']) ? $param['EndDate'] : false;
  259. $hotel_id = isset($param['hotel_id']) ? $param['hotel_id'] : false;
  260. $base_room_id = isset($param['parent_room_type']) ? $param['parent_room_type'] : false;
  261. $room_id = isset($param['room_type']) ? $param['room_type'] : false;
  262. //判断当前酒店、房型是否已经mapping
  263. if (!$begin_date || !$end_date || !$hotel_id || !$base_room_id || !$room_id) {
  264. $rs['code'] = 1;
  265. $rs['info'] = "获取渠携程渠道房价错误,缺少必要参数|$begin_date|$end_date|$hotel_id|$base_room_id|$room_id";
  266. return $rs;
  267. }
  268. $hotel = HotelRelation::findOne(['HotelId' => $param['hotel_id'], 'ChannelId' => Yii::$app->params['ctrip']['relation_supplier_id']]);
  269. $operate_hotel_room = OperaHotelRoom::findOne(['HOTEL_ID' => $param['hotel_id'], 'PARENT_ROOM_TYPE' => $param['parent_room_type'], 'ROOM_TYPE' => $param['room_type'], 'CANCEL_FLAG' => 0]);
  270. $room = RoomRelation::findOne(['RoomId' => $operate_hotel_room->ID, 'ChannelId' => Yii::$app->params['ctrip']['relation_supplier_id']]);
  271. if (!$hotel || !$room) {
  272. $rs['code'] = 2;
  273. $rs['info'] = "当前酒店或者房型未mapping,参数$begin_date|$end_date|$hotel_id|$base_room_id|$room_id";
  274. return $rs;
  275. }
  276. $query = RunHotelDistrib::find()
  277. ->joinWith('operaHotelRoom c')
  278. ->leftJoin('opera_room_distrib d', 'a.DISTRIB_ID=d.DISTRIB_ID and d.ROOM_ID=c.ID')
  279. ->from('run_hotel_distrib a');
  280. $query->select(['DISTINCT(a.RUN_DATE)', 'a.PROD_PRICE', 'c.BREAKFAST_INCLUDE', 'c.ID as ROOM_ID']);
  281. $query->where([
  282. 'a.DISTRIB_ID' => Yii::$app->params['ctrip']['supplier_id'],
  283. 'a.HOTEL_ID' => $hotel_id,
  284. 'a.BASE_ROOM_TYPE' => $base_room_id,
  285. 'a.ROOM_TYPE' => $room_id,
  286. 'd.AUTHORITY_STATUS' => 1
  287. ]);
  288. $query->andFilterWhere([
  289. 'between', 'a.RUN_DATE', $begin_date, $end_date
  290. ]);
  291. $res = $query->asArray()->all();
  292. $rs['code'] = 0;
  293. $rs['info'] = "数据获取成功!";
  294. $rs['data'] = $res;
  295. return $rs;
  296. }
  297. /**
  298. * User:Steven
  299. * Desc:获取保留房库存
  300. * @param $param array
  301. * param StartDate
  302. * param EndDate
  303. * param hotel_id
  304. * param parent_room_type
  305. * param room_type
  306. *
  307. * @return array|\yii\db\ActiveRecord[]
  308. */
  309. public function getRoomQuantity($param)
  310. {
  311. $begin_date = isset($param['StartDate']) ? ($param['StartDate'] >= date('Y-m-d', time()) ? $param['StartDate'] : date('Y-m-d', time())) : false;
  312. $end_date = isset($param['EndDate']) ? ($param['EndDate'] >= date('Y-m-d', time()) ? $param['EndDate'] : date('Y-m-d', time())) : false;
  313. $hotel_id = isset($param['hotel_id']) ? $param['hotel_id'] : false;
  314. $base_room_id = isset($param['parent_room_type']) ? $param['parent_room_type'] : false;
  315. $room_id = isset($param['room_type']) ? $param['room_type'] : false;
  316. if (!$begin_date || !$end_date || !$hotel_id || !$base_room_id || !$room_id) {
  317. $rs['code'] = 1;
  318. $rs['info'] = "获取保留房库存错误,缺少必要参数|$begin_date|$end_date|$hotel_id|$base_room_id|$room_id";
  319. return $rs;
  320. }
  321. $hotel = HotelRelation::findOne(['HotelId' => $param['hotel_id'], 'ChannelId' => Yii::$app->params['ctrip']['relation_supplier_id']]);
  322. $operate_hotel_room = OperaHotelRoom::findOne(['HOTEL_ID' => $param['hotel_id'], 'PARENT_ROOM_TYPE' => $param['parent_room_type'], 'ROOM_TYPE' => $param['room_type'], 'CANCEL_FLAG' => 0]);
  323. $room = RoomRelation::findOne(['RoomId' => $operate_hotel_room->ID, 'ChannelId' => Yii::$app->params['ctrip']['relation_supplier_id']]);
  324. if (!$hotel || !$room) {
  325. $rs['code'] = 2;
  326. $rs['info'] = "当前酒店或者房型未mapping,参数$begin_date|$end_date|$hotel_id|$base_room_id|$room_id";
  327. return $rs;
  328. }
  329. // 获取推送数据
  330. $query = RunHotelDistrib::find()
  331. ->joinWith('operaHotelRoom c')
  332. ->joinWith('runHotelSubRoom d')
  333. ->joinWith('operaHotel e')
  334. ->leftJoin('opera_room_distrib f', 'a.DISTRIB_ID=f.DISTRIB_ID AND f.ROOM_ID=c.ID')
  335. ->from('run_hotel_distrib a');
  336. $query->select(['DISTINCT(a.RUN_DATE)', 'a.REMAINING_COUNT', 'a.RUN_STATUS', 'a.OVERSELL_FLAG', 'c.IS_ONSALE', 'c.LASTEST_BOOK_TIME', 'c.ID as ROOM_ID', 'f.LATEST_COMFIRM_TIME as ReserveTime',
  337. 'd.IS_ONSALE as BASE_ROOM_IS_ONSALE', 'd.RUN_STATUS as BASE_ROOM_RUN_STATUS', 'f.AUTHORITY_STATUS']);
  338. $query->where([
  339. 'c.CANCEL_FLAG' => 0,
  340. 'e.CANCEL_FLAG' => 0,
  341. 'a.DISTRIB_ID' => Yii::$app->params['ctrip']['supplier_id'],
  342. 'a.HOTEL_ID' => $hotel_id,
  343. 'a.BASE_ROOM_TYPE' => $base_room_id,
  344. 'a.ROOM_TYPE' => $room_id,
  345. ]);
  346. $query->andFilterWhere([
  347. 'between', 'a.RUN_DATE', $begin_date, $end_date
  348. ]);
  349. // $sql = $query -> createCommand() -> getRawSql();
  350. $res = $query->asArray()->all();
  351. $rs['code'] = 0;
  352. $rs['info'] = "数据获取成功!";
  353. $rs['data'] = $res;
  354. return $rs;
  355. }
  356. /**
  357. * Author:Steven
  358. * Desc:清零失效保留房的库存
  359. * @param $distrib_id
  360. * @param $begin_date
  361. * @param $hotel_id
  362. * @param $parent_room_type
  363. * @param $room_type
  364. * @return bool
  365. * @throws Exception
  366. */
  367. public function clearReservingRoom($distrib_id, $end_date, $hotel_id, $parent_room_type, $room_type)
  368. {
  369. $transaction = Yii::$app->db->beginTransaction();
  370. try {
  371. //更新基础房型的库存
  372. $distribe_data = RunHotelDistrib::find()
  373. ->leftJoin('opera_hotel_base_room b', 'a.HOTEL_ID=b.HOTEL_ID and a.BASE_ROOM_TYPE=b.MAIN_ID')
  374. ->leftJoin('opera_hotel_room c', 'a.HOTEL_ID=c.HOTEL_ID and a.BASE_ROOM_TYPE=c.PARENT_ROOM_TYPE and a.ROOM_TYPE=c.ROOM_TYPE')
  375. ->leftJoin('base_supplier d', 'a.DISTRIB_ID=d.ID')
  376. ->from('run_hotel_distrib a')
  377. ->select(['a.DISTRIB_ID', 'a.HOTEL_ID', 'a.BASE_ROOM_TYPE', 'a.ROOM_TYPE', 'a.RUN_DATE', 'b.BASE_ROOM_NAME', 'c.ROOM_NAME', 'c.INNER_IDENTIFY',
  378. 'd.SUPPLIER_NAME', 'SUM(a.REMAINING_COUNT) as COUNT'])
  379. ->where([
  380. 'a.DISTRIB_ID' => $distrib_id,
  381. 'a.HOTEL_ID' => $hotel_id,
  382. 'a.BASE_ROOM_TYPE' => $parent_room_type,
  383. 'a.ROOM_TYPE' => $room_type,
  384. 'b.CANCEL_FLAG' => 0,
  385. 'c.CANCEL_FLAG' => 0,
  386. 'd.CANCEL_FLAG' => 0
  387. ])->groupBy(['a.RUN_DATE'])->andFilterWhere(['between', 'a.RUN_DATE', date('Y-m-d'), $end_date])->asArray()->all();
  388. $run_hotel = RunHotel::find()
  389. ->select(['HOTEL_ID', 'BASE_ROOM_TYPE', 'RUN_DATE', 'STOCK_TYPE', 'REMAINING_COUNT',
  390. 'SUM(case stock_type when 228 then remaining_count else 0 end) as BUYOUT', //买断
  391. 'SUM(case stock_type when 229 then remaining_count else 0 end) as INQUIRY', //现询
  392. 'SUM(case stock_type when 230 then remaining_count else 0 end) as RETAIN'])//保留
  393. ->where([
  394. 'HOTEL_ID' => $hotel_id,
  395. 'BASE_ROOM_TYPE' => $parent_room_type
  396. ])->andFilterWhere(['between', 'RUN_DATE', date('Y-m-d'), $end_date])->groupBy('RUN_DATE')->orderBy(['RUN_DATE' => SORT_ASC, 'STOCK_TYPE' => SORT_ASC])
  397. ->asArray()->all();
  398. foreach ($run_hotel as $item) { //每个日期有三条记录
  399. if ($item['RETAIN'] == 0 && $item['BUYOUT'] == 0) { //买断、保留均无库存,不再更新
  400. continue;
  401. }
  402. foreach ($distribe_data as $val) {
  403. if ($item['RUN_DATE'] == $val['RUN_DATE']) {
  404. if ($val['COUNT'] == 0) {
  405. continue;
  406. }
  407. if ($val['COUNT'] > $item['RETAIN']) { //说明保留房库存不够扣除,还需再扣除买断
  408. ////买断房需要扣除的库存
  409. $remain_count = ($item['BUYOUT'] - ($val['COUNT'] - $item['RETAIN'])) <= 0 ? 0 : ($item['BUYOUT'] - ($val['COUNT'] - $item['RETAIN']));
  410. //扣除买断
  411. $buyout_effect = RunHotel::updateAll([
  412. 'REMAINING_COUNT' => $remain_count,
  413. 'UPDATE_TIME' => date('Y-m-d H:i:s')
  414. ], [
  415. 'and', ['=', 'STOCK_TYPE', 228],
  416. ['=', 'RUN_DATE', $val['RUN_DATE']],
  417. ['=', 'HOTEL_ID', $hotel_id],
  418. ['=', 'BASE_ROOM_TYPE', $parent_room_type]
  419. ]);
  420. if ($buyout_effect == 0) {
  421. throw new \Exception();
  422. }
  423. $opera_hotel_log = new OperaHotelLog();
  424. $opera_hotel_log->CREATE_USER_ID = 2;
  425. $opera_hotel_log->CREATE_TIME = date('Y-m-d H:i:s');
  426. $opera_hotel_log->LOG_TYPE = 2; //房型操作日志
  427. $opera_hotel_log->HOTEL_ID = $hotel_id;
  428. $opera_hotel_log->PARENT_ROOM_TYPE = $parent_room_type;
  429. $opera_hotel_log->ROOM_TYPE = 0;
  430. $opera_hotel_log->LOG_DESC = '保留房失效设置:' . $val['BASE_ROOM_NAME'] . $val['RUN_DATE'] . '买断库存扣除' . $remain_count . '间';
  431. $opera_hotel_log->save();
  432. }
  433. //扣除保留库存
  434. if ($item['RETAIN'] > 0) {
  435. // 基础房型保留房数量库存小于渠道保留房剩余库存
  436. $rc_count = ($item['RETAIN'] - $val['COUNT']) <= 0 ? 0 : ($item['RETAIN'] - $val['COUNT']);
  437. $retain_effect = RunHotel::updateAll([
  438. 'REMAINING_COUNT' => $rc_count,
  439. 'UPDATE_TIME' => date('Y-m-d H:i:s')
  440. ], [
  441. 'and', ['=', 'STOCK_TYPE', 230],
  442. ['=', 'RUN_DATE', $val['RUN_DATE']],
  443. ['=', 'HOTEL_ID', $hotel_id],
  444. ['=', 'BASE_ROOM_TYPE', $parent_room_type]
  445. ]);
  446. if ($retain_effect == 0) {
  447. throw new \Exception();
  448. }
  449. $opera_hotel_log = new OperaHotelLog();
  450. $opera_hotel_log->CREATE_USER_ID = 2;
  451. $opera_hotel_log->CREATE_TIME = date('Y-m-d H:i:s');
  452. $opera_hotel_log->LOG_TYPE = 2; //房型操作日志
  453. $opera_hotel_log->HOTEL_ID = $hotel_id;
  454. $opera_hotel_log->PARENT_ROOM_TYPE = $parent_room_type;
  455. $opera_hotel_log->ROOM_TYPE = 0;
  456. $opera_hotel_log->LOG_DESC = '保留房失效设置:' . $val['BASE_ROOM_NAME'] . $val['RUN_DATE'] . '保留库存扣除' . $val['COUNT'] . '间';
  457. $opera_hotel_log->save();
  458. }
  459. }
  460. }
  461. }
  462. //更新渠道的固定数量(保留房) 直接将库存置为o
  463. $effect_num = RunHotelDistrib::updateAll(['REMAINING_COUNT' => 0, 'UPDATE_TIME' => date('Y-m-d H:i:s')], [
  464. 'and', ['=', 'DISTRIB_ID', $distrib_id],
  465. ['=', 'HOTEL_ID', $hotel_id],
  466. ['=', 'BASE_ROOM_TYPE', $parent_room_type],
  467. ['=', 'ROOM_TYPE', $room_type],
  468. ['between', 'RUN_DATE', date('Y-m-d'), $end_date]
  469. ]);
  470. foreach ($distribe_data as $value) {
  471. if ($value['COUNT'] == 0) {
  472. continue;
  473. }
  474. $opera_hotel_log = new OperaHotelLog();
  475. $opera_hotel_log->CREATE_USER_ID = 2;
  476. $opera_hotel_log->CREATE_TIME = date('Y-m-d H:i:s');
  477. $opera_hotel_log->LOG_TYPE = 2; //房型操作日志
  478. $opera_hotel_log->HOTEL_ID = $hotel_id;
  479. $opera_hotel_log->PARENT_ROOM_TYPE = $parent_room_type;
  480. $opera_hotel_log->ROOM_TYPE = 0;
  481. $opera_hotel_log->LOG_DESC = '保留房失效设置:' . "{$value['SUPPLIER_NAME']}/{$value['BASE_ROOM_NAME']}/{$value['ROOM_NAME']}{$value['INNER_IDENTIFY']}-"
  482. . date('Y-m-d') . "~~{$end_date}" . '保留库存扣除' . $value['COUNT'] . '间';
  483. $opera_hotel_log->save();
  484. }
  485. //推送房态数据到渠道(异步)
  486. $soap_param = array('hotel_id' => $hotel_id, 'parent_room_type' => $parent_room_type, 'room_type' => $room_type,
  487. 'begin_date' => date('Y-m-d'), 'end_date' => $end_date, 'channel_id' => $distrib_id);
  488. zHttp::syncRequest(CommonOrder::SEND_REQUEST_GET, Yii::$app->params['push_info_interface'], array('param' => $soap_param));
  489. $transaction->commit();
  490. } catch (\Exception $e) {
  491. $transaction->rollBack();
  492. return false;
  493. }
  494. return true;
  495. }
  496. /**
  497. * Des:根据日期及酒店ID获取子房型数据
  498. * Name: getAllRoomListByHotelDate
  499. * @param $params
  500. * @return array
  501. * @author 倪宗锋
  502. */
  503. public function getAllRoomListByHotelDate($params)
  504. {
  505. $baseSupplierSale = new BaseSupplierSale();
  506. $price = 'a.' . $baseSupplierSale->getSaleType($params['org_id']);
  507. $select = [
  508. 'hotel_id' => 'a.HOTEL_ID',//酒店ID
  509. 'base_room_type' => 'a.BASE_ROOM_TYPE',//基础房型ID
  510. 'room_type' => 'a.ROOM_TYPE',//房型ID
  511. 'room_id' => 'b.ID',//房型ID
  512. 'hotel_name' => new Expression("(select hotel_name from opera_hotel where hotel_id = a.HOTEL_ID)"),//酒店名称
  513. 'room_name' => new Expression("CONCAT(b.ROOM_NAME,IFNULL(d.DISTRIB_ROOM_NAME,''))"),//子房型名称
  514. 'base_room_name' => 'c.BASE_ROOM_NAME',//基础房型名称
  515. 'c.BED_TYPE',//床型
  516. 'area_size' => new Expression("IFNULL(c.AREA_SIZE,'')"),//房型面积
  517. 'avg_price' => new Expression("truncate(avg($price) ,2)"),//均价
  518. 'min_price' => new Expression("truncate(MIN($price) ,2)"),//最低价
  519. 'total_money' => new Expression("truncate(sum($price) ,2)"),//单份产品总价
  520. 'date_price' => new Expression("group_concat(concat(a.RUN_DATE,'|',truncate($price ,2)) SEPARATOR '||' )"),
  521. 'sub_room_sale_days' => //子房型上架天数
  522. new Expression("SUM((SELECT f.IS_ONSALE from run_hotel_sub_room f where a.HOTEL_ID=f.HOTEL_ID and a.BASE_ROOM_TYPE=f.BASE_ROOM_TYPE and a.ROOM_TYPE=f.ROOM_TYPE and a.RUN_DATE=f.RUN_DATE))"),
  523. 'room_sale_days' => //房型上架天数
  524. new Expression("COUNT(DISTINCT a.RUN_DATE)"),
  525. 'hotel_sale_days' => //酒店上架天数
  526. new Expression("SUM((SELECT if(SUM(1)=0,0,1) from run_hotel g where a.HOTEL_ID=g.HOTEL_ID and a.BASE_ROOM_TYPE=g.BASE_ROOM_TYPE and a.RUN_DATE=g.RUN_DATE))"),
  527. 'gift' => //礼包信息
  528. new Expression("IFNULL(GROUP_CONCAT((select CONCAT(ID,'|||',GIFT_NAME,'|||',a.RUN_DATE) from opera_hotel_gift where ID=a.GIFT_ID) SEPARATOR '||||'),'')"),
  529. 'room_open_days' =>//房型的房态开房天数
  530. new Expression("SUM((SELECT f.RUN_STATUS from run_hotel_sub_room f where a.HOTEL_ID=f.HOTEL_ID and a.BASE_ROOM_TYPE=f.BASE_ROOM_TYPE and a.ROOM_TYPE=f.ROOM_TYPE and a.RUN_DATE=f.RUN_DATE))"),
  531. 'org_room_open_days' => //渠道房型房态 开房天数
  532. new Expression("sum(if(a.RUN_STATUS=326,1,0))"),
  533. 'stock' => //库存
  534. new Expression("min(if(a.OVERSELL_FLAG=1,(SELECT SUM(REMAINING_COUNT) from run_hotel g where a.HOTEL_ID=g.HOTEL_ID and a.BASE_ROOM_TYPE=g.BASE_ROOM_TYPE and a.RUN_DATE=g.RUN_DATE and g.STOCK_TYPE in (228,229,230)), a.REMAINING_COUNT))"),
  535. 'b.LASTEST_BOOK_TIME',//最后预定时间 获取到PHP处理时间
  536. 'b.LASTEST_CANCEL_DAY',//最晚取消时间
  537. 'b.BREAKFAST_INCLUDE',//早餐人数
  538. 'room_img' => new Expression("ifnull(c.ROOM_IMG,'')"),//基础房型图片
  539. 'in_time' => new Expression("(select EARLIEST_CHECKIN_TIME from opera_hotel where hotel_id = a.HOTEL_ID)"),//最早入住时间
  540. ];
  541. $where = [
  542. 'and',
  543. ['=', 'a.HOTEL_ID', $params['hotel_id']],//酒店ID
  544. ['=', 'a.DISTRIB_ID', $params['org_id']],//分销商ID
  545. ['>=', 'a.RUN_DATE', $params['start_date']],//入住时间
  546. ['<', 'a.RUN_DATE', $params['end_date']],//离店时间
  547. ['=', 'd.AUTHORITY_STATUS', 1]
  548. ];
  549. if (empty($params['room_id']) == false) {//房型ID
  550. $where[] = ['=', 'b.ID', $params['room_id']];
  551. }
  552. $getList = self::find()->select($select)
  553. ->from(self::tableName() . ' a')
  554. ->innerJoin(OperaHotelRoom::tableName() . ' b', 'a.HOTEL_ID=b.HOTEL_ID and a.BASE_ROOM_TYPE=b.PARENT_ROOM_TYPE and a.ROOM_TYPE=b.ROOM_TYPE and b.CANCEL_FLAG=0 ')
  555. ->innerJoin(OperaRoomDistrib::tableName() . ' d', 'b.ID=d.ROOM_ID and a.DISTRIB_ID=d.DISTRIB_ID and d.CANCEL_FLAG=0')
  556. ->innerJoin(OperaHotelBaseRoom::tableName() . ' c', 'a.BASE_ROOM_TYPE=c.MAIN_ID and a.HOTEL_ID=c.HOTEL_ID and c.CANCEL_FLAG=0')
  557. ->where($where)
  558. ->groupBy('b.ID')
  559. ->orderBy('avg_price')
  560. // ->createCommand()
  561. // ->getRawSql();
  562. // print_r($getList);die;
  563. ->asArray()
  564. ->all();
  565. return $getList;
  566. }
  567. /**
  568. * Function Description:查询子房型数据列表,按日期、销售方式、渠道商(微信检索列表)
  569. * Function Name: getRoomTypeList
  570. * @param $start_date
  571. * @param $end_date
  572. * @param $base_supplier_sale
  573. * @param $distrib_id
  574. *
  575. * @return array|ActiveRecord[]
  576. *
  577. * @author 娄梦宁
  578. */
  579. public function getRoomTypeList($start_date, $end_date, $base_supplier_sale, $distrib_id)
  580. {
  581. $select = [
  582. 'a.room_type',
  583. 'e.hotel_id',
  584. 'e.hotel_name',
  585. 'e.star_level',
  586. 'area_id' => new Expression('(select parent_id from base_area where id=e.area_id)'),
  587. 'is_promotion' => new Expression('ifnull(e.is_promotion,"")'),
  588. 'hotel_label' => new Expression("ifnull((select GROUP_CONCAT(res_name) from base_resource where instr((select SALE_LABEL from opera_hotel where hotel_id=e.hotel_id),RES_ID) and res_type_id=709 GROUP BY res_type_id),'')"),
  589. 'brand' => new Expression('ifnull((select res_name from base_resource where res_id=e.brand),"")'),
  590. 'hotel_type' => new Expression('ifnull((select res_name from base_resource where res_id=e.hotel_type),"")'),
  591. 'sale_label' => new Expression("ifnull((select GROUP_CONCAT(res_name) from base_resource where instr((select SALE_LABEL from opera_hotel where hotel_id=a.hotel_id),RES_ID) and res_type_id=710 GROUP BY res_type_id),'')"),
  592. 'recommend_level' => new Expression('ifnull(e.recommend_level,"")'),
  593. 'hotel_image' => new Expression('ifnull(e.hotel_image,"")'),
  594. 'business_area' => new Expression('ifnull(e.business_area,"")'),
  595. 'b.breakfast_include',
  596. 'bed_type' => new Expression('(if(b.BED_TYPE=0,c.BED_TYPE,b.bed_type))'),
  597. 'a.run_date',
  598. 'a.room_type',
  599. 'price' => new Expression('a.' . $base_supplier_sale),
  600. 'a.room_type',
  601. 'a.run_status',
  602. 'a.base_room_type',
  603. 'area_name' => new Expression('(select area_name from base_area bs where bs.id=e.AREA_ID)'),
  604. 'stock' => new Expression('(if(a.run_status=326,(if(a.OVERSELL_FLAG=1,(SELECT SUM(REMAINING_COUNT) from run_hotel g where a.HOTEL_ID=g.HOTEL_ID and a.BASE_ROOM_TYPE=g.BASE_ROOM_TYPE and a.RUN_DATE=g.RUN_DATE), a.REMAINING_COUNT)),0))'),
  605. ];
  606. $where = [
  607. 'and',
  608. ['=', 'd.authority_status', 1],
  609. ['>=', 'a.run_date', $start_date],
  610. ['<', 'a.run_date', $end_date],
  611. ['=', 'a.distrib_id', $distrib_id],
  612. ];
  613. $room_list = self::find()
  614. ->select($select)
  615. ->from(self::tableName() . ' a')
  616. ->innerJoin(OperaHotelRoom::tableName() . ' b', 'a.HOTEL_ID=b.HOTEL_ID and a.BASE_ROOM_TYPE=b.PARENT_ROOM_TYPE and a.ROOM_TYPE=b.ROOM_TYPE and b.CANCEL_FLAG=0 ')
  617. ->innerJoin(OperaRoomDistrib::tableName() . ' d', 'b.ID=d.ROOM_ID and a.DISTRIB_ID=d.DISTRIB_ID and d.CANCEL_FLAG=0')
  618. ->innerJoin(OperaHotelBaseRoom::tableName() . ' c', 'a.BASE_ROOM_TYPE=c.MAIN_ID and a.HOTEL_ID=c.HOTEL_ID and c.CANCEL_FLAG=0')
  619. ->innerJoin(OperaHotel::tableName() . ' e', 'a.hotel_id=e.hotel_id and e.cancel_flag =0 and e.hotel_status=1')
  620. ->where($where)
  621. ->asArray()
  622. ->all();
  623. return $room_list;
  624. }
  625. /**
  626. * Notes:
  627. * User: Steven
  628. * Date: 2018/2/7
  629. * Time: 13:36
  630. * @param $params
  631. * @return bool
  632. * @throws Exception
  633. */
  634. public function setMultipleRoomPriceID($params)
  635. {
  636. //查询渠道的售卖方式
  637. $supplier = HotelSupplier::find()->select([
  638. 'a.SUPPLIER_NAME', 'b.SALE_TYPE', 'b.COMMISION_FLAG', 'b.COMMISION_TYPE', 'b.BACK_COMMISION_TYPE',
  639. 'b.BACK_COMMISION_METHOD', 'b.BACK_PERCENT', 'b.BACK_VALUE'])
  640. ->leftJoin('base_supplier_sale b', "b.SUPPLIER_ID=a.ID and b.PARENT_TYPE=25")
  641. ->from('base_supplier a')->where(['a.ID' => $params['distrib_id']])->asArray()->one();
  642. $price_type = $supplier['SALE_TYPE'] = HotelSupplier::SALE_TYPE_DISTRIB ? 'PROD_PRICE' : 'CUS_PRICE';
  643. if (empty($supplier)) {
  644. return false;
  645. }
  646. $row_arr = explode('||', $params['room_info_str']);
  647. $transaction = Yii::$app->db->beginTransaction();
  648. try {
  649. foreach ($row_arr as $room_info) {
  650. $room_info_row = substr($room_info, 1, (strlen($room_info) - 2));
  651. $item = explode(',', $room_info_row);
  652. //0:hotel_id;1:base_room_id;2:room_id;3:start_date;4:end_date;5:week;6:channel_id; 7:price;8:operator
  653. $date_arr = Utils::createDateByWeek($item[3], $item[4], str_split($item[5]));
  654. $count = RunHotelDistrib::updateAll(
  655. [
  656. "{$price_type}" => new Expression('PROD_PRICE' . $item[8] . $item[7]),
  657. 'UPDATE_TIME' => date('Y-m-d H:i:s')
  658. ],
  659. ['and',
  660. ['=', 'HOTEL_ID', $item[0]],
  661. ['=', 'BASE_ROOM_TYPE', $item[1]],
  662. ['=', 'ROOM_TYPE', $item[2]],
  663. ['=', 'DISTRIB_ID', $item[6]],
  664. ['in', 'RUN_DATE', $date_arr]
  665. ]);
  666. if ($count == 0) {
  667. throw new Exception('');
  668. }
  669. $request_param = array('hotel_id' => $item[0], 'parent_room_type' => $item[1], 'room_type' => $item[2],
  670. 'begin_date' => $item[3], 'end_date' => $item[4], 'channel_id' => $item[6]);
  671. zHttp::syncRequest(CommonOrder::SEND_REQUEST_GET, Yii::$app->params['push_info_interface'], array('param' => $request_param));
  672. }
  673. $transaction->commit();
  674. return true;
  675. } catch (\Exception $e) {
  676. $error = $e->getMessage();
  677. $transaction->rollBack();
  678. return false;
  679. }
  680. }
  681. }
  682. ?>