feat(business-logic): holiday implementation for leave Requests
This commit is contained in:
parent
c6ff3139f2
commit
2e6bafeb18
|
|
@ -0,0 +1,56 @@
|
|||
import { Injectable, Logger } from "@nestjs/common";
|
||||
import { PrismaService } from "src/prisma/prisma.service";
|
||||
|
||||
@Injectable()
|
||||
export class HolidayService {
|
||||
private readonly logger = new Logger(HolidayService.name);
|
||||
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
//return the sunday of the current week that includes the holiday
|
||||
private getWeekStart(date: Date): Date {
|
||||
const day = new Date(date);
|
||||
const offset = day.getDay();
|
||||
day.setDate(day.getDate() - offset);
|
||||
day.setHours(0,0,0,0);
|
||||
return day;
|
||||
}
|
||||
|
||||
//rounds minutes to 5s
|
||||
private computeHours(start: Date, end: Date): number {
|
||||
const durationMS = end.getTime() - start.getTime();
|
||||
const totalMinutes = durationMS / 60000;
|
||||
const rounded = Math.round(totalMinutes / 5) * 5;
|
||||
return rounded / 60;
|
||||
}
|
||||
|
||||
private async computeHoursPrevious4Weeks(employeeId: number, holidayDate: Date): Promise<number> {
|
||||
//sets the end of the window to 1ms before the week with the holiday
|
||||
const holidayWeekStart = this.getWeekStart(holidayDate);
|
||||
const windowEnd = new Date(holidayWeekStart.getTime() - 1);
|
||||
//sets the start of the window to 28 days ( 4 completed weeks ) before the week with the holiday
|
||||
const windowStart = new Date(windowEnd.getTime() - 28 * 24 * 60 * 60000 + 1 )
|
||||
|
||||
const validCodes = ['G1', 'G45', 'G56', 'G104', 'G105', 'G700'];
|
||||
//fetches all shift of the employee in said window ( 4 completed weeks )
|
||||
const shifts = await this.prisma.shifts.findMany({
|
||||
where: { timesheet: { employee_id: employeeId } ,
|
||||
date: { gte: windowStart, lte: windowEnd },
|
||||
bank_code: { bank_code: { in: validCodes } },
|
||||
},
|
||||
select: { date: true, start_time: true, end_time: true },
|
||||
});
|
||||
|
||||
const totalHours = shifts.map(s => this.computeHours(s.start_time, s.end_time)).reduce((sum, h)=> sum + h, 0);
|
||||
const dailyHours = totalHours / 20;
|
||||
|
||||
return dailyHours;
|
||||
}
|
||||
|
||||
async calculateHolidayPay( employeeId: number, holidayDate: Date, modifier: number): Promise<number> {
|
||||
const hours = await this. computeHoursPrevious4Weeks(employeeId, holidayDate);
|
||||
const dailyRate = Math.min(hours, 8);
|
||||
this.logger.debug(`Holiday pay calculation: hours=${hours.toFixed(2)}`);
|
||||
return dailyRate * modifier;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,10 +2,15 @@ import { PrismaService } from "src/prisma/prisma.service";
|
|||
import { LeaveRequestController } from "./controllers/leave-requests.controller";
|
||||
import { LeaveRequestsService } from "./services/leave-requests.service";
|
||||
import { Module } from "@nestjs/common";
|
||||
import { HolidayService } from "src/business-logic/holiday.service";
|
||||
|
||||
@Module({
|
||||
controllers: [LeaveRequestController],
|
||||
providers: [ LeaveRequestsService, PrismaService],
|
||||
providers: [
|
||||
LeaveRequestsService,
|
||||
PrismaService,
|
||||
HolidayService,
|
||||
],
|
||||
exports: [ LeaveRequestsService],
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -3,87 +3,78 @@ import { PrismaService } from "src/prisma/prisma.service";
|
|||
import { CreateLeaveRequestsDto } from "../dtos/create-leave-requests.dto";
|
||||
import { LeaveRequests, LeaveRequestsArchive } from "@prisma/client";
|
||||
import { UpdateLeaveRequestsDto } from "../dtos/update-leave-requests.dto";
|
||||
import { HolidayService } from "src/business-logic/holiday.service";
|
||||
|
||||
@Injectable()
|
||||
export class LeaveRequestsService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
constructor(
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly holidayService: HolidayService,
|
||||
) {}
|
||||
|
||||
async create(dto: CreateLeaveRequestsDto): Promise<LeaveRequests> {
|
||||
const {
|
||||
employee_id,
|
||||
bank_code_id,
|
||||
leave_type,
|
||||
start_date_time,
|
||||
end_date_time,
|
||||
comment,
|
||||
approval_status,
|
||||
} = dto;
|
||||
const { employee_id, bank_code_id, leave_type, start_date_time,
|
||||
end_date_time, comment, approval_status } = dto;
|
||||
|
||||
return this.prisma.leaveRequests.create({
|
||||
data: {
|
||||
employee_id,
|
||||
bank_code_id,
|
||||
leave_type,
|
||||
start_date_time,
|
||||
end_date_time,
|
||||
comment,
|
||||
approval_status: approval_status ?? undefined,
|
||||
},
|
||||
include: {
|
||||
employee: {
|
||||
include: {
|
||||
user: true
|
||||
},
|
||||
},
|
||||
data: { employee_id, bank_code_id, leave_type, start_date_time,
|
||||
end_date_time, comment, approval_status: approval_status ?? undefined
|
||||
},
|
||||
include: { employee: { include: { user: true } } },
|
||||
});
|
||||
}
|
||||
|
||||
findAll(): Promise<LeaveRequests[]> {
|
||||
return this.prisma.leaveRequests.findMany({
|
||||
include: {
|
||||
employee: {
|
||||
include: {
|
||||
user: true
|
||||
},
|
||||
},
|
||||
async findAll(): Promise<any[]> {
|
||||
const list = await this.prisma.leaveRequests.findMany({
|
||||
include: { employee: { include: { user: true } },
|
||||
bank_code: true,
|
||||
},
|
||||
});
|
||||
|
||||
return Promise.all(
|
||||
list.map(async request => {
|
||||
if(request.bank_code?.type === 'holiday') {
|
||||
const cost = await this.holidayService.calculateHolidayPay(
|
||||
request.employee_id,
|
||||
request.start_date_time,
|
||||
request.bank_code.modifier
|
||||
);
|
||||
return { ...request, cost };
|
||||
}
|
||||
return request;
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
async findOne(id:number): Promise<LeaveRequests> {
|
||||
const req = await this.prisma.leaveRequests.findUnique({
|
||||
async findOne(id:number): Promise<any> {
|
||||
const request = await this.prisma.leaveRequests.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
employee: {
|
||||
include: {
|
||||
user: true
|
||||
},
|
||||
},
|
||||
include: { employee: { include: { user: true } },
|
||||
bank_code: true,
|
||||
},
|
||||
});
|
||||
if(!req) {
|
||||
if(!request) {
|
||||
throw new NotFoundException(`LeaveRequest #${id} not found`);
|
||||
}
|
||||
return req;
|
||||
}
|
||||
|
||||
//search for leave type. if holiday
|
||||
if (request.bank_code?.type === 'holiday') {
|
||||
const cost = await this.holidayService.calculateHolidayPay(
|
||||
request.employee_id,
|
||||
request.start_date_time,
|
||||
request.bank_code.modifier,
|
||||
);
|
||||
return { ...request, cost };
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
async update(
|
||||
id: number,
|
||||
dto: UpdateLeaveRequestsDto,
|
||||
): Promise<LeaveRequests> {
|
||||
await this.findOne(id);
|
||||
const {
|
||||
employee_id,
|
||||
leave_type,
|
||||
start_date_time,
|
||||
end_date_time,
|
||||
comment,
|
||||
approval_status,
|
||||
} = dto;
|
||||
const { employee_id, leave_type, start_date_time, end_date_time, comment, approval_status } = dto;
|
||||
return this.prisma.leaveRequests.update({
|
||||
where: { id },
|
||||
data: {
|
||||
|
|
@ -94,13 +85,7 @@ export class LeaveRequestsService {
|
|||
...(comment !== undefined && { comment }),
|
||||
...(approval_status == undefined && { approval_status }),
|
||||
},
|
||||
include: {
|
||||
employee: {
|
||||
include: {
|
||||
user:true
|
||||
},
|
||||
},
|
||||
},
|
||||
include: { employee: { include: { user:true } } },
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user