public function perform()
 {
     //accountId, properties are required fileds
     $args = $this->args;
     if (empty($args['accountId']) || empty($args['properties'])) {
         ResqueUtil::log('Missing required arguments accountId or properties!');
         return false;
     }
     $date = empty($args['date']) ? '' : $args['date'];
     $datetime = TimeUtil::getDatetime($date);
     $dateStr = date('Y-m-d', $datetime);
     $start = new MongoDate($datetime);
     $end = new MongoDate(strtotime('+1 day', $datetime));
     $accountId = new MongoId($args['accountId']);
     $condition = ['accountId' => $accountId, 'createdAt' => ['$gte' => $start, '$lt' => $end]];
     $campaignLogs = self::getCampaignLog($condition);
     if (empty($campaignLogs)) {
         LogUtil::info(['date' => date('Y-m-d H:i:s'), 'message' => $dateStr . ': campaignLogs is empty,no need to store data'], 'resque');
         return true;
     }
     //get all member info
     $memberInfos = self::getMemberInfo($condition);
     //Get all the property mongo id for comparison
     $condition = ['propertyId' => ['$in' => $args['properties']], 'accountId' => $accountId];
     $propertyIdStrs = self::getPropertyIds($condition);
     //Generate the meta data for inserting
     $statsRows = [];
     foreach ($campaignLogs as $campaignLog) {
         $campaignLog = $campaignLog['_id'];
         $redeemTime = self::getRedeemTime($campaignLog);
         //check the redeem time whether exists
         $condition = ['code' => $campaignLog['code'], 'productId' => $campaignLog['productId'], 'month' => date('Y-m', $redeemTime)];
         $memberCampaignLogDaily = ModelStatsMemberCampaignLogDaily::findOne($condition);
         if (empty($memberCampaignLogDaily)) {
             $memProperty = self::getProperty((string) $campaignLog['member']['id'], $memberInfos, $propertyIdStrs);
             $statsRows[] = ['memberId' => $campaignLog['member']['id'], 'memProperty' => $memProperty, 'productId' => $campaignLog['productId'], 'code' => $campaignLog['code'], 'year' => date('Y', $redeemTime), 'month' => date('Y-m', $redeemTime), 'quarter' => TimeUtil::getQuarter($redeemTime), 'accountId' => $accountId, 'createdAt' => new MongoDate(strtotime('+1 day', $datetime) - 1)];
         }
     }
     ModelStatsMemberCampaignLogDaily::batchInsert($statsRows);
     unset($statsRows, $memberCampaignLogDaily, $condition, $memProperty, $memberInfos);
     return true;
 }
 public static function createDailyData($members, $campaignLogs, $propertyIdStrs, $accountId)
 {
     $statsRows = [];
     foreach ($campaignLogs as $campaignLog) {
         $campaignLog = $campaignLog['_id'];
         if ($campaignLog['redeemTime'] == $campaignLog['createdAt']) {
             $createdAt = $campaignLog['createdAt'];
         } else {
             $createdAt = $campaignLog['redeemTime'];
         }
         //check the redeem time whether exists
         $createdAt = MongodbUtil::MongoDate2TimeStamp($createdAt);
         $month = date('Y-m', $createdAt);
         $memberId = $campaignLog['member']['id'];
         $memProperty = [];
         if (isset($members[(string) $memberId])) {
             $member = $members[(string) $memberId];
             foreach ($member->properties as $property) {
                 $propertyId = (string) $property['id'];
                 if (in_array($propertyId, $propertyIdStrs)) {
                     $memProperty[$propertyId] = $property['value'];
                 }
             }
         }
         $statsRows[] = ['memberId' => $memberId, 'memProperty' => $memProperty, 'productId' => $campaignLog['productId'], 'code' => $campaignLog['code'], 'year' => date('Y', $createdAt), 'month' => $month, 'quarter' => TimeUtil::getQuarter($createdAt), 'accountId' => $accountId, 'createdAt' => $campaignLog['createdAt']];
     }
     StatsMemberCampaignLogDaily::batchInsert($statsRows);
     unset($statsRows, $members, $campaignLog, $campaignLogs);
 }