adminOperateLogger = new AdminOperate([ 'fetchClass' => Order::class, ]); } /** * @inheritdoc */ public function rules() { return [ [['sn', 'expressCompany', 'orderTrackNo', 'status', 'remark','type','addressId','payType','goodsId','goodsNum', 'payPassword','userName','consignee','acceptMobile','province'/*,'city','county'*/,'cityName','lgaName','detailaddress','email','decUserName'], 'trim'], [['sn', 'expressCompany', 'orderTrackNo', 'status', 'remark','type','addressId','payType','goodsId','goodsNum', 'payPassword','consignee','acceptMobile','province','city','county','detailaddress'/*,'email'*/,'decUserName'], 'required'], [['status'], 'isStatus'], [['addressId'], 'isAddress'], [['payType'], 'isPayType'], [['payPassword'], 'validatePassword'], ]; } public function attributeLabels() { return [ 'sn' => Yii::t('app', 'orderSn'), 'expressCompany' => Yii::t('app', 'expressCompany'), 'orderTrackNo' => Yii::t('app', 'orderTrackNo'), 'status' => Yii::t('app', 'state'), 'remark' => Yii::t('app', 'remark'), 'type' => Yii::t('app', 'orderType'), 'addressId' => Yii::t('app', 'shippingAddress'), 'payType' => Yii::t('app', 'payType'), 'goodsId' => Yii::t('app', 'productID'), 'goodsNum' => Yii::t('app', 'quantity'), 'userName' => Yii::t('app', 'repeatSalesMemberNo'), 'consignee' => Yii::t('app', 'consignee'), 'acceptMobile' => Yii::t('app', 'acceptMobile'), 'province' => Yii::t('app', 'province'), 'city' => Yii::t('app', 'city'), 'county' => Yii::t('app', 'county'), 'lgaName' =>Yii::t('app', 'lgaName'), 'cityName' => Yii::t('app', 'cityName'), 'detailaddress' => Yii::t('app', 'detailAddress'), 'email' => Yii::t('app', 'email'), 'decUserName' => Yii::t('app', 'decUserName'), ]; } /** * 指定校验场景 * @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', 'period'], // 帮会员复消下单 'reconsumeOrder' => ['type','userName', 'payType','goodsId','goodsNum', 'remark', 'payPassword','consignee','acceptMobile','province','cityName','lgaName','detailaddress','decUserName'], // 管理员退款 'adminRefund' => ['sn'], // AMP 'autoMaintenanceOrder' => ['type', 'userName', 'payType', 'goodsId', 'goodsNum', 'remark', 'payPassword', 'consignee', 'acceptMobile', 'province', 'cityName', 'lgaName', 'detailaddress', 'decUserName'], ]; return array_merge($parentScenarios, $customScenarios); } /** * 校验之前 * @return bool */ public function beforeValidate() { $parentValidate = parent::beforeValidate(); if ($this->sn) { $this->_model = Order::findOne(['SN'=>$this->sn]); if (!$this->_model){ $this->addError('sn', Yii::t('app', 'orderDoesNotExist')); return false; } } if ($this->scenario == 'adminDelivery'){ if($this->_model['STATUS'] == \Yii::$app->params['orderStatus']['cancel']) { $this->addError('sn', Yii::t('app', 'orderHasBeenCancelCanNotDeliver')); return false; } if($this->_model['STATUS'] == \Yii::$app->params['orderStatus']['del']) { $this->addError('sn', Yii::t('app', 'orderHasBeenDeleteCanNotDeliver')); return false; } } if ($this->scenario == 'adminRefund'){ if ($this->_model['STATUS'] != \Yii::$app->params['orderStatus']['paid']['value']) { $this->addError('sn', Yii::t('app', 'orderPayStatusDoesNotSupportRefund')); return false; } if ($this->_model['DELIVERY_STATUS'] != \Yii::$app->params['deliveryStatus']['notDelivery']['value']) { $this->addError('sn', Yii::t('app', 'orderLogisticsStatusDoesNotSupportRefund')); return false; } if ($this->_model['PAY_TYPE'] != 'pay_stack') { $this->addError('sn', Yii::t('app', 'orderPayTypeDoesNotSupportRefund')); return false; } if (!$this->_model['REMARK']) { $this->addError('sn', Yii::t('app', 'paymentInfoDoesNotExists')); return false; } } return $parentValidate; } /** * 校验支付密码 * @param $attribute * @param $params */ public function validatePassword($attribute, $params) { if (!User::validatePayPassword(\Yii::$app->user->id, $this->payPassword)) { $this->addError($attribute, Yii::t('app', 'paymentPasswordError')); } } /** * 判断收货地址是否存在 * @param $attribute */ public function isAddress($attribute){ if (!$receiveAddress = ReceiveAddress::find()->where(' ID=:ID', [':ID' => $this->addressId])->asArray()->one()) { $this->addError($attribute, Yii::t('app', 'shippingDoesNotExist')); } else { $this->_address = $receiveAddress; } } /** * 判断支付方式 * @param $attribute * @throws Exception */ public function isPayType($attribute){ if(!array_key_exists($this->payType, ShopGoods::payTypes())){ $this->addError($attribute, Yii::t('app', 'payTypeError')); return; } // 一个订单只能包含一类商品 $goods = ShopGoods::find()->select('ID,CATEGORY_TYPE')->where(['in', 'ID', $this->goodsId])->andWhere(['STATUS' => 1])->asArray()->all(); if (!$goods) { throw new Exception(Yii::t('app', 'productsDoesSoldOut')); return; } $goodsCategoryType = array_unique(array_column($goods, 'CATEGORY_TYPE')); if (count($goodsCategoryType) > 1) { $this->addError($attribute, Yii::t('app', 'orderCanNotHasMoreClassification')); return; } // 购买方式 $sellTypeLabelMap = array_column(ShopGoods::getSaleType(), NULL, 'label'); if (!array_key_exists($this->payType, $sellTypeLabelMap)) { $this->addError($attribute, Yii::t('app', 'payTypeError')); return; } // 所选支付方式必须是商品分类支持的类型 $categoryType = array_column(ShopGoods::CATEGORY_TYPE, NULL, 'id'); // 商品类型 $currCategoryType = $goodsCategoryType[0]; if (!array_key_exists($currCategoryType, $categoryType)) { $this->addError($attribute, Yii::t('app', 'shopGoodClassificationError')); return; } $sellType = $categoryType[$currCategoryType]['sell_type'] ?? []; if (!$sellType || !in_array($this->payType, array_column($sellType, 'label'))) { $this->addError($attribute, Yii::t('app', 'payTypeError')); return; } } /** * 校验类型 * @param $attribute */ public function isStatus($attribute){ if(!in_array($this->type, \Yii::$app->params['orderStatus'])){ $this->addError($attribute, Yii::t('app', 'orderStatusTypeError')); return ; } if ($this->scenario == 'adminStatus'){ if ($this->status == $this->_model['STATUS']) { $this->addError($attribute, Yii::t('app', 'orderStatusDoesNotChange')); return ; } if($this->status == \Yii::$app->params['orderStatus']['notPaid'] && $this->_model['STATUS'] >= \Yii::$app->params['orderStatus']['delivery']) { $this->addError($attribute, Yii::t('app', 'orderHasBeenLogisticsStatusDoesNotChangedUnpaid')); return ; } elseif($this->status == \Yii::$app->params['orderStatus']['paid'] && $this->_model['STATUS'] >= \Yii::$app->params['orderStatus']['cancel']) { $this->addError($attribute, Yii::t('app', 'orderHasBeenInvalidCanNotProcess')); return ; } elseif($this->status == \Yii::$app->params['orderStatus']['delivery']) { $this->addError($attribute, Yii::t('app', 'orderCanNotBeenChangedLogistics')); return ; } elseif($this->status == \Yii::$app->params['orderStatus']['complete'] && $this->_model['STATUS'] > \Yii::$app->params['orderStatus']['cancel']) { $this->addError($attribute, Yii::t('app', 'orderHasBeenInvalidCanNotProcess')); return ; } elseif($this->status == \Yii::$app->params['orderStatus']['cancel']) { if($this->_model['STATUS'] == \Yii::$app->params['orderStatus']['complete']) { $this->addError($attribute, Yii::t('app', 'orderHasBeenFinishedCanNotCancel')); return ; } if($this->_model['STATUS'] == \Yii::$app->params['orderStatus']['del']) { $this->addError($attribute, Yii::t('app', 'orderHasBeenDeletedCanNotCancel')); return ; } } elseif($this->status == \Yii::$app->params['orderStatus']['del']) { if($this->_model['STATUS'] == \Yii::$app->params['orderStatus']['complete']) { $this->addError($attribute, Yii::t('app', 'orderHasBeenFinishedCanNotDelete')); return ; } } } } /** * 管理员发货 * @return Order|null * @throws \yii\db\Exception */ public function adminDelivery(){ if(!$this->validate()){ return null; } $db = \Yii::$app->db; $transaction = $db->beginTransaction(); try { $period = Period::instance(); $this->_model->DELIVERY_STATUS = \Yii::$app->params['deliveryStatus']['delivered']['value']; $this->_model->DELIVERY_PERIOD = $period->getNowPeriodNum(); $this->_model->DELIVERY_AT = Date::nowTime(); $this->_model->EXPRESS_COMPANY = $this->expressCompany; $this->_model->ORDER_TRACK_NO = $this->orderTrackNo; $this->_model->STATUS = \Yii::$app->params['orderStatus']['delivery']['value']; if(!$this->_model->save()){ throw new Exception(Form::formatErrorsForApi($this->_model->getErrors())); } $transaction->commit(); } catch (Exception $e) { $transaction->rollBack(); $this->addError('edit', $e->getMessage()); return null; } return $this->_model; } /** * 校验支付 * @return Order|null * @throws Exception */ public function verifyPayStack(): ?Order { if(!$this->validate()){ return null; } // 调用PayStack支付校验 $payload = PayStack::transactionVerify($this->remark['reference']); if ($payload['status'] !== true) { throw new Exception(Form::formatErrorsForApi($payload['message'])); } if ($payload['data']['amount'] != $this->_model->PAY_AMOUNT * 100) { throw new Exception(Form::formatErrorsForApi(Yii::t('app', 'payAmountNotEqualOrderAmount'))); } $db = \Yii::$app->db; $transaction = $db->beginTransaction(); try { $this->_model->STATUS = \Yii::$app->params['orderStatus']['paid']['value']; $this->_model->REMARK = json_encode($this->remark); $this->_model->PAY_AT = Date::nowTime(); if (!$this->_model->save()) { throw new Exception(Form::formatErrorsForApi($this->_model->getErrors())); } $transaction->commit(); } catch (Exception $e) { $transaction->rollBack(); $this->addError('edit', $e->getMessage()); return null; } return $this->_model; } /** * 订单退款 * @return Order|null * @throws Exception */ public function adminRefund() { if(!$this->validate()){ return null; } // 支付信息存在于remark中 $remark = $this->_model->REMARK ? json_decode($this->_model->REMARK, true) : []; $reference = $remark['reference'] ?? ''; if (!$reference) { throw new Exception(Form::formatErrorsForApi(Yii::t('app', 'paymentInfoDoesNotExists'))); } // 退款金额. 订单支付金额 * 100 $amount = $this->_model->PAY_AMOUNT * 100; // 调用PayStack支付校验 $payload = PayStack::transactionRefund($reference, $amount); if ($payload['status'] !== true) { throw new Exception(Form::formatErrorsForApi($payload['message'])); } $db = \Yii::$app->db; $transaction = $db->beginTransaction(); try { $this->_model->STATUS = \Yii::$app->params['orderStatus']['refund']['value']; $this->_model->REMARK = json_encode([ 'payment' => $remark, 'refund' => $payload['data'] ] ); if (!$this->_model->save()) { throw new Exception(Form::formatErrorsForApi($this->_model->getErrors())); } $transaction->commit(); } catch (Exception $e) { $transaction->rollBack(); $this->addError('edit', $e->getMessage()); return null; } return $this->_model; } /** * BV分期 * * */ private function _pvSplit($oPv){ $sysConfig = Cache::getSystemConfig(); $mesureUpCondition = $sysConfig['monthPcsPvFxCondition']['VALUE']; if($oPv>$mesureUpCondition){ $currentPv = $oPv % $mesureUpCondition + $mesureUpCondition; $remainPv = $oPv - $currentPv; }else{ $currentPv = $oPv; $remainPv = 0; } return [ 'current' => $currentPv, 'remain' => $remainPv ]; } /** * 复销 * @throws Exception * @throws \yii\db\Exception */ public function add(){ if(!$this->validate()){ return null; } $ids = $this->goodsId; $totalAmount = 0; $totalPv = 0; $totalRealPv = 0; $totalAmountStandard = 0; $goodsType = ShopGoods::getGoodType(); $this->_remainPv = 0; $hasInstalment = 0; $loginUserId = \Yii::$app->user->id; $user = User::getEnCodeInfo(\Yii::$app->user->id); foreach ($this->goodsNum as $k => $v) { if ($v) { $goods = ShopGoods::findOneAsArray('ID=:ID AND STATUS=1',[':ID'=> $ids[$k]]); if (!$goods) { throw new Exception(Yii::t('app', 'productsDoesSoldOut')); } $goodsNature = ShopGoodsNature::findOneAsArray('GOODS_ID=:GOODS_ID AND COUNTRY_ID=:COUNTRY_ID', [':GOODS_ID' => $ids[$k], ':COUNTRY_ID' => $user['COUNTRY_ID']]); if (!$goodsNature) { throw new Exception(Yii::t('app', 'productsDoesSoldOut')); } // 汇率 $this->exchangeRate = CurrencyConversions::getToUSDRate($goodsNature['LOCAL_CURRENCY_ID']); if($goods['STORE_NUMS']>0){ if ($goods['TYPE'] == 1 || $goods['TYPE'] == 2) { $discount = $goodsType[$goods['TYPE']]['discount']; $realPrice = $goodsNature['SELL_PRICE'] * $discount/100; $realPv = $goods['PRICE_PV'] * $discount/100; $realPriceStandard = $goods['SELL_PRICE_STANDARD'] * $discount/100; } else { $discount = $goods['SELL_DISCOUNT']; $realPrice = $goodsNature['SELL_PRICE'] * $discount; $realPv = $goods['PRICE_PV'] * $discount; $realPriceStandard = $goods['SELL_PRICE_STANDARD'] * $discount; } if($goods['PV_SPLIT']==1){ // 当商品为PV分期时 $pvSplit = $this->_pvSplit($realPv); $currentPv = $pvSplit['current']; $remainPv = $pvSplit['remain']; $totalPv += $currentPv * intval($v); $totalRealPv += $realPv * intval($v); $this->_remainPv += $remainPv * intval($v); }else{ $currentPv = $goods['PRICE_PV']; $totalPv += $realPv * intval($v); $totalRealPv += $realPv * intval($v); $remainPv = 0; $this->_remainPv += 0; } $totalAmount += $realPrice * intval($v); $totalAmountStandard += $realPriceStandard * intval($v); // if($this->payType=='cash') { // $discount = $goodsType[$goods['TYPE']]['discount']; // $realPrice = $goods['SELL_PRICE'] * $discount/100; // $realPv = $goods['PRICE_PV'] * $discount/100; // $totalAmount += $realPrice * intval($v); // $totalPv += $realPv * intval($v); // }else{ // $realPrice = $goods['SELL_PRICE']; // $realPv = $goods['PRICE_PV']; // $totalAmount += $realPrice * intval($v); // $totalPv += $realPv * intval($v); // } $this->_orderGoods[] = [ 'GOODS_ID' => $goods['ID'], 'PRICE' => $goodsNature['SELL_PRICE'], 'PV' => $currentPv, // $goods['PRICE_PV'], 'REAL_PRICE' => $realPrice, 'REAL_PV' => $this->payType == 'prp' ? 0 : $realPv, 'REMAIN_PV' => $remainPv, 'POINT' => $goods['POINT'], 'BUY_NUMS' => intval($v), 'SKU_CODE' => $goods['GOODS_NO'], 'GOODS_TITLE' => $goods['GOODS_NAME'], 'CATEGORY_TYPE' => $goods['CATEGORY_TYPE'], 'PAY_TYPE' => $this->payType, 'EMAIL' => $this->email, 'STANDARD_PRICE' => $goods['SELL_PRICE_STANDARD'], 'REAL_STANDARD_PRICE' => $realPriceStandard, 'EXCHANGE_RATE' => $this->exchangeRate, 'TAX_RATE' => $goodsNature['TAX_RATE'], ]; } if($goods['INSTALMENT']>0){ // 如果有分期付款商品,检查用户的分期付款状态 if($v>1){ // 不可以购买多个 throw new Exception(Yii::t('app', 'allowOnlyOne')); } $userStage = Instalment::getStage($loginUserId); $userInstalmentInfo = Instalment::getInfo($loginUserId); // 分期的总期数 $instalment = intval(Cache::getSystemConfig()['instalment']['VALUE'] ?? 3); // 分期商品的期数不能大于总分期数限制 if (intval($goods['INSTALMENT']) > $instalment) { throw new Exception(Yii::t('app', 'instalmentGoodsNoError')); } if ($userStage != $instalment){ if ($userInstalmentInfo){ if($userInstalmentInfo['STAGE']>0 && $userInstalmentInfo['ORDER_TYPE']!='FX'){ throw new Exception(Yii::t('app', 'canNotBuy')); } } if ($userStage + 1 != $goods['INSTALMENT']){ // 若用户分期阶段+1不等于商品的分期阶段,则报异常 throw new Exception(Yii::t('app', 'canNotBuy')); } if ($userStage + 1 > $instalment){ // 若用户分期阶段+1大于总分期阶段,则报异常 throw new Exception(Yii::t('app', 'canNotBuy')); } } else { if ($goods['INSTALMENT'] != 1) { throw new Exception(Yii::t('app', 'canNotBuy')); } } $hasInstalment = $goods['INSTALMENT']; } } } // 运费模板 $freeTemplate = FreeTemplate::getByCountryId($user['COUNTRY_ID']); // 运费 $freight = $freeTemplate['freight'] ?? 0; // 普通商品免运费阈值 $freeShipping = $freeTemplate['free_shipping'] ?? 0; $this->_decAmount = $totalAmount; $this->_decPv = $totalPv; $this->_realPv = $totalRealPv; $this->_freight = ($totalAmount >= $freeShipping) ? 0 : $freight; if($this->_address['PROVINCE']==1){ $this->_freight = 0; } $this->_payAmount = $this->_decAmount + $this->_freight; $this->_decAmountStandard = $totalAmountStandard; $this->_standardAmount = $this->_decAmountStandard + $this->_freight; $db = \Yii::$app->db; $transaction = $db->beginTransaction(); try { //判断用户余额是否充足 $result = $this->getBalanceAdequate($this->payType, $this->_payAmount); if ($result['code'] !== 200) { throw new Exception($result['message']); } /** * 2022-04-28 * York * 支付后减少库存 */ foreach ($this->goodsNum as $k => $v){ if ($v){ $goods = ShopGoods::findOneAsArray('ID=:ID AND STATUS=1',[':ID'=> $ids[$k]]); if (!$goods) { throw new Exception(Yii::t('app', 'productsDoesSoldOut')); } if ($goods['STORE_NUMS'] >= $this->goodsNum[$k]){ $data = ShopGoods::find()->where(['ID' => $ids[$k]])->one(); $goods_store_nums = $data->STORE_NUMS - $this->goodsNum[$k]; $data->STORE_NUMS = $goods_store_nums; $data->update(); //下单后库存小于等于0 商品下架 if($goods_store_nums <= 0){ $data->STATUS = 0; $data->UPDATED_AT = Date::nowTime(); $data->update(); } }else{ throw new Exception($goods['GOODS_NAME'] . Yii::t('app', 'insufficientInventory')); } } } //写入订单 if (!$orderResult = $this->addOrder()) { throw new Exception(Form::formatErrorsForApi($orderResult->getErrors())); } if ($hasInstalment){ // 如果有分期付款的商品,写入信息至分期付款表 $instalmentModel = Instalment::findOne(['USER_ID'=>$loginUserId]); if(!$instalmentModel) { $instalmentModel = new Instalment(); } $instalmentModel->USER_ID = $loginUserId; $instalmentModel->STAGE = $hasInstalment; $instalmentModel->ORDER_TYPE = 'FX'; $instalmentModel->UPDATE_TIME = time(); $instalmentModel->save(); } $transaction->commit(); return $orderResult; }catch (\Exception $e){ $transaction->rollBack(); $this->addError('add', $e->getMessage()); return null; } } /** * 判断对应账户余额是否充足. * @param $payType string 支付方式. * @param $payAmount numeric 支付金额 * @return array|int[] */ public function getBalanceAdequate(string $payType, $payAmount): array { $loginUserId = \Yii::$app->user->id; if ($payType == 'cash') { if (Cash::getAvailableBalance($loginUserId) < $payAmount) { return ['code' => 500, 'message' => Yii::t('app', 'cashDoesNotAdequate')]; } } else if ($payType =='exchange') { if ($payAmount > Balance::getBalanceExchangePoints($loginUserId)) { return ['code' => 500, 'message' => Yii::t('app', 'exchangePointDoesNotAdequate')]; } } else if ($payType == 'prp') { if ($payAmount > UserPerformance::getAmounts($loginUserId)) { return ['code' => 500, 'message' => Yii::t('app', 'userPerformanceDoesNotAdequate')]; } } return ['code' => 200]; } /** * 复销订单 * @throws Exception */ public function addOrder(){ $periodObj = Period::instance(); $nowPeriodNum = $this->period ?: $periodObj->getNowPeriodNum(); $nowCalcMonth = $periodObj->getYearMonth($nowPeriodNum); $userId = \Yii::$app->user->id; $user = User::getEnCodeInfo(\Yii::$app->user->id); $userName = Info::getUserNameByUserId($userId); $userRealName = Info::getUserRealNameByUserId($userId); $userMobile = Info::getUserMobileByUserId($userId); $userEmail = Info::getUserEmailByUserId($userId); $country = Countries::getById($user['COUNTRY_ID']); // 加入订单信息 if ($this->_address['PROVINCE'] != 1) { $warehouse = Region::getWarehouseByCode($this->_address['PROVINCE']);//仓库 if (!$warehouse) { throw new Exception(Yii::t('app', 'deliveryTemporarilyNotSupported')); } }else{ $warehouse = '01'; } $_hasPV = in_array($this->payType, ['exchange', 'tourism_points', 'garage_points']) ? 0 : $this->_decPv; $_hasRealPV = in_array($this->payType, ['exchange', 'tourism_points', 'garage_points']) ? 0 : $this->_realPv; $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 = $userName; $orderModel->DEC_USER_ID = $this->decUserName;; $orderModel->ORDER_AMOUNT = $this->_decAmount; $orderModel->PV = $_hasPV; $orderModel->PAY_AMOUNT = $this->_payAmount; $orderModel->PAY_PV = $this->payType == 'prp' ? 0 : $_hasRealPV; // 兑换积分不能算业绩 $orderModel->REMAIN_PV = $this->payType == 'prp' ? 0 : $this->_remainPv; $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->_address['CONSIGNEE']; $orderModel->MOBILE = $this->_address['MOBILE']; $orderModel->PROVINCE = $this->_address['PROVINCE']; // $orderModel->CITY = $this->_address['CITY']; // $orderModel->COUNTY = $this->_address['COUNTY']; $orderModel->LGA_NAME = $this->_address['LGA_NAME']; $orderModel->CITY_NAME = $this->_address['CITY_NAME']; $orderModel->ADDRESS = $this->_address['ADDRESS']; $orderModel->FRONT_REMARK = $this->remark; $orderModel->WAREHOUSE = $warehouse; $orderModel->STATUS = \Yii::$app->params['orderStatus']['paid']['value']; $orderModel->CREATED_AT = Date::nowTime(); $orderModel->CREATE_USER = $userName; $orderModel->EMAIL = $userEmail ?? ''; $orderModel->ORDER_AMOUNT_STANDARD = $this->_decAmountStandard; $orderModel->PAY_AMOUNT_STANDARD = $this->_standardAmount; $orderModel->EXCHANGE_RATE = $this->exchangeRate; $orderModel->COUNTRY_ID = $user['COUNTRY_ID']; $orderModel->CURRENCY_ID = $country['LOCAL_CURRENCY_ID'] ?? 0; if($this->_address['PROVINCE']==1){ $orderModel->EXPRESS_TYPE = 1; $orderModel->CONSIGNEE = $userRealName; $orderModel->MOBILE = $userMobile; $orderModel->PROVINCE = 1; $orderModel->CITY = 1; $orderModel->COUNTY = 1; $orderModel->LGA_NAME = $this->_address['LGA_NAME']; $orderModel->CITY_NAME = $this->_address['CITY_NAME']; $orderModel->ADDRESS = 'Self Pick-up'; } if(!$orderModel->save()){ $this->addErrors($orderModel->getErrors()); return false; } // 加入商品到订单商品表 foreach($this->_orderGoods as $key=>$value){ // 增加判断,如果订单是兑换券购买,则AR_ORDER_GOODS中的REAL_PV真实PV应该是0 if (in_array($orderModel->PAY_TYPE, ['exchange', 'tourism_points', 'garage_points'])) { $this->_orderGoods[$key]['REAL_PV'] = 0; } $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(\Yii::$app->user->id, 'CASH', -abs($this->_payAmount), ['REMARK' => 'Members reselling balance payment', 'ORDER_SN' => $orderModel->SN]); // 会员复销余额支付 } else if ($this->payType=='exchange') { Balance::changeUserBonus(\Yii::$app->user->id,'exchange_points', -abs($this->_payAmount),['DEAL_TYPE_ID' => DealType::EXCHANGE_POINTS_EXCHANGE,'REMARK' => '会员兑换积分兑换', 'ORDER_SN' => $orderModel->SN]); } else if ($this->payType == 'prp') { UserPerformance::changeUserPerformance(\Yii::$app->user->id, $this->_payAmount, $orderModel->SN); } return $orderModel; } /** * 帮会员复销 * @return bool|null * @throws Exception * @throws \yii\db\Exception */ public function reconsumeAdd(){ if(!$this->validate()){ return null; } $ids = $this->goodsId; $totalAmount = 0; $totalPv = 0; $totalRealPv = 0; $totalAmountStandard = 0; $goodsType = ShopGoods::getGoodType(); $hasInstalment = 0; $userId = Info::getUserIdByUserName($this->userName); $user = User::getEnCodeInfo($userId); $decUserID = Info::getUserIdByUserName($this->decUserName); $stockist_user = User::getEnCodeInfo($decUserID); if(!$stockist_user || $stockist_user['IS_DEC'] != 1){ throw new Exception(Yii::t('app', 'stockistDoesNotExist')); } // 报单中心汇率 $decCountryId = User::getEnCodeInfo(\Yii::$app->user->id)['COUNTRY_ID']; $decCountry = Countries::getById($decCountryId); $decUserCurrencyRate = CurrencyConversions::getToUSDRate($decCountry['LOCAL_CURRENCY_ID']); // 会员汇率 $country = Countries::getById($user['COUNTRY_ID']); $currencyRate = CurrencyConversions::getToUSDRate($country['LOCAL_CURRENCY_ID']); //判断是否是报单中心 $loginUser = User::getEnCodeInfo(\Yii::$app->user->id); if($loginUser['IS_DEC'] == 1){ if($decUserID != \Yii::$app->user->id){ throw new Exception(Yii::t('app', 'decUserNameIsWrong')); } } foreach ($this->goodsNum as $k => $v) { if ($v) { $goods = ShopGoods::findOneAsArray('ID=:ID AND STATUS=1',[':ID'=> $ids[$k]]); if (!$goods) { throw new Exception(Yii::t('app', 'productsDoesSoldOut')); } $goodsNature = ShopGoodsNature::findOneAsArray('GOODS_ID=:GOODS_ID AND COUNTRY_ID=:COUNTRY_ID', [':GOODS_ID' => $ids[$k], ':COUNTRY_ID' => $user['COUNTRY_ID']]); if (!$goodsNature) { throw new Exception(Yii::t('app', 'productsDoesSoldOut')); } // 汇率 $this->exchangeRate = CurrencyConversions::getToUSDRate($goodsNature['LOCAL_CURRENCY_ID']); if($goods['STORE_NUMS']>0){ if ($goods['TYPE'] == 1 || $goods['TYPE'] == 2) { $discount = $goodsType[$goods['TYPE']]['discount']; $realPrice = $goodsNature['SELL_PRICE'] * $discount/100; $realPv = $goods['PRICE_PV'] * $discount/100; $realPriceStandard = $goods['SELL_PRICE_STANDARD'] * $discount/100; } else { $discount = $goods['SELL_DISCOUNT']; $realPrice = $goodsNature['SELL_PRICE'] * $discount; $realPv = $goods['PRICE_PV'] * $discount; $realPriceStandard = $goods['SELL_PRICE_STANDARD'] * $discount; } if($goods['PV_SPLIT']==1){ // 当商品为PV分期时 $pvSplit = $this->_pvSplit($realPv); $currentPv = $pvSplit['current']; $remainPv = $pvSplit['remain']; $totalPv += $this->payType == 'prp' ? 0 : $currentPv * intval($v); $totalRealPv += $this->payType == 'prp' ? 0 : $realPv * intval($v); $this->_remainPv += $remainPv * intval($v); }else{ $currentPv = $goods['PRICE_PV']; $totalPv += $this->payType == 'prp' ? 0 : $realPv * intval($v); $totalRealPv += $this->payType == 'prp' ? 0 : $realPv * intval($v); $remainPv = 0; $this->_remainPv += 0; } $totalAmount += $realPrice * intval($v); $totalAmountStandard += $realPriceStandard * intval($v); $this->_orderGoods[] = [ 'GOODS_ID' => $goods['ID'], 'PRICE' => $goodsNature['SELL_PRICE'], 'PV' => $this->payType == 'prp' ? 0 : $currentPv, // $goods['PRICE_PV'], 'REAL_PRICE' => $realPrice, 'REAL_PV' => $this->payType == 'prp' ? 0 : $realPv, 'REMAIN_PV' => $this->payType == 'prp' ? 0 : $remainPv, 'POINT' => $goods['POINT'], 'BUY_NUMS' => intval($v), 'SKU_CODE' => $goods['GOODS_NO'], 'GOODS_TITLE' => $goods['GOODS_NAME'], 'CATEGORY_TYPE' => $goods['CATEGORY_TYPE'], 'PAY_TYPE' => $this->payType, 'EMAIL' => $this->email, 'STANDARD_PRICE' => $goods['SELL_PRICE_STANDARD'], 'REAL_STANDARD_PRICE' => $realPriceStandard, 'EXCHANGE_RATE' => $currencyRate, 'TAX_RATE' => $goodsNature['TAX_RATE'], ]; } if($goods['INSTALMENT']>0){ // 如果有分期付款商品,检查用户的分期付款状态 if($v>1){ // 不可以购买多个 throw new Exception(Yii::t('app', 'allowOnlyOne')); } $userStage = Instalment::getStage($userId); $userInstalmentInfo = Instalment::getInfo($userId); // 分期的总期数 $instalment = intval(Cache::getSystemConfig()['instalment']['VALUE'] ?? 3); // 分期商品的期数不能大于总分期数限制 if (intval($goods['INSTALMENT']) > $instalment) { throw new Exception(Yii::t('app', 'instalmentGoodsNoError')); } if ($userStage == $instalment){ if ($goods['INSTALMENT'] != 1) { throw new Exception(Yii::t('app', 'canNotBuy')); } }else{ if($userInstalmentInfo){ if($userInstalmentInfo['STAGE']>0 && $userInstalmentInfo['ORDER_TYPE']!='FX'){ throw new Exception(Yii::t('app', 'canNotBuy')); } } if($userStage + 1 != $goods['INSTALMENT']){ // 若用户分期阶段+1不等于商品的分期阶段,则报异常 throw new Exception(Yii::t('app', 'canNotBuy')); } if ($userStage + 1 > $instalment){ // 若用户分期阶段+1大于总分期阶段,则报异常 throw new Exception(Yii::t('app', 'canNotBuy')); } } $hasInstalment = $goods['INSTALMENT']; } } } // 运费模板 $freeTemplate = FreeTemplate::getByCountryId($user['COUNTRY_ID']); // 运费 $freight = $freeTemplate['freight'] ?? 0; // 普通商品免运费阈值 $freeShipping = $freeTemplate['free_shipping'] ?? 0; $this->_decAmount = $totalAmount; $this->_decPv = $this->payType == 'prp' ? 0 : $totalPv; $this->_realPv = $this->payType == 'prp' ? 0 : $totalRealPv; $this->_freight = ($totalAmount >= $freeShipping) ? 0 : $freight; $this->_payAmount = $this->_decAmount + $this->_freight; $this->_decAmountStandard = $totalAmountStandard; $this->_standardAmount = $this->_decAmountStandard + $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 . Yii::t('app', 'doesNotYourSubMemberCanNotReconsume')); // } // } if ($this->payType == 'prp') { //看余额是否充足 $decCash = UserPerformance::getAmounts($loginUserId); } else { //看现金余额是否充足 $decCash = Cash::getAvailableBalance($loginUserId); } // 转换后的余额 $localCash = Tool::convertAmount($decCash, $decUserCurrencyRate, $currencyRate); if ($localCash < $this->_decAmount){ throw new Exception(Yii::t('app', 'applicantPrpShort'), 400); } foreach ($this->goodsNum as $k => $v){ if ($v){ $goods = ShopGoods::findOneAsArray('ID=:ID AND STATUS=1',[':ID'=> $ids[$k]]); if (!$goods) { throw new Exception(Yii::t('app', 'productsDoesSoldOut')); } if ($goods['STORE_NUMS'] >= $this->goodsNum[$k]){ $data = ShopGoods::find()->where(['ID' => $ids[$k]])->one(); $goods_store_nums = $data->STORE_NUMS - $this->goodsNum[$k]; $data->STORE_NUMS = $goods_store_nums; $data->update(); //下单后库存小于等于0 商品下架 if($goods_store_nums <= 0){ $data->STATUS = 0; $data->UPDATED_AT = Date::nowTime(); $data->update(); } }else{ throw new Exception($goods['GOODS_NAME'] . Yii::t('app', 'insufficientInventory')); } } } //写入订单 if (!$orderResult = $this->addUserOrder()) { throw new Exception(Form::formatErrorsForApi($orderResult->getErrors())); } if ($hasInstalment){ // 如果有分期付款的商品,写入信息至分期付款表 $instalmentModel = Instalment::findOne(['USER_ID'=>$userId]); if(!$instalmentModel) { $instalmentModel = new Instalment(); } $instalmentModel->USER_ID = $userId; $instalmentModel->STAGE = $hasInstalment; $instalmentModel->ORDER_TYPE = 'FX'; $instalmentModel->UPDATE_TIME = time(); $instalmentModel->save(); } $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); $countryId = Info::getUserCountryByUserId($userId); $email = Info::getEmailByUserId($this->userName); $country = Countries::getById($countryId); $warehouse = '01'; $ordNo = $this->_generateSn(); $orderModel = new Order(); $orderModel->SN = 'OS'.$ordNo; $orderModel->DEC_SN = 'DS'.$ordNo; $orderModel->ORDER_TYPE = $this->type; $orderModel->ORDER_CATEGORY = 'STUDIO'; $orderModel->USER_ID = $userId; $orderModel->USER_NAME = $this->userName; $orderModel->ORDER_AMOUNT = $this->_decAmount; $orderModel->PV = $this->payType == 'prp' ? 0 : $this->_decPv; $orderModel->PAY_AMOUNT = $this->_payAmount; $orderModel->PAY_PV = $this->payType == 'prp' ? 0 : $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[0]; $orderModel->LGA_NAME = $this->lgaName; $orderModel->CITY_NAME = $this->cityName; $orderModel->ADDRESS = $this->detailaddress; $orderModel->FRONT_REMARK = $this->remark; $orderModel->WAREHOUSE = $warehouse; $orderModel->STATUS = 1; $orderModel->CREATED_AT = Date::nowTime(); $orderModel->CREATE_USER = $loginUserName; $orderModel->EMAIL = $email ?? ''; $orderModel->ORDER_AMOUNT_STANDARD = $this->_decAmountStandard; $orderModel->PAY_AMOUNT_STANDARD = $this->_standardAmount; $orderModel->EXCHANGE_RATE = $this->exchangeRate; $orderModel->COUNTRY_ID = $countryId; $orderModel->CURRENCY_ID = $country['LOCAL_CURRENCY_ID'] ?? 0; $orderModel->DEC_USER_ID = $this->decUserName; $orderModel->AUTO_MAINTENANCE = $this->autoMaintenance ?? 0; if(!$orderModel->save()){ throw new Exception(Form::formatErrorsForApi($orderModel->getErrors())); } // 加入商品到订单商品表 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' => Yii::t('app', 'membersResellingBalancePayment')]); } else if ($this->payType == 'prp') { UserPerformance::changeUserPerformance($loginUserId, $this->_payAmount, $orderModel->SN); } else{ Balance::changeUserBonus($loginUserId,'reconsume_points', -abs($this->_payAmount),['DEAL_TYPE_ID' => DealType::RECONSUME_POINTS_EXCHANGE, 'REMARK' => Yii::t('app', 'membersExchangePointPayment')]); } if (($this->payType != 'prp') && ($this->autoMaintenance == 1)) { $this->orderAutoMaintenance($orderModel); } 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; } public function addFakeOrder($userId, $periodNum){ $userName = Info::getUserNameByUserId($userId); $sysConfig = Cache::getSystemConfig(); $mesureUpCondition = $sysConfig['monthPcsPvFxCondition']['VALUE']; // 月达标条件 NG默认30 $ordNo = $this->_generateSn(); $orderModel = new Order(); $orderModel->SN = 'OS'.$ordNo; $orderModel->DEC_SN = 'DS'.$ordNo; $orderModel->USER_ID = $userId; $orderModel->USER_NAME = $userName; $orderModel->PERIOD_NUM = $periodNum; $orderModel->CREATE_USER = 'AUTO'; $orderModel->ORDER_TYPE = 'FX'; $orderModel->STATUS = 1; $orderModel->PV = $mesureUpCondition; $orderModel->PAY_PV = $mesureUpCondition; $orderModel->P_CALC_MONTH = '1970-01-01'; $orderModel->CREATED_AT = Date::nowTime(); $orderModel->EXPRESS_TYPE = 1; $orderModel->IS_AUTO = 1; if(!$orderModel->save()){ $this->addErrors($orderModel->getErrors()); return false; } return $orderModel; } /** * AMP * @return bool|null * @throws Exception|\Throwable */ public function autoMaintenanceSureOrder() { if (!$this->validate()) { return null; } $ids = $this->goodsId; $totalAmount = 0; $totalPv = 0; $totalRealPv = 0; $totalAmountStandard = 0; $this->autoMaintenance = 1; $goodsType = ShopGoods::getGoodType(); $hasInstalment = 0; $userId = Info::getUserIdByUserName($this->userName); $user = User::getEnCodeInfo($userId); $decUserID = Info::getUserIdByUserName($this->decUserName); $stockist_user = User::getEnCodeInfo($decUserID); if(!$stockist_user || $stockist_user['IS_DEC'] != 1){ throw new Exception(Yii::t('app', 'stockistDoesNotExist')); } // 报单中心汇率 $decCountryId = User::getEnCodeInfo(\Yii::$app->user->id)['COUNTRY_ID']; $decCountry = Countries::getById($decCountryId); $decUserCurrencyRate = CurrencyConversions::getToUSDRate($decCountry['LOCAL_CURRENCY_ID']); // 会员汇率 $country = Countries::getById($user['COUNTRY_ID']); $currencyRate = CurrencyConversions::getToUSDRate($country['LOCAL_CURRENCY_ID']); // 判断是否是报单中心 $loginUser = User::getEnCodeInfo(\Yii::$app->user->id); if ($loginUser['IS_DEC'] == 1){ if($decUserID != \Yii::$app->user->id){ throw new Exception(Yii::t('app', 'decUserNameIsWrong')); } } if ($this->payType == 'prp') { throw new Exception(Yii::t('app', 'payTypeError')); } foreach ($this->goodsNum as $k => $v) { if ($v) { $goods = ShopGoods::findOneAsArray('ID=:ID AND STATUS=1 AND AUTO_MAINTENANCE=1',[':ID'=> $ids[$k]]); if (!$goods) { throw new Exception(Yii::t('app', 'productsDoesSoldOut')); } $goodsNature = ShopGoodsNature::findOneAsArray('GOODS_ID=:GOODS_ID AND COUNTRY_ID=:COUNTRY_ID', [':GOODS_ID' => $ids[$k], ':COUNTRY_ID' => $user['COUNTRY_ID']]); if (!$goodsNature) { throw new Exception(Yii::t('app', 'productsDoesSoldOut')); } $this->exchangeRate = CurrencyConversions::getToUSDRate($goodsNature['LOCAL_CURRENCY_ID']); if($goods['STORE_NUMS']>0){ if ($goods['TYPE'] == 1 || $goods['TYPE'] == 2) { $discount = $goodsType[$goods['TYPE']]['discount']; $realPrice = $goodsNature['SELL_PRICE'] * $discount/100; $realPv = $goods['PRICE_PV'] * $discount/100; $realPriceStandard = $goods['SELL_PRICE_STANDARD'] * $discount/100; } else { $discount = $goods['SELL_DISCOUNT']; $realPrice = $goodsNature['SELL_PRICE'] * $discount; $realPv = $goods['PRICE_PV'] * $discount; $realPriceStandard = $goods['SELL_PRICE_STANDARD'] * $discount; } $currentPv = $goods['PRICE_PV']; $totalPv += $realPv * intval($v); $totalRealPv += $realPv * intval($v); $remainPv = 0; $this->_remainPv += 0; $totalAmount += $realPrice * intval($v); $totalAmountStandard += $realPriceStandard * intval($v); $this->_orderGoods[] = [ 'GOODS_ID' => $goods['ID'], 'PRICE' => $goodsNature['SELL_PRICE'], 'PV' => $currentPv, 'REAL_PRICE' => $realPrice, 'REAL_PV' => $realPv, 'REMAIN_PV' => $remainPv, 'POINT' => $goods['POINT'], 'BUY_NUMS' => intval($v), 'SKU_CODE' => $goods['GOODS_NO'], 'GOODS_TITLE' => $goods['GOODS_NAME'], 'CATEGORY_TYPE' => $goods['CATEGORY_TYPE'], 'PAY_TYPE' => $this->payType, 'EMAIL' => $this->email, 'STANDARD_PRICE' => $goods['SELL_PRICE_STANDARD'], 'REAL_STANDARD_PRICE' => $realPriceStandard, 'EXCHANGE_RATE' => $currencyRate, 'TAX_RATE' => $goodsNature['TAX_RATE'], ]; } if($goods['INSTALMENT']>0){ if ($v > 1) { throw new Exception(Yii::t('app', 'allowOnlyOne')); } $userStage = Instalment::getStage($userId); $userInstalmentInfo = Instalment::getInfo($userId); // 分期的总期数 $instalment = intval(Cache::getSystemConfig()['instalment']['VALUE'] ?? 3); // 分期商品的期数不能大于总分期数限制 if (intval($goods['INSTALMENT']) > $instalment) { throw new Exception(Yii::t('app', 'instalmentGoodsNoError')); } if ($userStage == $instalment){ if ($goods['INSTALMENT'] != 1) { throw new Exception(Yii::t('app', 'canNotBuy')); } }else{ if($userInstalmentInfo){ if($userInstalmentInfo['STAGE']>0 && $userInstalmentInfo['ORDER_TYPE']!='FX'){ throw new Exception(Yii::t('app', 'canNotBuy')); } } if($userStage + 1 != $goods['INSTALMENT']){ // 若用户分期阶段+1不等于商品的分期阶段,则报异常 throw new Exception(Yii::t('app', 'canNotBuy')); } if ($userStage + 1 > $instalment){ // 若用户分期阶段+1大于总分期阶段,则报异常 throw new Exception(Yii::t('app', 'canNotBuy')); } } $hasInstalment = $goods['INSTALMENT']; } } } $sysConfig = Cache::getSystemConfig(); $ampDivideLine = (int)$sysConfig['ampBVCondition']['VALUE']; if ($totalPv < $ampDivideLine) { throw new Exception(Yii::t('app', 'ampOrderSubStandard', ['ampBv' => $ampDivideLine])); } // 运费模板 $freeTemplate = FreeTemplate::getByCountryId($user['COUNTRY_ID']); // 运费 $freight = $freeTemplate['freight'] ?? 0; // 普通商品免运费阈值 $freeShipping = $freeTemplate['free_shipping'] ?? 0; $this->_decAmount = $totalAmount; $this->_decPv = $totalPv; $this->_realPv = $totalRealPv; $this->_freight = ($totalAmount >= $freeShipping) ? 0 : $freight; $this->_payAmount = $this->_decAmount + $this->_freight; $this->_decAmountStandard = $totalAmountStandard; $this->_standardAmount = $this->_decAmountStandard + $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 . Yii::t('app', 'doesNotYourSubMemberCanNotReconsume')); // } // } $decCash = Cash::getAvailableBalance($loginUserId); // 转换后的余额 $localCash = Tool::convertAmount($decCash, $decUserCurrencyRate, $currencyRate); if ($localCash < $this->_decAmount){ throw new Exception(Yii::t('app', 'applicantPrpShort'), 400); } foreach ($this->goodsNum as $k => $v){ if ($v){ $goods = ShopGoods::findOneAsArray('ID=:ID AND STATUS=1',[':ID'=> $ids[$k]]); if (!$goods) { throw new Exception(Yii::t('app', 'productsDoesSoldOut')); } if ($goods['STORE_NUMS'] >= $this->goodsNum[$k]){ $data = ShopGoods::find()->where(['ID' => $ids[$k]])->one(); $goods_store_nums = $data->STORE_NUMS - $this->goodsNum[$k]; $data->STORE_NUMS = $goods_store_nums; $data->update(); //下单后库存小于等于0 商品下架 if($goods_store_nums <= 0){ $data->STATUS = 0; $data->UPDATED_AT = Date::nowTime(); $data->update(); } }else{ throw new Exception($goods['GOODS_NAME'] . Yii::t('app', 'insufficientInventory')); } } } //写入订单 if (!$orderResult = $this->addUserOrder()) { throw new Exception(Form::formatErrorsForApi($orderResult->getErrors())); } if ($hasInstalment){ // 如果有分期付款的商品,写入信息至分期付款表 $instalmentModel = Instalment::findOne(['USER_ID'=>$userId]); if(!$instalmentModel) { $instalmentModel = new Instalment(); } $instalmentModel->USER_ID = $userId; $instalmentModel->STAGE = $hasInstalment; $instalmentModel->ORDER_TYPE = 'FX'; $instalmentModel->UPDATE_TIME = time(); $instalmentModel->save(); } $transaction->commit(); }catch (\Exception $e){ $transaction->rollBack(); $this->addError('add', $e->getMessage()); return null; } return true; } private function orderAutoMaintenance($order) { $nowPeriodNum = Period::instance()->getNowPeriodNum(); try { $sysConfig = Cache::getSystemConfig(); $divideLine = (float)$sysConfig['monthPcsPvFxCondition']['VALUE']; $orderTotalBv = $order->PV; if ($orderTotalBv <= $divideLine) { return; } $lastAmpPeriod = AmpPeriod::find() ->where(['USER_ID' => $order->USER_ID]) ->orderBy(['PERIOD_NUM' => SORT_DESC]) ->one(); $startPeriodNum = $lastAmpPeriod ? $lastAmpPeriod->PERIOD_NUM + 1 : $nowPeriodNum; if (!$lastAmpPeriod) { $memberOrderBv = Order::find() ->select('SUM(PV) AS total_pv') ->where([ 'USER_ID' => $order->USER_ID, 'IS_DELETE' => 0, 'PERIOD_NUM' => $nowPeriodNum ]) ->andWhere(['!=', 'SN', $order->SN]) ->scalar(); if ($memberOrderBv >= $divideLine) { $startPeriodNum = $nowPeriodNum + 1; } LoggerTool::notice([ $lastAmpPeriod, $startPeriodNum, $divideLine, $memberOrderBv, $nowPeriodNum ]); } $periodCount = floor($orderTotalBv / $divideLine); $remainderBv = $orderTotalBv % $divideLine; $ampPeriods = []; for ($i = 1; $i <= $periodCount; $i++) { $currentBv = $i < $periodCount ? $divideLine : ($divideLine + $remainderBv); $ampPeriods[] = [ 'USER_ID' => $order->USER_ID, 'ORDER_SN' => $order->SN, 'PERIOD_NUM' => $startPeriodNum, 'BV' => $currentBv, ]; $startPeriodNum++; } if (!empty($ampPeriods)) { AmpPeriod::batchInsert($ampPeriods); } } catch (\Exception $e) { // 记录日志或进行错误处理 \Yii::error('Order auto maintenance failed: ' . $e->getMessage()); } } }