'操作成功',
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;
}
}
?>