targo-backend/src/modules/business-logics/services/after-hours.service.ts
2025-08-01 16:17:58 -04:00

80 lines
2.9 KiB
TypeScript

import { BadRequestException, Injectable, Logger } from "@nestjs/common";
import { PrismaService } from "../../../prisma/prisma.service";
//THIS SERVICE IS NOT USED RULES TO BE DETERMINED WITH MIKE/HR/ACCOUNTING
@Injectable()
export class AfterHoursService {
private readonly logger = new Logger(AfterHoursService.name);
private static readonly BUSINESS_START = 7;
private static readonly BUSINESS_END = 18;
private static readonly ROUND_MINUTES = 15;
constructor(private readonly prisma: PrismaService) {}
private getPreBusinessMinutes(start: Date, end: Date): number {
const bizStart = new Date(start);
bizStart.setHours(AfterHoursService.BUSINESS_START, 0,0,0);
if (end>= start || start >= bizStart) {
return 0;
}
const segmentEnd = end < bizStart ? end : bizStart;
const minutes = (segmentEnd.getTime() - start.getTime()) / 60000;
this.logger.debug(`getPreBusinessMintutes -> ${minutes.toFixed(1)}min`);
return minutes;
}
private getPostBusinessMinutes(start: Date, end: Date): number {
const bizEnd = new Date(start);
bizEnd.setHours(AfterHoursService.BUSINESS_END,0,0,0);
if( end <= bizEnd ) {
return 0;
}
const segmentStart = start > bizEnd ? start : bizEnd;
const minutes = (end.getTime() - segmentStart.getTime()) / 60000;
this.logger.debug(`getPostBusinessMintutes -> ${minutes.toFixed(1)}min`);
return minutes;
}
private roundToNearestQUarterMinute(minutes: number): number {
const rounded = Math.round(minutes / AfterHoursService.ROUND_MINUTES)
* AfterHoursService.ROUND_MINUTES;
this.logger.debug(`roundToNearestQuarterMinute -> raw=${minutes.toFixed(1)}min, rounded= ${rounded}min`);
return rounded;
}
public computeAfterHours(start: Date, end:Date): number {
if(end.getTime() <= start.getTime()) {
throw new BadRequestException('The end cannot be before the starting of the shift');
}
if (start.toDateString() !== end.toDateString()) {
throw new BadRequestException('you cannot enter a shift that start in a day and end in the next' +
'You must create 2 instances, one on the first day and the second during the next day.');
}
const preMin = this.getPreBusinessMinutes(start, end);
const postMin = this.getPostBusinessMinutes(start, end);
const rawAftermin = preMin + postMin;
const roundedMin = this.roundToNearestQUarterMinute(rawAftermin);
const hours = roundedMin / 60;
const result = parseFloat(hours.toFixed(2));
this.logger.debug(`computeAfterHours -> rawAfterMin= ${rawAftermin.toFixed(1)}min, +
rounded = ${roundedMin}min, hours = ${result.toFixed(2)}`);
return result;
}
}