/**
  * @args {"description": "Delay: Stats of questionnaire"}
  */
 public function perform()
 {
     $args = $this->args;
     //Get date from args or today
     $date = empty($args['date']) ? '' : $args['date'];
     $datetime = TimeUtil::getDatetime($date);
     $dateStr = date('Y-m-d', $datetime);
     $stats = QuestionnaireLog::getStats($dateStr);
     $statsRows = [];
     foreach ($stats as $stat) {
         $questionnaireId = $stat['_id']['questionnaireId'];
         $accountId = $stat['_id']['accountId'];
         //if $dailyStats exists, update it; else , create
         $dailyStats = ModelStatsQuestionnaireDaily::getByQuestionnaireAndDate($accountId, $questionnaireId, $dateStr);
         if (empty($dailyStats)) {
             $statsRows[] = ['accountId' => $accountId, 'questionnaireId' => $questionnaireId, 'date' => $dateStr, 'count' => $stat['count']];
         } else {
             $dailyStats->count = $stat['count'];
             //catch exception to avoid block batch insert
             try {
                 $dailyStats->save(true, ['count']);
             } catch (Exception $e) {
                 LogUtil::error(['Update StatsQuestionnaireDaily error' => $e->getMessage(), 'StatsQuestionnaireDaily' => $dailyStats]);
                 continue;
             }
         }
     }
     ModelStatsQuestionnaireDaily::batchInsert($statsRows);
     return true;
 }
 /**
  * @args {"description": "Delay: Stats of questionnaire answer"}
  */
 public function perform()
 {
     $args = $this->args;
     //Get date from args or today
     $date = empty($args['date']) ? '' : $args['date'];
     $datetime = TimeUtil::getDatetime($date);
     $dateStr = date('Y-m-d', $datetime);
     //in case of too much data, get stats by questionnaire
     $skip = 0;
     $limit = 100;
     $query = Questionnaire::find()->orderBy(['_id' => SORT_ASC]);
     $query = $query->offset($skip)->limit($limit);
     $questionnaires = $query->all();
     while (!empty($questionnaires)) {
         $statsRows = [];
         foreach ($questionnaires as $questionnaire) {
             $stats = QuestionnaireLog::getAnswerStats($questionnaire->_id, $dateStr);
             //group stats by questionId
             $rows = [];
             foreach ($stats as $stat) {
                 $questionIdStr = (string) $stat['_id']['questionId'];
                 $optionValue = $stat['_id']['value'];
                 $rows[$questionIdStr][] = ['option' => $optionValue, 'count' => $stat['count']];
             }
             //format stats data, and save it
             foreach ($rows as $questionIdStr => $answerStats) {
                 $questionId = new MongoId($questionIdStr);
                 $statsAnswerDaily = ModelStatsQuestionnaireAnswerDaily::getByQuestionIdAndDate($questionId, $dateStr);
                 if (empty($statsAnswerDaily)) {
                     $statsRows[] = ['questionId' => $questionId, 'stats' => $answerStats, 'date' => $dateStr, 'accountId' => $questionnaire->accountId];
                 } else {
                     $statsAnswerDaily->stats = $answerStats;
                     try {
                         $statsAnswerDaily->save();
                     } catch (Exception $e) {
                         ResqueUtil::log(['Update StatsQuestionnaireAnswerDaily error' => $e->getMessage(), 'StatsQuestionnaireAnswerDaily' => $statsAnswerDaily]);
                         continue;
                     }
                 }
             }
         }
         ModelStatsQuestionnaireAnswerDaily::batchInsert($statsRows);
         $skip += $limit;
         $query = $query->offset($skip)->limit($limit);
         //free $questionnaires
         unset($questionnaires);
         $questionnaires = $query->all();
     }
     return true;
 }
 /**
  * View Questionnaire by questionnaire.
  *
  * <b>Request Type</b>: GET<br/><br/>
  * <b>Request Endpoint</b>:http://{server-domain}/api/questionnaire/{questionnaireId}&channelId={channelId}&openId={openId}br/><br/>
  * <b>Response Content-type</b>: application/json<br/><br/>
  * <b>Summary</b>: This api is used for viewing questionnaire.
  * <br/><br/>
  *
  * <b>Request Params</b>:<br/>
  *    id, string<br/>
  *    channelId, string<br/>
  *    openId, string<br/>
  *
  * <b>Response Example:</b><br/>
  *     {
  *           "_id": "55d6cb8be9c2fb022c8b4579",
  *           "name": "name",
  *           "startTime": "1429000112193",
  *           "endTime": "1429000116193",
  *           "description": "good",
  *           "question": [
  *               {
  *                   "id": "55d6cb8be9c2fb022c8b4577",
  *                   "title": "math",
  *                   "type": "radio",
  *                   "order": 0,
  *                   "options": [
  *                       {
  *                           "icon": "support",
  *                           "content": "A option"
  *                       },
  *                       {
  *                           "icon": "support",
  *                           "content": "B option"
  *                       }
  *                   ]
  *               },
  *               {
  *                   "id": "55d6cb8be9c2fb022c8b4577",
  *                   "type": "input",
  *                   "title": "This is a problem",
  *                   "order": 1
  *               }
  *           ],
  *           "isPublished": false,
  *           "answerTime": "2015-08-26 10:28:55",
  *           "isAnswered": false
  *     }
  * <pre>
  * </pre>
  */
 public function actionView($id)
 {
     $channelId = $this->getQuery('channelId');
     $openId = $this->getQuery('openId');
     $isAnswered = false;
     $question = [];
     $answerTime = '';
     $questionnaire = [];
     $user = ["channelId" => $channelId, "openId" => $openId];
     $questionnaireInfo = Questionnaire::getById(new MongoId($id));
     if (empty($questionnaireInfo)) {
         throw new InvalidParameterException(Yii::t('content', 'questionnaire_no_exist'));
     }
     if (!empty($channelId) && !empty($openId)) {
         $questionnaireLogInfo = QuestionnaireLog::getByQuestionnaireAndUser(new MongoId($id), $user);
         if (!empty($questionnaireLogInfo)) {
             $answerTime = MongodbUtil::MongoDate2String($questionnaireLogInfo->createdAt, 'Y-m-d H:i:s');
             $isAnswered = true;
         }
     }
     $questionnaire = $questionnaireInfo->toArray();
     $questionnaire['answerTime'] = $answerTime;
     $questionnaire['isAnswered'] = $isAnswered;
     return $questionnaire;
 }
 /**
  * Get all answers by quesrionnaire and questionId
  */
 public function actionQuestionAnswers()
 {
     $params = $this->getQuery();
     if (empty($params['questionnaireId']) && empty($params['questionId'])) {
         throw new BadRequestHttpException(Yii::t('common', 'parameters_missing'));
     }
     $questionnaireId = new MongoId($params['questionnaireId']);
     $questionId = new MongoId($params['questionId']);
     $page = intval($this->getQuery('page', 1));
     $perPage = intval($this->getQuery('per-page', 20));
     $items = QuestionnaireLog::getAnswersByQuestionnaireId($questionnaireId, $questionId, $page, $perPage);
     foreach ($items as &$item) {
         $item['name'] = empty($item['name']) ? '' : $item['name'];
     }
     $totalCount = QuestionnaireLog::countByQuestionnaireId($questionnaireId);
     $meta = ['totalCount' => $totalCount, 'pageCount' => ceil($totalCount / $perPage), 'currentPage' => $page, 'perPage' => $perPage];
     return ['items' => $items, '_meta' => $meta];
 }
 public function actionView($id)
 {
     $questionnaireId = new MongoId($id);
     $questionnaire = Questionnaire::findByPk($questionnaireId);
     if (empty($questionnaire)) {
         throw new InvalidParameterException(Yii::t('common', 'invalid_questionnaire'));
     }
     $questionnaire = $questionnaire->toArray();
     $questionnaire['userCount'] = QuestionnaireLog::countByQuestionnaireId($questionnaireId);
     foreach ($questionnaire['questions'] as &$question) {
         $questionId = new MongoId($question['id']);
         $stats = StatsQuestionnaireAnswerDaily::getQuestionOptionStats($questionId);
         $statsMap = ArrayHelper::map($stats, 'option', 'count');
         if ($question['type'] !== Question::TYPE_INPUT) {
             foreach ($question['options'] as &$option) {
                 $option['count'] = empty($statsMap[$option['content']]) ? 0 : $statsMap[$option['content']];
             }
         }
     }
     return $questionnaire;
 }