refactor(shifts): added is_remote to track work from home shifts

This commit is contained in:
Matthieu Haineault 2025-09-08 15:25:09 -04:00
parent dac53c6780
commit 954411d995
10 changed files with 17 additions and 64 deletions

View File

@ -182,6 +182,7 @@ model Shifts {
start_time DateTime @db.Time(0)
end_time DateTime @db.Time(0)
is_approved Boolean @default(false)
is_remote Boolean @default(false)
archive ShiftsArchive[] @relation("ShiftsToArchive")

View File

@ -41,4 +41,6 @@ export class EmployeePeriodOverviewDto {
description: 'Tous les timesheets de la période sont approuvés pour cet employé',
})
is_approved: boolean;
is_remote: boolean;
}

View File

@ -68,38 +68,4 @@ export class PayPeriodsCommandService {
});
return {updated};
}
//function to approve a single pay-period of a single employee (deprecated)
// async approvalPayPeriod(pay_year: number , period_no: number): Promise<void> {
// const period = await this.prisma.payPeriods.findFirst({
// where: { pay_year, pay_period_no: period_no},
// });
// if (!period) throw new NotFoundException(`PayPeriod #${pay_year}-${period_no} not found`);
// //fetches timesheet of selected period if the timesheet has atleast 1 shift or 1 expense
// const timesheet_ist = await this.prisma.timesheets.findMany({
// where: {
// OR: [
// { shift: {some: { date: { gte: period.period_start,
// lte: period.period_end,
// },
// }},
// },
// { expense: { some: { date: { gte: period.period_start,
// lte: period.period_end,
// },
// }},
// },
// ],
// },
// select: { id: true },
// });
// //approval of both timesheet (cascading to the approval of related shifts and expenses)
// await this.prisma.$transaction(async (transaction)=> {
// for(const {id} of timesheet_ist) {
// await this.timesheets_approval.updateApprovalWithTransaction(transaction,id, true);
// }
// })
// }
}

View File

@ -151,6 +151,7 @@ export class PayPeriodsQueryService {
select: {
start_time: true,
end_time: true,
is_remote: true,
timesheet: { select: {
is_approved: true,
employee: { select: {
@ -205,6 +206,7 @@ export class PayPeriodsQueryService {
expenses: 0,
mileage: 0,
is_approved: true,
is_remote: true,
});
}
}
@ -221,6 +223,7 @@ export class PayPeriodsQueryService {
expenses: 0,
mileage: 0,
is_approved: true,
is_remote: true,
});
}
return by_employee.get(id)!;

View File

@ -108,7 +108,7 @@ export class ShiftsController {
r.total_overtime_hrs.toFixed(2),
r.total_expenses.toFixed(2),
r.total_mileage.toFixed(2),
r.is_validated,
r.is_approved,
].join(',');
}).join('\n');

View File

@ -18,7 +18,7 @@ export interface OverviewRow {
total_overtime_hrs: number;
total_expenses: number;
total_mileage: number;
is_validated: boolean;
is_approved: boolean;
}
@Injectable()
@ -168,7 +168,7 @@ export class ShiftsQueryService {
total_overtime_hrs: 0,
total_expenses: 0,
total_mileage: 0,
is_validated: false,
is_approved: false,
};
}
const hours = computeHours(shift.start_time, shift.end_time);
@ -200,7 +200,7 @@ export class ShiftsQueryService {
total_overtime_hrs: 0,
total_expenses: 0,
total_mileage: 0,
is_validated: false,
is_approved: false,
};
}
const amount = Number(exp.amount);

View File

@ -14,6 +14,7 @@ export class ShiftsDto {
end_time: string;
description: string;
is_approved: boolean;
is_remote: boolean;
}
export class ExpensesDto {

View File

@ -2,6 +2,7 @@ export class ShiftDto {
start: string;
end : string;
is_approved: boolean;
is_remote: boolean;
}
export class ExpenseDto {

View File

@ -119,6 +119,7 @@ export class TimesheetsCommandService extends BaseApprovalService<Timesheets>{
end_time: this.parseHHmm(shift.end_time),
description: shift.description ?? null,
is_approved: false,
is_remote: false,
},
});
}

View File

@ -18,17 +18,6 @@ export class TimesheetsQueryService {
private readonly overtime: OvertimeService,
) {}
// async create(dto : CreateTimesheetDto): Promise<Timesheets> {
// const { employee_id, is_approved } = dto;
// return this.prisma.timesheets.create({
// data: { employee_id, is_approved: is_approved ?? false },
// include: {
// employee: { include: { user: true }
// },
// },
// });
// }
async findAll(year: number, period_no: number, email: string): Promise<TimesheetPeriodDto> {
//finds the employee
const employee = await this.prisma.employees.findFirst({
@ -57,6 +46,7 @@ export class TimesheetsQueryService {
start_time: true,
end_time: true,
is_approved: true,
is_remote: true,
bank_code: { select: { type: true } },
},
orderBy:[ { date:'asc'}, { start_time: 'asc'} ],
@ -87,6 +77,7 @@ export class TimesheetsQueryService {
end_time: shift.end_time,
type: String(shift.bank_code?.type ?? '').toUpperCase(),
is_approved: shift.is_approved ?? true,
is_remote: shift.is_remote ?? true,
}));
const expenses: ExpenseRow[] = raw_expenses.map(expense => ({
@ -153,6 +144,7 @@ export class TimesheetsQueryService {
if(!timesheet) {
return {
is_approved: false,
is_remote: false,
start_day,
end_day,
label,
@ -172,6 +164,7 @@ export class TimesheetsQueryService {
end_time: to_HH_mm(sft.end_time),
description: sft.description ?? '',
is_approved: sft.is_approved ?? false,
is_remote: sft.is_remote ?? false,
}));
//maps all expenses of selected timsheet
@ -223,21 +216,6 @@ export class TimesheetsQueryService {
return { ...timesheet, shift: detailedShifts, weeklyOvertimeHours };
}
//deprecated
// async update(id: number, dto:UpdateTimesheetDto): Promise<Timesheets> {
// await this.findOne(id);
// const { employee_id, is_approved } = dto;
// return this.prisma.timesheets.update({
// where: { id },
// data: {
// ...(employee_id !== undefined && { employee_id }),
// ...(is_approved !== undefined && { is_approved }),
// },
// include: { employee: { include: { user: true } },
// },
// });
// }
async remove(id: number): Promise<Timesheets> {
await this.findOne(id);
return this.prisma.timesheets.delete({ where: { id } });