Passed
Push — master ( 0e29a7...dfba81 )
by Mathieu
02:20 queued 23s
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
        'task.id',
79
        'task.name'
80
      ])
81
      .where('user.id = :userId', { userId })
82
      .andWhere('extract(month FROM event.date) = :month', { month })
83
      .andWhere('extract(year FROM event.date) = :year', { year })
84
      .innerJoin('event.user', 'user')
85
      .leftJoin('event.project', 'project')
86
      .leftJoin('event.task', 'task')
87
      .orderBy('event.date', 'ASC')
88
      .getMany();
89
  }
90
91
  public findBillableEventsByMonthAndProject(
92
    date: Date,
93
    project: Project
94
  ): Promise<any[]> {
95
    const month = date.getMonth() + 1;
96
    const year = date.getFullYear();
97
98
    return this.repository
99
      .createQueryBuilder('event')
100
      .select([
101
        'SUM(event.time) as time_spent',
102
        'event.billable as billable',
103
        'task.name as task_name',
104
        'user.firstName as first_name',
105
        'user.lastName as last_name'
106
      ])
107
      .where('project.id = :id', { id: project.getId() })
108
      .andWhere('extract(month FROM event.date) = :month', { month })
109
      .andWhere('extract(year FROM event.date) = :year', { year })
110
      .andWhere('event.type = :type', { type: EventType.MISSION })
111
      .addSelect(query => {
112
        return query
113
          .select('dailyRate.amount')
114
          .from(DailyRate, 'dailyRate')
115
          .where('d_user.id = user.id')
116
          .andWhere('d_task.id = task.id')
117
          .andWhere('d_customer.id = customer.id')
118
          .innerJoin('dailyRate.user', 'd_user')
119
          .innerJoin('dailyRate.task', 'd_task')
120
          .innerJoin('dailyRate.customer', 'd_customer');
121
      }, 'daily_rate')
122
      .innerJoin('event.project', 'project')
123
      .innerJoin('event.user', 'user')
124
      .innerJoin('event.task', 'task')
125
      .innerJoin('project.customer', 'customer')
126
      .groupBy('user.id, customer.id, event.time, task.id, event.billable')
127
      .getRawMany();
128
  }
129
130
  public async countEventsByUserAndPeriod(
131
    user: User,
132
    startDate: string,
133
    endDate: string
134
  ): Promise<number> {
135
    const result = await this.repository
136
      .createQueryBuilder('event')
137
      .select('count(event.id) as id')
138
      .where('user.id = :id', { id: user.getId() })
139
      .andWhere('event.date BETWEEN :startDate AND :endDate', {
140
        startDate,
141
        endDate
142
      })
143
      .innerJoin('event.user', 'user')
144
      .getRawOne();
145
146
    return Number(result.id) || 0;
147
  }
148
149
  public findAllEventsByMonth(date: Date): Promise<FindAllEventsByMonth[]> {
150
    const month = date.getMonth() + 1;
151
    const year = date.getFullYear();
152
153
    return this.repository
154
      .createQueryBuilder('event')
155
      .select([
156
        'event.date as date',
157
        'user.id as user',
158
        'SUM(event.time)::int as duration'
159
      ])
160
      .where('extract(month FROM event.date) = :month', { month })
161
      .andWhere('extract(year FROM event.date) = :year', { year })      
162
      .innerJoin('event.user', 'user')
163
      .groupBy('event.date, user.id')
164
      .getRawMany();
165
  }
166
}
167