|
|
@@ -12,6 +12,7 @@ use common\helpers\user\Balance;
|
|
|
use common\helpers\user\Cash;
|
|
|
use common\helpers\user\Info;
|
|
|
use common\libs\logging\operate\AdminOperate;
|
|
|
+use common\models\AmpPeriod;
|
|
|
use common\models\Countries;
|
|
|
use common\models\CurrencyConversions;
|
|
|
use common\models\DealType;
|
|
|
@@ -62,6 +63,7 @@ class OrderForm extends Model
|
|
|
public $lgaName;
|
|
|
public $cityName;
|
|
|
public $county;
|
|
|
+ public $autoMaintenance;
|
|
|
public $detailaddress;
|
|
|
|
|
|
private $_address;
|
|
|
@@ -152,6 +154,8 @@ class OrderForm extends Model
|
|
|
'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);
|
|
|
}
|
|
|
@@ -1063,15 +1067,8 @@ class OrderForm extends Model
|
|
|
$email = Info::getEmailByUserId($this->userName);
|
|
|
$country = Countries::getById($countryId);
|
|
|
|
|
|
- // 加入订单信息
|
|
|
-// if($this->province!=1){
|
|
|
-// $warehouse = Region::getWarehouseByCode($this->province);//仓库
|
|
|
-// if(!$warehouse){
|
|
|
-// throw new Exception(Yii::t('app', 'deliveryTemporarilyNotSupported'));
|
|
|
-// }
|
|
|
-// }else{
|
|
|
- $warehouse = '01';
|
|
|
-// }
|
|
|
+ $warehouse = '01';
|
|
|
+
|
|
|
$ordNo = $this->_generateSn();
|
|
|
$orderModel = new Order();
|
|
|
$orderModel->SN = 'OS'.$ordNo;
|
|
|
@@ -1107,7 +1104,8 @@ class OrderForm extends Model
|
|
|
$orderModel->EXCHANGE_RATE = $this->exchangeRate;
|
|
|
$orderModel->COUNTRY_ID = $countryId;
|
|
|
$orderModel->CURRENCY_ID = $country['LOCAL_CURRENCY_ID'] ?? 0;
|
|
|
- $orderModel->DEC_USER_ID = $this->decUserName;;
|
|
|
+ $orderModel->DEC_USER_ID = $this->decUserName;
|
|
|
+ $orderModel->AUTO_MAINTENANCE = $this->autoMaintenance ?? 0;
|
|
|
if(!$orderModel->save()){
|
|
|
throw new Exception(Form::formatErrorsForApi($orderModel->getErrors()));
|
|
|
}
|
|
|
@@ -1126,6 +1124,11 @@ class OrderForm extends Model
|
|
|
} 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;
|
|
|
}
|
|
|
|
|
|
@@ -1180,4 +1183,289 @@ class OrderForm extends Model
|
|
|
}
|
|
|
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'));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ 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['AUTO_MAINTENANCE'] != 1) {
|
|
|
+ throw new Exception(Yii::t('app', 'productsDoesNotAmp'));
|
|
|
+ }
|
|
|
+
|
|
|
+ $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 += $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'];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $sysConfig = Cache::getSystemConfig();
|
|
|
+ $ampDivideLine = (int)$sysConfig['ampBVCondition']['VALUE'];
|
|
|
+ if ($totalPv < $ampDivideLine) {
|
|
|
+ throw new Exception(Yii::t('app', 'ampOrderSubStandard', ['']));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 运费模板
|
|
|
+ $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;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function orderAutoMaintenance($order)
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ $sysConfig = Cache::getSystemConfig();
|
|
|
+ $divideLine = (int)$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 : $order->PERIOD_NUM;
|
|
|
+
|
|
|
+ $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 + $i - 1,
|
|
|
+ 'BV' => $currentBv,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!empty($ampPeriods)) {
|
|
|
+ AmpPeriod::batchInsert($ampPeriods);
|
|
|
+ }
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ // 记录日志或进行错误处理
|
|
|
+ \Yii::error('Order auto maintenance failed: ' . $e->getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|