targo-backend/src/modules/pay-periods/services/pay-periods-overview.service.ts

70 lines
2.8 KiB
TypeScript

import { Injectable, NotFoundException } from "@nestjs/common";
import { EmployeePeriodOverviewDto } from "../dtos/overview-employee-period.dto";
import { PayPeriodOverviewDto } from "../dtos/overview-pay-period.dto";
import { PrismaService } from "src/prisma/prisma.service";
@Injectable()
export class PayPeriodsOverviewService {
constructor(private readonly prisma: PrismaService) {}
//function to get a full overview of a selected period filtered by employee ID
async getOverview(periodNumber: number): Promise<PayPeriodOverviewDto> {
//fetch the period
const period = await this.prisma.payPeriods.findUnique({
where: { period_number: periodNumber },
});
if(!period) {
throw new NotFoundException(`Period #${periodNumber} not found`);
}
//fetch all included shifts for that period
const shifts = await this.prisma.shifts.findMany({
where: {
date: {
gte: period.start_date,
lte: period.end_date,
},
},
include: {
timesheet: {
include: {
employee: { include: { user: true }},
},
},
},
});
//regroup by employee
const map = new Map<string, EmployeePeriodOverviewDto>();
for (const shift of shifts) {
const employee_record = shift.timesheet.employee;
const user = employee_record.user;
const employee_id = employee_record.user_id;
const employee_name = `${user.first_name} ${user.last_name}`;
const hours = (shift.end_time.getTime() - shift.start_time.getTime() / 3600000);
//check if employee had prior shifts and adds hours of found shift to the total hours
if (map.has(employee_id)) {
const summary = map.get(employee_id)!;
summary.total_hours += hours;
//keeps is_approved false as long as a single shift is left un-validated
summary.is_approved = summary.is_approved && shift.timesheet.is_approved;
} else {
//if first shift of an employee is found, it adds a new entry
map.set(employee_id, {
employee_id: employee_id,
employee_name: employee_name,
total_hours: hours,
is_approved: shift.timesheet.is_approved,
});
}
}
return {
period_number: period.period_number,
start_date: period.start_date,
end_date: period.end_date,
label: period.label,
employees_overview: Array.from(map.values()),
};
}
}