|
- <?php
- /**
- * Created by PhpStorm.
- * User: Steven
- * Date: 2017/12/25
- * Time: 18:40
- */
-
- namespace backend\modules\hotel\models;
-
- use backend\modules\api\logic\BaseBalance;
- use common\components\zOfficeWechat;
- use Yii;
- use yii\db\Exception;
- use backend\common\Utils;
- use common\components\zHttp;
-
- class CommonOrder extends OrderMain
- {
- public $HotelID; //酒店ID
- public $RoomID; //房型ID,opera_hotel_room中的ID
- public $RoomNum; //房间数量1
- public $CheckIn; //入住日期
- public $CheckOut; //离店日期
- public $DistribID; //渠道ID
- public $RoomPrices; //价格日历
- public $IfCheckPrice; //是否做价格校验
-
- public $ZZ_ORDER_ID; //我们系统的订单号(蜘蛛订单号)
-
- public $OrderID; //渠道订单号
- public $TotalPrice; //订单总价
- public $Currency; //币种
- public $ContactName; //联系人姓名
- public $ContactTel; //联系人电话
- public $OrderGuests; //入住人信息
- public $Comment; // 客人备注
- public $NeedInvoice; //是否需要开发票
- public $InvoiceInfos; //object 发票信息
- public $CreateUserID;
- public $RunTime; //最晚到店时间 格式2017-12-28 23:30:00
- public $PayType; //支付方式
- public $PayTradeNo; //支付流水号
- public $Reason; //订单取消原因
- public $CommentType; //备注类型 1:内部 2 外部
- public $Commission; //分销佣金
- public $OrderTitleID; //组合单号 如果不是组合订单,则为0,否则为组合单的订单号
-
-
- //返回值 该返回值为标准返回码,对渠道而言,需要根据渠道需要的
- const RETURN_CODE_SUCCESS = 0; //操作成功
- const RETURN_CODE_CANCEL_FAIL = 100; //取消失败/异常
- const RETURN_CODE_STOCK_FAIL = 101; //酒店满房/房量不足
- const RETURN_CODE_NOTICE_FAIL = 102; //备注不接受
- const RETURN_CODE_PRICE_FAIL = 103; //价格错误
- const RETURN_CODE_DATE_FAIL = 104; //日期错误/日期超过最大入住天数
- const RETURN_CODE_CHECKOUT = 105; //已入住不允许取消或修改
- const RETURN_CODE_EXPIRED = 106; //已过最晚取消修改时间
- const RETURN_CODE_NOT_EXIST = 107; //修改/取消原订单不存在
- const RETURN_CODE_PROGRAM_FAIL = 108; //程序错误
- const RETURN_CODE_NETWORK_FAIL = 109; //网络问题(程序错误)
- const RETURN_CODE_GUARANTEE_FAIL = 110; //担保错误
- const RETURN_CODE_HOTEL_CLOSED = 111; //酒店已停止合作
- const RETURN_CODE_MAPPING_FAIL = 112; //直连匹配错误(程序错误)
- const RETURN_CODE_REPEAT = 113; //重复预定
- const RETURN_CODE_NEED_TOTAL_GUARANTEE = 114; // 需要全额担保
- const RETURN_CODE_OVER_NUM = 115; //人数超限
- const RETURN_CODE_OVER_STOCK = 116; //客人当天累计已超间,请提供担保 重新预订
- const RETURN_CODE_SYSTEM_FAIL = 117; //服务器运行错误(程序错误)
- const RETURN_CODE_AUTH_FAIL = 118; //用户认证或授权错误(程序错误)
- const RETURN_CODE_PARAMS_FAIL = 119; //参数错误(程序错误)
- const RETURN_CODE_INFO_FAIL = 120; //预订信息不正确
- const RETURN_CODE_NOT_ALLOW_UPDATE = 121; //订单不允许修改
- const RETURN_CODE_NOT_ALLOW_CANCEL = 122; //订单不允许取消
- const RETURN_CODE_NEED_ALL_GUARANTEE = 123; //需要一律担保
- const RETURN_CODE_BREAKFAST_FAIL = 124; //早餐不一致
- const RETURN_CODE_CURRENCY_FAIL = 125; //币种错误
- const RETURN_CODE_UNAUTHORIZED = 126; //渠道未授权
- const RETURN_CODE_ROOM_CLOSED = 127; //房型已下线
- const RETURN_CODE_OTHER = 9999; //其他
- const RETURN_CODE_MAKE_ORDER = 180; // 下单扣款
- const RETURN_CODE_CANCEL_ORDER = 181; // 取消单扣款
- const RETURN_CODE_UPDATE_ORDER = 182; // 修改单扣款
- const SEND_REQUEST_GET = 1; // 请求类型GET
- const SEND_REQUEST_POST = 2; // 请求类型POST
-
-
- CONST RETURN_MSG = [
- self::RETURN_CODE_SUCCESS => '操作成功',
- 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 . '<br>' . $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 . '<br>' . $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;
- }
- }
-
- ?>
|