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 { //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; } }