'操作成功', self::RETURN_CODE_CANCEL_FAIL => '取消失败/异常', self::RETURN_CODE_STOCK_FAIL => '酒店满房/房量不足', self::RETURN_CODE_NOTICE_FAIL => '备注不接受', self::RETURN_CODE_PRICE_FAIL => '价格错误', self::RETURN_CODE_DATE_FAIL => '日期错误/日期超过最大入住天数', self::RETURN_CODE_CHECKOUT => '已入住不允许取消或修改', self::RETURN_CODE_EXPIRED => '已过最晚取消修改时间', self::RETURN_CODE_NOT_EXIST => '修改/取消原订单不存在', self::RETURN_CODE_PROGRAM_FAIL => '程序错误', self::RETURN_CODE_NETWORK_FAIL => '网络问题(程序错误)', self::RETURN_CODE_GUARANTEE_FAIL => '担保错误', self::RETURN_CODE_HOTEL_CLOSED => '酒店已停止合作/酒店已停售/下架', self::RETURN_CODE_MAPPING_FAIL => '直连匹配错误(程序错误)', self::RETURN_CODE_REPEAT => '重复预定', self::RETURN_CODE_NEED_TOTAL_GUARANTEE => '需要全额担保', self::RETURN_CODE_OVER_NUM => '人数超限', self::RETURN_CODE_OVER_STOCK => '客人当天累计已超间,请提供担保 重新预订', self::RETURN_CODE_SYSTEM_FAIL => '服务器运行错误(程序错误)', self::RETURN_CODE_AUTH_FAIL => '用户认证或授权错误(程序错误)', self::RETURN_CODE_PARAMS_FAIL => '参数错误(程序错误)', self::RETURN_CODE_INFO_FAIL => '预订信息不正确', self::RETURN_CODE_NOT_ALLOW_UPDATE => '订单不允许修改', self::RETURN_CODE_NOT_ALLOW_CANCEL => '订单不允许取消', self::RETURN_CODE_NEED_ALL_GUARANTEE => '需要一律担保', self::RETURN_CODE_BREAKFAST_FAIL => '早餐不一致', self::RETURN_CODE_CURRENCY_FAIL => '币种错误', self::RETURN_CODE_UNAUTHORIZED => '该渠道未授权', self::RETURN_CODE_CURRENCY_FAIL => '币种错误', self::RETURN_CODE_ROOM_CLOSED => '房型已下线', self::RETURN_CODE_OTHER => '其他', self::RETURN_CODE_MAKE_ORDER => '下单扣款失败', self::RETURN_CODE_CANCEL_ORDER => '取消订单金额回退失败', self::RETURN_CODE_UPDATE_ORDER => '修改单渠道预付款处理失败', self::ERROR_DEDUCTION_TYPE => '未知的扣款类型', ]; CONST BUYOUT = 228; //库存类型 买断 const REMAIN = 230; //库存类型 保留 const INQUIRY = 229;//库存类型 现询 const PAY_TYPE_ALIPAY = 638; //支付宝支付 const PAY_TYPE_CASH = 221; //现金支付 const PAY_TYPE_CREDIT = 275; //授信支付 const PAY_TYPE_WEIXIN = 278; //微信支付 const MAKE_ORDER_DEDUCTION_TYPE = 251; // 下单扣款 const CANCEL_ORDER_DEDUCTION_TYPE = 252; // 取消单扣款 const UPDATE_ORDER_DEDUCTION_TYPE = 253; // 修改单扣款 const ERROR_DEDUCTION_TYPE = 254; // 错误扣款类型 public function __construct(array $config = []) { parent::__construct($config); } public function scenarios() { $scenarios['BookHotelOrder'] = ['OrderID', 'HotelID', 'RoomID', 'DistribID', 'RoomNum', 'CheckIn', 'CheckOut', 'TotalPrice', 'Currency', 'ContactName', 'ContactTel', 'OrderGuests', 'Comment', 'NeedInvoice', 'InvoiceInfos', 'RoomPrices', 'CreateUserID', 'RunTime', 'PayType', 'PayTradeNo', 'Commission', 'CommentType', 'OrderTitleID']; $scenarios['CheckRoomAvail'] = ['HotelID', 'RoomID', 'RoomNum', 'CheckIn', 'CheckOut', 'DistribID', 'RoomPrices', 'IfCheckPrice', 'CreateUserID']; $scenarios['CancelHotelOrder'] = ['CreateUserID', 'OrderID', 'HotelID', 'RoomID', 'DistribID', 'Reason']; $scenarios['UpdateHotelOrder'] = ['ZZ_ORDER_ID', 'OrderID', 'HotelID', 'RoomID', 'DistribID', 'RoomNum', 'CheckIn', 'CheckOut', 'TotalPrice', 'Currency', 'ContactName', 'ContactTel', 'OrderGuests', 'Comment', 'NeedInvoice', 'InvoiceInfos', 'RoomPrices', 'CreateUserID', 'RunTime']; $scenarios['Product'] = ['RoomID', 'DistribID', 'CheckIn', 'CheckOut']; return $scenarios; } public function rules() { return [ [['HotelID', 'RoomID', 'RoomNum', 'CheckIn', 'CheckOut', 'DistribID', 'RoomPrices', 'IfCheckPrice'], 'required', 'on' => 'CheckRoomAvail'], [['OrderID', 'HotelID', 'RoomID', 'DistribID', 'RoomNum', 'CheckIn', 'CheckOut', 'TotalPrice', 'OrderGuests', 'NeedInvoice', 'RoomPrices', 'PayType'], 'required', 'on' => 'BookHotelOrder'], [['Currency', 'ContactName', 'Comment', 'InvoiceInfos', 'RunTime', 'PayTradeNo', 'ContactTel', 'Commission', 'CommentType', 'OrderTitleID'], 'safe', 'on' => 'BookHotelOrder'], [['CreateUserID', 'HotelID', 'OrderID', 'RoomID', 'DistribID'], 'required', 'on' => 'CancelHotelOrder'], [['ZZ_ORDER_ID', 'OrderID', 'HotelID', 'RoomID', 'DistribID', 'RoomNum', 'CheckIn', 'CheckOut', 'TotalPrice', 'OrderGuests', 'NeedInvoice', 'RoomPrices'], 'required', 'on' => 'UpdateHotelOrder'], [['Currency', 'ContactName', 'Comment', 'InvoiceInfos', 'RunTime'], 'safe', 'on' => 'UpdateHotelOrder'], [['Reason'], 'safe', 'on' => 'CancelHotelOrder'], [['HotelID'], 'checkOrderExist', 'on' => 'CancelHotelOrder'], [['RoomID', 'DistribID', 'CheckIn', 'CheckOut'], 'required', 'on' => 'Product'], //共用 [['CheckIn', 'CheckOut'], 'date', 'format' => 'yyyy-mm-dd'], [['RoomNum', 'NeedInvoice'], 'number'], ]; } /** * Notes: * User: Steven * Date: 2018/1/10 * Time: 14:48 * @param array $data * @param null $formName * @return bool */ public function load($data, $formName = null) { $scope = $formName === null ? $this->formName() : $formName; if ($scope === '' && !empty($data)) { $this->setAttributes($data); if ($this->NeedInvoice) { $this->InvoiceInfos = new OrderInvoiceInfo(); $this->InvoiceInfos->NeedInvoice = $this->NeedInvoice; $this->InvoiceInfos->OrderID = $this->OrderID; $this->InvoiceInfos->ChannelId = $this->DistribID; $this->InvoiceInfos->InvoiceMoney = "$this->TotalPrice"; $flag = $this->InvoiceInfos->load($data['InvoiceInfos'], '') && $this->InvoiceInfos->validate(); /*if (!$flag) { $error = array_values($this->InvoiceInfos->getFirstErrors()); $this->addError('InvoiceInfos', $error[0]); return false; }*/ } return true; } elseif (isset($data[$scope])) { $this->setAttributes($data[$scope]); return true; } else { return false; } } /** * Notes: 取消订单的时候查询订单是否 * User: Steven * Date: 2018/1/3 * Time: 10:45 */ public function checkOrderExist() { $res_order_id = OrderMain::find()->select(['ORDER_ID', 'CHANNEL_ORDER_STATUS', 'PROD_ID', 'PARENT_PROD_ID'])->where([ 'OUTSIDE_ORDER_NO' => "{$this->OrderID}", 'ORDER_PROD_TYPE' => OrderMain::ORDER_PROD_TYPE_MAIN, 'PARENT_ORDER_ID' => 0, 'order_main.CANCEL_FLAG' => 0, ])->limit(1)->asArray()->one(); if (empty($res_order_id)) { $this->addError('OrderID', '该订单不存在,请核实后在进行相关操作!'); } } /** * Notes:下单前的可定检查 * User: Steven * Date: 2018/1/10 * Time: 14:06 */ public function checkRoomAvail($order_id = 0) { $res = $this->getProductData(); $date_list = Utils::createDateRangeArray($this->CheckIn, $this->CheckOut); if (!empty($res) && count($res) == count($date_list)) { $roomPrice = []; $total_price = 0; $return_code = 0; $availInfo = []; $room_num = 0; if ($order_id) { $room_num = $this->getRoomNum($order_id); } foreach ($res as $item) { //检查渠道是否授权 if (!$item['AUTHORITY_STATUS']) { $return_code = self::RETURN_CODE_UNAUTHORIZED; } //检查产品是否上线 if ($item['ROOM_IS_ONSALE'] == 0 || $item['ROOM_DAY_IS_ONSALE'] == 0 || $item['DISTRIB_DAY_IS_ONSALE'] == 0) { $return_code = self::RETURN_CODE_ROOM_CLOSED; } //检查是否关房 if ($item['ROOM_RUN_STATUS'] == 0 || $item['DISTRIB_RUN_STATUS'] == 329) { //ROOM_RUN_STATUS=0 房型关房;DISTRIB_RUN_STATUS=329渠道关房 $return_code = self::RETURN_CODE_STOCK_FAIL; } //判断库存 if ($order_id) { if (($item['BUYOUT'] + $item['RETAIN'] + $item['INQUIRY'] + $room_num) < $this->RoomNum) { $return_code = self::RETURN_CODE_STOCK_FAIL; } if (($item['REMAINING_COUNT'] + $room_num) < $this->RoomNum && $item['OVERSELL_FLAG'] == 0) { //给渠道的库存不足且不允许超卖 $return_code = self::RETURN_CODE_STOCK_FAIL; } } else { if (($item['BUYOUT'] + $item['RETAIN']) < $this->RoomNum && $item['INQUIRY'] < $this->RoomNum) { $return_code = self::RETURN_CODE_STOCK_FAIL; } if ($item['REMAINING_COUNT'] < $this->RoomNum && $item['OVERSELL_FLAG'] == 0) { //给渠道的库存不足且不允许超卖 $return_code = self::RETURN_CODE_STOCK_FAIL; } } //价格校验 if ($this->IfCheckPrice) { foreach ($this->RoomPrices as $val) { $newPrice = $item['SALE_TYPE'] == 177 ? $item['PROD_PRICE'] : $item['CUS_PRICE'];//分销选取分销价,其他选择零售价 if ($val['RUN_DATE'] == $item['RUN_DATE']) { if ($newPrice != $val['PRICE']) { $return_code = self::RETURN_CODE_PRICE_FAIL; } } } } $newPrice = $item['SALE_TYPE'] == 177 ? $item['PROD_PRICE'] : $item['CUS_PRICE'];//分销选取分销价,其他选择零售价 $roomPrice[$item['RUN_DATE']] = [ 'run_date' => $item['RUN_DATE'], 'price' => $newPrice, 'avail_quantity' => (string)($availInfo['code'] <> 0 ? 0 : ($item['OVERSELL_FLAG'] == 1 ? ($item['BUYOUT'] + $item['INQUIRY'] + $item['RETAIN']) : $item['REMAINING_COUNT'])), ]; $total_price += $newPrice; } $availInfo = [ 'total_price' => $total_price * $this->RoomNum, 'room_price' => $roomPrice, ]; if ($return_code <> 0) { return ['code' => $return_code, 'info' => self::RETURN_MSG[$return_code]]; } } else { return ['code' => self::RETURN_CODE_PROGRAM_FAIL, 'info' => self::RETURN_MSG[self::RETURN_CODE_PROGRAM_FAIL]]; } return ['code' => self::RETURN_CODE_SUCCESS, 'info' => self::RETURN_MSG[self::RETURN_CODE_SUCCESS], 'data' => $availInfo]; } /** * Notes:下单接口 * User: Steven * Date: 2017/12/28 * Time: 15:19 * @return array * @throws \yii\db\Exception */ public function bookHotelOrder() { $flag = false; //标识是否设置订单为现询的(包括保留房和非保留房混合的情况,全是现询房) $data = $this->getProductData(); $hotelInfo = $this->getHotelInfo(); if ($data) { $transaction = Yii::$app->db->beginTransaction(); $stock_arr = []; //订单最终消耗的类型及数量 try { foreach ($data as $item) { //检查渠道是否授权 if (!$item['AUTHORITY_STATUS']) { return ['code' => self::RETURN_CODE_UNAUTHORIZED, 'info' => self::RETURN_MSG[self::RETURN_CODE_UNAUTHORIZED]]; } //检查产品是否上线 if ($item['ROOM_IS_ONSALE'] == 0 || $item['ROOM_DAY_IS_ONSALE'] == 0 || $item['DISTRIB_DAY_IS_ONSALE'] == 0) { return ['code' => self::RETURN_CODE_ROOM_CLOSED, 'info' => self::RETURN_MSG[self::RETURN_CODE_ROOM_CLOSED]]; } //检查是否关房 if ($item['ROOM_RUN_STATUS'] == 0 || $item['DISTRIB_RUN_STATUS'] == 329) { //ROOM_RUN_STATUS=0 房型关房;DISTRIB_RUN_STATUS=329渠道关房 return ['code' => self::RETURN_CODE_STOCK_FAIL, 'info' => self::RETURN_MSG[self::RETURN_CODE_STOCK_FAIL]]; } //判断库存 if (($item['BUYOUT'] + $item['RETAIN'] + $item['INQUIRY']) < $this->RoomNum) { //买断+保留库存和现询库存是不能同时消耗的 return ['code' => self::RETURN_CODE_STOCK_FAIL, 'info' => self::RETURN_MSG[self::RETURN_CODE_STOCK_FAIL]]; } if ($item['REMAINING_COUNT'] < $this->RoomNum && $item['OVERSELL_FLAG'] == 0) { //给渠道的库存不足且不允许超卖 return ['code' => self::RETURN_CODE_STOCK_FAIL, 'info' => self::RETURN_MSG[self::RETURN_CODE_STOCK_FAIL]]; } //价格校验 if ($this->IfCheckPrice) { //渠道下单是需要校验的,其他:如自己的系统下单,不需要校验价格的 foreach ($this->RoomPrices as $val) { $newPrice = $item['SALE_TYPE'] == 177 ? $item['PROD_PRICE'] : $item['CUS_PRICE'];//分销选取分销价,其他选择零售价 if ($val['RunDate'] == $item['RUN_DATE']) { if ($newPrice != $val['Price']) { return ['code' => self::RETURN_CODE_PRICE_FAIL, 'info' => self::RETURN_MSG[self::RETURN_CODE_PRICE_FAIL]]; } } } } //订单最终消耗的类型及数量 if ($item['BUYOUT'] >= $this->RoomNum) { //只消耗买断 $stock_arr[$item['RUN_DATE']][CommonOrder::BUYOUT] = ['room_num' => $this->RoomNum, 'product_data' => $item]; } elseif (($item['BUYOUT'] + $item['RETAIN']) >= $this->RoomNum) { //消耗买断和保留 $stock_arr[$item['RUN_DATE']][CommonOrder::BUYOUT] = ['room_num' => $item['BUYOUT'], 'product_data' => $item]; $stock_arr[$item['RUN_DATE']][CommonOrder::REMAIN] = ['room_num' => $this->RoomNum - $item['BUYOUT'], 'product_data' => $item]; } elseif (($item['BUYOUT'] + $item['RETAIN'] + $item['INQUIRY']) >= $this->RoomNum) { //需要消耗买断+保留+现询 $stock_arr[$item['RUN_DATE']][CommonOrder::BUYOUT] = ['room_num' => $item['BUYOUT'], 'product_data' => $item]; $stock_arr[$item['RUN_DATE']][CommonOrder::REMAIN] = ['room_num' => $item['RETAIN'], 'product_data' => $item]; $stock_arr[$item['RUN_DATE']][CommonOrder::INQUIRY] = ['room_num' => $this->RoomNum - $item['BUYOUT'] - $item['RETAIN'], 'product_data' => $item]; } else { return ['code' => self::RETURN_CODE_STOCK_FAIL, 'info' => self::RETURN_MSG[self::RETURN_CODE_STOCK_FAIL]]; } } //创建主订单 $main_order_id = $this->getHotelOrderID(); $order_description = ''; //主订单中的订单描述 $total_base_price = ''; //总成本 $total_commission = ''; //总佣金 $total_profit_value = ''; //总利润 $orderMainParam = []; $total_price = 0; $prices = array_column($this->RoomPrices, 'Price'); foreach ($prices as $price) { $total_price += $price * $this->RoomNum; } /*if ((string)$total_price != (string)$this->TotalPrice) { return ['code' => self::RETURN_CODE_PRICE_FAIL, 'info' => self::RETURN_MSG[self::RETURN_CODE_PRICE_FAIL]]; }*/ //订单总金额 //更新库存 ksort($stock_arr); foreach ($stock_arr as $run_date => $stock) { $roomPrice = []; #region 计算佣金 foreach ($this->RoomPrices as $room_price) { if (isset($hotelInfo['commission'][BaseSupplier::BACK_COMMISION_METHOD_SALE])) {//按照销售额 按返佣比例计算 取百分比 $commission_rate = $hotelInfo['commission'][BaseSupplier::BACK_COMMISION_METHOD_SALE]; $commission = $room_price['Price'] * ($commission_rate / 100); } elseif (isset($hotelInfo['commission'][BaseSupplier::BACK_COMMISION_METHOD_SETTLE])) { $commission_rate = $hotelInfo['commission'][BaseSupplier::BACK_COMMISION_METHOD_SETTLE]; $commission = $commission_rate; } else { $commission = 0; } $roomPrice[$room_price['RunDate']] = [ 'Price' => $room_price['Price'], 'Commission' => round($commission, 2)]; } #endregion // 消耗库存 $distrib = RunHotelDistrib::findOne([ 'HOTEL_ID' => $this->HotelID, 'ROOM_TYPE' => $data[0]['ROOM_TYPE'], 'BASE_ROOM_TYPE' => $data[0]['BASE_ROOM_TYPE'], 'RUN_DATE' => $run_date, 'DISTRIB_ID' => $this->DistribID, ]); $distrib->SALED_COUNT += $this->RoomNum; //更新已售数量 #region 1、扣渠道的库存 if ($distrib->REMAINING_COUNT < $this->RoomNum) { //说明固定数量的库存小于客人所需的间数,这个时候,还需要消耗超卖的库存 $distrib->REMAINING_COUNT = 0; $flag = true; //这个订单标记为现询单 } else { //直接扣除固定数量 $distrib->REMAINING_COUNT = ($distrib->REMAINING_COUNT - $this->RoomNum); } if (!$distrib->save()) { $msg = $this->getErrorMsg($distrib); throw new \Exception($msg); } #endregion $stock_count = 0; foreach ($stock as $stock_type => $room_num) { #region 2、扣基础房型的库存 $runHotel = RunHotel::findOne([ 'HOTEL_ID' => $this->HotelID, 'BASE_ROOM_TYPE' => $data[0]['BASE_ROOM_TYPE'], 'RUN_DATE' => $run_date, 'STOCK_TYPE' => $stock_type, ]); if (empty($runHotel)) { continue; } $runHotel->SALED_COUNT += $room_num['room_num']; $runHotel->REMAINING_COUNT -= $room_num['room_num']; if (!$runHotel->save()) { $msg = $this->getErrorMsg($runHotel); throw new \Exception($msg); } #endregion //根据库存类型判断售卖单价 $base_price = $stock_type == 228 ? $room_num['product_data']['BASE_PRICE_BUYOUT'] : ($stock_type == 230 ? $room_num['product_data']['BASE_PRICE_RESERVE'] : ($stock_type == 230 ? $room_num['product_data']['BASE_PRICE_INQUIRY'] : $room_num['product_data']['BASE_PRICE_INQUIRY'])); $total_base_price += $base_price * $room_num['room_num']; //总成本价格 #region 3、创建子订单 for ($i = 1; $i <= $room_num['room_num']; $i++) { $stock_count++; $order_id = $this->getHotelOrderID(); //最晚到店时间 if ($this->RunTime != '') { $timeArr = explode(':', date('H:i', $this->RunTime)); $minutes = $timeArr[0] * 60 + $timeArr[1]; } else { $minutes = 0; } //入住人信息 $order_guests = ''; foreach ($this->OrderGuests as $Guest) { $order_guests .= $order_guests == '' ? $Guest['Name'] : ',' . $Guest['Name']; } $fenxiao_commisssion = empty($this->Commission) ? 0 : $this->Commission / (Utils::diffBetweenTwoDays($this->CheckIn, $this->CheckOut) * $this->RoomNum); $orderMainParam = [ 'ID' => $order_id, 'MAIN_CREATE_USER_ID' => $this->CreateUserID, 'CREATE_USER_ID' => $this->CreateUserID, 'CREATE_TIME' => date('Y-m-d H:i:s'), 'UPDATE_USER_ID' => $this->CreateUserID, 'UPDATE_TIME' => date('Y-m-d H:i:s'), 'PROD_TOP_ORG_ID' => $hotelInfo['hotel_info']['SUPPLIER_ID'], //酒店供应商ID 'ORDER_ID' => $order_id, 'ORDER_VALID_STATUS' => 1, 'ORDER_BOOK_STATUS' => 0, 'ORDER_PAY_STATUS' => 1, 'ORDER_PAY_MAIN_ID' => $main_order_id, 'ORDER_PAY_USER_ID' => $this->CreateUserID, 'ORDER_PAY_TIME' => date('Y-m-d H:i:s'), 'PARENT_ORDER_ID' => $main_order_id, //主订单号码 'PROD_ID' => $hotelInfo['hotel_info']['ROOM_TYPE'], //子房型ID room_type 'PARENT_PROD_ID' => $this->HotelID, 'PROD_NAME' => $hotelInfo['hotel_info']['ROOM_NAME'], //子房型名称 'PARENT_PROD_NAME' => $hotelInfo['hotel_info']['HOTEL_NAME'], //酒店名称, 'ORDER_PRICE' => $roomPrice[$run_date]['Price'], 'ORDER_PROD_TYPE' => OrderMain::ORDER_PROD_TYPE_SUM, 'PROD_SUPPLY_ORG_NAME' => $hotelInfo['hotel_info']['SUPPLIER_NAME'], //酒店供应商名称 'BASE_PRICE' => $base_price, 'MID_PRICE' => $fenxiao_commisssion, 'RUN_ID' => $this->RoomID, 'RUN_DATE' => $run_date, 'RUN_TIME' => $this->RunTime != '' ? date('H:i', $this->RunTime) : '0', //最晚到店 'RUN_BUS_SEAT_TYPE' => $stock_count <= $item['REMAINING_COUNT'] ? 1 : 2, //酒店:消耗渠道的库存类型:1:固定数量:2:超卖 'RUN_TIME_MINUTES' => $minutes, 'PROD_START_STATION_DATE' => $run_date, 'PROD_START_STATION_TIME_MINUTES' => 0, 'PROD_START_STATION_AREA_ID' => $hotelInfo['hotel_info']['AREA_ID'], 'PROD_START_STATION_AREA_NAME' => $hotelInfo['hotel_info']['AREA_NAME'], 'PROD_END_STATION_DATE' => $this->CheckOut, 'CUSTOMER_NAME' => $order_guests, 'CUSTOMER_MOBILE' => $this->ContactTel, 'CUSTOMER_MEMO' => '', 'ORDER_STATUS' => OrderMain::ORDER_STATUS_WAITING_SEND, 'IF_LAST_PROD' => $room_num['product_data']['GIFT_ID'], //是否有礼盒 'ORDER_LEVEL' => OrderMain::ORDER_LEVEL_SURE, 'OUTSIDE_ORDER_NO' => $this->OrderID, 'OUTSIDE_SALE_ORG_ID' => $this->DistribID, 'ORDER_TITLE_ID' => $this->OrderTitleID, 'STOCK_TYPE' => $stock_type, 'REFUSE_FLAG' => $flag === true ? 1 : 0, //$flag为true,说明订单是现询的,可以拒单 'PROFIT_VALUE' => ($roomPrice[$run_date]['Price'] - $base_price - $roomPrice[$run_date]['Commission'] - $fenxiao_commisssion), 'TOTAL_COMMISSION' => $roomPrice[$run_date]['Commission'], 'SALES_MAN' => $hotelInfo['hotel_info']['PURCHASE_NAME'], //采购人 'PRINCIPAL_ID' => $hotelInfo['hotel_info']['PRINCIPAL'] //运营负责人 ]; $total_commission += $roomPrice[$run_date]['Commission']; $total_profit_value += ($roomPrice[$run_date]['Price'] - $base_price - $roomPrice[$run_date]['Commission']); $orderMain = new OrderMain(); if ($orderMain->load($orderMainParam, '') && $orderMain->validate()) { if (!$orderMain->save()) { $msg = $this->getErrorMsg($orderMain); throw new \Exception($msg); } } else { $msg = $this->getErrorMsg($orderMain); throw new \Exception($msg); } } #endregion } //主订单中的订单描述 $description = $hotelInfo['hotel_info']['ROOM_NAME'] . ',' . $run_date . ',' . $this->RoomNum; $order_description .= $order_description == '' ? $description : '|' . $description; } #region 4、创建主订单 $orderMainParam['ID'] = $main_order_id; $orderMainParam['ORDER_ID'] = $main_order_id; $orderMainParam['ORDER_DESCRIPTION'] = $order_description; $orderMainParam['ORDER_PAY_MAIN_ID'] = $main_order_id; $orderMainParam['PARENT_ORDER_ID'] = 0; $orderMainParam['ORDER_PRICE'] = $total_price; $orderMainParam['ORDER_PROD_TYPE'] = OrderMain::ORDER_PROD_TYPE_MAIN; $orderMainParam['BASE_PRICE'] = $total_base_price; $orderMainParam['RUN_DATE'] = ''; $orderMainParam['RUN_TIME'] = ''; $orderMainParam['MID_PRICE'] = empty($this->Commission) ? 0 : $this->Commission; $orderMainParam['RUN_TIME_MINUTES'] = 0; $orderMainParam['PROD_START_STATION_DATE'] = $this->CheckIn; $orderMainParam['PROD_END_STATION_DATE'] = $this->CheckOut; $orderMainParam['STOCK_TYPE'] = 0; $orderMainParam['ORDER_TITLE_ID'] = $this->OrderTitleID; $orderMainParam['PROFIT_VALUE'] = $total_profit_value - (empty($this->Commission) ? 0 : $this->Commission); $orderMainParam['TOTAL_COMMISSION'] = $total_commission; $main_order = new OrderMain(); if ($main_order->load($orderMainParam, '') && $main_order->validate()) { if (!$main_order->save()) { $msg = $this->getErrorMsg($main_order); throw new \Exception($msg); } } else { $msg = $this->getErrorMsg($main_order); throw new \Exception($msg); } //记录订单的备注信息 if (!empty($this->Comment)) { if (is_array($this->Comment)) { //这里是为了对应CS系统下单的时候,可以同时保存两个不同类型的备注 foreach ($this->Comment as $comment_k => $comment_v) { //备注类型$comment_k 备注内容 $comment_v /*if (trim($comment_v['comment']) != '') { //代理通逻辑 $order_comment = new OrderComment(); if (in_array($comment_k, ['orderMemo', 'specialMemo', 'additionalList'])) { //针对渠道设置的渠道备注标识 $order_comment->SPECIAL_FLAG = $comment_k == 'orderMemo' ? (OrderComment::SPECIAL_FLAG_COMMENT) : ($comment_k == 'specialMemo' ? (OrderComment::SPECIAL_FLAG_SERVICE) : OrderComment::SPECIAL_FLAG_EXTRA); } $order_comment->ORDER_ID = $main_order_id; $order_comment->COMMENT_TXT = $comment_v['comment']; $order_comment->COMMENT_TYPE = $comment_v['comment_type']; $order_comment->CREATE_USER_ID = $this->CreateUserID; $order_comment->CREATE_TIME = date('Y-m-d', time()); $order_comment->UPDATE_USER_ID = $this->CreateUserID; $order_comment->save(); }*/ if(trim($comment_v)!=''){ $order_comment = new OrderComment(); $order_comment->ORDER_ID = $main_order_id; $order_comment->COMMENT_TXT = $comment_v; $order_comment->COMMENT_TYPE = $comment_k; $order_comment->CREATE_USER_ID = $this->CreateUserID; $order_comment->CREATE_TIME = date('Y-m-d', time()); $order_comment->UPDATE_USER_ID = $this->CreateUserID; $order_comment->save(); } } } else { $order_comment = new OrderComment(); if ($this->CommentType == 1) { //内部备注 $order_comment->COMMENT_TYPE = OrderComment::TYPE_INTERNAL; } elseif ($this->CommentType == 2) { //公共备注 $order_comment->COMMENT_TYPE = OrderComment::TYPE_PUBLIC; } else { //没有设置CommentTypede 情况,像携程等渠道 $order_comment->COMMENT_TYPE = OrderComment::TYPE_INTERNAL; } $order_comment->ORDER_ID = $main_order_id; $order_comment->COMMENT_TXT = $this->Comment; $order_comment->CREATE_USER_ID = $this->CreateUserID; $order_comment->CREATE_TIME = date('Y-m-d', time()); $order_comment->UPDATE_USER_ID = $this->CreateUserID; $order_comment->save(); } } #endregion //更新支付相关 $this->setPayInfo($main_order_id, $total_price); //记录日志 $msg = $this->OrderTitleID == 0 ? "创建订单号为{$main_order_id}的订单" : "创建订单号为{$main_order_id}的组合订单,组合订单号为{$this->OrderTitleID}"; $this->setOrderLog($main_order_id, $hotelInfo['hotel_info']['PARENT_ROOM_TYPE'], $hotelInfo['hotel_info']['ROOM_TYPE'], $msg); if ($this->PayType != OrderPayMain::PAY_TYPE_CASH && $this->PayType != OrderPayMain::PAY_TYPE_CREDIT) { $pay_type = $this->PayType == OrderPayMain::PAY_TYPE_ALIPAY ? '支付宝支付' : ($this->PayType == OrderPayMain::PAY_TYPE_WEIXIN ? '微信支付' : '支付'); $msg = "支付订单,{$pay_type}流水号:{$this->PayTradeNo}"; $this->setOrderLog($main_order_id, $hotelInfo['hotel_info']['PARENT_ROOM_TYPE'], $hotelInfo['hotel_info']['ROOM_TYPE'], $msg); } $statusLog = new OrderHtStatusLog(); $statusLog->CREATE_USER_ID = $this->CreateUserID; $statusLog->UPDATE_USER_ID = $this->CreateUserID; $statusLog->ORDER_STATUS = OrderMain::ORDER_STATUS_WAITING_SEND; $statusLog->ORDER_ID = $main_order_id; $statusLog->save(); //如果有发票信息,需要记录发票 if ($this->NeedInvoice) { $this->InvoiceInfos->InvoiceMoney = "$total_price"; $this->InvoiceInfos->CreateUseId = $this->CreateUserID; $this->InvoiceInfos->Status = 1; $this->InvoiceInfos->ChannelId = $this->DistribID; $this->InvoiceInfos->OrderID = $main_order_id; $this->InvoiceInfos->save(); } $transaction->commit(); //这里处理共享库存逻辑 //Notes:库存共享导致的部分渠道的库存大于基础房型的买断+保留 // 解决方案:将其他库存大于基础房型买断+保留的渠道库存设置为买断+保留 $main_order->UpdateStockByShare(['hotel_id' => $this->HotelID, 'check_in' => $this->CheckIn, 'check_out' => $this->CheckOut, 'distrib_id' => $this->DistribID, 'room_id' => $this->RoomID]); $soap_param = array('hotel_id' => $this->HotelID, 'parent_room_type' => $hotelInfo['hotel_info']['PARENT_ROOM_TYPE'], 'room_type' => $hotelInfo['hotel_info']['ROOM_TYPE'], 'begin_date' => $this->CheckIn, 'end_date' => $this->CheckOut, 'channel_id' => $this->DistribID); // 异步扣除预付款 zHttp::syncRequest(self::SEND_REQUEST_GET, Yii::$app->params['prepay_interface'], array('type' => self::MAKE_ORDER_DEDUCTION_TYPE, 'order_id' => $main_order_id)); // 异步推送房态接口 zHttp::syncRequest(self::SEND_REQUEST_GET, Yii::$app->params['push_info_interface'], array('param' => $soap_param)); } catch (\Exception $e) { $error = $e->getMessage(); $transaction->rollBack(); return ['code' => self::RETURN_CODE_PROGRAM_FAIL, 'info' => self::RETURN_MSG[self::RETURN_CODE_PROGRAM_FAIL]]; } } else { return ['code' => self::RETURN_CODE_PROGRAM_FAIL, 'info' => self::RETURN_MSG[self::RETURN_CODE_PROGRAM_FAIL]]; } return ['code' => self::RETURN_CODE_SUCCESS, 'info' => self::RETURN_CODE_SUCCESS, 'data' => ['order_id' => $main_order_id]]; } /** * Notes:取消订单 * User: Steven * Date: 2018/1/26 * Time: 13:58 * @return array|int * @throws Exception * @throws \Exception */ public function cancelHotelOrder() { //这里查询到的是主订单 $order_main = OrderMain::findOne([ 'OUTSIDE_ORDER_NO' => "{$this->OrderID}", 'ORDER_PROD_TYPE' => OrderMain::ORDER_PROD_TYPE_MAIN, 'PARENT_ORDER_ID' => 0, 'OUTSIDE_SALE_ORG_ID' => $this->DistribID, 'order_main.CANCEL_FLAG' => 0, ]); if (empty($order_main)) { //订单不存在 return self::RETURN_CODE_NOT_EXIST; } $this->setOrderLog($order_main->ORDER_ID, $this->RoomID, $order_main->PROD_ID, "渠道商申请取消订单:" . $order_main->ORDER_ID . ',原因:' . (empty($this->Reason) ? '无' : $this->Reason)); if ($order_main->CHANNEL_ORDER_STATUS == OrderMain::ORDER_CHANNEL_STATUS_APPLY_CANCEL_CONFIRMED) { //渠道接单状态是已取消 ,依然返回同意取消 $this->setOrderLog($order_main->ORDER_ID, $this->RoomID, $order_main->PROD_ID, '渠道状态已经变更为已取消,二次取消,同意取消' . "[{$order_main->CHANNEL_ORDER_STATUS}]/[{$order_main->ORDER_STATUS}]"); return self::RETURN_CODE_SUCCESS; } $white_list = OrderHtExceptionList::find()->where(['order_id' => $order_main->ORDER_ID])->one(); if ($white_list != null) { //加入白名单的直接同意取消即可 if ($white_list->status == OrderHtExceptionList::AGREE_CANCEL) { //同意取消 $channel_status = OrderMain::ORDER_CHANNEL_STATUS_APPLY_CANCEL_CONFIRMED; } else { //拒绝取消 $channel_status = OrderMain::ORDER_CHANNEL_STATUS_APPLY_CANCEL_REJECT; } //变更渠道的订单状态为已取消,但是不取消订单,即不回退库存,发人工退改申请 $count = OrderMain::updateAll(['CHANNEL_ORDER_STATUS' => $channel_status, 'UPDATE_TIME' => date('Y-m-d H:i:s', time())], ['ORDER_PROD_TYPE' => [25, 26], 'CANCEL_FLAG' => 0, 'OUTSIDE_ORDER_NO' => $this->OrderID, 'DOCKING_TYPE' => OrderMain::ORDER_TYPE_CHANNEL]); if ($count == 0) { throw new \Exception(); } if ($channel_status == OrderMain::ORDER_CHANNEL_STATUS_APPLY_CANCEL_CONFIRMED) { $this->setOrderLog($order_main->ORDER_ID, $this->RoomID, $order_main->PROD_ID, '该订单已加入白名单,白名单类型:同意取消,同意渠道取消。' . "[{$order_main->CHANNEL_ORDER_STATUS}]/[{$order_main->ORDER_STATUS}]"); return self::RETURN_CODE_SUCCESS; } else { $this->setOrderLog($order_main->ORDER_ID, $this->RoomID, $order_main->PROD_ID, '该订单已加入白名单,白名单类型:拒绝取消,拒绝渠道取消。' . "[{$order_main->CHANNEL_ORDER_STATUS}]/[{$order_main->ORDER_STATUS}]"); return self::RETURN_CODE_NOT_ALLOW_CANCEL; } } //白名单的订单不需要在这里直接取消订单,先同意渠道取消订单,然后人工发退改申请 if ($order_main->CHANNEL_ORDER_STATUS != OrderMain::ORDER_CHANNEL_STATUS_WAITING || !in_array($order_main->ORDER_STATUS, [OrderMain::ORDER_STATUS_NO_PAID, OrderMain::ORDER_STATUS_WAITING_SEND])) { //该情况不能退单 $this->setOrderLog($order_main->ORDER_ID, $this->RoomID, $order_main->PROD_ID, "拒绝渠道商取消订单:" . $order_main->ORDER_ID); return self::RETURN_CODE_NOT_ALLOW_CANCEL; } $transaction = Yii::$app->db->beginTransaction(); try { if ($order_main->ORDER_STATUS == OrderMain::ORDER_STATUS_WAITING_SEND) { //待发单 需要直接取消订单 $order_main->ORDER_STATUS = OrderMain::ORDER_STATUS_CANCEL; $order_main->ORDER_VALID_STATUS = 0; $cancel = $order_main->rollbackStocks(); if (!$cancel) { throw new \Exception(); } } $count = OrderMain::updateAll(['CHANNEL_ORDER_STATUS' => OrderMain::ORDER_CHANNEL_STATUS_APPLY_CANCEL_CONFIRMED, 'ORDER_VALID_STATUS' => $order_main->ORDER_VALID_STATUS, 'ORDER_STATUS' => $order_main->ORDER_STATUS, 'UPDATE_TIME' => date('Y-m-d H:i:s', time())], ['ORDER_PROD_TYPE' => [25, 26], 'CANCEL_FLAG' => 0, 'OUTSIDE_ORDER_NO' => $this->OrderID, 'DOCKING_TYPE' => OrderMain::ORDER_TYPE_CHANNEL]); if ($count == 0) { throw new \Exception(); } $this->setOrderLog($order_main->ORDER_ID, $this->RoomID, $order_main->PROD_ID, "同意渠道商取消订单:" . $order_main->ORDER_ID); $orderComment = new OrderComment(); $orderComment->ORDER_ID = $order_main->ORDER_ID; $orderComment->COMMENT_TYPE = OrderComment::TYPE_CANCEL_NOTE; $orderComment->COMMENT_TXT = $this->Reason; $orderComment->CREATE_USER_ID = $this->CreateUserID; $orderComment->UPDATE_USER_ID = $this->CreateUserID; $orderComment->save(); $transaction->commit(); return self::RETURN_CODE_SUCCESS; } catch (Exception $exception) { $transaction->rollBack(); $this->setOrderLog($order_main->ORDER_ID, $this->RoomID, $order_main->PROD_ID, "订单取消失败:" . $exception->getMessage() . $order_main->ORDER_ID); return self::RETURN_CODE_CANCEL_FAIL; } } /** * Notes:修改订单 * User: Steven * Date: 2018/1/4 * Time: 19:05 * @return array * @throws Exception */ public function updateHotelOrder() { // 修改订单之前保留预定单的信息,用于渠道预付款处理 //这里查询到的是主订单 $order_main = OrderMain::findOne([ 'ORDER_ID' => $this->ZZ_ORDER_ID, 'ORDER_PROD_TYPE' => OrderMain::ORDER_PROD_TYPE_MAIN, 'PARENT_ORDER_ID' => 0, 'order_main.CANCEL_FLAG' => 0, 'CANCEL_FLAG' => 0, ]); $child_order = OrderMain::findAll([ 'CANCEL_FLAG' => 0, 'PARENT_ORDER_ID' => $this->ZZ_ORDER_ID, 'ORDER_PROD_TYPE' => self::ORDER_PROD_TYPE_SUM, ]); $order_level = in_array($order_main['ORDER_STATUS'], array(198, 382)) ? OrderMain::ORDER_LEVEL_CHANGE : OrderMain::ORDER_LEVEL_SURE; $supplier = BaseSupplier::find()->select(['ID', 'SUPPLIER_NAME'])->andFilterWhere([ 'IN', 'ID', [$order_main->OUTSIDE_SALE_ORG_ID, $this->DistribID], ])->indexBy('ID')->asArray()->all(); $old_log_desc = ''; $old_supplier_name = $supplier[$order_main->OUTSIDE_SALE_ORG_ID]['SUPPLIER_NAME'] . "({$order_main->OUTSIDE_ORDER_NO}): "; $new_log_desc = ''; $new_supplier_name = $supplier[$this->DistribID]['SUPPLIER_NAME'] . "({$this->OrderID}): "; foreach ($child_order as $c_o) { $old_log_desc .= '【' . $c_o->RUN_DATE . '/' . $c_o->BASE_PRICE . '(采)/' . $c_o->ORDER_PRICE . '(销)' . '】;'; } $old_log_desc = $old_supplier_name . '
' . $old_log_desc; $transaction = Yii::$app->db->beginTransaction(); try { //回退库存 $resRollback = $order_main->rollbackStocks(); if (!$resRollback) { throw new Exception('修改失败'); } //下单并修改主订单和子订单 $child_order_count = OrderMain::updateAll([ 'CANCEL_FLAG' => 1, 'UPDATE_USER_ID' => $this->CREATE_USER_ID, 'UPDATE_TIME' => date('Y-m-d H:i:s', time()), ], [ 'CANCEL_FLAG' => 0, 'PARENT_ORDER_ID' => $this->ZZ_ORDER_ID, 'ORDER_PROD_TYPE' => self::ORDER_PROD_TYPE_SUM, ]); if ($child_order_count <= 0) { throw new Exception('修改失败'); } $flag = false; //标识是否设置订单为现询的(包括保留房和非保留房混合的情况,全是现询房) $data = $this->getProductData(); $hotelInfo = $this->getHotelInfo(); if ($data) { $stock_arr = []; //订单最终消耗的类型及数量 foreach ($data as $item) { //检查渠道是否授权 if (!$item['AUTHORITY_STATUS']) { return ['code' => 2, 'info' => '不可订,渠道未授权']; } //检查产品是否上线 if ($item['ROOM_IS_ONSALE'] == 0 || $item['ROOM_DAY_IS_ONSALE'] == 0 || $item['DISTRIB_DAY_IS_ONSALE'] == 0) { return ['code' => 3, 'info' => '不可订,产品已下线']; } //检查是否关房 if ($item['ROOM_RUN_STATUS'] == 0 || $item['DISTRIB_RUN_STATUS'] == 329) { //ROOM_RUN_STATUS=0 房型关房;DISTRIB_RUN_STATUS=329渠道关房 $desc = $item['ROOM_RUN_STATUS'] == 0 ? '满房' : '关房'; return ['code' => 4, 'info' => '不可订,该日期下房型已' . $desc]; } //判断库存 if (($item['BUYOUT'] + $item['RETAIN'] + $item['INQUIRY']) < $this->RoomNum) { //买断+保留库存和现询库存是不能同时消耗的 return ['code' => 5, 'info' => '不可订,基础房型库存不足!']; } if ($item['REMAINING_COUNT'] < $this->RoomNum && $item['OVERSELL_FLAG'] == 0) { //给渠道的库存不足且不允许超卖 return ['code' => 6, 'info' => '不可订,渠道房型库存不足!']; } //价格校验 if ($this->IfCheckPrice) { //渠道下单是需要校验的,其他:如自己的系统下单,不需要校验价格的 foreach ($this->RoomPrices as $val) { $newPrice = $item['SALE_TYPE'] == 177 ? $item['PROD_PRICE'] : $item['CUS_PRICE'];//分销选取分销价,其他选择零售价 if ($val['RUN_DATE'] == $item['RUN_DATE']) { if ($newPrice != $val['PRICE']) { return ['code' => 6, 'info' => '不可订,价格已更新,请刷新后重试!']; } } } } //订单最终消耗的类型及数量 if ($item['BUYOUT'] >= $this->RoomNum) { //只消耗买断 $stock_arr[$item['RUN_DATE']][CommonOrder::BUYOUT] = ['room_num' => $this->RoomNum, 'product_data' => $item]; } elseif (($item['BUYOUT'] + $item['RETAIN']) >= $this->RoomNum) { //消耗买断和保留 $stock_arr[$item['RUN_DATE']][CommonOrder::BUYOUT] = ['room_num' => $item['BUYOUT'], 'product_data' => $item]; $stock_arr[$item['RUN_DATE']][CommonOrder::REMAIN] = ['room_num' => $this->RoomNum - $item['BUYOUT'], 'product_data' => $item]; } elseif (($item['BUYOUT'] + $item['RETAIN'] + $item['INQUIRY']) >= $this->RoomNum) { //需要消耗买断+保留+现询 $stock_arr[$item['RUN_DATE']][CommonOrder::BUYOUT] = ['room_num' => $item['BUYOUT'], 'product_data' => $item]; $stock_arr[$item['RUN_DATE']][CommonOrder::REMAIN] = ['room_num' => $item['RETAIN'], 'product_data' => $item]; $stock_arr[$item['RUN_DATE']][CommonOrder::INQUIRY] = ['room_num' => $this->RoomNum - $item['BUYOUT'] - $item['RETAIN'], 'product_data' => $item]; } else { return ['code' => 5, 'info' => '不可订,基础房型库存不足!']; } } //创建订单 $order_description = ''; //主订单中的订单描述 $gift_flag = false; //标识是否有礼盒 只有某一天有礼盒,那么该订单都属于有礼盒 $total_base_price = ''; //总成本 $total_commission = ''; //总佣金 $total_profit_value = ''; //总利润 $total_price = 0; $prices = array_column($this->RoomPrices, 'Price'); foreach ($prices as $price) { $total_price += $price * $this->RoomNum; } if ($total_price != $this->TotalPrice) { throw new \Exception('传入的价格信息不符,总金额和间夜金额不符!'); } //更新库存 foreach ($stock_arr as $run_date => $stock) { $roomPrice = []; #region 计算佣金 foreach ($this->RoomPrices as $room_price) { if (isset($hotelInfo['commission'][BaseSupplier::BACK_COMMISION_METHOD_SALE])) {//按照销售额 按返佣比例计算 取百分比 $commission_rate = $hotelInfo['commission'][BaseSupplier::BACK_COMMISION_METHOD_SALE]; $commission = $room_price['Price'] * ($commission_rate / 100); } elseif (isset($hotelInfo['commission'][BaseSupplier::BACK_COMMISION_METHOD_SETTLE])) { $commission_rate = $hotelInfo['commission'][BaseSupplier::BACK_COMMISION_METHOD_SETTLE]; $commission = $commission_rate; } else { $commission = 0; } $roomPrice[$room_price['RunDate']] = [ 'Price' => $room_price['Price'], 'Commission' => round($commission, 2)]; } #endregion // 消耗库存 $distrib = RunHotelDistrib::findOne([ 'HOTEL_ID' => $this->HotelID, 'ROOM_TYPE' => $data[0]['ROOM_TYPE'], 'BASE_ROOM_TYPE' => $data[0]['BASE_ROOM_TYPE'], 'RUN_DATE' => $run_date, 'DISTRIB_ID' => $this->DistribID, ]); $distrib->SALED_COUNT += $this->RoomNum; //更新已售数量 #region 1、扣渠道的库存 if ($item['REMAINING_COUNT'] < $this->RoomNum) { //说明固定数量的库存小于客人所需的间数,这个时候,还需要消耗超卖的库存 $distrib->REMAINING_COUNT = 0; $flag = true; //这个订单标记为现询单 } else { //直接扣除固定数量 $distrib->REMAINING_COUNT = ($item['REMAINING_COUNT'] - $this->RoomNum); } if (!$distrib->save()) { $msg = $this->getErrorMsg($distrib); throw new \Exception($msg); } #endregion $stock_count = 0; foreach ($stock as $stock_type => $room_num) { if ($room_num['product_data']['GIFT_ID'] > 0) { $gift_flag = true; } #region 2、扣基础房型的库存 $runHotel = RunHotel::findOne([ 'HOTEL_ID' => $this->HotelID, 'BASE_ROOM_TYPE' => $data[0]['BASE_ROOM_TYPE'], 'RUN_DATE' => $run_date, 'STOCK_TYPE' => $stock_type, ]); if (empty($runHotel)) { continue; } $runHotel->SALED_COUNT += $room_num['room_num']; $runHotel->REMAINING_COUNT -= $room_num['room_num']; if (!$runHotel->save()) { $msg = $this->getErrorMsg($runHotel); throw new \Exception($msg); } #endregion //根据库存类型判断售卖单价 $base_price = $stock_type == 228 ? $room_num['product_data']['BASE_PRICE_BUYOUT'] : ($stock_type == 230 ? $room_num['product_data']['BASE_PRICE_RESERVE'] : ($stock_type == 230 ? $room_num['product_data']['BASE_PRICE_INQUIRY'] : $room_num['product_data']['BASE_PRICE_INQUIRY'])); $total_base_price += $base_price * $room_num['room_num']; //总成本价格 #region 3、创建子订单 for ($i = 1; $i <= $room_num['room_num']; $i++) { $stock_count++; $order_id = $this->getHotelOrderID(); //最晚到店时间 if ($this->RunTime != '') { $timeArr = explode(':', date('H:i', $this->RunTime)); $minutes = $timeArr[0] * 60 + $timeArr[1]; } else { $minutes = 0; } //入住人信息 $order_guests = ''; foreach ($this->OrderGuests as $Guest) { $order_guests .= $order_guests == '' ? $Guest['Name'] : ',' . $Guest['Name']; } $orderMainParam = [ 'ID' => $order_id, 'MAIN_CREATE_USER_ID' => $this->CreateUserID, 'CREATE_USER_ID' => $this->CreateUserID, //将子订单的创建时间 'CREATE_TIME' => $order_main->CREATE_TIME, 'UPDATE_USER_ID' => $this->CreateUserID, 'UPDATE_TIME' => date('Y-m-d H:i:s'), 'PROD_TOP_ORG_ID' => $hotelInfo['hotel_info']['SUPPLIER_ID'], //酒店供应商ID 'ORDER_ID' => $order_id, 'ORDER_VALID_STATUS' => 1, 'ORDER_BOOK_STATUS' => 0, 'ORDER_PAY_STATUS' => 1, 'ORDER_PAY_MAIN_ID' => $order_main->ORDER_ID, 'ORDER_PAY_USER_ID' => $this->CreateUserID, 'ORDER_PAY_TIME' => date('Y-m-d H:i:s'), 'PARENT_ORDER_ID' => $order_main->ORDER_ID, //主订单号码 'PROD_ID' => $hotelInfo['hotel_info']['ROOM_TYPE'], //子房型ID room_type 'PARENT_PROD_ID' => $this->HotelID, 'PROD_NAME' => $hotelInfo['hotel_info']['ROOM_NAME'], //子房型名称 'PARENT_PROD_NAME' => $hotelInfo['hotel_info']['HOTEL_NAME'], //酒店名称, 'ORDER_PRICE' => $roomPrice[$run_date]['Price'], 'ORDER_PROD_TYPE' => OrderMain::ORDER_PROD_TYPE_SUM, 'PROD_SUPPLY_ORG_NAME' => $hotelInfo['hotel_info']['SUPPLIER_NAME'], //酒店供应商名称 'BASE_PRICE' => $base_price, 'RUN_ID' => $this->RoomID, 'RUN_DATE' => $run_date, 'RUN_TIME' => $this->RunTime != '' ? date('H:i', $this->RunTime) : '0', //最晚到店 'RUN_BUS_SEAT_TYPE' => $stock_count <= $item['REMAINING_COUNT'] ? 1 : 2, //酒店:消耗渠道的库存类型:1:固定数量:2:超卖 'RUN_TIME_MINUTES' => $minutes, 'PROD_START_STATION_DATE' => $run_date, 'PROD_START_STATION_TIME_MINUTES' => 0, 'PROD_START_STATION_AREA_ID' => $hotelInfo['hotel_info']['AREA_ID'], 'PROD_START_STATION_AREA_NAME' => $hotelInfo['hotel_info']['AREA_NAME'], 'PROD_END_STATION_DATE' => $this->CheckOut, 'CUSTOMER_NAME' => $order_guests, 'CUSTOMER_MOBILE' => $this->ContactTel, 'CUSTOMER_MEMO' => '', 'ORDER_STATUS' => OrderMain::ORDER_STATUS_WAITING_CONFIRM, 'IF_LAST_PROD' => $room_num['product_data']['GIFT_ID'], //是否有礼盒 'ORDER_LEVEL' => $order_level, 'OUTSIDE_ORDER_NO' => $this->OrderID, 'OUTSIDE_SALE_ORG_ID' => $this->DistribID, 'STOCK_TYPE' => $stock_type, 'REFUSE_FLAG' => $flag === true ? 1 : 0, //$flag为true,说明订单是现询的,可以拒单 'PROFIT_VALUE' => ($roomPrice[$run_date]['Price'] - $base_price - $roomPrice[$run_date]['Commission']), 'TOTAL_COMMISSION' => $roomPrice[$run_date]['Commission'], 'SALES_MAN' => $hotelInfo['hotel_info']['PURCHASE_NAME'], //采购人 'PRINCIPAL_ID' => $hotelInfo['hotel_info']['PRINCIPAL'] //运营负责人 ]; $total_commission += $roomPrice[$run_date]['Commission']; $total_profit_value += ($roomPrice[$run_date]['Price'] - $base_price - $roomPrice[$run_date]['Commission']); $orderMain = new OrderMain(); if ($orderMain->load($orderMainParam, '') && $orderMain->validate()) { if (!$orderMain->save()) { $msg = $this->getErrorMsg($orderMain); throw new \Exception($msg); } } else { $msg = $this->getErrorMsg($orderMain); throw new \Exception($msg); } $new_log_desc .= '【' . $run_date . '/' . $base_price . '(采)/' . $roomPrice[$run_date]['Price'] . '(销)' . '】;'; } #endregion } //主订单中的订单描述 $description = $hotelInfo['hotel_info']['ROOM_NAME'] . ',' . $run_date . ',' . $this->RoomNum; $order_description .= $order_description == '' ? $description : '|' . $description; } #region 4、更新主订单 $order_main->UPDATE_TIME = date('Y-m-d H:i:s'); $order_main->ORDER_DESCRIPTION = $order_description; $order_main->PROD_TOP_ORG_ID = $hotelInfo['hotel_info']['SUPPLIER_ID']; $order_main->OUTSIDE_ORDER_NO = "{$this->OrderID}"; $order_main->PROD_ID = $hotelInfo['hotel_info']['ROOM_TYPE']; $order_main->PROD_NAME = $hotelInfo['hotel_info']['ROOM_NAME']; $order_main->ORDER_PRICE = $total_price; $order_main->BASE_PRICE = $total_base_price; $order_main->PROD_START_STATION_DATE = $this->CheckIn; $order_main->PROD_END_STATION_DATE = $this->CheckOut; $order_main->CUSTOMER_NAME = $order_guests; $order_main->CUSTOMER_MOBILE = $this->ContactTel; $order_main->PROFIT_VALUE = $total_profit_value; $order_main->TOTAL_COMMISSION = $total_commission; $order_main->IF_LAST_PROD = $gift_flag === true ? 1 : 0; $order_main->OUTSIDE_SALE_ORG_ID = $this->DistribID; $order_main->ORDER_LEVEL = $order_level; if (!$order_main->save()) { $msg = $this->getErrorMsg($order_main); throw new \Exception($msg); } //记录日志 $old_log_desc = "修改订单:由{$old_log_desc}"; $this->setOrderLog($order_main->ORDER_ID, $hotelInfo['hotel_info']['PARENT_ROOM_TYPE'], $hotelInfo['hotel_info']['ROOM_TYPE'], $old_log_desc); $new_log_desc = $new_supplier_name . '
' . $new_log_desc; $new_log_desc = "修改为:{$new_log_desc}"; $this->setOrderLog($order_main->ORDER_ID, $hotelInfo['hotel_info']['PARENT_ROOM_TYPE'], $hotelInfo['hotel_info']['ROOM_TYPE'], $new_log_desc); } else { return ['code' => 2, 'info' => '数据获取失败']; } //修改订单备注信息 //2018年5月15日:这里的修改备注信息目前只适用于代理通直连(CS修改订单备注有单独的接口,阿里不能修改订单) //并且,携程的订单备注不管有几条都会拼接成一条传过来 /*if (!empty($this->Comment)) { $comment_model = OrderComment::findOne(['ORDER_ID' => $this->ZZ_ORDER_ID, 'CANCEL_FLAG' => 0, 'SPECIAL_FLAG' => OrderComment::SPECIAL_FLAG_COMMENT, 'CREATE_USER_ID' => Yii::$app->params['ctrip']['base_user_id']]); $comment_model->UPDATE_TIME = date('Y-m-d H:i:s'); $comment_model->COMMENT_TXT = $this->Comment; $comment_model->SPECIAL_FLAG = OrderComment::SPECIAL_FLAG_COMMENT; $comment_model->save(); }*/ $transaction->commit(); // 下单渠道供应商预付款处理及房态推送处理 $soap_param = array('hotel_id' => $this->HotelID, 'parent_room_type' => $hotelInfo['hotel_info']['PARENT_ROOM_TYPE'], 'room_type' => $hotelInfo['hotel_info']['ROOM_TYPE'], 'begin_date' => $this->CheckIn, 'end_date' => $this->CheckOut, 'channel_id' => $this->DistribID); zHttp::syncRequest(self::SEND_REQUEST_GET, Yii::$app->params['prepay_interface'], array('type' => CommonOrder::UPDATE_ORDER_DEDUCTION_TYPE, 'order_id' => $order_main->ORDER_ID)); zHttp::syncRequest(self::SEND_REQUEST_GET, Yii::$app->params['push_info_interface'], array('param' => $soap_param)); return ['code' => 0, 'info' => '修改成功']; } catch (\Exception $e) { $error = $e->getMessage(); $transaction->rollBack(); $arr = array( "agentid" => 1000002, "title" => '修改订单失败', "msg" => "关联订单号:" . $order_main->ORDER_ID . "\n错误信息:" . $error, "touser" => 'wanglg'); zOfficeWechat::sendMsg($arr); return ['code' => 1, 'info' => $error]; } } /** * Notes:订单的操作日志 * User: Steven * Date: 2018/1/3 * Time: 13:16 * @param $order_id * @param $parent_room_type * @param $room_type * @param $msg * @return bool */ public function setOrderLog($order_id, $parent_room_type, $room_type, $msg, $user_id = "", $hotel_id = "") { $orderLog = new OperaHotelLog(); $orderLog->CREATE_USER_ID = empty($user_id) ? $this->CreateUserID : $user_id; $orderLog->HOTEL_ID = empty($this->HotelID) ? $hotel_id : $this->HotelID; $orderLog->LOG_TYPE = OperaHotelLog::LOG_TYPE_ORDER; $orderLog->ROOM_TYPE = $room_type; $orderLog->PARENT_ROOM_TYPE = $parent_room_type; $orderLog->LOG_DESC = $msg; $orderLog->ORDER_ID = $order_id; $orderLog->save(); return true; } /** * Notes: 下单设置支付相关的信息 * User: Steven * Date: 2018/1/2 * Time: 12:10 * @param $order_id * @param $total_price * @return bool */ public function setPayInfo($order_id, $total_price) { $payMain = new OrderPayMain(); $payMain->ID = $order_id; $payMain->CREATE_USER_ID = $this->CreateUserID; $payMain->UPDATE_USER_ID = $this->CreateUserID; $payMain->PAY_TOTAL = $total_price; $payMain->ORDER_ID = $order_id; $payMain->save(); $payDetail = new OrderPayDetail(); $payDetail->ID = $order_id; $payDetail->PAY_MAIN_ID = $payMain->ID; $payDetail->CREATE_USER_ID = $this->CreateUserID; $payDetail->UPDATE_USER_ID = $this->CreateUserID; $payDetail->PAY_TYPE_ID_1 = $this->PayType; $payDetail->PAY_MONEY = $total_price; $payDetail->PAY_SERIAL_NUMBER = $this->PayTradeNo == '' ? '0' : "{$this->PayTradeNo}"; //ORDER_PAY_STATUS 订单是否已支付,0未支付,1已支付 //ORDER_PAY_MAIN_ID 支付记录主ID,ORDER_PAY_MAIN.ID //ORDER_PAY_USER_ID 支付操作用户ID,BASE_USER.ID //ORDER_PAY_TIME 支付操作时间 $payDetail->save(); return true; } public function updateRoomQuantity() { } /** * Author:Steven * Desc:获取可定订检查的数据 * @return array|\yii\db\ActiveRecord[] */ public function getProductData() { $end_date = date('Y-m-d', strtotime($this->CheckOut . '-1 day')); $query = RunHotelDistrib::find() ->select(['a.DISTRIB_ID', 'a.HOTEL_ID', 'a.BASE_ROOM_TYPE', 'b.ROOM_TYPE', 'a.RUN_DATE', 'a.REMAINING_COUNT', 'a.PROD_PRICE', 'a.CUS_PRICE', 'a.RUN_STATUS as DISTRIB_RUN_STATUS', 'a.OVERSELL_FLAG', 'c.STOCK_TYPE', 'c.IS_ONSALE as ROOM_DAY_IS_ONSALE', 'b.IS_ONSALE as ROOM_IS_ONSALE', 'd.IS_ONSALE as DISTRIB_DAY_IS_ONSALE', 'd.RUN_STATUS as ROOM_RUN_STATUS', 'e.AUTHORITY_STATUS', 'a.GIFT_ID', 'f.SALE_TYPE', 'd.BASE_PRICE_BUYOUT', 'd.BASE_PRICE_RESERVE', 'd.BASE_PRICE_INQUIRY', 'SUM(case c.stock_type when 228 then c.remaining_count else 0 end) as BUYOUT', //买断 'SUM(case c.stock_type when 229 then c.remaining_count else 0 end) as INQUIRY', //现询 'SUM(case c.stock_type when 230 then c.remaining_count else 0 end) as RETAIN'//保留 ]) ->joinWith('operaHotelRoom b', false) ->joinWith(['runHotel c'], false) ->joinWith(['runHotelSubRoom d'], false) ->leftJoin('opera_room_distrib e', 'e.ROOM_ID=b.ID and e.DISTRIB_ID=a.DISTRIB_ID') ->leftJoin('base_supplier_sale f', 'a.DISTRIB_ID=f.SUPPLIER_ID and f.CANCEL_FLAG=0 and PARENT_TYPE=25') ->from('run_hotel_distrib a') ->where([ 'a.HOTEL_ID' => $this->HotelID, 'b.ID' => $this->RoomID, 'a.DISTRIB_ID' => $this->DistribID, ]); $query->andFilterWhere(['between', 'a.RUN_DATE', $this->CheckIn, $end_date])->groupBy('a.ID'); $sql = $query->createCommand()->getRawSql(); $data = $query->asArray()->all(); return $data; } /** * @Author wanglg * @Desc获取库存信息 * @return array */ public function getHotelStock() { // 获取查询结果集中的最小值 $end_date = date('Y-m-d', strtotime($this->CheckOut . '-1 day')); $query = RunHotelDistrib::find() ->select(['a.OVERSELL_FLAG', 'a.REMAINING_COUNT', 'a.PROD_PRICE', 'a.CUS_PRICE', 'a.RUN_DATE', 'a.REMAINING_COUNT DISTRIB_REMAINING_COUNT', 'b.ID', 'b.HOTEL_ID', 'b.PARENT_ROOM_TYPE', 'b.ROOM_TYPE', 'c.REMAINING_COUNT as BASE_REMAINING_COUNT', 'a.DISTRIB_ID', 'd.BASE_PRICE_BUYOUT', 'd.BASE_PRICE_INQUIRY', 'd.BASE_PRICE_RESERVE', 'f.SALE_TYPE', 'f.COMMISION_FLAG', 'f.COMMISION_TYPE', 'f.BACK_COMMISION_TYPE', 'f.BACK_COMMISION_METHOD', 'f.BACK_PERCENT', 'f.BACK_VALUE', 'SUM(case c.stock_type when 228 then c.remaining_count else 0 end) as BUYOUT', // 买断 'SUM(case c.stock_type when 229 then c.remaining_count else 0 end) as INQUIRY', // 现询 'SUM(case c.stock_type when 230 then c.remaining_count else 0 end) as RETAIN' // 保留 ]) ->leftJoin('opera_hotel_room b', 'a.HOTEL_ID=b.HOTEL_ID AND a.ROOM_TYPE=b.ROOM_TYPE AND b.PARENT_ROOM_TYPE=a.BASE_ROOM_TYPE') ->leftJoin('run_hotel c', 'b.HOTEL_ID=c.HOTEL_ID AND b.PARENT_ROOM_TYPE=c.BASE_ROOM_TYPE AND a.RUN_DATE=c.RUN_DATE') ->leftJoin('run_hotel_sub_room d', 'b.HOTEL_ID=d.HOTEL_ID and b.ROOM_TYPE=d.ROOM_TYPE and b.PARENT_ROOM_TYPE=d.BASE_ROOM_TYPE AND d.RUN_DATE=a.RUN_DATE') ->leftJoin('base_supplier_sale f', 'a.DISTRIB_ID=f.SUPPLIER_ID and f.CANCEL_FLAG=0 and f.PARENT_TYPE=25') ->from('run_hotel_distrib a') ->where(['b.ID' => $this->RoomID, 'a.DISTRIB_ID' => $this->DistribID, 'd.IS_ONSALE' => 1, 'b.IS_ONSALE' => 1, 'a.RUN_STATUS' => RunHotelDistrib::ROOM_STATUS_SALE, 'd.RUN_STATUS' => 1, 'c.IS_ONSALE' => 1, 'b.CANCEL_FLAG' => 0]); $query->andFilterWhere(['between', 'a.RUN_DATE', $this->CheckIn, $end_date]); $availStock = $query->groupBy(['a.RUN_DATE', 'b.ID'])->orderBy(['a.RUN_DATE' => SORT_ASC])->createCommand() ->queryAll(); return $availStock; } /** * @Author wanglg * @Desc 获取房型日期段内最少的库存数 * @return mixed */ public function getMinStock() { $availStock = $this->getHotelStock(); $arr = []; foreach ($availStock as $item) { $arr[] = $item['OVERSELL_FLAG'] == 1 ? $item['BUYOUT'] + $item['INQUIRY'] + $item['RETAIN'] : $item['REMAINING_COUNT']; } $minStock = empty($arr) ? 0 : min($arr); return $minStock; } public function dealStock($order_id, $request) { $this->load($request, ''); $availStock = $this->getChannelStock($order_id); $arr = []; foreach ($availStock as $item) { $arr[] = $item['OVERSELL_FLAG'] == 1 ? $item['BUYOUT'] + $item['INQUIRY'] + $item['RETAIN'] : $item['REMAINING_COUNT']; } $minStock = empty($arr) ? 0 : min($arr); return $minStock; } /** * @Author wanglg * @Desc 获取房型日期段内最少的库存数 * @return mixed */ public function getChannelStock($order_id) { $order_main = OrderMain::find() ->select(['ORDER_ID', 'RUN_BUS_SEAT_TYPE', 'OUTSIDE_SALE_ORG_ID', 'RUN_DATE', 'STOCK_TYPE', 'LATEST_COMFIRM_TIME', 'PARENT_PROD_ID', 'PARENT_ROOM_TYPE']) ->joinWith('operaHotelRoom', false) ->leftJoin('opera_room_distrib b', 'opera_hotel_room.ID=b.ROOM_ID AND b.DISTRIB_ID=order_main.OUTSIDE_SALE_ORG_ID') ->where(['PARENT_ORDER_ID' => $order_id, 'order_main.CANCEL_FLAG' => 0, 'ORDER_PROD_TYPE' => 26, 'ORDER_VALID_STATUS' => 1, 'ORDER_LEVEL' => [0, 1]]) ->from('order_main') ->asArray()->all(); $availStock = $this->getHotelStock(); // 如果渠道相同,库存需要+原订单房间数 foreach ($order_main as $value) { foreach ($availStock as $key => $stock) { // 保留房超过最晚立即确认时间库存不回退,即库存等于现有库存+订单消耗库存 if ($value['RUN_BUS_SEAT_TYPE'] == self::DISTRIB_STOCK_TYPE_RESERVE) { // 保留房库存 if (!empty($value['LATEST_COMFIRM_TIME']) && $value['LATEST_COMFIRM_TIME'] != -1) { //保留房设置了最晚预定时间 $time = explode(',', $value['LATEST_COMFIRM_TIME']); $date = date('Y-m-d', strtotime($value['RUN_DATE'] . "{$time[0]} days")); $last_confirm_time = $date . ' ' . $time[1]; if ($time >= strtotime($last_confirm_time)) { // 超过了最晚预定时间,保留房库存不回退,现询及买断照常回退 if ($value['STOCK_TYPE'] != self::STOCK_TYPE_RESERVE) { if ($value['STOCK_TYPE'] == self::STOCK_TYPE_BUYOUT && $value['RUN_DATE'] == $stock['RUN_DATE']) { $availStock[$key]['BUYOUT'] += 1; } elseif ($value['STOCK_TYPE'] == self::STOCK_TYPE_INQUIRY && $value['RUN_DATE'] == $stock['RUN_DATE']) { $availStock[$key]['INQUIRY'] += 1; } } } else { // 未设置保留房确认时间,保留房坤村照常回退 if ($value['STOCK_TYPE'] == self::STOCK_TYPE_BUYOUT && $value['RUN_DATE'] == $stock['RUN_DATE']) { $availStock[$key]['BUYOUT'] += 1; } elseif ($value['STOCK_TYPE'] == self::STOCK_TYPE_INQUIRY && $value['RUN_DATE'] == $stock['RUN_DATE']) { $availStock[$key]['INQUIRY'] += 1; } elseif ($value['STOCK_TYPE'] == self::STOCK_TYPE_RESERVE && $value['RUN_DATE'] == $stock['RUN_DATE']) { $availStock[$key]['RETAIN'] += 1; } } } else { if ($value['STOCK_TYPE'] == self::STOCK_TYPE_BUYOUT && $value['RUN_DATE'] == $stock['RUN_DATE']) { $availStock[$key]['BUYOUT'] += 1; } elseif ($value['STOCK_TYPE'] == self::STOCK_TYPE_INQUIRY && $value['RUN_DATE'] == $stock['RUN_DATE']) { $availStock[$key]['INQUIRY'] += 1; } elseif ($value['STOCK_TYPE'] == self::STOCK_TYPE_RESERVE && $value['RUN_DATE'] == $stock['RUN_DATE']) { $availStock[$key]['RETAIN'] += 1; } } } else { if ($value['STOCK_TYPE'] == self::STOCK_TYPE_BUYOUT && $value['RUN_DATE'] == $stock['RUN_DATE']) { $availStock[$key]['BUYOUT'] += 1; } elseif ($value['STOCK_TYPE'] == self::STOCK_TYPE_INQUIRY && $value['RUN_DATE'] == $stock['RUN_DATE']) { $availStock[$key]['INQUIRY'] += 1; } elseif ($value['STOCK_TYPE'] == self::STOCK_TYPE_RESERVE && $value['RUN_DATE'] == $stock['RUN_DATE']) { $availStock[$key]['RETAIN'] += 1; } } } } return $availStock; } /** * Notes:获取酒店的信息以及渠道的信息 * User: Steven * Date: 2017/12/29 * Time: 14:07 * @return array */ public function getHotelInfo() { $hotel_info = OperaHotelRoom::find()->select([ 'a.PARENT_ROOM_TYPE', 'a.ROOM_TYPE', 'a.ROOM_NAME', 'b.SUPPLIER_ID', 'b.HOTEL_NAME', 'd.SUPPLIER_NAME', 'b.PRINCIPAL', 'b.PURCHASE_NAME', 'b.AREA_ID', 'c.AREA_NAME']) ->leftJoin('opera_hotel b', 'a.HOTEL_ID=b.HOTEL_ID and b.CANCEL_FLAG=0') ->leftJoin('base_area c', 'b.AREA_ID=c.ID and c.CANCEL_FLAG=0') ->leftJoin('base_supplier d', 'b.SUPPLIER_ID=d.ID and d.CANCEL_FLAG=0') ->from('opera_hotel_room a') ->where(['a.ID' => $this->RoomID])->asArray()->one(); $supplier = BaseSupplier::find()->select([ 'a.SUPPLIER_NAME', 'b.SALE_TYPE', 'b.COMMISION_FLAG', 'b.COMMISION_TYPE', 'b.BACK_COMMISION_TYPE', 'b.BACK_COMMISION_METHOD', 'b.BACK_PERCENT', 'b.BACK_VALUE']) ->leftJoin('base_supplier_sale b', "b.SUPPLIER_ID=a.ID and b.PARENT_TYPE=25 and b.CANCEL_FLAG=0") ->from('base_supplier a')->where(['a.ID' => $this->DistribID])->asArray()->one(); if ($supplier['COMMISION_FLAG'] == 1 && $supplier['COMMISION_TYPE'] == BaseSupplier::COMMISION_TYPE_CHANNEL && $supplier['BACK_COMMISION_TYPE'] == BaseSupplier::BACK_COMMISION_TYPE_FIXED) { if ($supplier['BACK_COMMISION_METHOD'] == BaseSupplier::BACK_COMMISION_METHOD_SALE) { //按照销售额 按返佣比例计算 取百分比 $commission[BaseSupplier::BACK_COMMISION_METHOD_SALE] = $supplier['BACK_PERCENT']; } elseif ($supplier['BACK_COMMISION_METHOD'] == BaseSupplier::BACK_COMMISION_METHOD_SETTLE) { //按结算金额 按返佣固定金额 取固定金额 $commission[BaseSupplier::BACK_COMMISION_METHOD_SETTLE] = $supplier['BACK_VALUE']; } else { $commission[BaseSupplier::BACK_COMMISION_METHOD_SETTLE] = 0; } } else { $commission[BaseSupplier::BACK_COMMISION_METHOD_SETTLE] = 0; } return ['hotel_info' => $hotel_info, 'commission' => $commission]; } /** * Notes:获取酒店订单号 * User: Steven * Date: 2017/12/28 * Time: 18:01 * @return mixed * @throws \yii\db\Exception */ public function getHotelOrderID() { $conn = Yii::$app->db; $get_unique_id = "select func_get_unique_id(1,1) as unique_id"; //得到新的出车任务ID $data_id = $conn->createCommand($get_unique_id)->queryAll(); return $data_id[0]['unique_id']; } /** * @Author wanglg * @Desc 渠道预付款处理逻辑 * @param $type * @param $order_id * @param int $base_price * @param int $order_price * @param int $channel_id * @return array */ public function previousBalance($type, $order_id) { $model = new BaseBalance($order_id, '', ''); // 预付款处理之前判断是结算方式是否是预付,如果不是预付则不进行预付款处理 $supplier_info = OrderMain::find() ->select(['a.SETT_TYPE as cType', 'b.SETT_TYPE as sType']) ->joinWith('baseChannel a') ->joinWith('baseSupplier b') ->where(['ORDER_ID' => $order_id, 'order_main.CANCEL_FLAG' => 0, 'ORDER_PROD_TYPE' => OrderMain::ORDER_PROD_TYPE_MAIN, 'PARENT_ORDER_ID' => 0]) ->asArray()->one(); if (!isset($supplier_info)) { return array('code' => self::RETURN_CODE_OTHER, 'msg' => '未找到订单相关信息'); } if ($type == self::MAKE_ORDER_DEDUCTION_TYPE) { $model->memo = '下单扣款'; $model->pay_type = BaseBalance::STATUS_REDUCE; // 添加供应商与渠道商扣款记录,如果供应商预付则添加记录 if ($supplier_info['sType'] == 288) { $supplier_insert = $model->insertBalanceMain(); if ($supplier_insert['code'] != self::RETURN_CODE_SUCCESS) { return array('code' => self::RETURN_CODE_MAKE_ORDER, 'msg' => '下单供应商预付款处理失败'); } } // 渠道预付则添加记录 if ($supplier_info['cType'] == 288) { $channel_insert = $model->insertChannelBalanceMain(); if ($channel_insert['code'] != self::RETURN_CODE_SUCCESS) { return array('code' => self::RETURN_CODE_MAKE_ORDER, 'msg' => '下单渠道商预付款处理失败'); } } } elseif ($type == self::CANCEL_ORDER_DEDUCTION_TYPE) { $model->memo = '订单取消,金额回退'; $model->pay_type = BaseBalance::STATUS_ADD; if ($supplier_info['sType'] == 288) { $supplier_cancel = $model->cancelBalanceMain(); if ($supplier_cancel['code'] != self::RETURN_CODE_SUCCESS) { return array('code' => self::RETURN_CODE_CANCEL_ORDER, 'msg' => '取消单供应商预付款处理失败'); } } // 渠道预付则添加记录 if ($supplier_info['cType'] == 288) { $channel_cancel = $model->cancelChannelBalanceMain(); if ($channel_cancel['code'] != self::RETURN_CODE_SUCCESS) { return array('code' => self::RETURN_CODE_CANCEL_ORDER, 'msg' => '取消单渠道预付款处理失败'); } } } elseif ($type == self::UPDATE_ORDER_DEDUCTION_TYPE) { // 供应商扣款方式 if ($supplier_info['sType'] == 288) { $model->memo = '订单修改,金额回退'; $model->pay_type = BaseBalance::STATUS_ADD; $supplier_cancel = $model->cancelBalanceMain(); $model->memo = '订单修改,重新扣款'; $model->pay_type = BaseBalance::STATUS_REDUCE; // 供应商修改添加新纪录 $supplier_insert = $model->insertBalanceMain(); if (($supplier_cancel['code'] != self::RETURN_CODE_SUCCESS && $supplier_cancel['code'] == 3) || $supplier_insert['code'] != self::RETURN_CODE_SUCCESS) { return array('code' => self::RETURN_CODE_UPDATE_ORDER, 'msg' => '修改单供应商预付款处理失败'); } } // 渠道扣款方式 if ($supplier_info['cType'] == 288) { $model->memo = '订单修改,金额回退'; $model->pay_type = BaseBalance::STATUS_ADD; // 渠道商已扣款取消、回退处理 $channel_cancel = $model->cancelChannelBalanceMain(); $model->memo = '订单修改,重新扣款'; $model->pay_type = BaseBalance::STATUS_REDUCE; $channel_insert = $model->insertChannelBalanceMain(); if (($channel_cancel['code'] != self::RETURN_CODE_SUCCESS && $channel_cancel['code'] == 3) || $channel_insert['code'] != self::RETURN_CODE_SUCCESS) { return array('code' => self::RETURN_CODE_UPDATE_ORDER, 'msg' => '修改单渠道预付款处理失败!'); } } } else { return array('code' => self::ERROR_DEDUCTION_TYPE, 'msg' => self::RETURN_MSG[self::ERROR_DEDUCTION_TYPE]); } return array('code' => self::RETURN_CODE_SUCCESS, 'msg' => self::RETURN_MSG[self::RETURN_CODE_SUCCESS]); } /** * @Author wanglg * @Desc携程阿里直连统一推送接口 * @param $type标识推送的渠道 * @param array $param推送数据 */ public function pushRoomStatus(array $param = []) { /*$param = [ 'hotel_id' => '197', 'parent_room_type' => '150246', 'room_type' => '9', 'begin_date' => '2017-10-30', 'end_date' => '2017-11-11', 'channel_id' => 669, ];*/ if ($param['channel_id'] == Yii::$app->params['ctrip']['supplier_id']) { // 判断房型是否是携程直连有效,无效不推送 $connection_info = $this->hotelConnect($param); if (empty($connection_info['ChannelHotelId']) || empty($connection_info['ChannelRoomId'])) { return array('code' => 2, 'msg' => '酒店房型未直连,酒店信息:' . $param['hotel_id'] . ',基础房型信息:' . $param['parent_room_type'] . ',子房型信息' . $param['room_type']); } $status_data = ['hotel_id' => $param['hotel_id'], 'parent_room_type' => $param['parent_room_type'], 'room_type' => $param['room_type'], 'StartDate' => $param['begin_date'], 'EndDate' => $param['end_date']]; Yii::$app->runAction('hotel/ctrip/set-room-info', ['param' => $status_data]); Yii::$app->runAction('hotel/ctrip/set-room-price', ['param' => $status_data]); Yii::$app->runAction('hotel/ctrip/update-room-quantity', ['param' => $status_data]); } if ($param['channel_id'] == Yii::$app->params['ali']['supplier_id']) { // 判断房型是否是阿里直连有效,无效不推送房态 $connection_info = $this->hotelConnect($param); if (empty($connection_info['ChannelHotelId']) || empty($connection_info['ChannelRoomId']) || empty($connection_info['RP_ID'])) { return array('code' => 2, 'msg' => '酒店房型未直连,酒店信息:' . $param['hotel_id'] . ',基础房型信息:' . $param['parent_room_type'] . ',子房型信息' . $param['room_type']); } unset($param['channel_id']); $data[] = $param; $room_info['room_info'] = json_encode($data); Yii::$app->runAction('/hotel/ali/rates-update', ['param' => $room_info]); } } /** * Notes: * User: Steven * Date: 2018/1/22 * Time: 15:49 * @param $supplier * @return mixed */ public static function calCommision($supplier) { if ($supplier['COMMISION_FLAG'] == 1 && $supplier['COMMISION_TYPE'] == BaseSupplier::COMMISION_TYPE_CHANNEL && $supplier['BACK_COMMISION_TYPE'] == BaseSupplier::BACK_COMMISION_TYPE_FIXED) { if ($supplier['BACK_COMMISION_METHOD'] == BaseSupplier::BACK_COMMISION_METHOD_SALE) { //按照销售额 按返佣比例计算 取百分比 $commission[BaseSupplier::BACK_COMMISION_METHOD_SALE] = $supplier['BACK_PERCENT']; } elseif ($supplier['BACK_COMMISION_METHOD'] == BaseSupplier::BACK_COMMISION_METHOD_SETTLE) { //按结算金额 按返佣固定金额 取固定金额 $commission[BaseSupplier::BACK_COMMISION_METHOD_SETTLE] = $supplier['BACK_VALUE']; } else { $commission[BaseSupplier::BACK_COMMISION_METHOD_SETTLE] = 0; } } else { $commission[BaseSupplier::BACK_COMMISION_METHOD_SETTLE] = 0; } return $commission; } /** * @Author wanglg * @Desc 渠道直连信息查询 * @param $param数组信息:酒店id、基础房型id、子房型type、渠道id * @return array|null|\yii\db\ActiveRecord */ public function hotelConnect($param) { $select = []; $where = ''; // 如果是阿里 if ($param['channel_id'] == Yii::$app->params['ali']['supplier_id']) { $select = ['b.ChannelHotelId', 'c.ChannelRoomId', 'a.RP_ID']; $where = 'a.PARENT_ROOM_TYPE'; } elseif ($param['channel_id'] == Yii::$app->params['ctrip']['supplier_id']) { // 携程 $select = ['b.ChannelHotelId', 'c.ChannelRoomId']; $where = 'a.ID'; } $connect_info = OperaHotelRoom::find() ->select($select) ->leftJoin('channel_hotel_relation b', 'a.HOTEL_ID=b.HotelId and b.ChannelId=' . $param['channel_id']) ->leftJoin('channel_room_relation c', $where . '=c.RoomId AND c.ChannelId=' . $param['channel_id']) ->from('opera_hotel_room a') ->where(['a.CANCEL_FLAG' => 0, 'a.HOTEL_ID' => $param['hotel_id'], 'a.PARENT_ROOM_TYPE' => $param['parent_room_type'], 'a.ROOM_TYPE' => $param['room_type']]) ->asArray()->one(); return $connect_info; } } ?>