public function perform() { $args = $this->args; if (empty($args['mainMember']) || empty($args['otherMemberIds'])) { ResqueUtil::log(['Merge member args error' => $args]); return; } $mainMember = unserialize($args['mainMember']); $otherMemberIds = unserialize($args['otherMemberIds']); //Get Name and phone $name = $phone = ''; foreach ($mainMember->properties as $mainProperty) { if ($mainProperty['name'] === Member::DEFAULT_PROPERTIES_NAME) { $name = $mainProperty['value']; } if ($mainProperty['name'] === Member::DEFAULT_PROPERTIES_MOBILE) { $phone = $mainProperty['value']; } } ScoreHistory::updateAll(['$set' => ['memberId' => $mainMember->_id]], ['memberId' => ['$in' => $otherMemberIds]]); MemberLogs::deleteAll(['memberId' => ['$in' => $otherMemberIds]]); CampaignLog::updateAll(['$set' => ['member.id' => $mainMember->_id, 'member.cardNumber' => $mainMember->cardNumber, 'member.name' => $name, 'member.phone' => $phone]], ['member.id' => ['$in' => $otherMemberIds]]); PromotionCode::updateAll(['$set' => ['usedBy.memberId' => $mainMember->_id, 'usedBy.memberNumber' => $mainMember->cardNumber]], ['usedBy.memberId' => ['$in' => $otherMemberIds]]); GoodsExchangeLog::updateAll(['$set' => ['memberId' => $mainMember->_id, 'memberName' => $name, 'telephone' => $phone]], ['memberId' => ['$in' => $otherMemberIds]]); $otherMemberStrIds = []; foreach ($otherMemberIds as $otherMemberId) { $otherMemberStrIds[] = (string) $otherMemberId; } Order::updateAll(['$set' => ['consumer.id' => (string) $mainMember->_id, 'consumer.name' => $name, 'consumer.phone' => $phone]], ['consumer.id' => ['$in' => $otherMemberStrIds]]); Qrcode::deleteAll(['type' => Qrcode::TYPE_MEMBER, 'associatedId' => ['$in' => $otherMemberIds]]); }
/** * export excel for the promotioncode to upload to qiniu,and return key to frontend */ public function actionExport() { $params = $this->getQuery(); if (empty($params['createdAt']) || empty($params['productId'])) { throw new BadRequestHttpException('missing param createdAt or productId'); } $productId = new MongoId($params['productId']); $product = Product::findByPk($productId); if (empty($product)) { throw new BadRequestHttpException('invalid productId'); } $startTime = new MongoDate($params['createdAt']); $endTime = new MongoDate($params['createdAt'] + 1); $condition = ['productId' => $productId, 'createdAt' => ['$gte' => $startTime, '$lt' => $endTime]]; $data = PromotionCode::findOne($condition); if ($data) { $accountId = $this->getAccountId(); list($sku, $code, $isUsed) = explode(',', Yii::t('product', 'export_promotioncode_title')); $header = ['code' => $code, 'isUsed' => $isUsed]; $key = $product['name'] . '_' . date('Ymd') . '_' . $product['sku']; $status = ['vaild' => 'Y', 'unvaild' => 'N']; $fields = 'code,isUsed'; $exportArgs = ['status' => $status, 'header' => $header, 'key' => $key, 'sku' => $product->sku, 'accountId' => (string) $accountId, 'condition' => serialize($condition), 'fields' => $fields, 'description' => 'Direct: export promotionCodes']; $jobId = Yii::$app->job->create('backend\\modules\\product\\job\\ExportPromotionCode', $exportArgs); $result = ['result' => 'success', 'message' => 'exporting file', 'data' => ['jobId' => $jobId, 'key' => $key]]; } else { $result = ['result' => 'error', 'message' => 'no datas', 'data' => []]; } return $result; }
public function extraFields() { return array_merge(parent::extraFields(), ['isAssociated' => function () { $campaign = Campaign::getByProductId($this->_id); return !empty($campaign); }, 'promotionCodeCount' => function () { return PromotionCode::countByProductIds([$this->_id]); }]); }
public function perform() { # Run task $args = $this->args; //job update productId switch ($args['type']) { case self::JOB_UPDATE: if (!empty($args['oldProductId']) && !empty($args['newProductId'])) { ModelPromotionCode::updateAll(['$set' => ['productId' => new \MongoId($args['newProductId'])]], ['productId' => new \MongoId($args['oldProductId']), 'isUsed' => false]); return true; } break; case self::JOB_GENERATE: //job generateCodes if (empty($accountId = $args['accountId']) || empty($productId = $args['productId']) || !array_key_exists('count', $args)) { ResqueUtil::log(['error' => 'generate codes params error', 'param' => $args]); return false; } $createdAt = new \MongoDate(time(), 0); $count = $args['count']; $successCount = 0; $batchCount = $count / self::PER_BATCH; for ($i = 0; $i < $batchCount; $i++) { $restCount = $count - self::PER_BATCH * $i; $rowsCount = $restCount >= self::PER_BATCH ? self::PER_BATCH : $restCount; $codes = ModelPromotionCode::generateCodes($rowsCount, new \MongoId($productId)); ResqueUtil::log(['info' => 'generate code ok', 'param' => $args]); $promotionCodes = []; foreach ($codes as $code) { $promotionCode = ['productId' => new \MongoId($productId), 'code' => $code, 'isUsed' => false, 'accountId' => new \MongoId($accountId), 'createdAt' => $createdAt, 'random' => rand()]; $promotionCodes[] = $promotionCode; } ResqueUtil::log(['info' => 'generate codes', 'param' => $args]); $result = ModelPromotionCode::batchInsert($promotionCodes); if (!$result) { ResqueUtil::log(['error' => 'save codes failed', 'param' => $args, 'success count' => $successCount]); } else { $successCount += $rowsCount; } } //change the isBindCode $this->changeProductStatus(new \MongoId($productId)); return true; case self::JOB_DELETE: if (!empty($args['productId'])) { $productId = new \MongoId($args['productId']); $condition = ['productId' => $productId]; } else { ResqueUtil::log(['error' => 'delete codes params error', 'param' => $args]); return false; } if (!empty($args['createdAt'])) { $createdAt = new \MongoDate($args['createdAt']); $condition = array_merge($condition, ['createdAt' => $createdAt]); } //if delete all code successfully,judge to change isBindCode if (ModelPromotionCode::deleteAll($condition)) { $count = ModelPromotionCode::count(["productId" => $productId]); if ($count <= 0) { Product::updateAll(['isBindCode' => false], ['_id' => $productId]); } } return true; case self::JOB_INSERT: if (!isset($args['accountId']) || !isset($args['productId']) || !isset($args['filename'])) { ResqueUtil::log(['error' => 'missing param accountId or productId or filename', 'param' => $args]); return false; } if (!isset($args['import'])) { $args['import'] = false; } $redis = \Yii::$app->cache->redis; $createdAt = new \MongoDate(time()); $product = Product::findOne($args['productId']); if (empty($product)) { ResqueUtil::log(['error' => 'product has been deleted', 'param' => $args]); return false; } $productId = $product['sku']; $cacheKey = $args['accountId'] . "_" . $productId . "_" . $args['filename']; $cacheSet = PromotionCheckCode::SET_HEAD . md5($cacheKey); $total = $redis->scard($cacheSet); //redis hash key name $cacheHash = md5($cacheKey); $k = 0; $promotionCodes = []; for ($i = 1; $i <= $total; ++$i) { // insert the code if ($args['import']) { $key = $redis->spop($cacheSet); if (!empty($key)) { $promotionCode = ['productId' => new \MongoId($args['productId']), 'code' => $key, 'isUsed' => false, 'accountId' => new \MongoId($args['accountId']), 'createdAt' => $createdAt]; $promotionCodes[$k++] = $promotionCode; } //set default value in redis to avoid to insert data in mongo failly $redis->HSET($cacheHash, 'right', 0); $redis->HSET($cacheHash, 'wrong', self::PROMO_CODE_REPEATED); //have data to store if (count($promotionCodes) > 0) { if ($k % self::PER_BATCH == 0 || $i == $total) { try { $result = ModelPromotionCode::batchInsert($promotionCodes); } catch (MongoDuplicateKeyException $e) { return false; } $promotionCodes = []; if (!$result) { ResqueUtil::log(['error' => 'save codes failed', 'param' => $args, 'success count' => $i - count($promotionCodes)]); } } } } } $redis->del($cacheSet); //change the isBindCode $this->changeProductStatus($product['_id']); //update duplicate key error $redis->HSET($cacheHash, 'wrong', 0); return true; break; case self::JOB_DELETE_REDIS_CODE: if (!isset($args['filename']) || !isset($args['productId']) || !isset($args['accountId'])) { ResqueUtil::log(['error' => 'missing param', 'param' => $args]); return false; } $redis = \Yii::$app->cache->redis; $cacheSet = PromotionCheckCode::SET_HEAD . md5($args['accountId'] . '_' . $args['productId'] . '_' . $args['filename']); $redis->del($cacheSet); unset($commonKey, $cacheTotalKey, $count); return true; break; default: break; } }
/** * check the status for code in offline * @param $codes,array * @param $accountId,objectId * @param $member,object * @param $exchangeTime,mongoDate */ public static function checkCodeStatus($codes, $accountId, $member, $exchangeTime, $params) { $invalid = $redeemed = $validCampaignCode = $redeemedMemberId = []; //check code redeem $condition = ['code' => ['$in' => $codes], 'isUsed' => true, 'accountId' => $accountId]; //get member info when code is redeemed $redeemedCodes = PromotionCode::findAll($condition); $redeemInfo = self::getRedeemCodeAndRedeemMemberId($redeemedCodes); $redeemed = $redeemInfo['code']; $redeemedMemberId = $redeemInfo['memberIds']; if (count($codes) != count($redeemed)) { //if the code are not all redeem, we need select campaign //1.get promotioncode which is vaild $unRedeemedCodes = array_diff($codes, $redeemed); //1.code is valid,2.code is not exists in collection $promocodes = self::getNotRedeemCode($unRedeemedCodes, $accountId); if (empty($promocodes)) { //if the promocodes is empty,the code all are invalid $invalid = $unRedeemedCodes; } else { //validCodeInfo struct is a array,key is code value is productId $validCodeProductId = self::getValidCodeInfoFromPromotionCode($promocodes); $validCode = array_keys($validCodeProductId); $validProductId = array_values($validCodeProductId); $notExistsCode = self::getNotExitsCode($unRedeemedCodes, $validCode); //get all campaign $condition = ['promotion.data' => ['$in' => $validProductId], 'accountId' => $accountId]; $campaigns = Campaign::findAll($condition); if (empty($campaigns)) { $invalid = $validCode; } else { //campaignCodeProductId is array.key is code value is productId $campaignCodeProductId = self::getCodeInfoFitWithCampaign($campaigns, $validCodeProductId); //merge not exists code and code whitch can not find any campaigns $invalid = array_merge($notExistsCode, array_diff($validCode, array_keys($campaignCodeProductId))); if (!empty($campaignCodeProductId)) { //order the code with source code,first-in first-out $campaignCodeProductId = self::orderCode($codes, $campaignCodeProductId); $validCampaignCode = self::checkCode2CampainStatus($campaignCodeProductId, $member, $exchangeTime, $params); } } } } $codes = []; if (!empty($invalid)) { foreach ($invalid as $invalidCode) { $codes[$invalidCode] = ['code' => $invalidCode, 'status' => self::CODE_STATUS_INVALID, 'score' => 0, 'description' => Yii::t('product', 'system_not_exists')]; } } if (!empty($redeemed)) { $codes = array_merge($codes, self::setMemberName($redeemedMemberId, $redeemedCodes)); } return array_merge($codes, $validCampaignCode); }