public static function preProcessCnyWinnerData($condition) { // TODO refine smsContent $smsTemplate = BulkSmsUtil::CNY_WINNERS_SMS_TEMPLATE; $winners = LuckyDrawWinner::find()->where($condition)->all(); $rows = array(); foreach ($winners as $winner) { $smsContent = str_replace("%username%", $winner->name, $smsTemplate); $smsContent = str_replace("%awardName%", $winner->awardName, $smsContent); $member = Member::getByMobile($winner->mobile, $condition['accountId']); if ($member != null) { $city = null; $site = null; foreach ($member->properties as $property) { if ($property['name'] == '縣市') { $city = $property['value']; } if ($property['name'] == '地址') { $site = $property['value']; } } $row = ['mobile' => " " . $winner->mobile, 'name' => $winner->name, 'city' => $city, 'site' => $site, 'awardName' => $winner->awardName, 'scoreAdded' => $winner->winInfo['scoreAdded'], 'createdAt' => MongodbUtil::MongoDate2String($winner->createdAt, 'Y-m-d H:i', null), 'remark' => $winner->winInfo['boughtAllProducts'] ? '已包含全部3支品項' : '', 'smsContent' => $smsContent]; $rows[] = $row; unset($row, $smsContent, $member, $city, $site); } } return $rows; }
/** * @args {"description": "Delay: Stats of StatsMemberGrowthMonthly every day"} * @author Rex Chen */ public function perform() { $args = $this->args; $date = empty($args['date']) ? '' : $args['date']; $datetime = TimeUtil::getDatetime($date); $dateStr = date('Y-m', $datetime); $startTime = new \MongoDate(strtotime($dateStr . '-01')); $endTime = new \MongoDate(strtotime($dateStr . '-01 +1 month')); $accounts = Account::findAll(['enabledMods' => 'member']); foreach ($accounts as $account) { $accountId = $account->_id; $totalMember = Member::countByAccount($accountId, null, $endTime); $totalActive = MemberLogs::getTotalActiveByAccount($accountId, $startTime, $endTime); $totalNew = Member::countByAccount($accountId, $startTime, $endTime); $statsGrowth = ModelStatsMemberGrowthMonthly::getByMonthAndAccount($accountId, $dateStr); if (empty($statsGrowth)) { $statsGrowth = new ModelStatsMemberGrowthMonthly(); $statsGrowth->accountId = $accountId; $statsGrowth->month = $dateStr; } $statsGrowth->totalNew = $totalNew; $statsGrowth->totalActive = $totalActive; $statsGrowth->totalInactive = $totalMember - $totalActive; try { $statsGrowth->save(); } catch (Exception $e) { ResqueUtil::log(['Update StatsMemberGrowthMonthly error' => $e->getMessage(), 'StatsMemberGrowthMonthly' => $statsGrowth]); continue; } } return true; }
/** * Check expired membership card. */ public function actionCheckCardExpiredTime() { $accounts = Account::find()->where(['isDeleted' => Account::NOT_DELETED])->all(); if (!empty($accounts)) { $nowTimestamp = strtotime(date('Y-m-d')) * 1000; $oneDayTimestamp = 24 * 60 * 60 * 1000; foreach ($accounts as $account) { $accountId = $account->_id; for ($day = 0; $day <= 7; $day++) { $startDayTimestamp = $nowTimestamp + $oneDayTimestamp * ($day - 1); $endDayTimestamp = $nowTimestamp + $oneDayTimestamp * $day; if ($day === 0) { $startDayTimestamp = 0; } $expiredCount = Member::find()->where(['accountId' => $accountId, 'cardExpiredAt' => ['$lte' => $endDayTimestamp, '$gt' => $startDayTimestamp], 'isDeleted' => Member::NOT_DELETED])->count(); if ($expiredCount > 0) { if ($day === 0) { $content = "有 {$expiredCount} 个会员的会员卡已过期, <a href='/member/member?cardState=3'>(点击查看)</a>"; } else { if ($day === 1) { $content = "有 {$expiredCount} 个会员的会员卡即将于1天内过期, <a href='/member/member?cardState=1'>(点击查看)</a>"; } else { $date = date("Y-m-d", $startDayTimestamp / 1000); $content = "有 {$expiredCount} 个会员的会员卡即将于 {$date} 过期, <a href='/member/member?cardState=2'>(点击查看)</a>"; } } $this->_recordMessage($accountId, $content); } } } } }
/** * @args {"description": "Delay: Stats of StatsMemberDaily", "runNextJob": true} * @author Rex Chen */ public function perform() { $args = $this->args; $date = empty($args['date']) ? '' : $args['date']; $datetime = TimeUtil::getDatetime($date); $dateStr = date('Y-m-d', $datetime); if (!empty(WECONNECT_DOMAIN)) { $channelNameMap = $this->_getChannelNameMap(); } $start = new \MongoDate($datetime); $end = new \MongoDate(strtotime('+1 day', $datetime)); $memberStats = Member::getNewMemberStats($start, $end); $rowStats = []; foreach ($memberStats as $stats) { $accountId = $stats['_id']['accountId']; $origin = $stats['_id']['origin']; $socialAccountId = $stats['_id']['socialAccountId']; $originName = empty($channelNameMap[$socialAccountId]) ? '' : $channelNameMap[$socialAccountId]; $total = $stats['total']; $statsMember = ModelStatsMemberDaily::getByDateAndOriginInfo($dateStr, $origin, $originName, $accountId); if (!empty($statsMember)) { $statsMember->total = $total; try { $statsMember->save(true, ['total']); } catch (Exception $e) { ResqueUtil::log(['Update StatsMemberDaily error' => $e->getMessage(), 'StatsMemberDaily' => $statsMember]); continue; } } else { $rowStats[] = ['date' => $dateStr, 'origin' => $origin, 'originName' => $originName, 'total' => $total, 'accountId' => $accountId]; } } ModelStatsMemberDaily::batchInsert($rowStats); return true; }
public function actionValidateNumber() { $mobile = Yii::$app->request->post("mobile"); $accountId = $this->getAccountId(); $result = Member::getByMobile($mobile, null); return $result; }
public function actionIndex() { $perPage = $this->getQuery('per-page', 20); $page = $this->getQuery('page', 1); $accountId = $this->getAccountId(); $account = Account::findByPk($accountId); $channels = Channel::getEnableChannelIds($accountId); $tags = empty($account->tags) ? [] : $account->tags; $tags = ArrayHelper::getColumn($tags, 'name', false); $totalCount = count($tags); rsort($tags); $tags = array_slice($tags, ($page - 1) * $perPage, $perPage); if (empty($tags)) { return ['items' => [], '_meta' => ['totalCount' => 0, 'pageCount' => 0, 'currentPage' => $page, 'perPage' => $perPage]]; } if (!defined('KLP') || !KLP) { if (!empty($channels)) { $followerTags = Yii::$app->weConnect->getTagStats($channels, $tags); } } $memberTags = Member::getTagStats($accountId, $tags, $channels); $memberTagMap = ArrayHelper::map($memberTags, '_id', 'count'); $items = []; foreach ($tags as $tag) { $items[] = ['name' => $tag, 'memberCount' => empty($memberTagMap[$tag]) ? 0 : $memberTagMap[$tag], 'followerCount' => empty($followerTags[$tag]) ? 0 : $followerTags[$tag]]; } $meta = ['totalCount' => $totalCount, 'pageCount' => ceil($totalCount / $perPage), 'currentPage' => $page, 'perPage' => $perPage]; return ['items' => $items, '_meta' => $meta]; }
public function actionIndex($accountId) { if (empty($accountId)) { echo 'accountId is invaild' . PHP_EOL; exit; } $where['accountId'] = new \MongoId($accountId); // delete member info Member::getCollection()->remove($where); //delete MemberLogs MemberLogs::getCollection()->remove($where); //delete scoreHistory ScoreHistory::getCollection()->remove($where); //delete CampaignLog CampaignLog::getCollection()->remove($where); //delete GoodsExchangeLog GoodsExchangeLog::getCollection()->remove($where); //delete MemberStatistics MemberStatistics::getCollection()->remove($where); //delete ReMemberCampaign ReMemberCampaign::getCollection()->remove($where); //delete StatsCampaignProductCodeQuarterly StatsCampaignProductCodeQuarterly::getCollection()->remove($where); //delete StatsMemberCampaignLogDaily StatsMemberCampaignLogDaily::getCollection()->remove($where); //delete StatsMemberDaily StatsMemberDaily::getCollection()->remove($where); //delete StatsMemberGrowthMonthly StatsMemberGrowthMonthly::getCollection()->remove($where); //delete StatsMemberGrowthQuarterly StatsMemberGrowthQuarterly::getCollection()->remove($where); //delete StatsMemberMonthly StatsMemberMonthly::getCollection()->remove($where); //delete StatsMemberPropAvgTradeQuarterly StatsMemberPropAvgTradeQuarterly::getCollection()->remove($where); //delete StatsMemberPropMonthly StatsMemberPropMonthly::getCollection()->remove($where); //delete StatsMemberPropQuaterly StatsMemberPropQuaterly::getCollection()->remove($where); //delete StatsMemberPropTradeCodeAvgQuarterly StatsMemberPropTradeCodeAvgQuarterly::getCollection()->remove($where); //delete StatsMemberPropTradeCodeQuarterly StatsMemberPropTradeCodeQuarterly::getCollection()->remove($where); //delete StatsMemberPropTradeQuarterly StatsMemberPropTradeQuarterly::getCollection()->remove($where); //delete PromotionCodeAnalysis PromotionCodeAnalysis::getCollection()->remove($where); //delete order Order::getCollection()->remove($where); //delete stats member order StatsMemberOrder::getCollection()->remove($where); //delete stats order StatsOrder::getCollection()->remove($where); //delete MembershipDiscount MembershipDiscount::getCollection()->remove($where); //delete couponLog CouponLog::getCollection()->remove($where); echo 'delete data successful.' . PHP_EOL; }
public function deleteTag($accountId, $name) { Account::updateAll(['$pull' => ['tags' => ['name' => $name]]], ['_id' => $accountId]); Member::updateAll(['$pull' => ['tags' => $name]], ['accountId' => $accountId, 'tags' => $name]); Campaign::updateAll(['$pull' => ['tags' => $name]], ['accountId' => $accountId, 'tags' => $name]); $data = ['type' => 'tag_deleted', 'account_id' => $accountId, 'name' => $name]; $this->notifyModules($data); }
/** * receive copon through oauth recall this api */ public function actionReceivedCoupon() { $params = $this->getQuery(); $defaultId = -1; $message = ''; if (empty($params['couponId']) || empty($params['memberId']) || empty($params['channelId'])) { LogUtil::error(['message' => 'missing params when receive coupon', 'params' => $params], 'product'); exit; } $number = !empty($params['number']) && intval($params['number']) > 1 ? intval($params['number']) : 1; $couponId = new MongoId($params['couponId']); $coupon = Coupon::findByPk($couponId); if (empty($coupon)) { LogUtil::error(['message' => 'invalid couponIdi when receive coupon', 'params' => $params], 'product'); exit; } $memberId = new MongoId($params['memberId']); $member = Member::findByPk($memberId); if (empty($member)) { LogUtil::error(['message' => 'invalid memberId when receive coupon', 'params' => $params], 'product'); exit; } $args = ['mainDomain' => Yii::$app->request->hostInfo . '/mobile/product/coupon', 'couponId' => $params['couponId'], 'id' => $defaultId, 'memberId' => $params['memberId'], 'result' => 'fail', 'channelId' => $params['channelId']]; //check the total if ($coupon->total < $number) { $message = Yii::t('product', 'coupon_no_exists'); return $this->_redirectCouponDetail($message, $args, $params); } //check limit $couponNumber = CouponLog::count(['couponId' => $couponId, 'member.id' => $memberId]); if ($couponNumber >= $coupon->limit) { $message = Yii::t('product', 'coupon_is_received'); return $this->_redirectCouponDetail($message, $args, $params); } //check the time $current = new MongoDate(strtotime(date('Y-m-d'))); if ($coupon->time['type'] == Coupon::COUPON_RELATIVE_TIME && $coupon->time['endTime'] < $current) { $message = Yii::t('product', 'coupon_expired'); return $this->_redirectCouponDetail($message, $args, $params); } //receive coupon $where = ['total' => ['$gte' => $number], '_id' => $couponId]; $number -= 2 * $number; if (Coupon::updateAll(['$inc' => ['total' => $number]], $where)) { $membershipDiscount = MembershipDiscount::transformMembershipDiscount($coupon, $member); if (false === $membershipDiscount->save()) { //to avoid the error show to user LogUtil::error(['message' => 'Failed to save couponLog error:' . $membershipDiscount->getErrors()], 'product'); $message = Yii::t('common', 'save_fail'); return $this->_redirectCouponDetail($message, $args, $params); } $args['id'] = isset($membershipDiscount->_id) ? $membershipDiscount->_id : $defaultId; $args['result'] = 'success'; } else { $message = '优惠券库存不足!'; } return $this->_redirectCouponDetail($message, $args, $params); }
/** * @param $member, object * @param $rule, string, score rule name */ public function updateItemByScoreRule($member) { //birthday score Member::birthdayScore($member); //perfect info score $ruleNames = [ScoreRule::NAME_PERFECT_INFO, ScoreRule::NAME_FIRST_CARD]; foreach ($ruleNames as $ruleName) { Member::rewardByScoreRule($ruleName, $member->_id, $member->accountId); } }
/** * The default implementation returns the names of the columns whose values have been populated into MemberShipCard. */ public function fields() { return array_merge(parent::fields(), ['name', 'poster', 'fontColor', 'privilege', 'condition', 'usageGuide', 'isEnabled', 'isDefault', 'isAutoUpgrade', 'scoreResetDate', 'provideCount' => function () { return Member::count(['cardId' => $this->_id]); }, 'createdAt' => function () { return MongodbUtil::MongoDate2String($this->createdAt, 'Y-m-d H:i:s'); }, 'updatedAt' => function () { return MongodbUtil::MongoDate2String($this->updatedAt, 'Y-m-d H:i:s'); }]); }
public function actionAddress($id) { $member = Member::findByPk(new \MongoId($id)); if (empty($member)) { throw new InvalidParameterException(Yii::t('member', 'no_member_find')); } $goodsExchangeLog = GoodsExchangeLog::getLastExpressByMember($member->_id); $address = empty($goodsExchangeLog->address) ? '' : $goodsExchangeLog->address; $postcode = empty($goodsExchangeLog->postcode) ? '' : $goodsExchangeLog->postcode; return ['address' => $address, 'postcode' => $postcode]; }
public static function getMemberInfo($condition) { $memberIds = CampaignLog::distinct('member.id', $condition); $members = Member::findAll(['_id' => ['$in' => $memberIds]]); $data = []; if (!empty($members)) { foreach ($members as $member) { $data[(string) $member->_id] = $member; } } return $data; }
public function perform() { $args = $this->args; if (empty($args['accountId']) || empty($args['key']) || empty($args['header'])) { ResqueUtil::log(['status' => 'fail to export member', 'message' => 'missing params', 'args' => $args]); return false; } Yii::$app->language = empty($args['language']) ? LanguageUtil::DEFAULT_LANGUAGE : $args['language']; $accountId = new \MongoId($args['accountId']); $header = $args['header']; // get member's customized properties $memberProperties = MemberProperty::getByAccount($accountId); foreach ($memberProperties as $memberProperty) { if ($memberProperty->isDefault) { $header[$memberProperty->name] = Yii::t('member', $memberProperty->name); } else { $header[$memberProperty->name] = $memberProperty->name; } } $socialAccountsMap = []; $account = Account::findByPk($accountId); $channelIds = Channel::getEnableChannelIds($accountId); if (!empty($channelIds)) { $socialAccounts = \Yii::$app->weConnect->getAccounts($channelIds); foreach ($socialAccounts as $socialAccount) { $socialAccountsMap[$socialAccount['id']] = $socialAccount['name']; } } $cardMap = []; $cards = MemberShipCard::getByAccount($accountId); foreach ($cards as $card) { $cardMap[(string) $card->_id] = $card->name; } $condition = unserialize($args['condition']); //get properties $memberProperties = MemberProperty::findAll(['accountId' => $accountId]); $base = ['cardMap' => $cardMap, 'socialAccountsMap' => $socialAccountsMap, 'memberProperties' => $memberProperties]; $fileName = $args['key']; $filePath = ExcelUtil::getFile($fileName, 'csv'); $orderBy = Member::normalizeOrderBy($args['params']); $object = Member::find(); $classFunction = '\\backend\\modules\\member\\models\\Member::preProcessMemberData'; ExcelUtil::processMultiData($header, $filePath, $base, $condition, $object, $classFunction, [], $orderBy); $hashKey = ExcelUtil::setQiniuKey($filePath, $fileName); if ($hashKey) { //notice frontend the job is finished \Yii::$app->tuisongbao->triggerEvent(Message::EVENT_EXPORT_FINISH, ['key' => $fileName], [Message::CHANNEL_GLOBAL . $args['accountId']]); return true; } else { return false; } }
private function preProcessDrawMembers($condition, $accountId) { $rows = array(); $scores = EarlybirdSmsUtil::getExchangeGoodsScore($condition['startDate'], $condition['endDate'], $accountId); asort($scores); foreach ($scores as $key => $value) { $row = array(); if (abs($value) >= $condition['pointsThree']) { $member = Member::findByPk(new \MongoId($key)); if (!$member->isDeleted) { $row['id'] = $key; $row['exchangeGoodsScore'] = abs($value); $row['cardNumber'] = $member->cardNumber; //拿到符合一等奖条件的人 if (abs($value) >= $condition['pointsOne']) { //eg: points>=2000 $row['prizeName'] = $condition['prizeNameOne']; $row['prizeLevel'] = '一等獎資格'; } //拿到符合二等奖条件的人 if (abs($value) < $condition['pointsOne'] && abs($value) >= $condition['pointsTwo']) { //eg: 1000<=points<2000 $row['prizeName'] = $condition['prizeNameTwo']; $row['prizeLevel'] = '二等獎資格'; } //拿到符合三等奖条件的人 if (abs($value) < $condition['pointsTwo'] && abs($value) >= $condition['pointsThree']) { //eg: 200<=points<1000 $row['prizeName'] = $condition['prizeNameThree']; $row['prizeLevel'] = '三等獎資格'; } if (!empty($member->properties)) { foreach ($member->properties as $property) { if ($property['name'] == 'tel') { $row['mobile'] = "'" . $property['value']; } if ($property['name'] == 'name') { $row['name'] = $property['value']; } } } } } $rows[] = $row; unset($row, $member); } return $rows; }
public function actionSendRedemptionMessage() { $params = $this->getParams(); $name = MessageTemplate::getTemplateName($params['type']); $mobileParams = MessageTemplate::getMobileVar($params); $accountId = $this->getAccountId(); $specialParams = MessageTemplate::getProductList($params); $template = MessageTemplate::getMobileTemplate($name, $accountId, $mobileParams, $specialParams); $params['memberId'] = new \MongoId($params['memberId']); $member = Member::getMemberInfo($params['memberId'], 'tel'); if (!empty($member['tel']) && !empty($template)) { return MessageUtil::sendMobileMessage($member['tel'], $template); } else { return false; } }
/** * @args {"description": "Delay: Automatic clear member score. every day"} */ public function perform() { $month = intval(date('m')); $day = intval(date('d')); $memberShipCards = MemberShipCard::find()->where(['isDeleted' => MemberShipCard::NOT_DELETED, 'scoreResetDate.month' => $month, 'scoreResetDate.day' => $day])->all(); if (!empty($memberShipCards)) { foreach ($memberShipCards as $memberShipCard) { $members = Member::find()->where(['isDeleted' => MemberShipCard::NOT_DELETED, 'cardId' => $memberShipCard->_id, 'score' => ['$ne' => 0]])->all(); if (!empty($members)) { foreach ($members as $member) { Member::resetScore($member->_id, $member->accountId); } } } } }
public function actionFixData($startData, $endData) { $accounts = Account::findAll(['enabledMods' => 'product']); foreach ($accounts as $account) { $accountId = $account->_id; $condition = ['accountId' => $accountId, 'createdAt' => ['$gte' => new MongoDate(strtotime($startData)), '$lt' => new Mongodate(strtotime($endData))]]; $pipeline = [['$match' => $condition], ['$group' => ['_id' => ['campaignId' => '$campaignId', 'code' => '$code'], 'count' => ['$sum' => 1]]], ['$match' => ['count' => ['$gt' => 1]]]]; $stats = CampaignLog::getCollection()->aggregate($pipeline); if (!empty($stats)) { foreach ($stats as $stat) { $code = $stat['_id']['code']; $logCondition = array_merge($condition, $stat['_id']); $logs = CampaignLog::find()->where($logCondition)->orderBy(['createdAt' => 1])->all(); $memberId = $logs[0]['member']['id']; $productName = $logs[0]['productName']; $description = $productName . ' ' . $code; $scoreHistoryCondition = ['memberId' => $memberId, 'brief' => ScoreHistory::ASSIGNER_EXCHANGE_PROMOTION_CODE, 'description' => $description]; $scoreHistorys = ScoreHistory::find()->where($scoreHistoryCondition)->orderBy(['createdAt' => 1])->all(); $keepScoreHistory = $scoreHistorys[0]; unset($scoreHistorys[0]); $removeScoreHistoryIds = []; $deduct = 0; foreach ($scoreHistorys as $scoreHistory) { $removeScoreHistoryIds[] = $scoreHistory->_id; $deduct += $scoreHistory->increment; } $member = Member::findByPk($memberId); if ($member->score <= $deduct || $member->totalScore <= $deduct || $member->totalScoreAfterZeroed <= $deduct) { echo 'Failed : Member' . $memberId . ' score not enough ' . 'score: ' . $member->score; echo ' totalScore: ' . $member->totalScore; echo ' totalScoreAfterZeroed: ' . $member->totalScoreAfterZeroed . PHP_EOL; continue; } $deductScore = 0 - $deduct; Member::updateAll(['$inc' => ['score' => $deductScore, 'totalScore' => $deductScore, 'totalScoreAfterZeroed' => $deductScore]], ['_id' => $memberId]); ScoreHistory::deleteAll(['_id' => ['$in' => $removeScoreHistoryIds]]); $logIds = ArrayHelper::getColumn($logs, '_id'); $keepLogId = $logIds[0]; unset($logIds[0]); CampaignLog::deleteAll(['_id' => ['$in' => array_values($logIds)]]); echo 'Success: ' . $productName . ' ' . $code . ' ' . $stat['count']; echo ' Deduct member ' . $memberId . ' score ' . $deduct . PHP_EOL; } } } echo 'Success' . PHP_EOL; }
/** * Get accountId and company when bind * @param array $params * @throws BadRequestHttpException * @throws InvalidParameterException * @return array */ public function bind($params) { \Yii::$app->language = LanguageUtil::LANGUAGE_ZH; $this->checkCode($params); $mobile = $params['mobile']; if (empty($params['channelId']) || empty($params['openId'])) { throw new BadRequestHttpException('Missing params'); } $channelId = $params['channelId']; $channel = Channel::getEnableByChannelId($channelId); $member = Member::getByMobile($mobile, $channel->accountId); if (!empty($member)) { throw new InvalidParameterException(['phone' => \Yii::t('common', 'phone_has_been_bound')]); } $account = Account::findByPk($channel->accountId); return ['accountId' => $channel->accountId, 'company' => empty($account->company) ? null : $account->company]; }
/** * @args {"description": "Delay: Send member expired message every day"} */ public function perform() { $accounts = Account::find()->where(['isDeleted' => Account::NOT_DELETED])->all(); if (!empty($accounts)) { $nowTimestamp = strtotime(date('Y-m-d')) * 1000; $oneDayTimestamp = 24 * 60 * 60 * 1000; foreach ($accounts as $account) { $accountId = $account->_id; for ($day = 0; $day <= 7; $day++) { $startDayTimestamp = $nowTimestamp + $oneDayTimestamp * ($day - 1); $endDayTimestamp = $nowTimestamp + $oneDayTimestamp * $day; if ($day === 0) { $startDayTimestamp = 0; } $expiredCount = Member::find()->where(['accountId' => $accountId, 'cardExpiredAt' => ['$lte' => $endDayTimestamp, '$gt' => $startDayTimestamp], 'isDeleted' => Member::NOT_DELETED])->count(); if ($expiredCount > 0) { if ($day === 0) { if ($expiredCount == 1) { $content = "msg_have {$expiredCount} msg_had_expired <a href='/member/member?cardState=3'> msg_click_read </a>"; } else { $content = "msg_have {$expiredCount} msg_had_expireds <a href='/member/member?cardState=3'> msg_click_read </a>"; } } else { if ($day === 1) { if ($expiredCount == 1) { $content = "msg_have {$expiredCount} msg_having_expired <a href='/member/member?cardState=1'> msg_click_read </a>"; } else { $content = "msg_have {$expiredCount} msg_had_expireds <a href='/member/member?cardState=1'> msg_click_read </a>"; } } else { $date = date("Y-m-d", $startDayTimestamp / 1000); if ($expiredCount == 1) { $content = "msg_have {$expiredCount} msg_having {$date} msg_expired <a href='/member/member?cardState=2'> msg_click_read </a>"; } else { $content = "msg_have {$expiredCount} msg_havings {$date} msg_expired <a href='/member/member?cardState=2'> msg_click_read </a>"; } } } $this->recordMessage($accountId, $content); } } } } }
public function operationCoupon($membershipDiscount) { //record log when get coupon $memberItem = Member::getMemberInfo($membershipDiscount->member['id'], ['tel']); $memberInfo = ['id' => $membershipDiscount->member['id'], 'name' => $membershipDiscount->member['name'], 'phone' => empty($memberItem['tel']) ? '' : $memberItem['tel'], 'receiveType' => $membershipDiscount->coupon['receiveType']]; $couponLog = new CouponLog(); $couponLog->couponId = $membershipDiscount->coupon['id']; $couponLog->membershipDiscountId = $membershipDiscount->_id; $couponLog->type = $membershipDiscount->coupon['type']; $couponLog->title = $membershipDiscount->coupon['title']; $couponLog->status = CouponLog::RECIEVED; $couponLog->member = $memberInfo; $couponLog->total = 1; $couponLog->operationTime = $couponLog->createdAt = new MongoDate(); $couponLog->accountId = $membershipDiscount->accountId; if (false === $couponLog->save()) { //to avoid the error show to user LogUtil::error(['message' => 'Failed to save couponLog error:' . $couponLog->getErrors()], 'product'); } }
public function actionIndex() { $params = $this->getQuery(); if (empty($params['memberId'])) { throw new BadRequestHttpException(Yii::t('common', 'parameters_missing')); } //get members openIds $member = Member::findByPk(new MongoId($params['memberId'])); $openIds = empty($member->socials) ? [] : ArrayHelper::getColumn($member->socials, 'openId'); $openIds[] = $member->openId; //get lastChatDate $lastConversation = ChatConversation::getLastByOpenIds($openIds); $lastChatDate = empty($lastConversation) ? '' : $lastConversation->date; //get conversations $params['openIds'] = $openIds; $accountId = $this->getAccountId(); $conversations = ChatConversation::search($params, $accountId); $result = $this->serializeData($conversations); $result['lastChatDate'] = $lastChatDate; return $result; }
public function perform() { $args = $this->args; if (empty($args['accountId']) || empty($args['properties'][0])) { ResqueUtil::log('Missing required arguments accountId or properties!'); return false; } $accountId = new \MongoId($args['accountId']); $property = $args['properties'][0]; $memberProperty = MemberProperty::findOne(['propertyId' => $property, 'accountId' => $accountId]); if (empty($memberProperty)) { ResqueUtil::log('Can not find member property with propertyId:' . $property); return false; } $date = empty($args['date']) ? '' : $args['date']; $date = TimeUtil::getDatetime($date); $month = date('Y-m', $date); $startDate = strtotime($month); $endDate = strtotime(date('Y-m', strtotime('+1 month', $date))); $raw = Member::getCollection()->aggregate([['$unwind' => '$properties'], ['$match' => ['createdAt' => ['$gte' => new \MongoDate($startDate), '$lt' => new \MongoDate($endDate)], 'properties.id' => $memberProperty->_id, 'accountId' => $accountId]], ['$group' => ['_id' => '$properties.value', 'total' => ['$sum' => 1]]]]); foreach ($raw as $item) { $total = $item['total']; $propValue = $item['_id']; // save the stats member property monthly $statsMemberPropMonthly = ModelStatsMemberPropMonthly::findOne(['propId' => $property, 'propValue' => $propValue, 'month' => $month, 'accountId' => $accountId]); if (empty($statsMemberPropMonthly)) { $statsMemberPropMonthly = new ModelStatsMemberPropMonthly(); $statsMemberPropMonthly->propId = $property; $statsMemberPropMonthly->propValue = $propValue; $statsMemberPropMonthly->month = $month; $statsMemberPropMonthly->accountId = $accountId; } $statsMemberPropMonthly->total = $total; ResqueUtil::log($statsMemberPropMonthly->attributes); $statsMemberPropMonthly->save(); } return true; }
public function actionListByTag() { $tagName = $this->getQuery('tagName'); $orderBy = $this->getQuery('orderBy', 'createdAt'); $accountId = $this->getAccountId(); $result = ['items' => [], 'memberCount' => 0]; $result['items'] = HelpDesk::getByAccountAndTags($tagName, $accountId, $orderBy); $result['memberCount'] = Member::getMemberCountByTags($tagName, $accountId); return $result; }
/** * Follower bind to be a member. * * <b>Request Type</b>: POST<br/><br/> * <b>Request Endpoint</b>:http://{server-domain}/api/mobile/bind<br/><br/> * <b>Response Content-type</b>: application/json<br/><br/> * <b>Summary</b>: This api is used for follower bind. * <br/><br/> * * <b>Request Params</b>:<br/> * mobile: string<br/> * openId: string<br/> * unionId: string<br/> * channelId: string<br/> * captcha: string<br/> * <br/><br/> * * <b>Response Params:</b><br/> * <br/><br/> * * <br/><br/> * * <b>Response Example</b>:<br/> * <pre> * { * "message": "OK", * "data": "http://wm.com?memberId=55d29e86d6f97f72618b4569" * </pre> */ public function actionBind() { //set language zh_cn when bind Yii::$app->language = LanguageUtil::LANGUAGE_ZH; $params = $this->getParams(); if (empty($params['mobile']) || empty($params['openId']) || empty($params['channelId']) || empty($params['captcha'])) { throw new BadRequestHttpException('missing param'); } $isTest = false; if ($params['mobile'] == self::TEST_PHONE && $params['captcha'] == self::TEST_CODE) { $isTest = true; } else { $this->attachBehavior('CaptchaBehavior', new CaptchaBehavior()); $this->checkCaptcha($params['mobile'], $params['captcha']); } //get accountId $openId = $params['openId']; $channel = Channel::getEnableByChannelId($params['channelId']); $origin = $channel->origin; $accountId = $channel->accountId; //create accessToken $token = Token::createForMobile($accountId); if (empty($token['accessToken'])) { throw new ServerErrorHttpException('Failed to create token for unknown reason.'); } $accessToken = $token['accessToken']; $this->setAccessToken($accessToken); //if member has bind if (empty($params['unionId'])) { $member = Member::getByOpenId($openId); } else { $unionId = $params['unionId']; $member = Member::getByUnionid($unionId); } if (!empty($member)) { $memberId = (string) $member->_id; $url = $this->buildBindRedirect($memberId, $params); return ['message' => 'OK', 'data' => $url]; } //check mobile has been bind $member = Member::getByMobile($params['mobile'], new \MongoId($accountId)); if (!empty($member)) { throw new InvalidParameterException(['phone' => Yii::t('common', 'phone_has_been_bound')]); } $follower = Yii::$app->weConnect->getFollowerByOriginId($openId, $params['channelId']); $originScene = empty($follower['firstSubscribeSource']) ? '' : $follower['firstSubscribeSource']; //init avatar and location $avatar = !empty($follower['headerImgUrl']) ? $follower['headerImgUrl'] : Yii::$app->params['defaultAvatar']; $location = []; !empty($follower['city']) ? $location['city'] = $follower['city'] : null; !empty($follower['province']) ? $location['province'] = $follower['province'] : null; !empty($follower['country']) ? $location['country'] = $follower['country'] : null; LogUtil::info(['message' => 'get follower info', 'follower' => $follower], 'channel'); //init member properties $memberProperties = MemberProperty::getByAccount($accountId); $propertyMobile = []; $propertyGender = []; $propertyName = []; $properties = []; foreach ($memberProperties as $memberProperty) { if ($memberProperty['name'] == Member::DEFAULT_PROPERTIES_MOBILE) { $propertyMobile['id'] = $memberProperty['_id']; $propertyMobile['name'] = $memberProperty['name']; $propertyMobile['value'] = $params['mobile']; $properties[] = $propertyMobile; } if ($memberProperty['name'] == Member::DEFAULT_PROPERTIES_GENDER) { $propertyGender['id'] = $memberProperty['_id']; $propertyGender['name'] = $memberProperty['name']; $propertyGender['value'] = !empty($follower['gender']) ? strtolower($follower['gender']) : 'male'; $properties[] = $propertyGender; } if ($memberProperty['name'] == Member::DEFAULT_PROPERTIES_NAME) { $propertyName['id'] = $memberProperty['_id']; $propertyName['name'] = $memberProperty['name']; $propertyName['value'] = $follower['nickname']; $properties[] = $propertyName; } } //get default card $card = MemberShipCard::getDefault($accountId); $memberId = new \MongoId(); $memberAttribute = ['$set' => ['_id' => $memberId, 'avatar' => $avatar, 'cardId' => $card['_id'], 'location' => $location, 'score' => 0, 'socialAccountId' => $params['channelId'], 'properties' => $properties, 'openId' => $openId, 'origin' => $origin, 'originScene' => $originScene, 'unionId' => empty($unionId) ? '' : $unionId, 'accountId' => $accountId, 'cardNumber' => Member::generateCardNumber($card['_id']), 'cardProvideTime' => new \MongoDate(), 'createdAt' => new \MongoDate(), 'socials' => [], 'isDeleted' => false]]; if (!$isTest) { $result = Member::updateAll($memberAttribute, ['openId' => $openId], ['upsert' => true]); } else { $result = true; } if ($result) { // reword score first bind card $this->attachBehavior('MemberBehavior', new MemberBehavior()); $this->updateItemByScoreRule(Member::findByPk($memberId)); Yii::$app->qrcode->create(Yii::$app->request->hostInfo, Qrcode::TYPE_MEMBER, $memberId, $accountId); $memberId = (string) $memberId; $url = $this->buildBindRedirect($memberId, $params); return ['message' => 'OK', 'data' => $url]; } else { LogUtil::error(['error' => 'member save error', 'params' => Json::encode($member)], 'member'); throw new ServerErrorHttpException("bind fail"); } }
private function _repairData() { $fileName = 'deleted-' . time(); $result = $this->_getRepairData(); foreach ($result as $item) { $condition = ['properties' => ['$elemMatch' => ['name' => Member::DEFAULT_PROPERTIES_MOBILE, 'value' => $item['_id']['tel']]], 'accountId' => $item['_id']['accountId']]; $members = Member::findAll($condition); $score = []; $keepMember = []; $deleteMember = []; foreach ($members as $member) { if (!in_array($member->score, $score)) { $score[] = $member->score; $keepMember[] = $member->_id; } else { $msg = 'deleted member ' . $member->_id . PHP_EOL; $deleteMember[] = $member->_id; echo $msg; $this->_saveFile($msg, $fileName); } } $deleteCondition = ['_id' => ['$in' => $deleteMember]]; Member::deleteAll($deleteCondition); } }
/** * get member info even if the member is deleted * @param $condition, array */ public static function getAllMember($condition) { $members = Member::find()->where($condition)->all(); return $members; }
/** * Conversion format for couponLog. * @param $coupon Object * @param $member Object * @param $tokenInfo Object */ public static function transformCouponLog($coupon, $member, $membershipDiscountId) { $memberItem = Member::getMemberInfo($member->_id, ['name', 'tel']); $memberInfo = ['id' => $member->_id, 'name' => empty($memberItem['name']) ? '' : $memberItem['name'], 'phone' => empty($memberItem['tel']) ? '' : $memberItem['tel']]; $couponLog = new CouponLog(); $couponLog->couponId = $coupon->_id; $couponLog->membershipDiscountId = $membershipDiscountId; $couponLog->type = $coupon->type; $couponLog->title = $coupon->title; $couponLog->status = self::RECIEVED; $couponLog->member = $memberInfo; $couponLog->total = 1; $couponLog->operationTime = new \MongoDate(); $couponLog->createdAt = new \MongoDate(); $couponLog->accountId = $coupon->accountId; return $couponLog; }
/** * This function is just for fix error promotionCode redeem data * @param MongoId $accountId * @param MongoId $memberId * @param Array $codes * @return boolean, true, if there is no error data */ private function fixData($accountId, $memberId, $codes) { $condition = ['accountId' => $accountId, 'member.id' => $memberId, 'code' => ['$in' => $codes]]; $pipeline = [['$match' => $condition], ['$group' => ['_id' => ['campaignId' => '$campaignId', 'code' => '$code'], 'count' => ['$sum' => 1]]], ['$match' => ['count' => ['$gt' => 1]]]]; $stats = CampaignLog::getCollection()->aggregate($pipeline); if (empty($stats)) { return true; } $logCondition = ['accountId' => $accountId, 'member.id' => $memberId]; $failedMessages = []; $successMessages = []; foreach ($stats as $stat) { $code = $stat['_id']['code']; //get campaign log $logCondition = array_merge($logCondition, $stat['_id']); $logs = CampaignLog::find()->where($logCondition)->orderBy(['createdAt' => SORT_ASC])->all(); $memberId = $logs[0]['member']['id']; $productName = $logs[0]['productName']; //get score history $description = $productName . ' ' . $code; $scoreHistoryCondition = ['memberId' => $memberId, 'brief' => ScoreHistory::ASSIGNER_EXCHANGE_PROMOTION_CODE, 'description' => $description]; $scoreHistorys = ScoreHistory::find()->where($scoreHistoryCondition)->orderBy(['createdAt' => SORT_ASC])->all(); $keepScoreHistory = $scoreHistorys[0]; unset($scoreHistorys[0]); $removeScoreHistoryIds = []; $deduct = 0; foreach ($scoreHistorys as $scoreHistory) { $removeScoreHistoryIds[] = $scoreHistory->_id; $deduct += $scoreHistory->increment; } $member = Member::findByPk($memberId); //if member score not enough, log continue if ($member->score <= $deduct || $member->totalScore <= $deduct || $member->totalScoreAfterZeroed <= $deduct) { $failedMessages[] = ['Failed' => 'Member score not enough', 'member' => $member->toArray(), 'deduct' => $deduct]; continue; } //fix member score $deductScore = 0 - $deduct; Member::updateAll(['$inc' => ['score' => $deductScore, 'totalScore' => $deductScore, 'totalScoreAfterZeroed' => $deductScore]], ['_id' => $memberId]); //remove scorehistory ScoreHistory::deleteAll(['_id' => ['$in' => $removeScoreHistoryIds]]); //remove campaignlog $logIds = ArrayHelper::getColumn($logs, '_id'); $keepLogId = $logIds[0]; unset($logIds[0]); CampaignLog::deleteAll(['_id' => ['$in' => array_values($logIds)]]); $successMessages[] = ['Success' => $productName . ' ' . $code . ' ' . $stat['count'], 'memberId' => $memberId, 'deduct' => $deduct]; } LogUtil::error(['Failed' => $failedMessages, 'Success' => $successMessages], 'fix-campaign-data'); }
/** * Get member by birth according score rule trigger time * @param string $triggerTime * @return member list */ private function getMembers($accountId, $triggerTime, $memberId = null) { $timeCondition = $this->getTimeCondition($triggerTime); $memberIds = []; if (!empty($timeCondition['timeFrom']) && !empty($timeCondition['timeTo'])) { if (empty($memberId)) { $members = Member::searchByBirth($timeCondition['timeFrom'], $timeCondition['timeTo'], $accountId); $memberIds = Member::getIdList($members); } else { $condition = ['birth' => ['$gte' => $timeCondition['timeFrom'], '$lte' => $timeCondition['timeTo']]]; $member = Member::findByPk($memberId, $condition); if (!empty($member)) { $memberIds = [$member->_id]; } } } return $memberIds; }