ExcelWorksheet.ts 4.57 KB
Newer Older
Fullarton's avatar
Fullarton committed
1 2
import * as xlsx from 'excel4node';
import * as MessageFormat from 'messageformat';
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
3 4 5 6 7
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';
8
import { excelDefaultWorksheetOptions } from './lib/excel_default_options';
Fullarton's avatar
Fullarton committed
9

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

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

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

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

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

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

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

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

  protected _ws: xlsx.Worksheet;

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

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

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

    this._columnsToFormat = 4;
    if (questionIndex) {
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
75
      this._responsesWithConfidenceValue = this._quiz.memberGroups[0].members.filter(nickname => {
Fullarton's avatar
Fullarton committed
76 77 78
        return nickname.responses[questionIndex].confidence > -1;
      });
    } else {
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
79
      this._responsesWithConfidenceValue = this._quiz.memberGroups[0].members.filter(nickname => {
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
80
        return nickname.responses.filter(responseItem => responseItem.confidence > -1);
Fullarton's avatar
Fullarton committed
81 82 83 84 85
      });
    }
    if (this._responsesWithConfidenceValue.length > 0) {
      this._columnsToFormat++;
    }
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
86
    if (this._quiz.sessionConfig.nicks.restrictToCasLogin) {
Fullarton's avatar
Fullarton committed
87 88 89 90 91 92 93 94 95 96 97 98 99
      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
100
  protected getLeaderboardData(questionIndex: number): Array<ILeaderBoardItemBase> {
Fullarton's avatar
Fullarton committed
101 102 103
    const leaderBoard = new Leaderboard();
    const correctResponses: any = {};

Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
104
    const question: AbstractQuestionEntity = this.quiz.questionList[questionIndex];
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
105
    this.quiz.memberGroups[0].members.forEach(attendee => {
Fullarton's avatar
Fullarton committed
106 107
      if (leaderBoard.isCorrectResponse(attendee.responses[questionIndex], question) === 1) {
        if (!correctResponses[attendee.name]) {
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
108 109 110 111 112
          correctResponses[attendee.name] = {
            responseTime: 0,
            correctQuestions: [],
            confidenceValue: 0,
          };
Fullarton's avatar
Fullarton committed
113 114 115 116 117 118 119 120 121 122 123
        }
        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);
  }
124 125 126 127

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