fix(shifts): modified ensureTimesheet

This commit is contained in:
Matthieu Haineault 2025-10-14 11:59:26 -04:00
parent 5ec131c863
commit a88aaf34f0
2 changed files with 21 additions and 12 deletions

View File

@ -6,7 +6,6 @@ import { normalizeShiftPayload, overlaps } from "../utils/shifts.utils";
import { weekStartSunday, formatHHmm } from "./shifts-date-time-helpers"; import { weekStartSunday, formatHHmm } from "./shifts-date-time-helpers";
import { BankCodesResolver } from "src/modules/shared/utils/resolve-bank-type-id.utils"; import { BankCodesResolver } from "src/modules/shared/utils/resolve-bank-type-id.utils";
import { OvertimeService } from "src/modules/business-logics/services/overtime.service"; import { OvertimeService } from "src/modules/business-logics/services/overtime.service";
import { UpsertAction } from "src/modules/shared/types/upsert-actions.types";
export type Tx = Prisma.TransactionClient; export type Tx = Prisma.TransactionClient;
@ -19,7 +18,7 @@ export class ShiftsHelpersService {
private readonly overtimeService: OvertimeService, private readonly overtimeService: OvertimeService,
) { } ) { }
async ensureTimesheet(tx: Tx, employee_id: number, date_only: Date) { async findOrUpsertTimesheet(tx: Tx, employee_id: number, date_only: Date) {
const start_of_week = weekStartSunday(date_only); const start_of_week = weekStartSunday(date_only);
return tx.timesheets.upsert({ return tx.timesheets.upsert({
where: { employee_id_start_date: { employee_id, start_date: start_of_week } }, where: { employee_id_start_date: { employee_id, start_date: start_of_week } },
@ -28,6 +27,15 @@ export class ShiftsHelpersService {
select: { id: true }, select: { id: true },
}); });
} }
async ensureTimesheet(tx: Tx, employee_id: number, date_only: Date) {
const start_of_week = weekStartSunday(date_only);
return tx.timesheets.findUnique({
where: { employee_id_start_date: { employee_id, start_date: start_of_week } },
select: { id: true },
});
}
async normalizeRequired( async normalizeRequired(
raw: UpsertShiftDto['new_shift'] | UpsertShiftDto['old_shift'] | undefined | null, raw: UpsertShiftDto['new_shift'] | UpsertShiftDto['old_shift'] | undefined | null,
label: 'old_shift' | 'new_shift' = 'new_shift', label: 'old_shift' | 'new_shift' = 'new_shift',
@ -113,7 +121,7 @@ export class ShiftsHelpersService {
}); });
} }
async afterWriteOvertimeAndLog(tx: Tx, employee_id: number, date_only: Date, action: UpsertAction) { async afterWriteOvertimeAndLog(tx: Tx, employee_id: number, date_only: Date) {
// Switch regular → weekly overtime si > 40h // Switch regular → weekly overtime si > 40h
await this.overtimeService.transformRegularHoursToWeeklyOvertime(employee_id, date_only, tx); await this.overtimeService.transformRegularHoursToWeeklyOvertime(employee_id, date_only, tx);
const [daily, weekly] = await Promise.all([ const [daily, weekly] = await Promise.all([

View File

@ -84,7 +84,7 @@ export class ShiftsCommandService extends BaseApprovalService<Shifts> {
): Promise<{action: UpsertAction; day: DayShiftResponse[]}> { ): Promise<{action: UpsertAction; day: DayShiftResponse[]}> {
return this.prisma.$transaction(async (tx) => { return this.prisma.$transaction(async (tx) => {
const date_only = toDateOnly(date_iso); const date_only = toDateOnly(date_iso);
const { id: timesheet_id } = await this.helpersService.ensureTimesheet(tx, employee_id, date_only); const { id: timesheet_id } = await this.helpersService.findOrUpsertTimesheet(tx, employee_id, date_only);
const new_norm_shift = await this.helpersService.normalizeRequired(dto.new_shift); const new_norm_shift = await this.helpersService.normalizeRequired(dto.new_shift);
const new_bank_code_id = await this.helpersService.resolveBankIdRequired(tx, new_norm_shift.type, 'new_shift'); const new_bank_code_id = await this.helpersService.resolveBankIdRequired(tx, new_norm_shift.type, 'new_shift');
@ -105,7 +105,7 @@ export class ShiftsCommandService extends BaseApprovalService<Shifts> {
bank_code_id: new_bank_code_id, bank_code_id: new_bank_code_id,
}, },
}); });
await this.helpersService.afterWriteOvertimeAndLog(tx, employee_id, date_only,'create'); await this.helpersService.afterWriteOvertimeAndLog(tx, employee_id, date_only);
const fresh_shift = await this.helpersService.getDayShifts(tx, timesheet_id, date_only); const fresh_shift = await this.helpersService.getDayShifts(tx, timesheet_id, date_only);
return { action: 'create', day: await this.helpersService.mapDay(fresh_shift)}; return { action: 'create', day: await this.helpersService.mapDay(fresh_shift)};
}); });
@ -121,7 +121,7 @@ export class ShiftsCommandService extends BaseApprovalService<Shifts> {
): Promise<{ action: UpsertAction; day: DayShiftResponse[];}>{ ): Promise<{ action: UpsertAction; day: DayShiftResponse[];}>{
return this.prisma.$transaction(async (tx) => { return this.prisma.$transaction(async (tx) => {
const date_only = toDateOnly(date_iso); const date_only = toDateOnly(date_iso);
const { id: timesheet_id } = await this.helpersService.ensureTimesheet(tx, employee_id, date_only); const { id: timesheet_id } = await this.helpersService.findOrUpsertTimesheet(tx, employee_id, date_only);
const old_norm_shift = await this.helpersService.normalizeRequired(dto.old_shift, 'old_shift'); const old_norm_shift = await this.helpersService.normalizeRequired(dto.old_shift, 'old_shift');
const new_norm_shift = await this.helpersService.normalizeRequired(dto.new_shift, 'new_shift'); const new_norm_shift = await this.helpersService.normalizeRequired(dto.new_shift, 'new_shift');
@ -150,7 +150,7 @@ export class ShiftsCommandService extends BaseApprovalService<Shifts> {
bank_code_id: new_bank_code_id, bank_code_id: new_bank_code_id,
}, },
}); });
await this.helpersService.afterWriteOvertimeAndLog(tx, employee_id, date_only, 'update'); await this.helpersService.afterWriteOvertimeAndLog(tx, employee_id, date_only);
const fresh_shift = await this.helpersService.getDayShifts(tx, timesheet_id, date_only); const fresh_shift = await this.helpersService.getDayShifts(tx, timesheet_id, date_only);
return { action: 'update', day: await this.helpersService.mapDay(fresh_shift)}; return { action: 'update', day: await this.helpersService.mapDay(fresh_shift)};
}); });
@ -166,15 +166,16 @@ export class ShiftsCommandService extends BaseApprovalService<Shifts> {
dto: UpsertShiftDto, dto: UpsertShiftDto,
): Promise<{ day: DayShiftResponse[]; }>{ ): Promise<{ day: DayShiftResponse[]; }>{
return this.prisma.$transaction(async (tx) => { return this.prisma.$transaction(async (tx) => {
const date_only = toDateOnly(date_iso); const date_only = toDateOnly(date_iso); //converts to Date format
const employee_id = await this.emailResolver.findIdByEmail(email); const employee_id = await this.emailResolver.findIdByEmail(email);
const { id: timesheet_id } = await this.helpersService.ensureTimesheet(tx, employee_id, date_only); const timesheet = await this.helpersService.ensureTimesheet(tx, employee_id, date_only);
if(!timesheet) throw new NotFoundException('Timesheet not found')
const norm_shift = await this.helpersService.normalizeRequired(dto.old_shift, 'old_shift'); const norm_shift = await this.helpersService.normalizeRequired(dto.old_shift, 'old_shift');
const bank_code_id = await this.typeResolver.findByType(norm_shift.type); const bank_code_id = await this.typeResolver.findByType(norm_shift.type);
const existing = await this.helpersService.findExactOldShift(tx, { const existing = await this.helpersService.findExactOldShift(tx, {
timesheet_id, timesheet_id: timesheet.id,
date_only, date_only,
norm: norm_shift, norm: norm_shift,
bank_code_id: bank_code_id.id, bank_code_id: bank_code_id.id,
@ -183,8 +184,8 @@ export class ShiftsCommandService extends BaseApprovalService<Shifts> {
await tx.shifts.delete({ where: { id: existing.id } }); await tx.shifts.delete({ where: { id: existing.id } });
await this.helpersService.afterWriteOvertimeAndLog(tx, employee_id, date_only, 'delete'); await this.helpersService.afterWriteOvertimeAndLog(tx, employee_id, date_only);
const fresh_shift = await this.helpersService.getDayShifts(tx, timesheet_id, date_only); const fresh_shift = await this.helpersService.getDayShifts(tx, timesheet.id, date_only);
return { day: await this.helpersService.mapDay(fresh_shift)}; return { day: await this.helpersService.mapDay(fresh_shift)};
}); });
} }