'订单号', ]; } /** * 指定校验场景 * @return array */ public function scenarios() { $parentScenarios = parent::scenarios(); $customScenarios = [ // // 管理员发货 // 'adminDelivery' => ['sn', 'expressCompany', 'orderTrackNo'], // // 会员确认收货 // 'userConfirm' => ['sn', 'expressCompany', 'orderTrackNo'], // // 管理员修改订单状态 // 'adminStatus' => ['sn', 'status'], // // 管理员修改备注 // 'adminRemark' => ['sn', 'remark'], // // 会员下单 // 'userOrder' => ['type','addressId', 'payType','goodsId','goodsNum', 'remark', 'payPassword'], // // 帮会员复消下单 // 'reconsumeOrder' => ['type','userName', 'payType','goodsId','goodsNum', 'remark', 'payPassword','consignee','acceptMobile','province','city','county','detailaddress'], ]; return array_merge($parentScenarios, $customScenarios); } /** * @throws Exception */ public function returnOrder() { if(!$this->validate()){ return null; } $sn = $this->orderSn; // 获取订单详情 $orderInfo = Order::findUseDbCalc() ->select('ID,DEC_SN,SN,USER_ID,ORDER_TYPE,IS_DELETE,PAY_AMOUNT,PAY_TYPE,ORDER_AMOUNT,USER_NAME,PV,PAY_PV,PERIOD_NUM,PROVINCE,CITY,COUNTY,ADDRESS,STATUS,NOTE,ORDER_CATEGORY,CREATE_USER') ->where("SN=:SN", [':SN' => $sn]) ->asArray() ->one(); $approachOrderInfo = []; // 如果是PayStack支付,订单是未支付状态,则去中间表查询,如果两个表都没有数据,订单不存在 if (!$orderInfo) { $approachOrderInfo = ApproachOrder::findUseDbCalc() ->select('ID,DEC_SN,SN,USER_ID,ORDER_TYPE,IS_DELETE,PAY_AMOUNT,PAY_TYPE,ORDER_AMOUNT,USER_NAME,PV,PAY_PV,PERIOD_NUM,PROVINCE,CITY,COUNTY,ADDRESS,STATUS,NOTE,ORDER_CATEGORY,CREATE_USER') ->where("SN=:SN", [':SN' => $sn]) ->asArray() ->one(); } if (!$orderInfo && !$approachOrderInfo) { throw new Exception('订单不存在'); } $orderInfo = $orderInfo ?: $approachOrderInfo; // 如果会员已经是锁定状态了,删除订单的时候,是否还要退还金额 $db = \Yii::$app->db; $transaction = $db->beginTransaction(); try { $userId = $orderInfo['USER_ID']; $decInfo = []; $isLock = 0 ; // 是否锁定会员单 // 如果是注册订单,则删除订单并退还金额,然后再冻结用户 if ($orderInfo['ORDER_TYPE'] == 'ZC') { // 查询报单数据,因为如果是报单,则要退还给报单中心 if (!$approachOrderInfo) { $decInfo = DecOrder::findUseDbCalc() ->select('USER_ID,TO_USER_ID,DETAIL_TYPE,UPGRADE_TYPE,ORI_LV,UPGRADE_LV') ->where("ORDER_SN=:ORDER_SN", [':ORDER_SN' => $sn]) ->asArray() ->one(); // 删除报单 $delDecOrder = DecOrder::updateAll( ['IS_DEL'=>1, 'DELETED_AT'=>Date::nowTime()], 'ORDER_SN=:ORDER_SN', ['ORDER_SN'=>$sn] ); } else { $decInfo = ApproachDecOrder::findUseDbCalc() ->select('USER_ID,TO_USER_ID,DETAIL_TYPE,UPGRADE_TYPE,ORI_LV,UPGRADE_LV') ->where("ORDER_SN=:ORDER_SN", [':ORDER_SN' => $sn]) ->asArray() ->one(); // 删除报单 $delDecOrder = ApproachDecOrder::updateAll( ['IS_DEL'=>1, 'DELETED_AT'=>Date::nowTime()], 'ORDER_SN=:ORDER_SN', ['ORDER_SN'=>$sn] ); } $userId = $decInfo['USER_ID']; if (!$delDecOrder) { $transaction->rollBack(); throw new Exception(\Yii::t('ctx', 'shopDeleteDecOrderAndOrderFailedNotice')); } // 支付成功才需要处理 if ($orderInfo['STATUS'] == \Yii::$app->params['orderStatus']['paid']['value']) { // 如果删除的是升级单,则需要回退用户的级别 if ($decInfo['DETAIL_TYPE'] == 2) { $oriLv = $decInfo['ORI_LV']; $userModel = User::findOne(['ID' => $orderInfo['USER_ID']]); $userModel->DEC_LV = $oriLv; $userModel->UPDATED_AT = Date::nowTime(); if(!$userModel->save(false)) { $transaction->rollBack(); throw new Exception(\Yii::t('ctx', 'shopBackOrderFailedNotice')); } } else { // 锁定用户 $userModel = User::findOne(['ID' => $orderInfo['USER_ID']]); $userModel->STATUS = 0; $userModel->STATUS_AT = Date::nowTime(); if(!$userModel->save(false)) { $transaction->rollBack(); throw new Exception(\Yii::t('ctx', 'shopLockFailedDeleteOrderFailed')); } $isLock = 1; } } // PayStack支付退单不处理 } else if (!$approachOrderInfo && $orderInfo['ORDER_CATEGORY'] === 'STUDIO') { // 工作室复消:退款给下单人 $createUser = User::findOneAsArray('USER_NAME=:USER_NAME', [':USER_NAME' => $orderInfo['CREATE_USER']]); if (!$createUser) { $transaction->rollBack(); throw new Exception('删除订单失败。查找下单人失败'); } $userId = $createUser['ID']; } if (!$approachOrderInfo) { // 公共的退钱,删除订单操作 $delOrder = Order::updateAll( ['IS_DELETE' => 1, 'DELETED_AT' => Date::nowTime()], 'SN=:SN', ['SN' => $sn] ); } else { // 公共的退钱,删除订单操作 $delOrder = ApproachOrder::updateAll( ['IS_DELETE' => 1, 'DELETED_AT' => Date::nowTime()], 'SN=:SN', ['SN' => $sn] ); } if (!$delOrder) { $transaction->rollBack(); throw new Exception(\Yii::t('ctx', 'shopDeleteOrderFailed')); } $payType = $orderInfo['PAY_TYPE']; // 支付方式 if ($payType != 'pay_stack') { // 记录退还前的账户原资金 $cash = $point = $bonus = $exchange = 0; $userBonus = UserBonus::findUseSlaves() ->select('BONUS,RECONSUME_POINTS,EXCHANGE_POINTS') ->where('USER_ID=:USER_ID', [':USER_ID' => $userId]) ->asArray() ->one(); if ($userBonus) { $point = $userBonus['RECONSUME_POINTS']; $bonus = $userBonus['BONUS']; $exchange = $userBonus['EXCHANGE_POINTS']; } $cashWallet = UserWallet::findOneAsArray('USER_ID=:USER_ID', [':USER_ID' => $userId], 'CASH'); if ($cashWallet) { $cash = $cashWallet['CASH']; } // 开始退钱,退积分等 $payAmount = $orderInfo['PAY_AMOUNT']; // 支付的金额 //退还 if ($payType == 'cash') { $amountResult = Cash::changeUserCash($userId, 'CASH', +abs($payAmount), ['REMARK' => '退货退还余额', 'ORDER_SN' => $orderInfo['SN']]); } else if ($payType == 'exchange') { $amountResult = Balance::changeUserBonus($userId, 'exchange_points', +abs($payAmount), ['DEAL_TYPE_ID' => DealType::EXCHANGE_POINTS_EXCHANGE, 'REMARK' => '退货退还无业绩兑换点数', 'ORDER_SN' => $orderInfo['SN']]); } else { $amountResult = Balance::changeUserBonus($userId, 'reconsume_points', +abs($payAmount), ['DEAL_TYPE_ID' => DealType::RECONSUME_POINTS_EXCHANGE, 'REMARK' => '退货退还复销点数', 'ORDER_SN' => $orderInfo['SN']]); } if ($amountResult !== true) { $transaction->rollBack(); throw new Exception(\Yii::t('ctx', 'shopBackAmountFailedDeleteOrderFailed')); } $upgradeType = 0; // 升级单类型 $returnLv = ''; $oriLvs = ''; if (!empty($decInfo)) { $upgradeType = $decInfo['UPGRADE_TYPE']; $returnLv = $decInfo['ORI_LV']; $oriLvs = $decInfo['UPGRADE_LV']; } // 退款成功,记录数据信息 $periodObj = Period::instance(); $nowPeriodNum = $periodObj->getNowPeriodNum(); $returnOrderModel = new ReturnOrder(); $returnOrderModel->ID = SnowFake::instance()->generateId(); $returnOrderModel->SN = $sn; $returnOrderModel->DEC_SN = $orderInfo['DEC_SN']; $returnOrderModel->CREATE_AT = Date::nowTime(); $returnOrderModel->ORDER_TYPE = $orderInfo['ORDER_TYPE']; $returnOrderModel->ORDER_AMOUNT = $orderInfo['ORDER_AMOUNT']; $returnOrderModel->PV = $orderInfo['PV']; $returnOrderModel->PAY_PV = $orderInfo['PAY_PV']; $returnOrderModel->PAY_AMOUNT = $orderInfo['PAY_AMOUNT']; $returnOrderModel->PAY_TYPE = $orderInfo['PAY_TYPE']; $returnOrderModel->USER_ID = $orderInfo['USER_ID']; $returnOrderModel->PERIOD_NUM = $nowPeriodNum; $returnOrderModel->PAY_STATUS = $orderInfo['STATUS']; $returnOrderModel->PAY_NOTE = $orderInfo['NOTE']; $returnOrderModel->ORDER_PERIOD_NUM = $orderInfo['PERIOD_NUM']; $returnOrderModel->UPGRADE_TYPE = $upgradeType; $returnOrderModel->USER_NAME = $orderInfo['USER_NAME']; $returnOrderModel->PROVINCE = $orderInfo['PROVINCE']; $returnOrderModel->CITY = $orderInfo['CITY'] ?? 0; $returnOrderModel->COUNTY = $orderInfo['COUNTY'] ?? 0; $returnOrderModel->ADDRESS = $orderInfo['ADDRESS'] ?? ''; $returnOrderModel->ADMIN_ID = \Yii::$app->user->id; $returnOrderModel->ORI_CASH = $cash; $returnOrderModel->ORI_BONUS = $bonus; $returnOrderModel->ORI_EXCHANGE_POINTS = $exchange; $returnOrderModel->ORI_RECONSUME_POINTS = $point; $returnOrderModel->ORI_DEC_LV = $oriLvs; $returnOrderModel->RETURN_DEC_LV = $returnLv; $returnOrderModel->IS_LOCKING = $isLock; if (!$returnOrderModel->save()) { $transaction->rollBack(); $this->addErrors($returnOrderModel->getErrors()); return false; } } else { // 如果是PayStack支付,只处理支付成功的 $upgradeType = 0; // 升级单类型 $returnLv = ''; $oriLvs = ''; if (!empty($decInfo)) { $upgradeType = $decInfo['UPGRADE_TYPE']; $returnLv = $decInfo['ORI_LV']; $oriLvs = $decInfo['UPGRADE_LV']; } // 退款成功,记录数据信息 $periodObj = Period::instance(); $nowPeriodNum = $periodObj->getNowPeriodNum(); $returnOrderModel = new ReturnOrder(); $returnOrderModel->ID = SnowFake::instance()->generateId(); $returnOrderModel->SN = $sn; $returnOrderModel->DEC_SN = $orderInfo['DEC_SN']; $returnOrderModel->CREATE_AT = Date::nowTime(); $returnOrderModel->ORDER_TYPE = $orderInfo['ORDER_TYPE']; $returnOrderModel->ORDER_AMOUNT = $orderInfo['ORDER_AMOUNT']; $returnOrderModel->PV = $orderInfo['PV']; $returnOrderModel->PAY_PV = $orderInfo['PAY_PV']; $returnOrderModel->PAY_AMOUNT = $orderInfo['PAY_AMOUNT']; $returnOrderModel->PAY_TYPE = $orderInfo['PAY_TYPE']; $returnOrderModel->USER_ID = $orderInfo['USER_ID']; $returnOrderModel->PERIOD_NUM = $nowPeriodNum; $returnOrderModel->PAY_STATUS = $orderInfo['STATUS']; $returnOrderModel->PAY_NOTE = $orderInfo['NOTE']; $returnOrderModel->ORDER_PERIOD_NUM = $orderInfo['PERIOD_NUM']; $returnOrderModel->UPGRADE_TYPE = $upgradeType; $returnOrderModel->USER_NAME = $orderInfo['USER_NAME']; $returnOrderModel->PROVINCE = $orderInfo['PROVINCE']; $returnOrderModel->CITY = $orderInfo['CITY'] ?? 0; $returnOrderModel->COUNTY = $orderInfo['COUNTY'] ?? 0; $returnOrderModel->ADDRESS = $orderInfo['ADDRESS'] ?? ''; $returnOrderModel->ADMIN_ID = \Yii::$app->user->id; $returnOrderModel->ORI_CASH = 0; $returnOrderModel->ORI_BONUS = 0; $returnOrderModel->ORI_EXCHANGE_POINTS = 0; $returnOrderModel->ORI_RECONSUME_POINTS = 0; $returnOrderModel->ORI_DEC_LV = $oriLvs; $returnOrderModel->RETURN_DEC_LV = $returnLv; $returnOrderModel->IS_LOCKING = $isLock; if (!$returnOrderModel->save()) { $transaction->rollBack(); $this->addErrors($returnOrderModel->getErrors()); return false; } } $transaction->commit(); } catch(Exception $e) { $transaction->rollBack(); $this->addError('add', $e->getMessage()); return null; } return true; } // 判断订单类型 public function checkOrderType($attribute) { $sn = $this->orderSn; $orderDetail = Order::findUseDbCalc() ->select('ID,DEC_SN,USER_ID,ORDER_TYPE,IS_DELETE,PERIOD_NUM') ->where("SN=:SN", [':SN' => $sn]) ->asArray() ->one(); $approachOrderDetail = []; if (!$orderDetail) { $orderDetail = $approachOrderDetail = ApproachOrder::findUseDbCalc() ->select('ID,DEC_SN,USER_ID,ORDER_TYPE,IS_DELETE,PERIOD_NUM') ->where("SN=:SN", [':SN' => $sn]) ->asArray() ->one(); } if (empty($orderDetail)) { $this->addError($attribute, \Yii::t('ctx', 'shopNotFindOrder').$this->orderSn); return ; } if ($orderDetail['IS_DELETE'] == 1) { $this->addError($attribute, \Yii::t('ctx', 'shopOrderAlreadyDeleted').$this->orderSn); return ; } // 已挂网或者挂网中的业绩期订单,不能进行删除操作 $periodNum = $orderDetail['PERIOD_NUM']; $periodObj = Period::findOneAsArray(['PERIOD_NUM'=>$periodNum]); if (empty($periodObj)) { $this->addError($attribute, \Yii::t('ctx', 'shopOrderPeriodNumNotExist', [ 'sn' => $this->orderSn, 'periodNum' => $periodNum ])); return ; } if ($periodObj['IS_SENT'] == 1) { $this->addError($attribute, \Yii::t('ctx', 'shopOrderPeriodNumIsSented', [ 'sn' => $this->orderSn, 'periodNum' => $periodNum ])); return ; } if ($periodObj['IS_SENDING'] == 1) { $this->addError($attribute, \Yii::t('ctx', 'shopOrderPeriodNumSenting', [ 'sn' => $this->orderSn, 'periodNum' => $periodNum ])); return ; } if ($orderDetail['ORDER_TYPE'] == 'ZC') { if (!$approachOrderDetail) { $decDetail = DecOrder::findUseDbCalc() ->select('TO_USER_ID,DETAIL_TYPE,UPGRADE_TYPE,IS_DEL') ->where("ORDER_SN=:ORDER_SN", [':ORDER_SN' => $sn]) ->asArray() ->one(); } else { $decDetail = ApproachDecOrder::findUseDbCalc() ->select('TO_USER_ID,DETAIL_TYPE,UPGRADE_TYPE,IS_DEL') ->where("ORDER_SN=:ORDER_SN", [':ORDER_SN' => $sn]) ->asArray() ->one(); } if (empty($decDetail)) { $this->addError($attribute, \Yii::t('ctx', 'shopNotFindDecOrder').$this->orderSn); return ; } if ($decDetail['IS_DEL'] == 1) { $this->addError($attribute, \Yii::t('ctx', 'shopDecAlreadyDeleted').$this->orderSn); return ; } if ($decDetail['DETAIL_TYPE'] == 2) { if (!$approachOrderDetail) { // 如果删除升级单,则此升级单必须是用户的最后一个升级单 $lastUpgradeOrder = DecOrder::findUseDbCalc() ->select('ORDER_SN') ->where("TO_USER_ID=:TO_USER_ID AND IS_DEL=0 AND DETAIL_TYPE=2", [':TO_USER_ID' => $decDetail['TO_USER_ID']]) ->orderBy('CREATED_AT DESC') ->asArray() ->one(); } else { // 如果删除升级单,则此升级单必须是用户的最后一个升级单 $lastUpgradeOrder = ApproachDecOrder::findUseDbCalc() ->select('ORDER_SN') ->where("TO_USER_ID=:TO_USER_ID AND IS_DEL=0 AND DETAIL_TYPE=2", [':TO_USER_ID' => $decDetail['TO_USER_ID']]) ->orderBy('CREATED_AT DESC') ->asArray() ->one(); } $lastUpgradeSn = $lastUpgradeOrder['ORDER_SN']; if ($sn != $lastUpgradeSn) { $this->addError($attribute, \Yii::t('ctx', 'shopHasLaterOrder').$this->orderSn); return ; } } else { // 如果是注册单,但是这个用户存在升级单,则也不能进行删除 if (!$approachOrderDetail) { $hasUpgradeOrder = DecOrder::findUseDbCalc() ->select('TO_USER_ID,DETAIL_TYPE,UPGRADE_TYPE,IS_DEL') ->where("TO_USER_ID=:TO_USER_ID AND IS_DEL=0 AND DETAIL_TYPE=2", [':TO_USER_ID' => $decDetail['TO_USER_ID']]) ->asArray() ->one(); } else { $hasUpgradeOrder = ApproachDecOrder::findUseDbCalc() ->select('TO_USER_ID,DETAIL_TYPE,UPGRADE_TYPE,IS_DEL') ->where("TO_USER_ID=:TO_USER_ID AND IS_DEL=0 AND DETAIL_TYPE=2", [':TO_USER_ID' => $decDetail['TO_USER_ID']]) ->asArray() ->one(); } if (!empty($hasUpgradeOrder)) { $this->addError($attribute, \Yii::t('ctx', 'shopRegisterHasUpgradeOrder').$this->orderSn); return ; } if (!$approachOrderDetail) { // 删除注册单,判断是否有复消单,如果存在复消单,需要先删除复消单 $hasFxOrder = Order::findUseDbCalc() ->select('SN') ->where("USER_ID=:USER_ID AND IS_DELETE=0 AND ORDER_TYPE='FX'", [':USER_ID' => $decDetail['TO_USER_ID']]) ->asArray() ->one(); } else { // 删除注册单,判断是否有复消单,如果存在复消单,需要先删除复消单 $hasFxOrder = ApproachOrder::findUseDbCalc() ->select('SN') ->where("USER_ID=:USER_ID AND IS_DELETE=0 AND ORDER_TYPE='FX'", [':USER_ID' => $decDetail['TO_USER_ID']]) ->asArray() ->one(); } if (!empty($hasFxOrder)) { $this->addError($attribute, \Yii::t('ctx', 'shopRegisterHasFxOrder').$this->orderSn); return ; } } } return true; } }