targo-backend/src/modules/business-logics/services/sick-leave.service.ts

62 lines
2.6 KiB
TypeScript

import { Injectable, Logger } from "@nestjs/common";
import { PrismaService } from "../../../prisma/prisma.service";
import { getYearStart, roundToQuarterHour } from "src/common/utils/date-utils";
@Injectable()
export class SickLeaveService {
constructor(private readonly prisma: PrismaService) {}
private readonly logger = new Logger(SickLeaveService.name);
async calculateSickLeavePay(employeeId: number, referenceDate: Date, daysRequested: number, modifier: number): Promise<number> {
//sets the year to jan 1st to dec 31st
const periodStart = getYearStart(referenceDate);
const periodEnd = referenceDate;
//fetches all shifts of a selected employee
const shifts = await this.prisma.shifts.findMany({
where: {
timesheet: { employee_id: employeeId },
date: { gte: periodStart, lte: periodEnd},
},
select: { date: true },
});
//count the amount of worked days
const workedDates = new Set(
shifts.map(shift => shift.date.toISOString().slice(0,10))
);
const daysWorked = workedDates.size;
this.logger.debug(`Sick leave: days worked= ${daysWorked} in ${periodStart.toDateString()} -> ${periodEnd.toDateString()}`);
//less than 30 worked days returns 0
if (daysWorked < 30) {
return 0;
}
//default 3 days allowed after 30 worked days
let acquiredDays = 3;
//identify the date of the 30th worked day
const orderedDates = Array.from(workedDates).sort();
const thresholdDate = new Date(orderedDates[29]); // index 29 is the 30th day
//calculate each completed month, starting the 1st of the next month
const firstBonusDate = new Date(thresholdDate.getFullYear(), thresholdDate.getMonth() +1, 1);
let months = (periodEnd.getFullYear() - firstBonusDate.getFullYear()) * 12 +
(periodEnd.getMonth() - firstBonusDate.getMonth()) + 1;
if(months < 0) months = 0;
acquiredDays += months;
//cap of 10 days
if (acquiredDays > 10) acquiredDays = 10;
this.logger.debug(`Sick leave: threshold Date = ${thresholdDate.toDateString()}, bonusMonths = ${months}, acquired Days = ${acquiredDays}`);
const payableDays = Math.min(acquiredDays, daysRequested);
const rawHours = payableDays * 8 * modifier;
const rounded = roundToQuarterHour(rawHours)
this.logger.debug(`Sick leave pay: days= ${payableDays}, modifier= ${modifier}, hours= ${rounded}`);
return rounded;
}
}