kevinElken 8 месяцев назад
Родитель
Сommit
53b995fcff

+ 4 - 2
backendApi/modules/v1/controllers/ShopController.php

@@ -79,6 +79,7 @@ class ShopController extends BaseController {
             'SELL_TYPE'=> 'SELL_TYPE',
             'PRICE_PV'=> 'PRICE_PV',
             'CATEGORY_TYPE' => 'CATEGORY_TYPE',
+            'AUTO_MAINTENANCE' => 'AUTO_MAINTENANCE',
         ]);
         $condition = $filter['condition'];
         $params = $filter['params'];
@@ -116,6 +117,7 @@ class ShopController extends BaseController {
             'SELL_TYPE'=> 'SELL_TYPE',
             'PRICE_PV'=> 'PRICE_PV',
             'CATEGORY_TYPE' => 'CATEGORY_TYPE',
+            'AUTO_MAINTENANCE' => 'AUTO_MAINTENANCE',
         ]);
         $form = new ShopExportForm();
         $result = $form->run($filter, \Yii::t('ctx', 'shopExportListName')); // 商品列表
@@ -465,7 +467,7 @@ class ShopController extends BaseController {
             'ORDER_TYPE'=> 'O.ORDER_TYPE',
             'STATUS' => 'O.STATUS',
             'COUNTRY' => 'O.COUNTRY_ID',
-            'IS_AUTO' => 'O.IS_AUTO'
+            'AUTO_MAINTENANCE' => 'O.AUTO_MAINTENANCE'
         ]);
 
         $condition = ' 1=1 ' . $filter['condition'];
@@ -505,7 +507,7 @@ class ShopController extends BaseController {
             'CREATED_AT'=> 'O.CREATED_AT',
             'ORDER_TYPE'=> 'O.ORDER_TYPE',
             'STATUS' => 'O.STATUS',
-            'IS_AUTO' => 'O.IS_AUTO'
+            'AUTO_MAINTENANCE' => 'O.AUTO_MAINTENANCE'
         ]);
 
         $isSuper = AdminRole::isSuperAdmin(\Yii::$app->getUser()->getUserInfo()['roleId']);

+ 9 - 0
backendApi/modules/v1/models/lists/shop/GoodsList.php

@@ -99,6 +99,15 @@ class GoodsList extends \common\libs\dataList\DataList implements DataListInterf
                         ];
                     },
                 ],
+                'AUTO_MAINTENANCE' => [
+                    'header' => \Yii::t('ctx', 'shopListAutoMaintenance'),
+                    'value' => function($row) {
+                        return $row['AUTO_MAINTENANCE'] == 1 ? \Yii::t('ctx', 'yes') : \Yii::t('ctx', 'no');
+                    },
+                    'headerOther' => [
+                        'width' => '110',
+                    ],
+                ],
             ];
         }
         return $this->columns;

+ 10 - 10
backendApi/modules/v1/models/lists/shop/OrderList.php

@@ -377,12 +377,12 @@ class OrderList extends \common\libs\dataList\DataList implements DataListInterf
                        return $this->getDeliveryStatus()[$row['DELIVERY_STATUS']]['label'] ?? '';
                     },
                 ],
-//                'IS_AUTO' => [
-//                    'header' => \Yii::t('ctx', 'shopOrderListIsAuto'), // 是否自动
-//                    'value' => function ($row) {
-//                        return $row['IS_AUTO'] == 1 ? \Yii::t('ctx', 'shopOrderListIsAutoYes') : \Yii::t('ctx', 'shopOrderListIsAutoNo');
-//                    },
-//                ],
+                'AUTO_MAINTENANCE' => [
+                    'header' => \Yii::t('ctx', 'shopListAutoMaintenance'),
+                    'value' => function ($row) {
+                        return $row['AUTO_MAINTENANCE'] == 1 ? \Yii::t('ctx', 'yes') : \Yii::t('ctx', 'no');
+                    },
+                ],
             ];
         }
         return $this->columns;
@@ -423,12 +423,12 @@ class OrderList extends \common\libs\dataList\DataList implements DataListInterf
                         ['id' => $this->getOrderStatus()['failPaid']['value'], 'name' => $this->getOrderStatus()['failPaid']['label']]
                     ]
                 ],
-                'IS_AUTO' => [
-                    'name'=>\Yii::t('ctx', 'shopOrderListIsAuto'),
+                'AUTO_MAINTENANCE' => [
+                    'name'=>\Yii::t('ctx', 'shopListAutoMaintenance'),
                     'other'=> 'select',
                     'selectData'=> [
-                        ['id'=>1, 'name'=>\Yii::t('ctx', 'shopOrderListIsAutoYes')],
-                        ['id'=>0, 'name'=>\Yii::t('ctx', 'shopOrderListIsAutoNo')],
+                        ['id'=>1, 'name'=>\Yii::t('ctx', 'yes')],
+                        ['id'=>0, 'name'=>\Yii::t('ctx', 'no')],
                     ]
                 ]
             ];

+ 11 - 0
common/helpers/PayStack.php

@@ -20,6 +20,17 @@ class PayStack
     {
         $secretKey = self::getSecretKey();
 
+        LoggerTool::info('env: ' . YII_ENV);
+
+        if (YII_ENV != YII_ENV_PROD) {
+            return [
+                'status' => true,
+                'data' => [
+                    'amount' => $amount
+                ]
+            ];
+        }
+
         try {
             $url = "https://api.paystack.co/transaction/initialize";
             $fields = [

+ 3 - 0
common/messages/en-US/app.php

@@ -33,6 +33,8 @@ return [
     'instalmentGoodsNoError' => 'Products No. error',
     'instalmentOrderInProcess' => '分期商品订单未完成',
     'productsDoesSoldOut' => 'Products has sold out!',
+    'productsDoesNotAmp' => 'Products does not Auto Maintenance!',
+    'ampOrderSubStandard' => 'Minimum {ampBv} amp BV required. Please meet that criteria to proceed with the purchase.',
     'cashDoesNotAdequate' => 'Insufficient balance, unable to make the payment.',
     'userPerformanceDoesNotAdequate' => 'Performance bonus, unable to make the payment.',
     'exchangePointDoesNotAdequate' => '兑换积分不足,无法购买商品',
@@ -57,6 +59,7 @@ return [
     'cityName' => 'City Name',
     'detailAddress' => 'Address',
     'shippingAddress' => 'shipping Address',
+    'amp' => 'Auto Maintenance',
 
     'orderDoesNotExist' => 'the order does not exist',
     'orderHasBeenCancelCanNotDeliver ' => '订单已取消不能发货',

+ 2 - 0
common/messages/en-US/ctx.php

@@ -212,6 +212,7 @@ return [
     'shopListTax' => 'Tax(₦)',
     'shopListInventory' => 'Inventory',
     'shopListStatus' => 'Status',
+    'shopListAutoMaintenance' => 'AMP',
     'shopListOnSale' => 'On sale',
     'shopListSoldOut' => 'Sold out',
     'shopListUpdatedAt' => 'Update Time',
@@ -797,6 +798,7 @@ return [
     'dbConfigWithdrawFee' => '提现手续费',
     'dbConfigWithdrawFreezeDays' => '提现预付款天数',
     'dbConfigReportAlarmOpen' => '是否开启预警信息推送',
+    'dbConfigAmpBVCondition' => 'AMP订单最低限制',
 
     # 【参数】
     # 钱包类型

+ 3 - 1
common/messages/zh-CN/app.php

@@ -33,6 +33,8 @@ return [
     'instalmentGoodsNoError' => '分期商品的期数错误',
     'instalmentOrderInProcess' => '分期商品订单未完成',
     'productsDoesSoldOut' => '商品已下架',
+    'productsDoesNotAmp' => '非AMP商品!',
+    'ampOrderSubStandard' => 'AMP订单最少需要 {ampBv} BV. 请满足该标准以继续购买.',
     'cashDoesNotAdequate' => '余额不足,无法购买商品',
     'userPerformanceDoesNotAdequate' => '绩效奖金不足,无法购买商品',
     'exchangePointDoesNotAdequate' => '兑换积分不足,无法购买商品',
@@ -173,7 +175,7 @@ return [
     'isModifyPassword' => '是否修改密码',
     'isStudio' => '是否是工作室',
     'email' => '电子邮箱',
-
+    'amp' => 'Auto Maintenance',
 
 
     'fillingUpOfADeficit' => '补差额',

+ 2 - 0
common/messages/zh-CN/ctx.php

@@ -202,6 +202,7 @@ return [
     'shopListTax' => '税额(₦)',
     'shopListInventory' => '库存',
     'shopListStatus' => '状态',
+    'shopListAutoMaintenance' => 'AMP',
     'shopListOnSale' => '已上架',
     'shopListSoldOut' => '已下架',
     'shopListUpdatedAt' => '更新时间',
@@ -801,6 +802,7 @@ return [
     'dbConfigWithdrawFee' => '提现手续费',
     'dbConfigWithdrawFreezeDays' => '提现预付款天数',
     'dbConfigReportAlarmOpen' => '是否开启预警信息推送',
+    'dbConfigAmpBVCondition' => 'AMP订单最低限制',
 
     # 【参数】
     # 钱包类型

+ 49 - 0
common/models/AmpPeriod.php

@@ -0,0 +1,49 @@
+<?php
+
+namespace common\models;
+
+/**
+ * This is the model class for table "{{%AMP_PERIOD}}".
+ *
+ * @property string ID
+ * @property string USER_ID 用户ID
+ * @property string ORDER_SN 订单号
+ * @property int    PERIOD_NUM 周期
+ * @property double BV BV
+ */
+class AmpPeriod extends \common\components\ActiveRecord
+{
+    /**
+     * @inheritdoc
+     */
+    public static function tableName()
+    {
+        return '{{%AMP_PERIOD}}';
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function rules()
+    {
+        return [
+            [['USER_ID', 'ORDER_SN', 'PERIOD_NUM', 'BV'], 'required'],
+            [['PERIOD_NUM', 'BV'], 'number'],
+            [['ID'], 'unique'],
+        ];
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function attributeLabels()
+    {
+        return [
+            'ID' => 'ID',
+            'USER_ID' => '用户ID',
+            'ORDER_SN' => '订单号',
+            'PERIOD_NUM' => '周期',
+            'BV' => 'BV',
+        ];
+    }
+}

+ 2 - 0
common/models/ApproachDecOrder.php

@@ -34,6 +34,7 @@ use Yii;
  * @property int $UPGRADE_TYPE 升级类型
  * @property string $ORI_LV 升级前级别
  * @property string $UPGRADE_LV 升级后级别
+ * @property int AUTO_MAINTENANCE AMP订单
  */
 class ApproachDecOrder extends \common\components\ActiveRecord
 {
@@ -92,6 +93,7 @@ class ApproachDecOrder extends \common\components\ActiveRecord
             'UPDATED_AT' => '更新时间',
             'IS_DEL' => '是否删除',
             'DELETED_AT' => '删除时间',
+            'AUTO_MAINTENANCE' => 'AMP订单',
         ];
     }
 }

+ 2 - 1
common/models/ApproachOrder.php

@@ -75,7 +75,7 @@ class ApproachOrder extends \common\components\ActiveRecord
         return [
             [['USER_ID',  'ORDER_TYPE', 'CREATE_USER'], 'required'],
             [['ORDER_AMOUNT', 'PV', 'PAY_AMOUNT', 'PAY_PV', 'FREIGHT', 'PAY_FREIGHT'], 'number'],
-            [['PAY_AT', 'DELIVERY_STATUS', 'DELIVERY_PERIOD', 'DELIVERY_AT', 'EXPRESS_TYPE', 'PERIOD_NUM', 'STATUS', 'PROVINCE', 'CITY', 'COUNTY', 'CREATED_AT', 'UPDATED_AT', 'IS_DELETE', 'DELETED_AT'], 'integer'],
+            [['PAY_AT', 'DELIVERY_STATUS', 'DELIVERY_PERIOD', 'DELIVERY_AT', 'EXPRESS_TYPE', 'PERIOD_NUM', 'STATUS', 'PROVINCE', 'CITY', 'COUNTY', 'CREATED_AT', 'UPDATED_AT', 'IS_DELETE', 'DELETED_AT', 'AUTO_MAINTENANCE'], 'integer'],
             [['ID','SN', 'DEC_SN', 'USER_ID', 'ORDER_TRACK_NO','PAY_TYPE','DEC_USER_ID'], 'string', 'max' => 32],
             [['USER_NAME', 'TEL', 'CREATE_USER', 'UPDATER', 'WAREHOUSE'], 'string', 'max' => 16],
             [['ORDER_TYPE'], 'string', 'max' => 12],
@@ -140,6 +140,7 @@ class ApproachOrder extends \common\components\ActiveRecord
             'EMAIL' => 'Email',
             'COUNTRY_ID' => '国家ID',
             'CURRENCY_ID' => '币种ID',
+            'AUTO_MAINTENANCE' => 'AMP'
         ];
     }
 

+ 6 - 1
common/models/ApproachReconsumeOrder.php

@@ -53,6 +53,10 @@ use Yii;
  * @property string $PAY_AMOUNT_STANDARD 支付价格
  * @property string $ORDER_AMOUNT_STANDARD 订单总价格($)
  * @property string $EXCHANGE_RATE 汇率
+ * @property string $COUNTRY_ID 国家ID
+ * @property int $CURRENCY_ID 币种ID
+ * @property int $AUTO_MAINTENANCE AMP订单
+ * @property string $DEC_USER_ID  会员编号
  */
 class ApproachReconsumeOrder extends \common\components\ActiveRecord
 {
@@ -133,7 +137,8 @@ class ApproachReconsumeOrder extends \common\components\ActiveRecord
             'IS_DELETE' => '是否删除',
             'DELETED_AT' => '删除时间',
             'WAREHOUSE' => '发货仓',
-            'EMAIL' => 'Email'
+            'EMAIL' => 'Email',
+            'AUTO_MAINTENANCE' => 'AMP',
         ];
     }
 

+ 3 - 1
common/models/Order.php

@@ -56,6 +56,7 @@ use Yii;
  * @property string $NOTE 备注说明
  * @property string COUNTRY_ID 国家ID
  * @property int CURRENCY_ID 币种ID
+ * @property int AUTO_MAINTENANCE AMP订单
  */
 class Order extends \common\components\ActiveRecord
 {
@@ -75,7 +76,7 @@ class Order extends \common\components\ActiveRecord
         return [
             [['USER_ID', 'ORDER_TYPE', 'CREATE_USER'/*, 'EMAIL'*/], 'required'],
             [['ORDER_AMOUNT', 'PV', 'PAY_AMOUNT', 'PAY_PV', 'FREIGHT', 'PAY_FREIGHT', 'ORDER_AMOUNT_STANDARD', 'PAY_AMOUNT_STANDARD', 'EXCHANGE_RATE'], 'number'],
-            [['PAY_AT', 'DELIVERY_STATUS', 'DELIVERY_PERIOD', 'DELIVERY_AT', 'EXPRESS_TYPE', 'PERIOD_NUM', 'STATUS', 'PROVINCE', /*'CITY', 'COUNTY', */'CREATED_AT', 'UPDATED_AT', 'IS_DELETE', 'DELETED_AT'], 'integer'],
+            [['PAY_AT', 'DELIVERY_STATUS', 'DELIVERY_PERIOD', 'DELIVERY_AT', 'EXPRESS_TYPE', 'PERIOD_NUM', 'STATUS', 'PROVINCE', /*'CITY', 'COUNTY', */'CREATED_AT', 'UPDATED_AT', 'IS_DELETE', 'DELETED_AT', 'AUTO_MAINTENANCE'], 'integer'],
             [['ID','SN', 'DEC_SN', 'USER_ID', 'ORDER_TRACK_NO','PAY_TYPE','DEC_USER_ID'], 'string', 'max' => 32],
             [['USER_NAME', 'TEL', 'CREATE_USER', 'UPDATER', 'WAREHOUSE'], 'string', 'max' => 16],
             [['ORDER_TYPE'], 'string', 'max' => 12],
@@ -138,6 +139,7 @@ class Order extends \common\components\ActiveRecord
             'EMAIL' => 'Email',
             'COUNTRY_ID' => '国家ID',
             'CURRENCY_ID' => '币种ID',
+            'AUTO_MAINTENANCE' => 'AMP订单',
         ];
     }
     /*

+ 4 - 0
common/models/Period.php

@@ -4,6 +4,7 @@ namespace common\models;
 
 use common\helpers\bonus\Calc\CalcConsole;
 use common\helpers\Date;
+use common\helpers\LoggerTool;
 use common\helpers\Tool;
 use Yii;
 use yii\db\Exception;
@@ -520,6 +521,9 @@ class Period extends \common\components\ActiveRecord
     public function isCanCalc($periodNum = null) {
         // 没有挂网可以结算
         $period = $this->setPeriodNum($periodNum);
+
+        LoggerTool::notice([$period, $period['IS_SENT'], self::SEND_FINISH, ($period['IS_SENT'] == self::SEND_FINISH), $period['START_TIME'] > time()]);
+
         if ($period['IS_SENT'] == self::SEND_FINISH) {
             return false;
         }

+ 4 - 2
common/models/ShopGoods.php

@@ -27,6 +27,7 @@ namespace common\models;
  * @property int $DELETED_AT 删除时间
  * @property int $STATUS 状态
  * @property string $SORT 排序
+ * @property int $AUTO_MAINTENANCE AMP
  */
 class ShopGoods extends \common\components\ActiveRecord
 {
@@ -115,8 +116,8 @@ class ShopGoods extends \common\components\ActiveRecord
     public function rules()
     {
         return [
-            [['SELL_DISCOUNT','GOODS_NAME', 'CATE_ID','GIFT_TYPE', 'GOODS_NO', 'PRICE_PV','STORE_NUMS', 'SELL_TYPE', 'CATEGORY_TYPE', 'SELL_PRICE_STANDARD'], 'required'],
-            [['STORE_NUMS'], 'integer'],
+            [['SELL_DISCOUNT','GOODS_NAME', 'CATE_ID','GIFT_TYPE', 'GOODS_NO', 'PRICE_PV','STORE_NUMS', 'SELL_TYPE', 'CATEGORY_TYPE', 'SELL_PRICE_STANDARD', 'AUTO_MAINTENANCE'], 'required'],
+            [['STORE_NUMS', 'AUTO_MAINTENANCE'], 'integer'],
             [['PRICE_PV','POINT', 'CATEGORY_TYPE' ,'SELL_PRICE_STANDARD'], 'number'],
             [['ID','CATE_ID', 'GOODS_NO','GIFT_TYPE'], 'string', 'max' => 32],
             [['UNIT'], 'string', 'max' => 16],
@@ -154,6 +155,7 @@ class ShopGoods extends \common\components\ActiveRecord
             'UPDATED_AT' => '更新时间',
             'DELETED_AT' => '更新时间',
             'SORT' => '排序',
+            'AUTO_MAINTENANCE' => 'AMP'
         ];
     }
 

+ 759 - 0
common/models/forms/ApproachAutoMaintenanceOrderForm.php

@@ -0,0 +1,759 @@
+<?php
+namespace common\models\forms;
+
+use common\helpers\Cache;
+use common\helpers\Date;
+use common\components\Model;
+use common\helpers\Form;
+use common\helpers\Log;
+use common\helpers\LoggerTool;
+use common\helpers\PayStack;
+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\ApproachDecOrder;
+use common\models\ApproachOrder;
+use common\models\ApproachReconsumeOrder;
+use common\models\ApproachOrderGoods;
+use common\models\BaUser;
+use common\models\Countries;
+use common\models\CurrencyConversions;
+use common\models\DealType;
+use common\models\DecLevelLog;
+use common\models\DecOrder;
+use common\models\FreeTemplate;
+use common\models\Order;
+use common\models\OrderGoods;
+use common\models\Period;
+use common\models\ReceiveAddress;
+use common\models\Region;
+use common\models\ShopGoods;
+use common\models\ShopGoodsNature;
+use common\models\User;
+use common\models\UserNetwork;
+use common\models\Instalment;
+use Yii;
+use yii\base\Exception;
+class ApproachAutoMaintenanceOrderForm extends Model
+{
+    public $sn;
+    public $expressCompany;
+    public $orderTrackNo;
+    public $status;
+    public $remark;
+    public $note;
+
+    public $type;
+    public $addressId;
+    public $payType;
+    public $goodsId;
+    public $goodsNum;
+    public $payPassword;
+    public $email;
+
+    public $userName;
+    public $decUserName;
+    public $consignee;
+    public $acceptMobile;
+    public $province;
+    public $city;
+    public $county;
+    public $lgaName;
+    public $cityName;
+    public $autoMaintenance;
+    public $exchangeRate;
+    public $detailaddress;
+
+    private $_address;
+    private $_decAmount;
+    private $_decPv;
+    private $_realPv;
+    private $_freight;
+    private $_payAmount;
+    private $_orderGoods;
+    private $_standardAmount;
+    private $_decAmountStandard;
+
+    /**
+     * @var ApproachOrder
+     */
+    private $_model;
+
+    public function init() {
+        parent::init();
+        $this->adminOperateLogger = new AdminOperate([
+            'fetchClass' => ApproachOrder::class,
+        ]);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function rules()
+    {
+        return [
+            [['sn', 'expressCompany', 'orderTrackNo', 'status', 'remark','type','addressId','payType','goodsId','goodsNum', 'payPassword','userName','consignee','acceptMobile','province',/*'city','county',*/'lgaName','cityName','detailaddress','email', 'decUserName'], 'trim'],
+            [['sn', 'expressCompany', 'orderTrackNo', 'status', 'remark','type','addressId','payType','goodsId','goodsNum', 'payPassword','userName','consignee','acceptMobile','province',/*'city','county',*/'detailaddress' ,'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 = [
+            // 管理员修改订单状态
+            'adminStatus' => ['sn', 'status'],
+            // 校验订单支付
+            'verifyPayStack' => ['sn', 'note', 'status'],
+            // 会员下单
+            'userOrder' => ['type','addressId', 'payType','goodsId','goodsNum', 'note', 'payPassword'],
+            // 为会员复消
+            '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 = ApproachOrder::findOne(['SN' => $this->sn]);
+            if (!$this->_model){
+                $this->addError('sn', Yii::t('app', 'orderDoesNotExist'));
+                return false;
+            }
+        }
+
+        if ($this->scenario == 'verifyPayStack'){
+            if ($this->_model->STATUS != \Yii::$app->params['orderStatus']['notPaid']['value']) {
+                $this->addError('sn', Yii::t('app', 'payTypeError'));
+                return false;
+            }
+        }
+
+        return $parentValidate;
+    }
+
+    /**
+     * 判断收货地址是否存在
+     * @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
+     * @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
+     * @throws Exception
+     */
+    public function isPayType($attribute)
+    {
+        if ($this->payType != 'pay_stack'){
+            $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', 'orderCanNotContainMultipleProductCategories'));
+        }
+        $goodsCategoryType = array_unique(array_column($goods, 'CATEGORY_TYPE'));
+        if (count($goodsCategoryType) > 1) {
+            $this->addError($attribute, Yii::t('app', 'orderCanNotHasMoreClassification'));
+            return;
+        }
+
+        // 购买方式
+        $sellTypeLabelMap = array_column(ShopGoods::SALE_TYPE, 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'));
+        }
+    }
+
+    /**
+     * 校验类型
+     * @param $attribute
+     */
+    public function isStatus($attribute){
+        if($this->type && !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 ;
+                }
+            }
+        }
+
+    }
+
+    /**
+     * 校验PayStack支付,更新订单状态.同步到正式订单.
+     * @throws Exception
+     */
+    public function verifyPayStack(): ?ApproachOrder
+    {
+        if (!$this->validate()) {
+            return null;
+        }
+
+        // 调用PayStack支付校验
+        LoggerTool::info([$this->note['reference'], $this->note]);
+        $payload = PayStack::transactionVerify($this->note['reference']);
+        LoggerTool::info($payload);
+        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')));
+        }
+
+        // 订单类型:userOrder(会员订单)、userUpgrade(会员升级)、userDec(会员报单)
+        $orderType = $this->note['metadata']['custom_fields'][1]['value'] ?? false;
+
+        $db = \Yii::$app->db;
+        $transaction = $db->beginTransaction();
+        try {
+            // 更新准订单状态为已支付
+            $this->_model->STATUS = $this->status;
+            $this->_model->NOTE = json_encode($this->note);
+            $this->_model->PAY_AT = Date::utcToTime($this->note['paid_at']);
+            $this->_model->EMAIL = $this->note['email'];
+            if (!$this->_model->save()) {
+                throw new Exception(Form::formatErrorsForApi($this->_model->getErrors()));
+            }
+            // 更新订单商品的支付Email
+            ApproachOrderGoods::updateAll(['EMAIL' => $this->note['email']], 'ORDER_SN = :ORDER_SN', [':ORDER_SN' => $this->sn]);
+
+            // 同步准订单到正式订单
+            Order::insertOne($this->_model->toArray());
+            // 同步准订单商品到正式订单商品
+            $approachOrderGoods = ApproachOrderGoods::findAllAsArray('ORDER_SN = :ORDER_SN', [':ORDER_SN' => $this->sn]);
+            foreach ($approachOrderGoods as &$approachOrderGood) {
+                $approachOrderGood['EMAIL'] = $this->email;
+            }
+            OrderGoods::batchInsert($approachOrderGoods);
+
+            // AMP订单
+            $order = Order::findOne($this->_model->ID);
+            if ($order['AUTO_MAINTENANCE'] == 1) {
+                $this->orderAutoMaintenance($order);
+            }
+
+            // 会员报单、BA升级
+            if (in_array($orderType, ['userDec', 'baUpgrade', 'userUpgrade'])) {
+                // 同步报单
+                $approachDecOrder = ApproachDecOrder::findOneAsArray('ORDER_SN = :ORDER_SN', [':ORDER_SN' => $this->sn]);
+                if ($approachDecOrder) {
+                    unset($approachDecOrder['STATUS']);
+
+                    // 同步报单
+                    DecOrder::insertOne($approachDecOrder);
+
+                    // 修改会员锁定状态
+                    if (in_array($orderType, ['userDec', 'baUpgrade'])) {
+                        if (!User::updateAll(['STATUS' => 1], 'ID=:USER_ID', [':USER_ID' => $approachDecOrder['TO_USER_ID']])) {
+                            throw new Exception(Form::formatErrorsForApi(Yii::t('app', 'changeUserStatusError')));
+                        }
+                    }
+                    // 修改BA会员升级状态
+                    if ($orderType === 'baUpgrade') {
+                        // 查询BA会员名
+                        $userInfo = User::findOneAsArray('ID=:USER_ID', [':USER_ID' => $approachDecOrder['TO_USER_ID']]);
+                        if (!BaUser::updateAll(['WHETHER_UPGRADE' => 1, 'BA_UPGRADE_AT' => time()], 'USER_NAME=:USER_NAME', [':USER_NAME' => $userInfo['USER_NAME']])) {
+                            throw new Exception(Form::formatErrorsForApi(Yii::t('app', 'brandAmbassadorUpgradeError')));
+                        }
+                    }
+
+                    // 正式会员-升级单
+                    if ($orderType === 'userUpgrade') {
+                        // 会员升级 报单类型:2会员升级单
+                        if ($approachDecOrder['DETAIL_TYPE'] == 2) {
+                            // 为被升级人进行升级操作
+                            $decLevelLog = new DecLevelLog();
+                            $decLog = [
+                                'userId' => $approachDecOrder['TO_USER_ID'],//会员ID
+                                'fromId' => $approachDecOrder['ORI_LV'], // 变动前的级别
+                                'levelId' => $approachDecOrder['UPGRADE_LV'],// 变动后的级别
+                                'actionId' => $approachDecOrder['USER_ID'],
+                                'remark' => $approachDecOrder['REMARK'],
+                                'lvPv' => $this->_model->PV,
+                            ];
+                            $modifyDecLv = $decLevelLog->frontendChange($decLog);
+                            if (empty($modifyDecLv)) {
+                                $transaction->rollBack();
+                                throw new Exception(Yii::t('app', 'failedToUpgrade'));
+                            }
+                        }
+                    }
+
+                    // 删除中间表
+                    ApproachDecOrder::deleteAll('ORDER_SN = :ORDER_SN', [':ORDER_SN' => $this->sn]);
+                }
+            }
+
+            // 删除中间表
+            ApproachOrder::deleteAll('SN = :SN', [':SN' => $this->sn]);
+            ApproachOrderGoods::deleteAll('ORDER_SN = :ORDER_SN', [':ORDER_SN' => $this->sn]);
+
+            $transaction->commit();
+        } catch (Exception $e) {
+            $transaction->rollBack();
+            $this->addError('edit', $e->getFile() . '  ' . $e->getMessage());
+            return null;
+        }
+
+        return $this->_model;
+    }
+
+    /**
+     * AMP
+     * @throws Exception
+     * @throws \yii\db\Exception
+     */
+    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 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 += $this->payType == 'prp' ? 0 : $realPv * intval($v);
+                    $totalRealPv += $this->payType == 'prp' ? 0 : $realPv * intval($v);
+
+                    $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' => 0,
+                        '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']) {
+                            throw new Exception(Yii::t('app', 'canNotBuy'));
+                        }
+
+                        if ($userStage + 1 > $instalment){
+                            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 {
+            //写入订单
+            if (!$orderResult = $this->addOrder()) {
+                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->UPDATE_TIME = time();
+                $instalmentModel->save();
+            }
+
+            $transaction->commit();
+
+            return $orderResult;
+        }catch (\Exception $e){
+            $transaction->rollBack();
+            $this->addError('add', $e->getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * 复销订单
+     * @throws Exception
+     */
+    public function addOrder()
+    {
+        $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';
+        $_hasPV = $this->_decPv;
+
+        $ordNo = $this->_generateSn();
+        $orderModel = new ApproachReconsumeOrder();
+        $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 = $_hasPV;
+        $orderModel->PAY_AMOUNT = $this->_payAmount;
+        $orderModel->PAY_PV = $_hasPV;
+        $orderModel->PAY_AT = 0;
+        $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 = Yii::$app->params['orderStatus']['notPaid']['value'];
+        $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);
+        }
+        ApproachOrderGoods::batchInsert($this->_orderGoods);
+
+        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;
+    }
+
+    private function orderAutoMaintenance($order)
+    {
+        $nowPeriodNum = Period::instance()->getNowPeriodNum();
+
+        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 : $nowPeriodNum;
+
+            if (!$lastAmpPeriod) {
+                $memberOrderBv = Order::find()
+                    ->select('SUM(PV) AS total_pv')
+                    ->where([
+                        'USER_ID' => $order->USER_ID,
+                        'IS_DELETE' => 0,
+                        'PERIOD_NUM' => $nowPeriodNum
+                    ])
+                    ->scalar();
+
+                if ($memberOrderBv >= $divideLine) {
+                    $startPeriodNum = $nowPeriodNum + 1;
+                }
+            }
+
+            $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());
+        }
+    }
+}

+ 75 - 18
common/models/forms/ApproachOrderForm.php

@@ -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\ApproachDecOrder;
 use common\models\ApproachOrder;
 use common\models\ApproachOrderGoods;
@@ -127,6 +128,7 @@ class ApproachOrderForm extends Model
             'cityName' => Yii::t('app', 'cityName'),
             'detailaddress' => Yii::t('app', 'detailAddress'),
             'email' => Yii::t('app', 'email'),
+            'autoMaintenance' => Yii::t('app', 'amp'),
         ];
     }
 
@@ -303,14 +305,14 @@ class ApproachOrderForm extends Model
 
         // 调用PayStack支付校验
         LoggerTool::info([$this->note['reference'], $this->note]);
-        $payload = PayStack::transactionVerify($this->note['reference']);
-        LoggerTool::info($payload);
-        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')));
-        }
+//        $payload = PayStack::transactionVerify($this->note['reference']);
+//        LoggerTool::info($payload);
+//        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')));
+//        }
 
         // 订单类型:userOrder(会员订单)、userUpgrade(会员升级)、userDec(会员报单)
         $orderType = $this->note['metadata']['custom_fields'][1]['value'] ?? false;
@@ -338,6 +340,12 @@ class ApproachOrderForm extends Model
             }
             OrderGoods::batchInsert($approachOrderGoods);
 
+            // AMP订单
+            $order = Order::findOne($this->_model->ID);
+            if ($order['AUTO_MAINTENANCE'] == 1) {
+                $this->orderAutoMaintenance($order);
+            }
+
             // 会员报单、BA升级
             if (in_array($orderType, ['userDec', 'baUpgrade', 'userUpgrade'])) {
                 // 同步报单
@@ -354,14 +362,6 @@ class ApproachOrderForm extends Model
                             throw new Exception(Form::formatErrorsForApi(Yii::t('app', 'changeUserStatusError')));
                         }
                     }
-                    // 修改BA会员升级状态
-//                    if ($orderType === 'baUpgrade') {
-//                        // 查询BA会员名
-//                        $userInfo = User::findOneAsArray('ID=:USER_ID', [':USER_ID' => $approachDecOrder['TO_USER_ID']]);
-//                        if (!BaUser::updateAll(['WHETHER_UPGRADE' => 1, 'BA_UPGRADE_AT' => time()], 'USER_NAME=:USER_NAME', [':USER_NAME' => $userInfo['USER_NAME']])) {
-//                            throw new Exception(Form::formatErrorsForApi(Yii::t('app', 'brandAmbassadorUpgradeError')));
-//                        }
-//                    }
 
                     // 正式会员-升级单
                     if ($orderType === 'userUpgrade') {
@@ -634,8 +634,6 @@ class ApproachOrderForm extends Model
         }
         ApproachOrderGoods::batchInsert($this->_orderGoods);
 
-        // TODO: 记录流水
-
         return $orderModel;
     }
 
@@ -663,4 +661,63 @@ class ApproachOrderForm extends Model
         }
         return $hash;
     }
+
+    private function orderAutoMaintenance($order)
+    {
+        $nowPeriodNum = Period::instance()->getNowPeriodNum();
+
+        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 : $nowPeriodNum;
+
+            if (!$lastAmpPeriod) {
+                $memberOrderBv = Order::find()
+                    ->select('SUM(PV) AS total_pv')
+                    ->where([
+                        'USER_ID' => $order->USER_ID,
+                        'IS_DELETE' => 0,
+                        'PERIOD_NUM' => $nowPeriodNum
+                    ])
+                    ->scalar();
+
+                if ($memberOrderBv >= $divideLine) {
+                    $startPeriodNum = $nowPeriodNum + 1;
+                }
+            }
+
+            $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());
+        }
+    }
 }

+ 318 - 11
common/models/forms/OrderForm.php

@@ -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);
     }
@@ -1050,7 +1054,8 @@ class OrderForm extends Model
     /**
      * 帮会员复消的订单
      */
-    public function addUserOrder(){
+    public function addUserOrder()
+    {
         $periodObj = Period::instance();
         $nowPeriodNum = $periodObj->getNowPeriodNum();
         $nowCalcMonth = $periodObj->getYearMonth($nowPeriodNum);
@@ -1063,15 +1068,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 +1105,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 +1125,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 +1184,307 @@ 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'));
+            }
+        }
+
+        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());
+        }
+    }
 }

+ 6 - 2
common/models/forms/ShopGoodsForm.php

@@ -37,6 +37,7 @@ class ShopGoodsForm extends Model
     public $status;
     public $categoryType;
     public $nature;
+    public $autoMaintenance = 0;
 
     private $_model;
 
@@ -85,6 +86,7 @@ class ShopGoodsForm extends Model
             'storeNums' => 'Inventory', // 库存
             'content' => 'Content',
             'listOrder' => 'Order',// 排序
+            'autoMaintenance' => 'Auto Maintenance',
         ];
     }
 
@@ -96,8 +98,8 @@ class ShopGoodsForm extends Model
     {
         $parentScenarios =  parent::scenarios();
         $customScenarios = [
-            'add' => ['goodsName','sellDiscount','giftType', 'sellType','goodsNo','unit','pricePv','storeNums', 'content','sort','cover', 'categoryType', 'sellPriceStandard', 'taxRate', 'taxAmount','pvSplit', 'nature'],
-            'edit' => ['id','goodsName','sellDiscount','giftType', 'sellType','goodsNo','unit','pricePv', 'storeNums', 'content','sort','cover', 'categoryType', 'sellPriceStandard', 'nature','pvSplit'],
+            'add' => ['goodsName','sellDiscount','giftType', 'sellType','goodsNo','unit','pricePv','storeNums', 'content','sort','cover', 'categoryType', 'sellPriceStandard', 'taxRate', 'taxAmount','pvSplit', 'nature', 'autoMaintenance'],
+            'edit' => ['id','goodsName','sellDiscount','giftType', 'sellType','goodsNo','unit','pricePv', 'storeNums', 'content','sort','cover', 'categoryType', 'sellPriceStandard', 'nature','pvSplit', 'autoMaintenance'],
             'changeStatus' => ['selectedIds', 'status'],
         ];
         return array_merge($parentScenarios, $customScenarios);
@@ -211,6 +213,7 @@ class ShopGoodsForm extends Model
             $shopGoods->CATE_ID = '1';
             $shopGoods->CREATED_AT = Date::nowTime();
             $shopGoods->CATEGORY_TYPE = $this->categoryType;
+            $shopGoods->AUTO_MAINTENANCE = $this->autoMaintenance ?? 0;
             if (!$shopGoods->save()) {
                 throw new Exception(Form::formatErrorsForApi($shopGoods->getErrors()));
             }
@@ -271,6 +274,7 @@ class ShopGoodsForm extends Model
             $model->SORT = $this->sort;
             $model->UPDATED_AT = Date::nowTime();
             $model->CATEGORY_TYPE = $this->categoryType;
+            $model->AUTO_MAINTENANCE = $this->autoMaintenance ?? 0;
             if (!$model->save()) {
                 throw new Exception(Form::formatErrorsForApi($model->getErrors()));
             }

+ 1 - 0
frontendApi/config/menu.php

@@ -41,6 +41,7 @@ return [
         'child'=>[
             ['name'=>'Member Welcome Pack', 'class'=>'', 'icon'=>'', 'controller'=>'user', 'action'=>'dec', 'routePath'=>'user/dec', 'show'=>1,  'wiki' => 'welcomePack',], // 会员报单
             ['name'=>'Member Repeat Purchase', 'class'=>'', 'icon'=>'', 'controller'=>'user', 'action'=>'reconsume', 'routePath'=>'shop/reconsume', 'show'=>1, 'wiki' => 'memberRepeatPurchase',],//会员复消
+            ['name'=>'Member Auto Maintenance', 'class'=>'', 'icon'=>'', 'controller'=>'user', 'action'=>'reconsume', 'routePath'=>'shop/auto-maintenance', 'show'=>1, 'wiki' => 'memberAutoMaintenance',],//AMP
             ['name'=>'Member Upgrade', 'class'=>'', 'icon'=>'', 'controller'=>'user', 'action'=>'dec', 'routePath'=>'user/upgrade', 'show'=>1, /**'allow'=>'declarer',**/ 'wiki' => 'memberUpgrade',],//会员升级
             ['name'=>'Member Order', 'class'=>'', 'icon'=>'', 'controller'=>'user', 'action'=>'member-order', 'routePath'=>'shop/member-order', 'show'=>1, 'wiki' => 'memberOrder',],//会员订单
         ]

+ 3 - 0
frontendApi/config/urlManagerRules.php

@@ -96,6 +96,9 @@ return [
             'GET ba-dec-order-list' => 'ba-dec-order-list',
             'GET ba-dec-order-export/<orderSn>' => 'ba-dec-order-export',
             'POST sure-approach-reconsume-order' => 'sure-approach-reconsume-order',
+            'GET auto-maintenance' => 'auto-maintenance',
+            'POST auto-maintenance-sure-order' => 'auto-maintenance-sure-order',
+            'POST auto-maintenance-approach-sure-order' => 'auto-maintenance-approach-sure-order',
         ],
     ],
     [

+ 91 - 0
frontendApi/modules/v1/controllers/ShopController.php

@@ -29,6 +29,7 @@ use common\models\Currency;
 use common\models\CurrencyConversions;
 use common\models\DecOrder;
 use common\models\BaDecOrder;
+use common\models\forms\ApproachAutoMaintenanceOrderForm;
 use common\models\forms\ApproachOrderForm;
 use common\models\forms\ApproachReconsumeOrderForm;
 use common\models\forms\BaApproachOrderForm;
@@ -47,6 +48,7 @@ use common\models\UserBonus;
 use common\models\UserPerformance;
 use common\models\UserWallet;
 use Yii;
+use yii\base\Exception;
 use yii\data\Pagination;
 use yii\db\Query;
 use yii\web\HttpException;
@@ -179,6 +181,14 @@ class ShopController extends BaseController {
 
         $isDec = User::getEnCodeInfo(\Yii::$app->user->id)['IS_DEC'];
 
+        // 账户币种
+        $country = Countries::getById($user['COUNTRY_ID']);
+        $coin = Currency::getById($country['LOCAL_CURRENCY_ID']);
+
+        // AMP
+        $sysConfig = Cache::getSystemConfig();
+        $ampDivideLine = (int)$sysConfig['ampBVCondition']['VALUE'];
+
         return static::notice(
             [
                 'payList'=>$payList,
@@ -189,6 +199,7 @@ class ShopController extends BaseController {
                 'freeShipping' => $freeShipping,
                 'isDec' => $isDec,
                 'coin' => $coin['CODE'] ?? '',
+                'ampDivideLine' => floatval($ampDivideLine),
             ]);
     }
 
@@ -1866,4 +1877,84 @@ ORDER;
 
         return static::notice(['fileUrl' => $path, 'targetName' => $file_name]);
     }
+
+    /**
+     * AMP
+     */
+    public function actionAutoMaintenance()
+    {
+        // 会员信息
+        $user = User::findOneAsArray('ID=:ID', [':ID' => \Yii::$app->request->get('userId')]);
+        if (!$user) {
+            return static::notice(Yii::t('app', 'memberDoesNotExist'), 400);
+        }
+
+        $condition = ' AND STATUS=1 AND (FIND_IN_SET(2,GIFT_TYPE)>0 OR FIND_IN_SET(4,GIFT_TYPE)>0) AND N.COUNTRY_ID=:COUNTRY_ID AND AUTO_MAINTENANCE=1';
+        $data = ShopGoods::lists($condition, [':COUNTRY_ID' => $user['COUNTRY_ID']], [
+            'select' => 'S.*,N.MARKET_PRICE,N.SELL_PRICE,N.TAX_RATE,N.LOCAL_CURRENCY_ID,N.COUNTRY_ID',
+            'from' => ShopGoods::tableName() . ' AS S',
+            'join' => [
+                ['INNER JOIN', ShopGoodsNature::tableName() . ' AS N', 'N.GOODS_ID = S.ID'],
+            ],
+            'orderBy' => 'SORT ASC,CREATED_AT DESC',
+            'limit' => 100,
+        ]);
+
+        $currencies = Currency::getAllData();
+        $currencies = array_column($currencies, NULL, 'ID');
+
+        foreach ($data['list'] as $key => $value) {
+            $data['list'][$key]['DISCOUNT'] = in_array($value['TYPE'], [1, 2]) ? ShopGoods::getGoodType()[$value['TYPE']]['discount'] : $value['SELL_DISCOUNT'] * 100;
+            $data['list'][$key]['COIN'] = $currencies[$value['LOCAL_CURRENCY_ID']]['CODE'] ?? '';
+        }
+
+        return static::notice($data);
+    }
+
+    /**
+     * AMP
+     */
+    public function actionAutoMaintenanceSureOrder()
+    {
+        if (\Yii::$app->request->isPost) {
+            $formModel = new OrderForm();
+            $formModel->scenario = 'autoMaintenanceOrder';
+            $formModel->remark = Yii::t('app', 'autoMaintenance');
+            $post = \Yii::$app->request->post();
+            $post['type'] = DeclarationForm::TYPE_FX;
+
+            try {
+                if ($formModel->load($post, '') && $formModel->autoMaintenanceSureOrder()) {
+                    return static::notice(Yii::t('app', 'successfully'));
+                } else {
+                    return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
+                }
+            } catch (HttpException|Exception|\Throwable $e) {
+                return static::notice(Form::formatErrorsForApi($e->getMessage()), 400);
+            }
+        }
+    }
+
+    /**
+     * AMP
+     */
+    public function actionAutoMaintenanceApproachSureOrder(){
+        if (\Yii::$app->request->isPost) {
+            $formModel = new ApproachAutoMaintenanceOrderForm();
+            $formModel->scenario = 'autoMaintenanceOrder';
+            $formModel->remark = 'Auto Maintenance Order';
+            $post = \Yii::$app->request->post();
+            $post['type'] = DeclarationForm::TYPE_FX;
+
+            try {
+                if ($formModel->load($post, '') && $order = $formModel->autoMaintenanceSureOrder()) {
+                    return static::notice($order);
+                } else {
+                    return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
+                }
+            } catch (\yii\db\Exception|HttpException|Exception $e) {
+                return static::notice(Form::formatErrorsForApi($e->getMessage()), 400);
+            }
+        }
+    }
 }