20], [['ChannelHotelId'], 'unique'], [['HotelId', 'ChannelId'], 'unique', 'targetAttribute' => ['HotelId', 'ChannelId'], 'message' => 'The combination of 本地酒店ID and 渠道ID 1:携程 has already been taken.'], [['ChannelHotelId', 'ChannelId'], 'unique', 'targetAttribute' => ['ChannelHotelId', 'ChannelId'], 'message' => 'The combination of 渠道酒店ID and 渠道ID 1:携程 has already been taken.'], ]; } /** * @inheritdoc */ public function attributeLabels() { return [ 'id' => 'ID', 'cancel_flag' => 'Cancel Flag', 'ChannelHotelId' => '渠道酒店ID', 'HotelId' => '本地酒店ID', 'ChannelId' => '渠道', ]; } public function getOperaHotel() { return $this->hasOne(OperaHotel::className(), ['HOTEL_ID' => 'HotelId']); } public function getHotelPriceConversion() { return $this->hasOne(HotelPriceConversion::className(), ['hotel_id' => 'HotelId']); } public function getOperaHotelRoom() { return $this->hasOne(OperaHotelRoom::className(), ['HOTEL_ID' => 'HotelId']); } public function index($filter) { $query = PriceComparedHotel::find() ->joinWith('operaHotel as b') ->joinWith('hotelPriceConversion c') ->leftJoin('price_compared_room as e', 'a.HotelId =e.hotel_id') ->leftJoin('opera_hotel_room as d', 'e.room_id = d.ID') ->from('price_compared_hotel as a') ->select(['a.id', 'a.ChannelHotelId', 'a.HotelId', 'a.ChannelId', 'b.HOTEL_NAME', 'a.cancel_flag', 'c.remain_room_conversion', 'c.breakfast_conversion', 'c.cancel_rules_conversion', 'c.pay_type_conversion', 'IF(e.hotel_id, count(a.HotelId), 0) as room_num', 'a.SendMsg']) ->where(['b.cancel_flag' => 0]) ->groupBy(['a.HotelId']); if ($filter['channel_id'] != null) { $query->andFilterWhere(['=', 'a.ChannelHotelId', $filter['channel_id']]); } if ($filter['cancel_flag'] != null && $filter['cancel_flag'] != -1) { $query->andFilterWhere(['=', 'a.cancel_flag', $filter['cancel_flag']]); } if ($filter['hotel_name'] != null) { $query->andFilterWhere(['like', 'b.HOTEL_NAME', $filter['hotel_name']]); } if ($filter['channel'] != null && $filter['channel'] != -1) { $query->andFilterWhere(['=', 'a.ChannelId', $filter['channel']]); } // 采购负责人、客服、客服管理员不能查看比较数据 if(Yii::$app->user->identity['USER_ROLE'] == BaseUserAuth::HOTEL_PURCHASE || Yii::$app->user->identity['USER_ROLE'] == BaseUserAuth::HOTEL_CUSTOMER || Yii::$app->user->identity['USER_ROLE'] == BaseUserAuth::HOTEL_CUS_ADMIN){ $query->andFilterWhere(['a.id' => -1]); } $dataProvider = new ActiveDataProvider([ 'query' => $query->asArray(), 'pagination' => [ 'pageSize' => 15, ], ]); return $dataProvider; } /** * 修改酒店比价状态 */ public function setCancelFlag($id, $cancel_flag) { $hotel = PriceComparedHotel::findOne($id); $hotel->cancel_flag = $cancel_flag; $hotel->save(); if ($hotel->update()) { return true; } else { return false; } } public function getHotelList() { $sql = 'SELECT HOTEL_ID, HOTEL_NAME FROM opera_hotel WHERE HOTEL_ID not in (SELECT HotelId FROM price_compared_hotel) AND CANCEL_FLAG = 0'; $hotel_list = Yii::$app->db->createCommand($sql)->queryAll(); return $hotel_list; } /** * Author:Steven * Desc:获取酒店价格总览列表 * @param $channel_id * @return SqlDataProvider */ public function getHotelOverview($channel_id, $hotel_name, $hotel_pricipal) { $end_date = date('Y-m-d'); $start_date = date('Y-m-d', strtotime('-30 days')); $str = $hotel_pricipal == -1 ? 'and (1 = 1)' : 'and e.PRINCIPAL=' . $hotel_pricipal; // 采购负责人、客服、客服管理员不能查看比较数据 if(Yii::$app->user->identity['USER_ROLE'] ==BaseUserAuth::HOTEL_PURCHASE || Yii::$app->user->identity['USER_ROLE'] ==BaseUserAuth::HOTEL_CUSTOMER || Yii::$app->user->identity['USER_ROLE'] ==BaseUserAuth::HOTEL_CUS_ADMIN){ $str = ' and c.id=-1'; } $sql = "select c.*,count(d.room_id) as room_count,e.hotel_name from (select a.*,sum(b.SALED_COUNT) as saled_count from price_compared_hotel a LEFT JOIN run_hotel b on a.HotelId=b.HOTEL_ID and b.RUN_DATE BETWEEN :start_date and :end_date where a.ChannelId=:channel_id GROUP BY a.HotelId,a.ChannelId) c LEFT JOIN price_compared_room d on c.HotelId=d.hotel_id and d.cancel_flag=0 and d.channel_id=:channel_id LEFT JOIN opera_hotel e on c.HotelId=e.HOTEL_ID and e.CANCEL_FLAG=0 WHERE e.HOTEL_NAME LIKE :hotel_name $str GROUP BY c.HotelId,c.ChannelId ORDER BY c.saled_count DESC"; $count = Yii::$app->db->createCommand("select count(1) from " . "(" . $sql . ")" . "as count ", [':start_date' => $start_date, ':end_date' => $end_date, ':channel_id' => $channel_id, ':hotel_name' => "%$hotel_name%"])->queryScalar(); $dataProvider = new SqlDataProvider([ 'sql' => $sql, 'params' => [':start_date' => $start_date, ':end_date' => $end_date, ':channel_id' => (int)$channel_id, ':hotel_name' => "%$hotel_name%"], 'totalCount' => $count, 'sort' => false, 'pagination' => [ 'pagesize' => 20 ] ]); return $dataProvider; } /** * User:Steven * Desc:获取比价总览页面的数据 * @param $hotel_id * @param $price * @param $start_date * @param $end_date * @return bool */ public static function GetOverviewData($hotel_id, &$price, $start_date, $end_date) { $ctripHotelPrice = new CtripHotelPrice(); $data = $ctripHotelPrice->getCtripData($hotel_id, $start_date, $end_date); if (empty($data)) { return false; } // $disadvantage = $price->ctripDataService($data, $hotel_id, false); //未进行价差折算 价格劣势 $competitiveness = $price->ctripDataService($data, $hotel_id); //进行价差折算 竞争力不足 $inferiority = 0; $no_show = 0; $competitive = 0; if (!empty($data)) { /*foreach ($disadvantage as $key => $value) { foreach ($value as $item) { if (empty($item)) { continue; } foreach ($item as $k => $v) { if (!is_null($v['a_price']) && !is_null($v['b_price'])) { //劣势 $inferiority++; } elseif (!is_null($v['a_price']) && is_null($v['b_price'])) { $no_show++; } } } }*/ foreach ($competitiveness as $key => $value) { foreach ($value as $item) { if (empty($item)) { continue; } foreach ($item as $k => $v) { if (!is_null($v['a_price']) && !is_null($v['b_price']) && $v['inferiority'] == 2) { //劣势 $inferiority++; } if (!is_null($v['a_price']) && is_null($v['b_price'])) { $no_show++; } if ($v['inferiority'] == 3) { //劣势 $competitive++; } } } } } $lose = $inferiority + $no_show + $competitive; $price->inferiority = $inferiority; $price->no_show = $no_show; $price->competitive = $competitive; $price->lose = $lose; // return ['inferiority' => $inferiority, 'no_show' => $no_show, 'competitive' => $competitive, 'lose' => $lose]; } /** * Author:Steven * Desc:比价数据处理 * @param $ctrip_data * @param $price_conversion * @param $flag * @return array */ public function ctripDataService($ctrip_data, $HOTEL_ID, $flag = true) { //查询当前有直连关系的房型ID $ctripHotelPrice = new CtripHotelPrice(); $room_arr = $ctripHotelPrice->getRelationRoom($ctrip_data[0]['spider_hotel_id']); $room_list = []; foreach ($room_arr as $room) { $room_list[] = $room['channel_room_id']; } //a_表示携程 b_表示蜘蛛 $arr = array(); if ($flag) { $ctripHotelPrice = new CtripHotelPrice(); $price_conversion = $ctripHotelPrice->getHotelConversion($HOTEL_ID); $price_conversion = $price_conversion[0]; } foreach ($ctrip_data as $item) { $spider_price = $item['b_price']; $ctrip_price = $item['a_price']; $origin_spider_price = $item['b_price']; //用于记录没有折算价差的时候的价格 $origin_ctrip_price = $item['a_price']; if ($flag) {//携程价格折算 $remain_room_conversion = isset($price_conversion['remain_room_conversion']) ? $price_conversion['remain_room_conversion'] : 0; $breakfast_conversion = isset($price_conversion['breakfast_conversion']) ? $price_conversion['breakfast_conversion'] : 0; $cancel_rules_conversion = isset($price_conversion['cancel_rules_conversion']) ? $price_conversion['cancel_rules_conversion'] : 0; $pay_type_conversion = isset($price_conversion['pay_type_conversion']) ? $price_conversion['pay_type_conversion'] : 0; //早餐(非早餐类型的早餐折算) 以我们的价格为基数,加上或者减去早餐数之差*价差 $ctrip_breakfast = $this->calBreakfastLevel($item['a_breakfast']); $spider_breakfast = $this->calBreakfastLevel($item['b_breakfast']); $spider_price = $spider_price - ($spider_breakfast - $ctrip_breakfast) * $breakfast_conversion; //别墅类型的早餐折算 $ctrip_breakfast1 = $this->calbreakfast1($item['a_breakfast']); $spider_breakfast2 = $this->calbreakfast1($item['b_breakfast']); $ctrip_person = $this->number($item['a_room_person']); $spider_person = $this->number($item['b_room_person']); $spider_price = $spider_price + ($spider_breakfast2 * $spider_person - $ctrip_breakfast1 * $ctrip_person) * $breakfast_conversion; //现预付 蜘蛛是预付 if ($item['a_payment_txt'] == '到店付' || $item['a_payment_txt'] == '担保') {//现付 $ctrip_price = $ctrip_price - $pay_type_conversion; } //保留房 $item['a_confirm_info'] == '立即确认' ? '' : $ctrip_price = $ctrip_price + $remain_room_conversion; $item['b_confirm_info'] == '立即确认' ? '' : $spider_price = $spider_price + $remain_room_conversion; //取消规则 $item['a_room_policy'] == '免费取消' ? '' : $ctrip_price = $ctrip_price + $cancel_rules_conversion; $item['b_room_policy'] == '免费取消' ? '' : $spider_price = $spider_price + $cancel_rules_conversion; } if ($spider_price > $ctrip_price || is_null($item['b_price'])) { //蜘蛛价格为null时,即价格未在携程前台显示 $room_type = preg_replace('/^([^\d]+).*/', '$1', str_replace(array("\r\n", "\r", " ", "\n"), "", $item['room_type'])); $arr[$item['spider_hotel_id']][$room_type][$item['start_date']] = array( 'a_bed_type' => $item['a_bed_type'], 'b_bed_type' => $item['b_bed_type'], 'a_breakfast' => $item['a_breakfast'], 'b_breakfast' => $item['b_breakfast'], 'a_room_policy' => $item['a_room_policy'], 'b_room_policy' => $item['b_room_policy'], 'a_confirm_info' => $item['a_confirm_info'], 'b_confirm_info' => $item['b_confirm_info'], 'a_supply_id' => $item['a_supply_id'], 'a_showdow_id' => $item['a_showdow_id'], 'a_payment_txt' => $item['a_payment_txt'], 'b_payment_txt' => $item['b_payment_txt'], 'a_room_person' => $item['a_room_person'], 'b_room_person' => $item['b_room_person'], 'a_price' => $item['a_price'], 'b_price' => $item['b_price'], 'b_son_room_id' => $item['son_room_id'], 'inferiority' => 2, ); if (($origin_spider_price < $origin_ctrip_price) && !is_null($item['b_price'])) { //这种属于竞争力不足 $arr[$item['spider_hotel_id']][$room_type][$item['start_date']]['inferiority'] = 3; } //判断当前房型是不是直连的房型 if (!in_array($item['son_room_id'], $room_list)) { unset($arr[$item['spider_hotel_id']][$room_type][$item['start_date']]); } } } //当某个房型下所有的日期,蜘蛛的数据都是空的,表明我们没有合作此房型 foreach ($arr as $itmem_k => $item) { foreach ($item as $key => $value) { $i = 0; foreach ($value as $k => $v) { if (is_null($v['b_price'])) { $i++; if ($i == count($value)) { unset($arr[$itmem_k][$key]); } } } } } return $arr; } /** * User:Steven * Desc:计算早餐级别 * @param $breakfast * @return int */ public function calBreakfastLevel($breakfast) { switch ($breakfast) { case '无早': $breakfast_level = 0; break; case '每天单早': $breakfast_level = 1; break; case '每天双早': $breakfast_level = 2; break; case '每天三早': $breakfast_level = 3; break; case '每天四早': $breakfast_level = 4; break; case '每天五早': $breakfast_level = 5; break; case '每天六早': $breakfast_level = 6; break; case '每天七早': $breakfast_level = 7; break; case '每天八早': $breakfast_level = 8; break; case '每天九早': $breakfast_level = 9; break; case '每天十早': $breakfast_level = 10; break; default: $breakfast_level = 0; break; } return $breakfast_level; } /** * User:Steven * Desc:对于别墅类型的房,计算早餐个数的时候需要考虑到入住人数 * @param $breakfast * @return int|string */ public function calbreakfast1($breakfast) { $arr = array(1 => '一', 2 => '二', 3 => '三', 4 => '四', 5 => '五', 6 => '六', 7 => '七', 8 => '八', 9 => '九', 10 => '十', 11 => '十一', 12 => '十二'); foreach ($arr as $k => $v) { if ($breakfast == '每天每人' . $v . '份早') { return $k; } else { return 0; } } } /** * User:Steven * Desc:获取字符串中的数字部分 * @param $str * @return mixed */ public function number($str) { return preg_replace('/\D/s', '', $str); } public function beforeSave($insert) { if ($this->isNewRecord) { $this->cancel_flag = 0; } return parent::beforeSave($insert); } }