Exemplo n.º 1
0
 public function actionOfflineExchange()
 {
     $params = $this->getParams();
     if (empty($params['goods']) || empty($params['memberId']) || !isset($params['usedScore']) || empty($params['address']) || empty($params['receiveMode'])) {
         throw new BadRequestHttpException(Yii::t('common', 'parameters_missing'));
     }
     $userId = $this->getUserId();
     $user = User::findByPk($userId);
     $user = ['id' => $user->_id, 'name' => $user->name];
     if ($params['usedScore'] < 0) {
         throw new BadRequestHttpException(Yii::t('common', 'data_error'));
     }
     $member = Member::findByPk(new \MongoId($params['memberId']));
     if (empty($member) || $member->isDisabled) {
         throw new InvalidParameterException(Yii::t('member', 'invalid_member_id'));
     }
     $goodsExchangeMap = [];
     $goodsIds = [];
     foreach ($params['goods'] as $item) {
         if ($item['count'] <= 0) {
             throw new BadRequestHttpException(Yii::t('common', 'data_error'));
         }
         $goodsExchangeMap[$item['id']] = $item['count'];
         $goodsIds[] = new \MongoId($item['id']);
     }
     $allExchangeGoods = Goods::getByIds($goodsIds);
     if (count($allExchangeGoods) != count($goodsIds)) {
         throw new InvalidParameterException(Yii::t('product', 'product_deleted'));
     }
     $usedScore = $params['usedScore'];
     $expectedScore = 0;
     $exchanges = [];
     foreach ($allExchangeGoods as $goods) {
         $exchangeCount = $goodsExchangeMap[(string) $goods->_id];
         if ($goods->total === 0) {
             throw new InvalidParameterException([(string) $goods->_id => Yii::t('product', 'goods_sold_out')]);
         } else {
             if (!empty($goods->total) && $exchangeCount > $goods->total) {
                 throw new InvalidParameterException([(string) $goods->_id => Yii::t('product', 'goods_not_enough')]);
             }
         }
         $expectedScore += $goods->score * $exchangeCount;
         $exchanges[] = ['goods' => $goods, 'count' => $exchangeCount];
     }
     $params['expectedScore'] = $expectedScore;
     if ($member->score < $usedScore) {
         throw new InvalidParameterException(Yii::t('product', 'member_score_not_enough'));
     }
     $successExchange = [];
     foreach ($exchanges as $exchangeItem) {
         $goods = $exchangeItem['goods'];
         $count = $exchangeItem['count'];
         $goodsCondition = ['_id' => $goods->_id];
         $goodsModifier = ['$inc' => ['usedCount' => $count]];
         $goodsRollbackModifier = ['$inc' => ['usedCount' => 0 - $count]];
         if ($goods->total !== '') {
             $goodsCondition['total'] = ['$gte' => $count];
             $goodsModifier['$inc']['total'] = 0 - $count;
             $goodsRollbackModifier['$inc']['total'] = $count;
         }
         $goodsUpdatedCount = Goods::updateAll($goodsModifier, $goodsCondition);
         if ($goodsUpdatedCount !== 1) {
             $this->_rollBackUsedCount($successExchange);
             throw new InvalidParameterException([(string) $goods->_id => Yii::t('product', 'goods_not_enough')]);
         } else {
             $goodsId = (string) $goods->_id;
             $successExchange[$goodsId] = $goodsRollbackModifier;
         }
     }
     $memberUpdatedCount = Member::updateAll(['$inc' => ['score' => 0 - $usedScore]], ['_id' => $member->_id, 'score' => ['$gte' => $usedScore]]);
     if ($memberUpdatedCount === 1) {
         $this->_saveLog($member, $exchanges, $params, $user);
         if (!empty($params['useWebhook'])) {
             $eventData = ['type' => Webhook::EVENT_PRODUCT_REDEEMED, 'member_id' => $params['memberId'], 'products' => $params['goods'], 'address' => $params['address'], 'postcode' => $params['postcode'], 'used_score' => $params['usedScore'], 'origin' => Member::PORTAL, 'account_id' => (string) $member->accountId, 'created_at' => TimeUtil::msTime2String(time() * TimeUtil::MILLI_OF_SECONDS, \DateTime::ATOM)];
             Yii::$app->webhook->triggerEvent($eventData);
         }
     } else {
         $this->_rollBackUsedCount($successExchange);
         throw new InvalidParameterException(Yii::t('product', 'member_score_not_enough'));
     }
 }