ExcelWorksheet.ts 4.63 KB
Newer Older
Fullarton's avatar
Fullarton committed
1 2
import * as xlsx from 'excel4node';
import * as MessageFormat from 'messageformat';
3
import MemberDAO from '../db/MemberDAO';
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
4 5 6 7 8
import { AbstractQuestionEntity } from '../entities/question/AbstractQuestionEntity';
import { IMemberEntity } from '../interfaces/entities/Member/IMemberEntity';
import { ILeaderBoardItemBase } from '../interfaces/leaderboard/ILeaderBoardItemBase';
import { IQuizEntity } from '../interfaces/quizzes/IQuizEntity';
import { Leaderboard } from '../lib/leaderboard/leaderboard';
9
import { excelDefaultWorksheetOptions } from './lib/excel_default_options';
Fullarton's avatar
Fullarton committed
10

11
import { ExcelTheme } from './lib/excel_default_styles';
Fullarton's avatar
Fullarton committed
12 13

export abstract class ExcelWorksheet {
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
14
  get responsesWithConfidenceValue(): Array<IMemberEntity> {
Fullarton's avatar
Fullarton committed
15 16
    return this._responsesWithConfidenceValue;
  }
17

Fullarton's avatar
Fullarton committed
18 19 20
  get columnsToFormat(): number {
    return this._columnsToFormat;
  }
21

Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
22
  get quiz(): IQuizEntity {
Fullarton's avatar
Fullarton committed
23 24
    return this._quiz;
  }
25

Fullarton's avatar
Fullarton committed
26 27 28
  get createdAt(): string {
    return this._createdAt;
  }
29

30
  get mf(): MessageFormat.Msg {
Fullarton's avatar
Fullarton committed
31 32
    return this._mf;
  }
33

Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
34
  protected _leaderBoardData: Array<ILeaderBoardItemBase>;
35

Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
36
  get leaderBoardData(): Array<ILeaderBoardItemBase> {
37 38 39 40 41
    return this._leaderBoardData;
  }

  protected _ws: xlsx.Worksheet;

Fullarton's avatar
Fullarton committed
42 43 44
  get ws(): xlsx.Worksheet {
    return this._ws;
  }
45 46 47 48

  protected _options: Object;
  protected _theme: ExcelTheme;
  protected _translation: string;
49
  private readonly _mf: MessageFormat.Msg;
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
50
  private readonly _createdAt: string;
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
51
  private readonly _quiz: IQuizEntity;
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
52
  private readonly _columnsToFormat: number;
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
53
  private readonly _responsesWithConfidenceValue: Array<IMemberEntity>;
Fullarton's avatar
Fullarton committed
54

55
  protected constructor({ theme, translation, quiz, mf, questionIndex }) {
Fullarton's avatar
Fullarton committed
56 57 58 59 60 61 62
    this._theme = theme;
    this._translation = translation;
    this._quiz = quiz;
    this._mf = mf;
    this._createdAt = this.generateCreatedAtString();
    this._options = Object.assign({}, excelDefaultWorksheetOptions, {
      headerFooter: {
63
        firstHeader: mf('export.page_header', { createdAt: this._createdAt }),
Fullarton's avatar
Fullarton committed
64
        firstFooter: mf('export.page_footer'),
65
        evenHeader: mf('export.page_header', { createdAt: this._createdAt }),
Fullarton's avatar
Fullarton committed
66
        evenFooter: mf('export.page_footer'),
67
        oddHeader: mf('export.page_header', { createdAt: this._createdAt }),
Fullarton's avatar
Fullarton committed
68 69
        oddFooter: mf('export.page_footer'),
        alignWithMargins: true,
70 71
        scaleWithDoc: false,
      },
Fullarton's avatar
Fullarton committed
72 73 74 75
    });

    this._columnsToFormat = 4;
    if (questionIndex) {
76
      this._responsesWithConfidenceValue = MemberDAO.getMembersOfQuiz(this._quiz.name).filter(nickname => {
Fullarton's avatar
Fullarton committed
77 78 79
        return nickname.responses[questionIndex].confidence > -1;
      });
    } else {
80
      this._responsesWithConfidenceValue = MemberDAO.getMembersOfQuiz(this._quiz.name).filter(nickname => {
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
81
        return nickname.responses.filter(responseItem => responseItem.confidence > -1);
Fullarton's avatar
Fullarton committed
82 83 84 85 86
      });
    }
    if (this._responsesWithConfidenceValue.length > 0) {
      this._columnsToFormat++;
    }
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
87
    if (this._quiz.sessionConfig.nicks.restrictToCasLogin) {
Fullarton's avatar
Fullarton committed
88 89 90 91 92 93 94 95 96 97 98 99 100
      this._columnsToFormat += 2;
    }

    this._leaderBoardData = this.getLeaderboardData(questionIndex);
  }

  protected generateCreatedAtString(): string {
    const date = new Date();
    const dateYMD = `${this.prefixNumberWithZero(date.getDate())}.${this.prefixNumberWithZero(date.getMonth() + 1)}.${date.getFullYear()}`;
    const dateHM = `${this.prefixNumberWithZero(date.getHours())}:${this.prefixNumberWithZero(date.getMinutes())}`;
    return `${dateYMD} ${this._mf('export.exported_at')} ${dateHM} ${this._mf('export.exported_at_time')}`;
  }

Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
101
  protected getLeaderboardData(questionIndex: number): Array<ILeaderBoardItemBase> {
Fullarton's avatar
Fullarton committed
102 103 104
    const leaderBoard = new Leaderboard();
    const correctResponses: any = {};

Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
105
    const question: AbstractQuestionEntity = this.quiz.questionList[questionIndex];
106
    MemberDAO.getMembersOfQuiz(this._quiz.name).forEach(attendee => {
Fullarton's avatar
Fullarton committed
107 108
      if (leaderBoard.isCorrectResponse(attendee.responses[questionIndex], question) === 1) {
        if (!correctResponses[attendee.name]) {
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
109 110 111 112 113
          correctResponses[attendee.name] = {
            responseTime: 0,
            correctQuestions: [],
            confidenceValue: 0,
          };
Fullarton's avatar
Fullarton committed
114 115 116 117 118 119 120 121 122 123 124
        }
        correctResponses[attendee.name].responseTime += <number>attendee.responses[questionIndex].responseTime;
        correctResponses[attendee.name].correctQuestions.push(questionIndex);
        correctResponses[attendee.name].confidenceValue += <number>attendee.responses[questionIndex].confidence;
      } else {
        delete correctResponses[attendee.name];
      }
    });

    return leaderBoard.objectToArray(correctResponses);
  }
125 126 127 128

  private prefixNumberWithZero(num: number): string {
    return `${num < 10 ? '0' : ''}${num}`;
  }
Fullarton's avatar
Fullarton committed
129
}