/**
  * @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;
 }
 /**
  * Get question option answer's stats info
  * @throws BadRequestHttpException
  * @return array, [{"option": "Yes", "count": 12}]
  */
 public function actionAnswers()
 {
     $params = $this->getQuery();
     if (empty($params['questionId'])) {
         throw new BadRequestHttpException(Yii::t('common', 'parameters_missing'));
     }
     $question = Question::findByPk(new MongoId($params['questionId']));
     if (empty($question) || $question->type === Question::TYPE_INPUT) {
         throw new InvalidParameterException(Yii::t('content', 'invalid_question'));
     }
     //turn unix timestamp to string
     $startDateStr = isset($params['startTime']) ? TimeUtil::msTime2String($params['startTime'], 'Y-m-d') : null;
     $endDateStr = isset($params['endTime']) ? TimeUtil::msTime2String($params['endTime'], 'Y-m-d') : null;
     $stats = StatsQuestionnaireAnswerDaily::getQuestionOptionStats(new MongoId($params['questionId']), $startDateStr, $endDateStr);
     $statsMap = ArrayHelper::map($stats, 'option', 'count');
     $options = [];
     $count = [];
     foreach ($question->options as $option) {
         $options[] = $option['content'];
         $count[] = empty($statsMap[$option['content']]) ? 0 : $statsMap[$option['content']];
     }
     return ['options' => $options, 'count' => $count];
 }
 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;
 }