'订单号', ]; } /** * 指定校验场景 * @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); } public function returnOrder() { if(!$this->validate()){ return null; } $sn = $this->orderSn; // 获取订单详情 $orderInfo = Order::findUseDbCalc() ->select('ID,DEC_SN,USER_ID,ORDER_TYPE,IS_DELETE') ->where("SN=:SN", [':SN' => $sn]) ->asArray() ->one(); // 如果是注册订单,则删除订单并退还金额,然后再冻结用户 // 如果是复消单,则删除订单并退还金额 } /** * 判断支付方式 * @param $attribute */ public function isPayType($attribute){ if(!array_key_exists($this->payType, ShopGoods::payTypes())){ $this->addError($attribute, '支付方式错误'); return; } } // 判断订单类型 public function checkOrderType($attribute) { $sn = $this->orderSn; $orderDetail = Order::findUseDbCalc() ->select('ID,DEC_SN,USER_ID,ORDER_TYPE,IS_DELETE') ->where("SN=:SN", [':SN' => $sn]) ->asArray() ->one(); if (empty($orderDetail)) { $this->addError($attribute, '未找到订单信息,订单编号为:'.$this->orderSn); return ; } if ($orderDetail['IS_DELETE'] == 1) { $this->addError($attribute, '订单已被删除,订单编号为'.$this->orderSn); return ; } // 已挂网或者挂网中的业绩期订单,不能进行删除操作 $periodNum = $orderDetail['PERIOD_NUM']; $periodObj = Period::findOneAsArray(['PERIOD_NUM'=>$periodNum]); if (empty($periodObj)) { $this->addError($attribute, '订单对应业绩期不存在,订单编号为'.$this->orderSn.' 业绩期为:'.$periodNum); return ; } if ($periodObj['IS_SENT'] == 1) { $this->addError($attribute, '订单对应业绩期已挂网,订单编号为'.$this->orderSn.' 业绩期为:'.$periodNum); return ; } if ($periodObj['IS_SENDING'] == 1) { $this->addError($attribute, '订单对应业绩期正在挂网,订单编号为'.$this->orderSn.' 业绩期为:'.$periodNum); return ; } if ($orderDetail['ORDER_TYPE'] == 'ZC') { $decDetail = DecOrder::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, '未获取到对应报单信息,订单编号为:'.$this->orderSn); return ; } if ($decDetail['IS_DEL'] == 1) { $this->addError($attribute, '对应报单信息已被删除,订单编号为:'.$this->orderSn); return ; } // 如果是注册订单,则判断是否是升级单,如果是升级单,则不能进行删除 if ($decDetail['DETAIL_TYPE'] == 2) { $this->addError($attribute, '升级单无法删除,订单编号为:'.$this->orderSn); return ; } else { // 如果是注册单,但是这个用户存在升级单,则也不能进行删除 $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(); if (!empty($hasUpgradeOrder)) { $this->addError($attribute, '此注册报单用户,存在升级单,无法删除,订单编号为:'.$this->orderSn); return ; } // 删除注册单,判断是否有复消单,如果存在复消单,需要先删除复消单 $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(); if (!empty($hasFxOrder)) { $this->addError($attribute, '此注册报单用户,存在复消单,无法删除,订单编号为:'.$this->orderSn); return ; } } } return true; } /** * 校验类型 * @param $attribute */ public function isStatus($attribute){ if(!in_array($this->type, \Yii::$app->params['orderStatus'])){ $this->addError($attribute, '类型错误'); return ; } if ($this->scenario == 'adminStatus'){ if ($this->status == $this->_model['STATUS']) { $this->addError($attribute, '订单状态没有改变'); return ; } if($this->status == \Yii::$app->params['orderStatus']['notPaid'] && $this->_model['STATUS'] >= \Yii::$app->params['orderStatus']['delivery']) { $this->addError($attribute, '订单已经进入物流状态不能改为未支付'); return ; } elseif($this->status == \Yii::$app->params['orderStatus']['paid'] && $this->_model['STATUS'] >= \Yii::$app->params['orderStatus']['cancel']) { $this->addError($attribute, '订单已失效不能处理'); return ; } elseif($this->status == \Yii::$app->params['orderStatus']['delivery']) { $this->addError($attribute, '订单不能单独处理为物流状态'); return ; } elseif($this->status == \Yii::$app->params['orderStatus']['complete'] && $this->_model['STATUS'] > \Yii::$app->params['orderStatus']['cancel']) { $this->addError($attribute, '订单已失效不能处理'); return ; } elseif($this->status == \Yii::$app->params['orderStatus']['cancel']) { if($this->_model['STATUS'] == \Yii::$app->params['orderStatus']['complete']) { $this->addError($attribute, '订单已完成不能取消'); return ; } if($this->_model['STATUS'] == \Yii::$app->params['orderStatus']['del']) { $this->addError($attribute, '订单已删除不能取消'); return ; } } elseif($this->status == \Yii::$app->params['orderStatus']['del']) { if($this->_model['STATUS'] == \Yii::$app->params['orderStatus']['complete']) { $this->addError($attribute, '订单已完成不能删除'); return ; } } } } /** * 帮会员复销 * @return bool|null * @throws Exception * @throws \yii\db\Exception */ public function reconsumeAdd(){ if(!$this->validate()){ return null; } $ids = $this->goodsId; $totalAmount = 0; $totalPv = 0; $goodsType = ShopGoods::GOODS_TYPE; foreach ($this->goodsNum as $k => $v) { if ($v) { $goods = ShopGoods::findOneAsArray('ID=:ID AND STATUS=1',[':ID'=> $ids[$k]]); if($goods['STORE_NUMS']>0){ if ($goods['TYPE'] == 1 || $goods['TYPE'] == 2) { $discount = $goodsType[$goods['TYPE']]['discount']; $realPrice = $goods['SELL_PRICE'] * $discount/100; $realPv = $goods['PRICE_PV'] * $discount/100; } else { $discount = $goods['SELL_DISCOUNT']; $realPrice = $goods['SELL_PRICE'] * $discount; $realPv = $goods['PRICE_PV'] * $discount; } $totalAmount += $realPrice * intval($v); $totalPv += $realPv * intval($v); $this->_orderGoods[] = [ 'GOODS_ID' => $goods['ID'], 'PRICE' => $goods['SELL_PRICE'], 'PV' => $goods['PRICE_PV'], 'REAL_PRICE' => $realPrice, 'REAL_PV' => $realPv, 'POINT' => $goods['POINT'], 'BUY_NUMS' => intval($v), 'SKU_CODE' => $goods['GOODS_NO'], 'GOODS_TITLE' => $goods['GOODS_NAME'] ]; } } } $this->_decAmount = $totalAmount; $this->_decPv = $totalPv; $this->_freight = ($totalAmount>=300) ? 0 : 15; $this->_payAmount = $this->_decAmount + $this->_freight; $db = \Yii::$app->db; $transaction = $db->beginTransaction(); try { $loginUserId = \Yii::$app->user->id; //是否开启伞下会员限制 $isResaleUmbrella = Cache::getSystemConfig()['isResaleUmbrella']['VALUE']; if($isResaleUmbrella){ $userId = Info::getUserIdByUserName($this->userName); $userNetwork = UserNetwork::find()->where("USER_ID=:USER_ID AND INSTR(PARENT_UIDS,'{$loginUserId}')>0", ['USER_ID'=>$userId])->count(); if(!$userNetwork){ throw new Exception($this->userName.'不是您的伞下会员,不能为其复消!'); } } //判断用户余额是否充足 if($this->payType=='cash') { if (Cash::getAvailableBalance($loginUserId) < $this->_payAmount) { throw new Exception('余额不足,无法购买商品'); } }else{ if ($this->_payAmount > Balance::getBalanceReconsumePoints($loginUserId)) { throw new Exception('复消积分不足,无法购买商品'); } } //写入订单 if (!$orderResult = $this->addUserOrder()) { throw new Exception(Form::formatErrorsForApi($orderResult->getErrors())); } $transaction->commit(); }catch (\Exception $e){ $transaction->rollBack(); $this->addError('add', $e->getMessage()); return null; } return true; } /** * 帮会员复消的订单 */ public function addUserOrder(){ $periodObj = Period::instance(); $nowPeriodNum = $periodObj->getNowPeriodNum(); $nowCalcMonth = $periodObj->getYearMonth($nowPeriodNum); //帮复消会员Id(登陆会员) $loginUserId = \Yii::$app->user->id; $loginUserName = Info::getUserNameByUserId($loginUserId); //订单会员Id $userId = Info::getUserIdByUserName($this->userName); // 加入订单信息 $warehouse = Region::getWarehouseByCode($this->province);//仓库 if(!$warehouse){ throw new Exception('地区暂时不支持配送,具体联系客服'); } $ordNo = $this->_generateSn(); $orderModel = new Order(); $orderModel->SN = 'OS'.$ordNo; $orderModel->DEC_SN = 'DS'.$ordNo; $orderModel->ORDER_TYPE = $this->type; $orderModel->USER_ID = $userId; $orderModel->USER_NAME = $this->userName; $orderModel->ORDER_AMOUNT = $this->_decAmount; $orderModel->PV = $this->_decPv; $orderModel->PAY_AMOUNT = $this->_payAmount; $orderModel->PAY_PV = $this->_decPv; $orderModel->PAY_AT = Date::nowTime(); $orderModel->PAY_TYPE = $this->payType; $orderModel->PERIOD_NUM = $nowPeriodNum; $orderModel->P_CALC_MONTH = Date::ociToDate($nowCalcMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH); $orderModel->FREIGHT = $this->_freight; $orderModel->PAY_FREIGHT = $this->_freight; $orderModel->CONSIGNEE = $this->consignee; $orderModel->MOBILE = $this->acceptMobile; $orderModel->PROVINCE = $this->province; $orderModel->CITY = $this->city; $orderModel->COUNTY = $this->county; $orderModel->ADDRESS = $this->detailaddress; $orderModel->FRONT_REMARK = $this->remark; $orderModel->WAREHOUSE = $warehouse; $orderModel->STATUS = 1; $orderModel->CREATED_AT = Date::nowTime(); $orderModel->CREATE_USER = $loginUserName; if(!$orderModel->save()){ $this->addErrors($orderModel->getErrors()); return false; } // 加入商品到订单商品表 foreach($this->_orderGoods as $key=>$value){ $this->_orderGoods[$key]['ORDER_SN'] = $orderModel->SN; $this->_orderGoods[$key]['P_CALC_MONTH'] = Date::ociToDate($nowCalcMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH); } OrderGoods::batchInsert($this->_orderGoods); //扣除会员余额/积分 if($this->payType=='cash') { Cash::changeUserCash($loginUserId, 'CASH', -abs($this->_payAmount), ['REMARK' => '会员复销余额支付']); }else{ Balance::changeUserBonus($loginUserId,'reconsume_points', -abs($this->_payAmount),['DEAL_TYPE_ID' => DealType::RECONSUME_POINTS_EXCHANGE, 'REMARK' => '会员复销积分兑换']); } return $orderModel; } /** * 生成流水号 * @return string */ private function _generateSn() { return Date::today('Ymd') . $this->_random(10, 1); } /** * 生成随机数 * @param $length * @param int $numeric * @return string */ private function _random($length, $numeric = 0) { $seed = base_convert(md5(microtime() . $_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35); $seed = $numeric ? (str_replace('0', '', $seed) . '012340567890') : ($seed . 'zZ' . strtoupper($seed)); $hash = ''; $max = strlen($seed) - 1; for ($i = 0; $i < $length; $i++) { $hash .= $seed[mt_rand(0, $max)]; } return $hash; } }