Passed
Pull Request — master (#248)
by
unknown
04:57
created

GetUsersElementsQueryHandler.execute   B

Complexity

Conditions 3

Size

Total Lines 43
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 39
dl 0
loc 43
c 0
b 0
f 0
rs 8.9439
cc 3
1
import { QueryHandler } from '@nestjs/cqrs';
2
import { Inject } from '@nestjs/common';
3
import { IUserRepository } from 'src/Domain/HumanResource/User/Repository/IUserRepository';
4
import { UserElementsView } from '../View/UserElementsView';
5
import { GetUsersElementsQuery } from './GetUsersElementsQuery';
6
import { GetMealTicketsPerMonthQueryHandler } from '../../MealTicket/Query/GetMealTicketsPerMonthQueryHandler';
7
import { GetMealTicketsPerMonthQuery } from '../../MealTicket/Query/GetMealTicketsPerMonthQuery';
8
import { GetLeavesByMonthQueryHandler } from '../../Leave/Query/GetLeavesByMonthQueryHandler';
9
import { GetLeavesByMonthQuery } from '../../Leave/Query/GetLeavesByMonthQuery';
10
import { LeaveRequest } from 'src/Domain/HumanResource/Leave/LeaveRequest.entity';
11
import { IDateUtils } from 'src/Application/IDateUtils';
12
import { MonthDate } from 'src/Application/Common/MonthDate';
13
import { UserLeavesView } from '../View/UserLeavesView';
14
import { LeaveRequestSlotView } from '../../Leave/View/LeaveRequestSlotView';
15
16
@QueryHandler(GetUsersElementsQuery)
17
export class GetUsersElementsQueryHandler {
18
  constructor(
19
    @Inject('IUserRepository')
20
    private readonly userRepository: IUserRepository,
21
    private readonly getLeavesByMonthQueryHandler: GetLeavesByMonthQueryHandler,
22
    private readonly getMealTicketsPerMonth: GetMealTicketsPerMonthQueryHandler,
23
    @Inject('IDateUtils')
24
    private readonly dateUtils: IDateUtils
25
  ) {}
26
27
  public async execute(
28
    query: GetUsersElementsQuery
29
  ): Promise<UserElementsView[]> {
30
31
    const userViews: UserElementsView[] = [];
32
33
    const date = query.date;
34
35
    const [ users, leaves, mealTickets ] = await Promise.all([
36
      this.userRepository.findUsersWithPayslipInfo(),
37
      this.getLeavesByMonthQueryHandler.execute(new GetLeavesByMonthQuery(date)),
38
      this.getMealTicketsPerMonth.execute(new GetMealTicketsPerMonthQuery(date))
39
    ]);
40
41
    const mealTicketsByUser: Record<string, number> = {};
42
    mealTickets.forEach(view => {
43
      mealTicketsByUser[view.userId] = view.mealTickets;
44
    });
45
46
    for (const user of users) {
47
        const userLeaves = leaves.getLeavesByUser(user);
48
49
        userViews.push(new UserElementsView(
50
            user.getFirstName(),
51
            user.getLastName(),
52
            user.getUserAdministrative().getContract(),
53
            user.getUserAdministrative().isExecutivePosition(),
54
            user.getUserAdministrative().getJoiningDate(),
55
            user.getUserAdministrative().getAnnualEarnings() * 0.01,
56
            user.getUserAdministrative().getAnnualEarnings() / 1200,
57
            user.getUserAdministrative().getWorkingTime(),
58
            user.getUserAdministrative().getTransportFee() * 0.01,
59
            mealTicketsByUser[user.getId()],
60
            user.getUserAdministrative().haveHealthInsurance() ? 'yes' : 'no',
61
            this.createUserLeavesView(userLeaves.paid, date),
62
            this.createUserLeavesView(userLeaves.unpaid, date),
63
            this.createUserLeavesView(userLeaves.medical, date),
64
            this.createUserLeavesView(userLeaves.special, date)
65
        ));
66
    }
67
68
    return userViews;
69
  }
70
71
  private createUserLeavesView(leaves: LeaveRequest[], date: Date): UserLeavesView {
72
    const monthDate = this.dateUtils.getMonth(date);
73
74
    let leaveCount = 0;
75
    const leavesSlotViews: LeaveRequestSlotView[] = [];
76
77
    for (const leave of leaves) {
78
      const monthScopedLeave = this.getMonthScopedLeave(leave, monthDate);
79
80
      leaveCount += this.dateUtils.getLeaveDuration(
81
        monthScopedLeave.startDate,
82
        monthScopedLeave.startsAllDay,
83
        monthScopedLeave.endDate,
84
        monthScopedLeave.endsAllDay
85
      );
86
      leavesSlotViews.push(new LeaveRequestSlotView(monthScopedLeave.startDate, monthScopedLeave.endDate));
87
    }
88
89
    return new UserLeavesView(leaveCount, leavesSlotViews);
90
  }
91
92
  private getMonthScopedLeave(leave: LeaveRequest, month: MonthDate): LeaveSlot
93
  {
94
    const scopedLeave = new LeaveSlot();
95
96
    if (new Date(leave.getStartDate()) >= month.getFirstDay()) {
97
      scopedLeave.startDate = leave.getStartDate();
98
      scopedLeave.startsAllDay = leave.isStartsAllDay();
99
    } else {
100
      scopedLeave.startDate = month.getFirstDay().toISOString();
101
      scopedLeave.startsAllDay = true;
102
    }
103
104
    if (new Date(leave.getEndDate()) <= month.getLastDay()) {
105
      scopedLeave.endDate = leave.getEndDate();
106
      scopedLeave.endsAllDay = leave.isEndsAllDay();
107
    } else {
108
      scopedLeave.endDate = month.getLastDay().toISOString();
109
      scopedLeave.endsAllDay = true;
110
    }
111
112
    return scopedLeave;
113
  }
114
}
115
116
class LeaveSlot {
117
  public startDate: string;
118
  public startsAllDay: boolean;
119
  public endDate: string;
120
  public endsAllDay: boolean;
121
}
122