109 lines
4.4 KiB
TypeScript
109 lines
4.4 KiB
TypeScript
import { Injectable } from "@nestjs/common";
|
|
import { Result } from "src/common/errors/result-error.factory";
|
|
import { computeHours } from "src/common/utils/date-utils";
|
|
import { PrismaService } from "src/prisma/prisma.service";
|
|
import { BankedHoursService } from "src/time-and-attendance/domains/services/banking-hours.service";
|
|
import { SickLeaveService } from "src/time-and-attendance/domains/services/sick-leave.service";
|
|
import { VacationService } from "src/time-and-attendance/domains/services/vacation.service";
|
|
import { paid_time_off_mapping, paid_time_off_types } from "src/time-and-attendance/paid-time-off/paid-time-off.dto";
|
|
|
|
@Injectable()
|
|
export class PaidTimeOFfBankHoursService {
|
|
constructor(
|
|
private readonly prisma: PrismaService,
|
|
private readonly bankingService: BankedHoursService,
|
|
private readonly vacationService: VacationService,
|
|
private readonly sickLeaveService: SickLeaveService,
|
|
) { }
|
|
|
|
//called during update function of Shifts Module
|
|
updatePaidTimeOffBankHoursWhenShiftUpdate = async (
|
|
start_time: Date,
|
|
end_time: Date,
|
|
type: string,
|
|
employee_id: number,
|
|
og_start: Date,
|
|
og_end: Date
|
|
): Promise<Result<boolean, string>> => {
|
|
let original_hours = computeHours(og_start, og_end);
|
|
let ajusted_hours = computeHours(start_time, end_time);
|
|
|
|
if (type === 'BANKING') {
|
|
original_hours = original_hours * 1.5;
|
|
ajusted_hours = ajusted_hours * 1.5;
|
|
}
|
|
|
|
const diff_hours = Math.abs(ajusted_hours - original_hours);
|
|
|
|
if (diff_hours === 0) return { success: true, data: true };
|
|
if (!paid_time_off_types.includes(type)) return { success: false, error: 'INVALID_SHIFT_TYPE' };
|
|
|
|
if (ajusted_hours > original_hours) {
|
|
const validation = await this.validateAndDeductPaidTimeOff(employee_id, type, diff_hours);
|
|
if (!validation.success) return { success: false, error: validation.error };
|
|
} else {
|
|
const restoration = await this.restorePaidTimeOffHours(employee_id, type, diff_hours);
|
|
if (!restoration.success) return { success: false, error: restoration.error };
|
|
}
|
|
return { success: true, data: true };
|
|
}
|
|
|
|
validateAndDeductPaidTimeOff = async (employee_id: number, type: string, hours: number): Promise<Result<number, string>> => {
|
|
const banking_types: string[] = ['BANKING', 'WITHDRAW_BANKED'];
|
|
if (banking_types.includes(type)) {
|
|
return await this.bankingService.manageBankingHours(employee_id, hours, type);
|
|
}
|
|
|
|
switch (type) {
|
|
case 'VACATION': {
|
|
return await this.vacationService.manageVacationHoursBank(employee_id, hours);
|
|
}
|
|
case 'SICK': {
|
|
return await this.sickLeaveService.takeSickLeaveHours(employee_id, hours);
|
|
}
|
|
default:
|
|
return { success: false, error: 'INVALID_PAID_TIME_OFF_TYPE' };
|
|
}
|
|
}
|
|
|
|
|
|
restorePaidTimeOffHours = async (employee_id: number, type: string, hours: number): Promise<Result<boolean, string>> => {
|
|
try {
|
|
const config = paid_time_off_mapping[type];
|
|
if (!config) return { success: false, error: 'INVALID_PAID_TIME_OFF_TYPE' }
|
|
const operation = config.invert_logic ? 'decrement' : 'increment';
|
|
|
|
await this.prisma.paidTimeOff.update({
|
|
where: { employee_id },
|
|
data: {
|
|
[config.field]: { [operation]: hours },
|
|
last_updated: new Date(),
|
|
},
|
|
});
|
|
return { success: true, data: true };
|
|
} catch (error) {
|
|
return { success: false, error: 'PAID_TIME_OFF_NOT_FOUND' };
|
|
}
|
|
};
|
|
|
|
|
|
//called during delete function of Shifts Module
|
|
updatePaidTimeoffBankHoursWhenShiftDelete = async (start: Date, end: Date, type: string, employee_id: number) => {
|
|
let ajusted_hours = computeHours(start, end);
|
|
if (!paid_time_off_types.includes(type)) return;
|
|
if (type === 'BANKING') {
|
|
ajusted_hours = ajusted_hours * 1.5;
|
|
}
|
|
|
|
const config = paid_time_off_mapping[type];
|
|
await this.prisma.paidTimeOff.update({
|
|
where: { employee_id },
|
|
data: {
|
|
[config.field]: { [config.operation]: ajusted_hours },
|
|
last_updated: new Date(),
|
|
},
|
|
});
|
|
|
|
}
|
|
}
|