refactor(sick-leave): remake methods to calculate and update sick leave available
This commit is contained in:
parent
17f06e7867
commit
53ec64ba1e
|
|
@ -55,6 +55,7 @@ model Employees {
|
|||
user Users @relation("UserEmployee", fields: [user_id], references: [id])
|
||||
leave_request LeaveRequests[] @relation("LeaveRequestEmployee")
|
||||
timesheet Timesheets[] @relation("TimesheetEmployee")
|
||||
paid_time_off PaidTimeOff? @relation("EmployeePaidTimeOff")
|
||||
|
||||
@@map("employees")
|
||||
}
|
||||
|
|
@ -321,6 +322,18 @@ model Preferences {
|
|||
@@map("preferences")
|
||||
}
|
||||
|
||||
model PaidTimeOff {
|
||||
id Int @id @default(autoincrement())
|
||||
employee_id Int @unique
|
||||
vacation_hours Int @default(0)
|
||||
sick_hours Int @default(0)
|
||||
last_updated DateTime @db.Date
|
||||
|
||||
employee Employees @relation("EmployeePaidTimeOff", fields: [employee_id], references: [id])
|
||||
|
||||
@@map("paid_time_off")
|
||||
}
|
||||
|
||||
view PayPeriods {
|
||||
pay_year Int
|
||||
pay_period_no Int
|
||||
|
|
|
|||
|
|
@ -2,11 +2,114 @@
|
|||
import { Injectable, Logger } from "@nestjs/common";
|
||||
import { PrismaService } from "src/prisma/prisma.service";
|
||||
import { Result } from "src/common/errors/result-error.factory";
|
||||
import { Prisma } from "@prisma/client";
|
||||
|
||||
@Injectable()
|
||||
export class SickLeaveService {
|
||||
constructor(private readonly prisma: PrismaService) { }
|
||||
|
||||
async updateSickLeaveHours(employee_id: number): Promise<Result<boolean, string>> {
|
||||
const THIRTY_DAYS = 1000 * 60 * 60 * 24 * 30;
|
||||
const FOURTEEN_DAYS = 1000 * 60 * 60 * 24 * 14;
|
||||
const today = new Date();
|
||||
|
||||
// get employee info
|
||||
const employee = await this.prisma.employees.findUnique({
|
||||
where: { id: employee_id },
|
||||
select: {
|
||||
first_work_day: true,
|
||||
last_work_day: true,
|
||||
id: true,
|
||||
}
|
||||
})
|
||||
|
||||
if (!employee) return { success: false, error: 'EMPLOYEE_NOT_FOUND' };
|
||||
|
||||
// check if employee has been inactive for more than 2 weeks
|
||||
if (employee.last_work_day) {
|
||||
if (today.getTime() - employee.last_work_day.getTime() >= FOURTEEN_DAYS) {
|
||||
return { success: false, error: "EMPLOYEE_NOT_ACTIVE" };
|
||||
}
|
||||
}
|
||||
|
||||
// get employee's PTO info, or create new details if not yet existing
|
||||
let pto_details: Prisma.Result<typeof this.prisma.paidTimeOff, Prisma.PaidTimeOffDefaultArgs, 'findUnique' | 'create'>;
|
||||
|
||||
pto_details = await this.prisma.paidTimeOff.findUnique({
|
||||
where: { employee_id: employee.id },
|
||||
})
|
||||
|
||||
if (!pto_details) {
|
||||
const new_pto_entry = await this.createNewPTORow(employee.id, today);
|
||||
|
||||
if (!new_pto_entry.success) return { success: false, error: "FAILED_TO_CREATE_EMPLOYEE_PTO" };
|
||||
|
||||
pto_details = new_pto_entry.data;
|
||||
}
|
||||
|
||||
// check if employee has gotten his 3 days from completing his 30-day qualifying period from hiring date
|
||||
if (today.getTime() - employee.first_work_day.getTime() >= THIRTY_DAYS && employee.first_work_day.toISOString() === pto_details?.last_updated?.toISOString()) {
|
||||
const updated_pto = await this.addHoursToPTO(3 * 8, employee.id, today);
|
||||
|
||||
if (!updated_pto.success) return { success: updated_pto.success, error: updated_pto.error }
|
||||
}
|
||||
|
||||
const year_difference = today.getFullYear() - (pto_details!.last_updated.getFullYear() ?? today.getFullYear());
|
||||
const months_since_last_update = (today.getMonth() + year_difference * 12) - pto_details!.last_updated.getMonth();
|
||||
|
||||
if (months_since_last_update > 0) {
|
||||
const updated_pto = await this.addHoursToPTO(months_since_last_update * 8, employee.id, today);
|
||||
|
||||
if (updated_pto.success) {
|
||||
return {success: true, data: true}
|
||||
}
|
||||
}
|
||||
|
||||
return { success: false, error: 'UNKNOWN_PTO_UPDATE_ERROR' };
|
||||
}
|
||||
|
||||
// create a new PTO row
|
||||
async createNewPTORow(employee_id: number, today: Date): Promise<Result<Prisma.Result<typeof this.prisma.paidTimeOff, Prisma.PaidTimeOffDefaultArgs, 'findUnique' | 'create'>, string>> {
|
||||
try {
|
||||
const new_pto_entry = await this.prisma.paidTimeOff.create({
|
||||
data: {
|
||||
employee_id: employee_id,
|
||||
last_updated: today,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
employee_id: true,
|
||||
sick_hours: true,
|
||||
vacation_hours: true,
|
||||
last_updated: true,
|
||||
}
|
||||
});
|
||||
|
||||
return { success: true, data: new_pto_entry };
|
||||
} catch (error) {
|
||||
return { success: false, error };
|
||||
}
|
||||
}
|
||||
|
||||
// add n number of sick PTO hours to employee PTO
|
||||
async addHoursToPTO(sick_hours: number, employee_id: number, last_updated: Date) {
|
||||
try {
|
||||
const update_pto = await this.prisma.paidTimeOff.update({
|
||||
where: {
|
||||
employee_id,
|
||||
},
|
||||
data: {
|
||||
sick_hours,
|
||||
last_updated,
|
||||
}
|
||||
})
|
||||
|
||||
return { success: true, data: update_pto };
|
||||
} catch (error) {
|
||||
return { success: false, error };
|
||||
}
|
||||
};
|
||||
|
||||
// switch employeeId for email
|
||||
async calculateSickLeavePay(
|
||||
employee_id: number,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user