feat(timesheet-approval): add overtime calculation for overview and timesheet details
This commit is contained in:
parent
8f93c2b0f7
commit
fa64b7d919
|
|
@ -3,7 +3,6 @@ import { UserMessageDto } from 'src/chatbot/dtos/user-message.dto';
|
|||
import { HttpService } from '@nestjs/axios';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { PageContextDto } from 'src/chatbot/dtos/page-context.dto';
|
||||
import { UserDto } from 'src/identity-and-account/users-management/user.dto';
|
||||
import { Message } from 'src/chatbot/dtos/dialog-message.dto';
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -19,8 +18,6 @@ export class ChatbotService {
|
|||
),
|
||||
);
|
||||
|
||||
console.log('chatbot response: ', response);
|
||||
|
||||
const cleanText =
|
||||
Array.isArray(response.data) && response.data[0]?.output
|
||||
? response.data[0].output
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { Injectable } from "@nestjs/common";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { Result } from "src/common/errors/result-error.factory";
|
||||
import { computeHours, computePeriod, toDateFromString } from "src/common/utils/date-utils";
|
||||
import { computeHours, computePeriod, sevenDaysFrom, toDateFromString, toStringFromDate } from "src/common/utils/date-utils";
|
||||
import { PrismaService } from "src/prisma/prisma.service";
|
||||
import { EmployeePeriodOverviewDto, Overview, PayPeriodOverviewDto } from "src/time-and-attendance/pay-period/dtos/overview-pay-period.dto";
|
||||
|
||||
|
|
@ -62,12 +63,15 @@ export class GetOverviewService {
|
|||
select: {
|
||||
id: true,
|
||||
is_approved: true,
|
||||
start_date: true,
|
||||
shift: {
|
||||
select: {
|
||||
start_time: true,
|
||||
end_time: true,
|
||||
date: true,
|
||||
bank_code: { select: { type: true } },
|
||||
},
|
||||
orderBy: { date: 'asc' },
|
||||
},
|
||||
expense: {
|
||||
select: {
|
||||
|
|
@ -117,37 +121,60 @@ export class GetOverviewService {
|
|||
|
||||
for (const timesheet of employee.timesheet) {
|
||||
let total_weekly_hours: number = 0;
|
||||
let daily_hours: number = 0;
|
||||
let previous_shift_date: string = '';
|
||||
|
||||
//totals by types for shifts
|
||||
for (const shift of timesheet.shift) {
|
||||
const hours = computeHours(shift.start_time, shift.end_time);
|
||||
const type = (shift.bank_code?.type ?? '').toUpperCase();
|
||||
|
||||
if (previous_shift_date !== toStringFromDate(shift.date)) {
|
||||
previous_shift_date = toStringFromDate(shift.date);
|
||||
daily_hours = 0;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case "EVENING": record.other_hours.evening_hours += hours;
|
||||
case "EVENING":
|
||||
if (total_weekly_hours + hours <= 40) {
|
||||
record.other_hours.evening_hours += Math.min(hours, 8 - daily_hours);
|
||||
record.other_hours.overtime_hours += Math.max(daily_hours + hours - 8, 0);
|
||||
} else {
|
||||
record.other_hours.evening_hours += Math.max(40 - total_weekly_hours, 0);
|
||||
record.other_hours.overtime_hours += Math.min(total_weekly_hours + hours - 40, hours);
|
||||
}
|
||||
total_weekly_hours += hours;
|
||||
record.total_hours += hours;
|
||||
break;
|
||||
case "EMERGENCY":
|
||||
record.other_hours.emergency_hours += hours;
|
||||
record.total_hours += hours;
|
||||
total_weekly_hours += hours;
|
||||
break;
|
||||
case "EMERGENCY": record.other_hours.emergency_hours += hours;
|
||||
record.total_hours += hours;
|
||||
total_weekly_hours += hours;
|
||||
case "SICK":
|
||||
record.other_hours.sick_hours += hours;
|
||||
break;
|
||||
case "OVERTIME": record.other_hours.overtime_hours += hours;
|
||||
record.total_hours += hours;
|
||||
total_weekly_hours += hours;
|
||||
break;
|
||||
case "SICK": record.other_hours.sick_hours += hours;
|
||||
break;
|
||||
case "HOLIDAY": record.other_hours.holiday_hours += hours;
|
||||
case "HOLIDAY":
|
||||
record.other_hours.holiday_hours += hours;
|
||||
record.total_hours += hours;
|
||||
total_weekly_hours += hours;
|
||||
break;
|
||||
case "VACATION": record.other_hours.vacation_hours += hours;
|
||||
break;
|
||||
case "REGULAR": record.regular_hours += hours;
|
||||
record.total_hours += hours;
|
||||
case "REGULAR":
|
||||
if (total_weekly_hours + hours <= 40) {
|
||||
record.regular_hours += Math.min(hours, 8 - daily_hours);
|
||||
record.other_hours.overtime_hours += Math.max(daily_hours + hours - 8, 0);
|
||||
} else {
|
||||
record.regular_hours += Math.max(40 - total_weekly_hours, 0);
|
||||
record.other_hours.overtime_hours += Math.min(total_weekly_hours + hours - 40, hours);
|
||||
}
|
||||
total_weekly_hours += hours;
|
||||
record.total_hours += hours;
|
||||
break;
|
||||
}
|
||||
|
||||
daily_hours += hours;
|
||||
}
|
||||
//totals by type for expenses
|
||||
for (const expense of timesheet.expense) {
|
||||
|
|
@ -203,7 +230,7 @@ export class GetOverviewService {
|
|||
employee_last_name: string,
|
||||
supervisor: {
|
||||
first_name: string;
|
||||
last_name:string;
|
||||
last_name: string;
|
||||
email: string;
|
||||
} | null = null,
|
||||
): EmployeePeriodOverviewDto => ({
|
||||
|
|
|
|||
|
|
@ -74,9 +74,27 @@ export const mapOneTimesheet = async (timesheet: Prisma.TimesheetsGetPayload<{
|
|||
for (const shift of shifts_source) {
|
||||
const hours = diffOfHours(shift.start_time, shift.end_time);
|
||||
const subgroup = hoursSubGroupFromBankCode(shift.bank_code);
|
||||
const worked_weekly_hours = weekly_hours.regular + weekly_hours.emergency + weekly_hours.banking + weekly_hours.evening + weekly_hours.overtime + weekly_hours.holiday;
|
||||
|
||||
if ((worked_weekly_hours + hours <= 40) && (subgroup === 'regular' || subgroup === 'evening')) {
|
||||
daily_hours['overtime'] += Math.max(daily_hours[subgroup] + hours - 8, 0);
|
||||
weekly_hours['overtime'] += Math.max(daily_hours[subgroup] + hours - 8, 0);
|
||||
|
||||
weekly_hours[subgroup] += Math.min(hours, 8 - daily_hours[subgroup]);
|
||||
daily_hours[subgroup] += Math.min(hours, 8 - daily_hours[subgroup]);
|
||||
} else if (subgroup === 'regular' || subgroup === 'evening') {
|
||||
daily_hours[subgroup] += Math.max((40 - worked_weekly_hours), 0);
|
||||
daily_hours['overtime'] += Math.min((worked_weekly_hours + hours) - 40, hours);
|
||||
|
||||
weekly_hours[subgroup] += Math.max((40 - worked_weekly_hours), 0);
|
||||
weekly_hours['overtime'] += Math.min((worked_weekly_hours + hours) - 40, hours);
|
||||
} else {
|
||||
daily_hours[subgroup] += hours;
|
||||
weekly_hours[subgroup] += hours;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//totals by expense types
|
||||
for (const expense of expenses_source) {
|
||||
|
|
@ -108,6 +126,9 @@ export const mapOneTimesheet = async (timesheet: Prisma.TimesheetsGetPayload<{
|
|||
};
|
||||
});
|
||||
|
||||
weekly_hours['overtime'] = Math.max(weekly_hours['regular'] - 40, 0);
|
||||
weekly_hours['regular'] = Math.min(weekly_hours['regular'], 40);
|
||||
|
||||
return {
|
||||
timesheet_id: timesheet.id,
|
||||
is_approved: timesheet.is_approved ?? false,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user