Passed
Pull Request — master (#235)
by Mathieu
01:39
created

EventRepository.findAllEventsByMonth   A

Complexity

Conditions 1

Size

Total Lines 16
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 15
dl 0
loc 16
c 0
b 0
f 0
rs 9.65
cc 1
1
import { Injectable } from '@nestjs/common';
2
import { InjectRepository } from '@nestjs/typeorm';
3
import { Repository } from 'typeorm';
4
import { FindAllEventsByMonth, IEventRepository } from 'src/Domain/FairCalendar/Repository/IEventRepository';
5
import { Event, EventType } from 'src/Domain/FairCalendar/Event.entity';
6
import { User } from 'src/Domain/HumanResource/User/User.entity';
7
import { DailyRate } from 'src/Domain/Accounting/DailyRate.entity';
8
import { Project } from 'src/Domain/Project/Project.entity';
9
10
@Injectable()
11
export class EventRepository implements IEventRepository {
12
  constructor(
13
    @InjectRepository(Event)
14
    private readonly repository: Repository<Event>
15
  ) {}
16
17
  public save(event: Event): Promise<Event> {
18
    return this.repository.save(event);
19
  }
20
21
  public delete(event: Event): void {
22
    this.repository.delete(event.getId());
23
  }
24
25
  public async sumOfTimeSpentByUserAndDate(
26
    user: User,
27
    date: string
28
  ): Promise<number> {
29
    const result = await this.repository
30
      .createQueryBuilder('event')
31
      .select('SUM(event.time) as time')
32
      .where('event.date = :date', { date })
33
      .andWhere('user.id = :user', { user: user.getId() })
34
      .innerJoin('event.user', 'user')
35
      .getRawOne();
36
37
    return Number(result.time) || 0;
38
  }
39
40
  public findOneById(id: string): Promise<Event> {
41
    return this.repository
42
      .createQueryBuilder('event')
43
      .select([
44
        'event.id',
45
        'event.time',
46
        'event.summary',
47
        'event.billable',
48
        'event.date',
49
        'event.type',
50
        'user.id',
51
        'project.id',
52
        'project.name',
53
        'task.id',
54
        'task.name'
55
      ])
56
      .where('event.id = :id', { id })
57
      .innerJoin('event.user', 'user')
58
      .leftJoin('event.project', 'project')
59
      .leftJoin('event.task', 'task')
60
      .getOne();
61
  }
62
63
  public findMonthlyEvents(date: string, userId: string): Promise<Event[]> {
64
    const month = new Date(date).getMonth() + 1;
65
    const year = new Date(date).getFullYear();
66
67
    return this.repository
68
      .createQueryBuilder('event')
69
      .select([
70
        'event.id',
71
        'event.time',
72
        'event.date',
73
        'event.summary',
74
        'event.billable',
75
        'event.type',
76
        'project.id',
77
        'project.name',
78
        'project.dayDuration',
79
        'task.id',
80
        'task.name'
81
      ])
82
      .where('user.id = :userId', { userId })
83
      .andWhere('extract(month FROM event.date) = :month', { month })
84
      .andWhere('extract(year FROM event.date) = :year', { year })
85
      .innerJoin('event.user', 'user')
86
      .leftJoin('event.project', 'project')
87
      .leftJoin('event.task', 'task')
88
      .orderBy('event.date', 'ASC')
89
      .getMany();
90
  }
91
92
  public findBillableEventsByMonthAndProject(
93
    date: Date,
94
    project: Project
95
  ): Promise<any[]> {
96
    const month = date.getMonth() + 1;
97
    const year = date.getFullYear();
98
99
    return this.repository
100
      .createQueryBuilder('event')
101
      .select([
102
        'SUM(event.time) as time_spent',
103
        'event.billable as billable',
104
        'task.name as task_name',
105
        'user.firstName as first_name',
106
        'user.lastName as last_name'
107
      ])
108
      .where('project.id = :id', { id: project.getId() })
109
      .andWhere('extract(month FROM event.date) = :month', { month })
110
      .andWhere('extract(year FROM event.date) = :year', { year })
111
      .andWhere('event.type = :type', { type: EventType.MISSION })
112
      .addSelect(query => {
113
        return query
114
          .select('dailyRate.amount')
115
          .from(DailyRate, 'dailyRate')
116
          .where('d_user.id = user.id')
117
          .andWhere('d_task.id = task.id')
118
          .andWhere('d_customer.id = customer.id')
119
          .innerJoin('dailyRate.user', 'd_user')
120
          .innerJoin('dailyRate.task', 'd_task')
121
          .innerJoin('dailyRate.customer', 'd_customer');
122
      }, 'daily_rate')
123
      .innerJoin('event.project', 'project')
124
      .innerJoin('event.user', 'user')
125
      .innerJoin('event.task', 'task')
126
      .innerJoin('project.customer', 'customer')
127
      .groupBy('user.id, customer.id, event.time, task.id, event.billable')
128
      .getRawMany();
129
  }
130
131
  public async countEventsByUserAndPeriod(
132
    user: User,
133
    startDate: string,
134
    endDate: string
135
  ): Promise<number> {
136
    const result = await this.repository
137
      .createQueryBuilder('event')
138
      .select('count(event.id) as id')
139
      .where('user.id = :id', { id: user.getId() })
140
      .andWhere('event.date BETWEEN :startDate AND :endDate', {
141
        startDate,
142
        endDate
143
      })
144
      .innerJoin('event.user', 'user')
145
      .getRawOne();
146
147
    return Number(result.id) || 0;
148
  }
149
150
  public findAllEventsByMonth(date: Date): Promise<FindAllEventsByMonth[]> {
151
    const month = date.getMonth() + 1;
152
    const year = date.getFullYear();
153
154
    return this.repository
155
      .createQueryBuilder('event')
156
      .select([
157
        'event.date as date',
158
        'user.id as user',
159
        'SUM(event.time)::int as duration'
160
      ])
161
      .where('extract(month FROM event.date) = :month', { month })
162
      .andWhere('extract(year FROM event.date) = :year', { year })      
163
      .innerJoin('event.user', 'user')
164
      .groupBy('event.date, user.id')
165
      .getRawMany();
166
  }
167
}
168