feat(pay-period): added comments to pay-periods-query.service.ts

This commit is contained in:
Matthieu Haineault 2025-08-11 15:47:04 -04:00
parent 4c880e47bf
commit 22fb29b8fa

View File

@ -50,7 +50,7 @@ export class PayPeriodsQueryService {
const whereEmployee = opts?.restrictEmployeeIds?.length ? { employee_id: { in: opts.restrictEmployeeIds } }: {}; const whereEmployee = opts?.restrictEmployeeIds?.length ? { employee_id: { in: opts.restrictEmployeeIds } }: {};
// SHIFTS (filtrés par crew si besoin) // SHIFTS (filtered by crew)
const shifts = await this.prisma.shifts.findMany({ const shifts = await this.prisma.shifts.findMany({
where: { where: {
date: { gte: start, lte: end }, date: { gte: start, lte: end },
@ -74,7 +74,7 @@ export class PayPeriodsQueryService {
}, },
}); });
// EXPENSES (filtrés par crew si besoin) // EXPENSES (filtered by crew)
const expenses = await this.prisma.expenses.findMany({ const expenses = await this.prisma.expenses.findMany({
where: { where: {
date: { gte: start, lte: end }, date: { gte: start, lte: end },
@ -96,10 +96,9 @@ export class PayPeriodsQueryService {
}, },
}); });
// Agrégation
const byEmployee = new Map<number, EmployeePeriodOverviewDto>(); const byEmployee = new Map<number, EmployeePeriodOverviewDto>();
// seed pour employés sans données // seed for employee without data
if (opts?.seedNames) { if (opts?.seedNames) {
for (const [id, name] of opts.seedNames.entries()) { for (const [id, name] of opts.seedNames.entries()) {
byEmployee.set(id, { byEmployee.set(id, {
@ -182,31 +181,30 @@ export class PayPeriodsQueryService {
async getCrewOverview(year: number, periodNumber: number, userId: string, includeSubtree: boolean): Promise<PayPeriodOverviewDto> { async getCrewOverview(year: number, periodNumber: number, userId: string, includeSubtree: boolean): Promise<PayPeriodOverviewDto> {
// 1) Trouver la période // 1) Search for the period
const period = await this.prisma.payPeriods.findFirst({ where: { year, period_number: periodNumber } }); const period = await this.prisma.payPeriods.findFirst({ where: { year, period_number: periodNumber } });
if (!period) throw new NotFoundException(`Pay period ${year}-${periodNumber} not found`); if (!period) throw new NotFoundException(`Pay period ${year}-${periodNumber} not found`);
// 2) Résoudre l'employé superviseur depuis l'utilisateur courant (Users.id -> Employees) // 2) fetch supervisor
const supervisor = await this.prisma.employees.findUnique({ const supervisor = await this.prisma.employees.findUnique({
where: { user_id: userId }, where: { user_id: userId },
select: { id: true }, select: { id: true },
}); });
if (!supervisor) throw new ForbiddenException('No employee record linked to current user'); if (!supervisor) throw new ForbiddenException('No employee record linked to current user');
// 3) Récupérer la liste des employés du crew (directs ou sous-arbo complète) // 3)fetchs crew memebrs
const crew = await this.resolveCrew(supervisor.id, includeSubtree); // [{ id, first_name, last_name }] const crew = await this.resolveCrew(supervisor.id, includeSubtree); // [{ id, first_name, last_name }]
const crewIds = crew.map(c => c.id); const crewIds = crew.map(c => c.id);
// seed names map for employés sans données // seed names map for employee without data
const seedNames = new Map<number, string>(crew.map(c => [c.id, `${c.first_name} ${c.last_name}`.trim()])); const seedNames = new Map<number, string>(crew.map(c => [c.id, `${c.first_name} ${c.last_name}`.trim()]));
// 4) Construire loverview filtré par ce crew // 4) overview build
return this.buildOverview(period, { restrictEmployeeIds: crewIds, seedNames }); return this.buildOverview(period, { restrictEmployeeIds: crewIds, seedNames });
} }
private async resolveCrew(supervisorId: number, includeSubtree: boolean): Promise<Array<{ id: number; first_name: string; last_name: string }>> { private async resolveCrew(supervisorId: number, includeSubtree: boolean): Promise<Array<{ id: number; first_name: string; last_name: string }>> {
const result: Array<{ id: number; first_name: string; last_name: string }> = []; const result: Array<{ id: number; first_name: string; last_name: string }> = [];
// niveau 1 (directs)
let frontier = await this.prisma.employees.findMany({ let frontier = await this.prisma.employees.findMany({
where: { supervisor_id: supervisorId }, where: { supervisor_id: supervisorId },
select: { id: true, user: { select: { first_name: true, last_name: true } } }, select: { id: true, user: { select: { first_name: true, last_name: true } } },
@ -215,7 +213,6 @@ private async resolveCrew(supervisorId: number, includeSubtree: boolean): Promis
if (!includeSubtree) return result; if (!includeSubtree) return result;
// BFS pour les niveaux suivants
while (frontier.length) { while (frontier.length) {
const parentIds = frontier.map(e => e.id); const parentIds = frontier.map(e => e.id);
const next = await this.prisma.employees.findMany({ const next = await this.prisma.employees.findMany({