Passed
Pull Request — master (#143)
by Mathieu
01:52
created

AddEventCommandHandler.execute   B

Complexity

Conditions 5

Size

Total Lines 40
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 34
dl 0
loc 40
rs 8.5973
c 0
b 0
f 0
cc 5
1
import { CommandHandler } from '@nestjs/cqrs';
2
import { Inject } from '@nestjs/common';
3
import { AddEventCommand } from './AddEventCommand';
4
import { ITaskRepository } from 'src/Domain/Task/Repository/ITaskRepository';
5
import { IProjectRepository } from 'src/Domain/Project/Repository/IProjectRepository';
6
import { IEventRepository } from 'src/Domain/FairCalendar/Repository/IEventRepository';
7
import { IsMaximumTimeSpentReached } from 'src/Domain/FairCalendar/Specification/IsMaximumTimeSpentReached';
8
import { Event, EventType } from 'src/Domain/FairCalendar/Event.entity';
9
import { IDateUtils } from 'src/Application/IDateUtils';
10
import { ProjectOrTaskMissingException } from 'src/Domain/FairCalendar/Exception/ProjectOrTaskMissingException';
11
import { AbstractProjectAndTaskGetter } from './AbstractProjectAndTaskGetter';
12
import { NoDateDuringThisPeriodException } from 'src/Domain/FairCalendar/Exception/NoDateDuringThisPeriodException';
13
import { AddEventsView } from '../View/AddEventsView';
14
import { MaximumEventReachedException } from 'src/Domain/FairCalendar/Exception/MaximumEventReachedException';
15
16
@CommandHandler(AddEventCommand)
17
export class AddEventCommandHandler extends AbstractProjectAndTaskGetter {
18
  constructor(
19
    @Inject('ITaskRepository') taskRepository: ITaskRepository,
20
    @Inject('IProjectRepository') projectRepository: IProjectRepository,
21
    @Inject('IEventRepository')
22
    private readonly eventRepository: IEventRepository,
23
    @Inject('IDateUtils')
24
    private readonly dateUtils: IDateUtils,
25
    private readonly isMaximumTimeSpentReached: IsMaximumTimeSpentReached
26
  ) {
27
    super(taskRepository, projectRepository);
28
  }
29
30
  public async execute(command: AddEventCommand): Promise<AddEventsView> {
31
    const {type, startDate, endDate, projectId, taskId, summary, time, user} = command;
32
    const errors: string[] = [];
33
34
    if (type === EventType.MISSION && (!projectId || !taskId)) {
35
      throw new ProjectOrTaskMissingException();
36
    }
37
38
    const days = this.getDays(startDate, endDate);
39
    const [project, task] = await Promise.all([
40
      this.getProject(projectId),
41
      this.getTask(taskId)
42
    ]);
43
44
    for (const day of days) {
45
      const date = this.dateUtils.format(day, 'y-MM-dd');
46
      const event = new Event(
47
        type,
48
        user,
49
        time,
50
        date,
51
        project,
52
        task,
53
        summary
54
      );
55
56
      if (true === (await this.isMaximumTimeSpentReached.isSatisfiedBy(event))) {
57
        if (days.length === 1) {
58
          throw new MaximumEventReachedException();
59
        }
60
61
        errors.push(date);
62
        continue;
63
      }
64
65
      this.eventRepository.save(event);
66
    }
67
68
    return new AddEventsView(errors);
69
  }
70
71
  private getDays(startDate: Date, endDate: Date): Date[] {
72
    const days = this.dateUtils.getWorkedDaysDuringAPeriod(startDate, endDate);
73
74
    if (0 === days.length) {
75
      throw new NoDateDuringThisPeriodException();
76
    }
77
78
    return days;
79
  }
80
}
81