feat(presets): add possibility for user with right permissions to apply presets to employee timesheets

This commit is contained in:
Nic D 2026-01-27 16:12:28 -05:00
parent 0b31fc829b
commit 652bc1cba1
2 changed files with 51 additions and 14 deletions

View File

@ -50,11 +50,22 @@ export class SchedulePresetsController {
@Post('apply-preset') @Post('apply-preset')
@ModuleAccessAllowed(ModulesEnum.timesheets) @ModuleAccessAllowed(ModulesEnum.timesheets)
async applyPresetToTimesheet( async applyPresetToTimesheet(
@Access('email') email: string, @Body('timesheet_id') timesheet_id: number, @Access('email') email: string,
@Body('timesheet_id') timesheet_id: number,
) { ) {
return await this.applyService.applyPresetToTimesheet(email, timesheet_id); return await this.applyService.applyPresetToTimesheet(email, timesheet_id);
} }
@Post('apply-preset/:employeeEmail')
@ModuleAccessAllowed(ModulesEnum.timesheets_approval)
async applyPresetToTimesheetFromApproval(
@Access('email') email: string,
@Body('timesheet_id') timesheet_id: number,
@Param('employeeEmail') employee_email: string,
) {
return await this.applyService.applyPresetToTimesheet(email, timesheet_id, employee_email);
}
@Post('apply-day-preset') @Post('apply-day-preset')
@ModuleAccessAllowed(ModulesEnum.timesheets) @ModuleAccessAllowed(ModulesEnum.timesheets)
async applyPresetToDay( async applyPresetToDay(
@ -65,4 +76,16 @@ export class SchedulePresetsController {
) { ) {
return await this.applyService.applyPresetToDay(email, timesheet_id, week_day_index, date); return await this.applyService.applyPresetToDay(email, timesheet_id, week_day_index, date);
} }
@Post('apply-day-preset/:employeeEmail')
@ModuleAccessAllowed(ModulesEnum.timesheets_approval)
async applyPresetToDayFromApproval(
@Access('email') email: string,
@Body('timesheet_id') timesheet_id: number,
@Body('week_day_index') week_day_index: number,
@Body('date') date: string,
@Param('employeeEmail') employee_email: string,
) {
return await this.applyService.applyPresetToDay(email, timesheet_id, week_day_index, date, employee_email);
}
} }

View File

@ -24,8 +24,9 @@ export class SchedulePresetsApplyService {
private readonly payPeriodEventService: PayPeriodEventService, private readonly payPeriodEventService: PayPeriodEventService,
) { } ) { }
async applyPresetToTimesheet(email: string, timesheet_id: number): Promise<Result<boolean, string>> { async applyPresetToTimesheet(email: string, timesheet_id: number, employee_email?: string): Promise<Result<boolean, string>> {
const employee_id = await this.emailResolver.findIdByEmail(email); const user_email = employee_email ?? email;
const employee_id = await this.emailResolver.findIdByEmail(user_email);
if (!employee_id.success) return { success: false, error: 'EMPLOYEE_NOT_FOUND' }; if (!employee_id.success) return { success: false, error: 'EMPLOYEE_NOT_FOUND' };
const employee_default_schedule_preset = await this.prisma.employees.findFirst({ const employee_default_schedule_preset = await this.prisma.employees.findFirst({
@ -76,16 +77,27 @@ export class SchedulePresetsApplyService {
created_shifts.push(shift.data); created_shifts.push(shift.data);
} }
const response = await this.shiftService.createOneOrManyShifts(email, created_shifts); const response = await this.shiftService.createOneOrManyShifts(user_email, created_shifts);
if (response.success) if (response.success) {
// notify timesheet-approval observers of changes
if (!employee_email) {
this.payPeriodEventService.emit({
employee_email: user_email,
event_type: 'preset',
action: 'create',
})
}
return { success: true, data: true }; return { success: true, data: true };
}
else else
return { success: false, error: 'There was an error applying presets for this week' }; return { success: false, error: 'There was an error applying presets for this week' };
} }
async applyPresetToDay(email: string, timesheet_id: number, week_day_index: number, date: string): Promise<Result<boolean, string>> { async applyPresetToDay(email: string, timesheet_id: number, week_day_index: number, date: string, employee_email?: string): Promise<Result<boolean, string>> {
const employee_id = await this.emailResolver.findIdByEmail(email); const user_email = employee_email ?? email;
const employee_id = await this.emailResolver.findIdByEmail(user_email);
if (!employee_id.success) return { success: false, error: 'EMPLOYEE_NOT_FOUND' }; if (!employee_id.success) return { success: false, error: 'EMPLOYEE_NOT_FOUND' };
const week_day = Object.keys(WEEKDAY_MAP)[week_day_index]; const week_day = Object.keys(WEEKDAY_MAP)[week_day_index];
@ -118,16 +130,18 @@ export class SchedulePresetsApplyService {
if (!created_shift.success) if (!created_shift.success)
return { success: false, error: 'SHIFT_CREATE_FAILED' } return { success: false, error: 'SHIFT_CREATE_FAILED' }
await this.shiftService.createShift(employee_id.data, created_shift.data); await this.shiftService.createShift(employee_id.data, created_shift.data);
} }
// notify timesheet-approval observers of changes // notify timesheet-approval observers of changes
this.payPeriodEventService.emit({ if (!employee_email) {
employee_email: email, this.payPeriodEventService.emit({
event_type: 'preset', employee_email: user_email,
action: 'create', event_type: 'preset',
}) action: 'create',
})
}
return { success: true, data: true }; return { success: true, data: true };
} }
@ -145,7 +159,7 @@ export class SchedulePresetsApplyService {
is_approved: false, is_approved: false,
is_remote: preset.is_remote!, is_remote: preset.is_remote!,
}; };
return { success: true, data: shift }; return { success: true, data: shift };
} }
} }