diff --git a/prisma/migrations/20251204135338_schedule_presets_ajustments/migration.sql b/prisma/migrations/20251204135338_schedule_presets_ajustments/migration.sql new file mode 100644 index 0000000..b5c3e74 --- /dev/null +++ b/prisma/migrations/20251204135338_schedule_presets_ajustments/migration.sql @@ -0,0 +1,20 @@ +/* + Warnings: + + - You are about to drop the column `employee_id` on the `schedule_presets` table. All the data in the column will be lost. + +*/ +-- DropForeignKey +ALTER TABLE "public"."schedule_presets" DROP CONSTRAINT "schedule_presets_employee_id_fkey"; + +-- DropIndex +DROP INDEX "public"."schedule_presets_employee_id_name_key"; + +-- AlterTable +ALTER TABLE "employees" ADD COLUMN "schedule_preset_id" INTEGER; + +-- AlterTable +ALTER TABLE "schedule_presets" DROP COLUMN "employee_id"; + +-- AddForeignKey +ALTER TABLE "employees" ADD CONSTRAINT "employees_schedule_preset_id_fkey" FOREIGN KEY ("schedule_preset_id") REFERENCES "schedule_presets"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index a016790..f9db8e2 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -47,11 +47,13 @@ model userModuleAccess { } model Employees { - id Int @id @default(autoincrement()) - user Users @relation("UserEmployee", fields: [user_id], references: [id]) - user_id String @unique @db.Uuid - supervisor Employees? @relation("EmployeeSupervisor", fields: [supervisor_id], references: [id]) - supervisor_id Int? + id Int @id @default(autoincrement()) + user Users @relation("UserEmployee", fields: [user_id], references: [id]) + user_id String @unique @db.Uuid + supervisor Employees? @relation("EmployeeSupervisor", fields: [supervisor_id], references: [id]) + supervisor_id Int? + schedule_preset SchedulePresets? @relation("EmployeesSchedulePreset", fields: [schedule_preset_id], references: [id]) + schedule_preset_id Int? external_payroll_id Int company_code Int @@ -60,10 +62,9 @@ model Employees { job_title String? is_supervisor Boolean @default(false) - crew Employees[] @relation("EmployeeSupervisor") - timesheet Timesheets[] @relation("TimesheetEmployee") - leave_request LeaveRequests[] @relation("LeaveRequestEmployee") - schedule_presets SchedulePresets[] @relation("SchedulePreset") + crew Employees[] @relation("EmployeeSupervisor") + timesheet Timesheets[] @relation("TimesheetEmployee") + leave_request LeaveRequests[] @relation("LeaveRequestEmployee") @@map("employees") } @@ -149,16 +150,13 @@ model TimesheetsArchive { } model SchedulePresets { - id Int @id @default(autoincrement()) - employee Employees @relation("SchedulePreset", fields: [employee_id], references: [id]) - employee_id Int - + id Int @id @default(autoincrement()) name String is_default Boolean @default(false) - shifts SchedulePresetShifts[] @relation("SchedulePresetShiftsSchedulePreset") + shifts SchedulePresetShifts[] @relation("SchedulePresetShiftsSchedulePreset") + employees Employees[] @relation("EmployeesSchedulePreset") - @@unique([employee_id, name], name: "unique_preset_name_per_employee") @@map("schedule_presets") } diff --git a/src/identity-and-account/employees/dtos/employee-detailed.dto.ts b/src/identity-and-account/employees/dtos/employee-detailed.dto.ts index 1a6769b..55d3801 100644 --- a/src/identity-and-account/employees/dtos/employee-detailed.dto.ts +++ b/src/identity-and-account/employees/dtos/employee-detailed.dto.ts @@ -16,4 +16,5 @@ export class EmployeeDetailedDto { @IsString() @IsOptional() residence?: string; @IsInt() @IsPositive() @Type(() => Number) external_payroll_id: number; @IsArray() @IsString({ each: true }) user_module_access: string[]; + @IsInt() @IsOptional() preset_id?: number; } diff --git a/src/identity-and-account/employees/dtos/employee.dto.ts b/src/identity-and-account/employees/dtos/employee.dto.ts index e4dc1a8..ed94c9b 100644 --- a/src/identity-and-account/employees/dtos/employee.dto.ts +++ b/src/identity-and-account/employees/dtos/employee.dto.ts @@ -6,7 +6,7 @@ export class EmployeeDto { @IsString() last_name!: string; @IsString() @IsEmail() email!: string; @IsString() @IsOptional() supervisor_full_name: string | ''; - @IsString() company_name: number; + @IsString() company_name: string; @IsString() @IsOptional() job_title: string; @IsInt() @Type(()=> Number) external_payroll_id: number; } \ No newline at end of file diff --git a/src/identity-and-account/employees/services/employees-create.service.ts b/src/identity-and-account/employees/services/employees-create.service.ts index ac388c7..ee64101 100644 --- a/src/identity-and-account/employees/services/employees-create.service.ts +++ b/src/identity-and-account/employees/services/employees-create.service.ts @@ -44,6 +44,7 @@ export class EmployeesCreateService { first_work_day: dto.first_work_day, is_supervisor: dto.is_supervisor, supervisor_id: supervisor_id, + schedule_preset_id: dto.preset_id, }, }); }); diff --git a/src/identity-and-account/employees/services/employees-get.service.ts b/src/identity-and-account/employees/services/employees-get.service.ts index 619474d..bfaa85b 100644 --- a/src/identity-and-account/employees/services/employees-get.service.ts +++ b/src/identity-and-account/employees/services/employees-get.service.ts @@ -1,12 +1,14 @@ import { Injectable } from "@nestjs/common"; -import { Result } from "src/common/errors/result-error.factory"; -import { EmailToIdResolver } from "src/common/mappers/email-id.mapper"; +import { PrismaService } from "src/prisma/prisma.service"; + import { Modules, toStringFromBoolean } from "src/common/mappers/module-access.mapper"; +import { EmailToIdResolver } from "src/common/mappers/email-id.mapper"; import { toStringFromDate } from "src/common/utils/date-utils"; +import { Result } from "src/common/errors/result-error.factory"; + +import { toStringFromCompanyCode } from "src/identity-and-account/employees/utils/employee.utils"; import { EmployeeDetailedDto } from "src/identity-and-account/employees/dtos/employee-detailed.dto"; import { EmployeeDto } from "src/identity-and-account/employees/dtos/employee.dto"; -import { toStringFromCompanyCode } from "src/identity-and-account/employees/utils/employee.utils"; -import { PrismaService } from "src/prisma/prisma.service"; @Injectable() export class EmployeesGetService { @@ -44,13 +46,12 @@ export class EmployeesGetService { first_name: r.user.first_name, last_name: r.user.last_name, email: r.user.email, - company_name: r.company_code, + company_name: toStringFromCompanyCode(r.company_code), job_title: r.job_title ?? '', external_payroll_id: r.external_payroll_id, employee_full_name: `${r.user.first_name} ${r.user.last_name}`, supervisor_full_name: `${r.supervisor?.user.first_name} ${r.supervisor?.user.last_name}`, - })), - ) + })),) return { success: true, data: employee_list } } @@ -148,6 +149,7 @@ export class EmployeesGetService { last_work_day: true, external_payroll_id: true, is_supervisor: true, + schedule_preset_id: true, } }); if (!employee) return { success: false, error: `EMPLOYEE_NOT_FOUND` }; diff --git a/src/identity-and-account/employees/services/employees-update.service.ts b/src/identity-and-account/employees/services/employees-update.service.ts index 5b7b8d3..d87bf6c 100644 --- a/src/identity-and-account/employees/services/employees-update.service.ts +++ b/src/identity-and-account/employees/services/employees-update.service.ts @@ -1,12 +1,14 @@ import { Injectable } from "@nestjs/common"; -import { Result } from "src/common/errors/result-error.factory"; -import { EmailToIdResolver } from "src/common/mappers/email-id.mapper"; -import { toBooleanFromString } from "src/common/mappers/module-access.mapper"; -import { toDateFromString } from "src/common/utils/date-utils"; -import { EmployeeDetailedDto } from "src/identity-and-account/employees/dtos/employee-detailed.dto"; -import { toCompanyCodeFromString } from "src/identity-and-account/employees/utils/employee.utils"; import { PrismaService } from "src/prisma/prisma.service"; +import { toBooleanFromString } from "src/common/mappers/module-access.mapper"; +import { EmailToIdResolver } from "src/common/mappers/email-id.mapper"; +import { toDateFromString } from "src/common/utils/date-utils"; +import { Result } from "src/common/errors/result-error.factory"; + +import { toCompanyCodeFromString } from "src/identity-and-account/employees/utils/employee.utils"; +import { EmployeeDetailedDto } from "src/identity-and-account/employees/dtos/employee-detailed.dto"; + @Injectable() export class EmployeesUpdateService { constructor( @@ -62,6 +64,8 @@ export class EmployeesUpdateService { last_work_day: dto.last_work_day, is_supervisor: dto.is_supervisor, supervisor_id: supervisor_id, + schedule_preset_id: dto.preset_id, + external_payroll_id: dto.external_payroll_id, }, }); diff --git a/src/time-and-attendance/schedule-presets/controller/schedule-presets.controller.ts b/src/time-and-attendance/schedule-presets/controller/schedule-presets.controller.ts index 6915dad..0e43e1d 100644 --- a/src/time-and-attendance/schedule-presets/controller/schedule-presets.controller.ts +++ b/src/time-and-attendance/schedule-presets/controller/schedule-presets.controller.ts @@ -1,57 +1,46 @@ import { Controller, Param, Body, Get, Post, ParseIntPipe, Delete, Patch } from "@nestjs/common"; -import { SchedulePresetsDto } from "src/time-and-attendance/schedule-presets/dtos/create-schedule-presets.dto"; -import { SchedulePresetsApplyService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-apply.service"; -import { SchedulePresetsGetService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-get.service"; + import { SchedulePresetsCreateService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-create.service"; -import { SchedulePresetUpdateDeleteService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-update-delete.service"; +import { SchedulePresetUpdateService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-update.service"; +import { SchedulePresetDeleteService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-delete.service"; +import { SchedulePresetsGetService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-get.service"; +import { SchedulePresetsDto } from "src/time-and-attendance/schedule-presets/dtos/create-schedule-presets.dto"; + import { ModuleAccessAllowed } from "src/common/decorators/modules-guard.decorators"; import { Modules as ModulesEnum } from ".prisma/client"; -import { Access } from "src/common/decorators/module-access.decorators"; @Controller('schedule-presets') export class SchedulePresetsController { constructor( - private readonly createService: SchedulePresetsCreateService, private readonly getService: SchedulePresetsGetService, - private readonly applyPresetsService: SchedulePresetsApplyService, - private readonly updateDeleteService: SchedulePresetUpdateDeleteService, + private readonly createService: SchedulePresetsCreateService, + private readonly updateService: SchedulePresetUpdateService, + private readonly deleteService: SchedulePresetDeleteService, ) { } - // used to create a schedule preset - @Post('create') - @ModuleAccessAllowed(ModulesEnum.employee_management) - async createPreset(@Access('email') email: string, @Body() dto: SchedulePresetsDto) { - return await this.createService.createPreset(email, dto); - } - - //used to update an already existing schedule preset - @Patch('update/:preset_id') - @ModuleAccessAllowed(ModulesEnum.employee_management) - async updatePreset( - @Param('preset_id', ParseIntPipe) preset_id: number, @Body() dto: SchedulePresetsDto, @Access('email') email: string) { - return await this.updateDeleteService.updatePreset(preset_id, dto, email); - } - - //used to delete a schedule preset - @Delete('delete/:preset_id') - @ModuleAccessAllowed(ModulesEnum.employee_management) - async deletePreset( - @Param('preset_id', ParseIntPipe) preset_id: number, @Access('email') email: string) { - return await this.updateDeleteService.deletePreset(preset_id, email); - } - - //used to show the list of available schedule presets @Get('find-list') @ModuleAccessAllowed(ModulesEnum.employee_management) - async findListById(@Access('email') email: string) { - return this.getService.getSchedulePresets(email); + async findListById() { + return this.getService.getSchedulePresets(); } - //used to apply a preset to a timesheet - @Post('apply-presets') - @ModuleAccessAllowed(ModulesEnum.timesheets) - async applyPresets( - @Body('preset') preset_id: number, @Body('start') start_date: string, @Access('email') email: string) { - return this.applyPresetsService.applyToTimesheet(email, preset_id, start_date); + @Post('create') + @ModuleAccessAllowed(ModulesEnum.employee_management) + async createPreset(@Body() dto: SchedulePresetsDto) { + return await this.createService.createPreset(dto); + } + + @Patch('update') + @ModuleAccessAllowed(ModulesEnum.employee_management) + async updatePreset( + @Body() dto: SchedulePresetsDto) { + return await this.updateService.updatePreset(dto); + } + + @Delete('delete/:id') + @ModuleAccessAllowed(ModulesEnum.employee_management) + async deletePreset( + @Param('id', ParseIntPipe) id: number) { + return await this.deleteService.deletePreset(id); } } \ No newline at end of file diff --git a/src/time-and-attendance/schedule-presets/dtos/create-schedule-preset-shifts.dto.ts b/src/time-and-attendance/schedule-presets/dtos/create-schedule-preset-shifts.dto.ts index 117e331..19adf4d 100644 --- a/src/time-and-attendance/schedule-presets/dtos/create-schedule-preset-shifts.dto.ts +++ b/src/time-and-attendance/schedule-presets/dtos/create-schedule-preset-shifts.dto.ts @@ -3,11 +3,11 @@ import { HH_MM_REGEX } from "src/common/utils/constants.utils"; import { Weekday } from "@prisma/client"; export class SchedulePresetShiftsDto { - @IsInt() preset_id!: number; + @IsInt() preset_id!: number; @IsEnum(Weekday) week_day!: Weekday; @IsInt() @Min(1) sort_order!: number; - @IsString() type!: string; + @IsString() type!: string; @IsString() @Matches(HH_MM_REGEX) start_time!: string; @IsString() @Matches(HH_MM_REGEX) end_time!: string; - @IsOptional() @IsBoolean() is_remote?: boolean; + @IsOptional() @IsBoolean() is_remote?: boolean; } \ No newline at end of file diff --git a/src/time-and-attendance/schedule-presets/dtos/create-schedule-presets.dto.ts b/src/time-and-attendance/schedule-presets/dtos/create-schedule-presets.dto.ts index 7c41ff0..5da3f2f 100644 --- a/src/time-and-attendance/schedule-presets/dtos/create-schedule-presets.dto.ts +++ b/src/time-and-attendance/schedule-presets/dtos/create-schedule-presets.dto.ts @@ -1,9 +1,10 @@ import { ArrayMinSize, IsArray, IsBoolean, IsInt, IsOptional, IsString } from "class-validator"; + import { SchedulePresetShiftsDto } from "src/time-and-attendance/schedule-presets/dtos/create-schedule-preset-shifts.dto"; export class SchedulePresetsDto { @IsInt() id!: number; @IsString() name!: string; - @IsBoolean() @IsOptional() is_default: boolean; + @IsBoolean() @IsOptional() is_default: boolean; @IsArray() @ArrayMinSize(1) preset_shifts: SchedulePresetShiftsDto[]; } \ No newline at end of file diff --git a/src/time-and-attendance/schedule-presets/schedule-presets.module.ts b/src/time-and-attendance/schedule-presets/schedule-presets.module.ts index 09be865..ccce23b 100644 --- a/src/time-and-attendance/schedule-presets/schedule-presets.module.ts +++ b/src/time-and-attendance/schedule-presets/schedule-presets.module.ts @@ -1,25 +1,25 @@ - import { Module } from "@nestjs/common"; + import { SchedulePresetsController } from "src/time-and-attendance/schedule-presets/controller/schedule-presets.controller"; -import { SchedulePresetsApplyService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-apply.service"; -import { SchedulePresetsCreateService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-create.service"; import { SchedulePresetsGetService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-get.service"; -import { SchedulePresetUpdateDeleteService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-update-delete.service"; +import { SchedulePresetsCreateService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-create.service"; +import { SchedulePresetUpdateService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-update.service"; +import { SchedulePresetDeleteService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-delete.service"; @Module({ controllers: [SchedulePresetsController], providers: [ - SchedulePresetsCreateService, - SchedulePresetUpdateDeleteService, SchedulePresetsGetService, - SchedulePresetsApplyService, + SchedulePresetsCreateService, + SchedulePresetUpdateService, + SchedulePresetDeleteService, ], exports: [ - SchedulePresetsCreateService, - SchedulePresetUpdateDeleteService, SchedulePresetsGetService, - SchedulePresetsApplyService, + SchedulePresetsCreateService, + SchedulePresetUpdateService, + SchedulePresetDeleteService, ], }) export class SchedulePresetsModule { } \ No newline at end of file diff --git a/src/time-and-attendance/schedule-presets/services/schedule-presets-create.service.ts b/src/time-and-attendance/schedule-presets/services/schedule-presets-create.service.ts index 1daf617..8ef60c1 100644 --- a/src/time-and-attendance/schedule-presets/services/schedule-presets-create.service.ts +++ b/src/time-and-attendance/schedule-presets/services/schedule-presets-create.service.ts @@ -1,35 +1,30 @@ import { Injectable } from "@nestjs/common"; -import { Weekday } from "@prisma/client"; + import { PrismaService } from "src/prisma/prisma.service"; -import { BankCodesResolver } from "src/common/mappers/bank-type-id.mapper"; -import { EmailToIdResolver } from "src/common/mappers/email-id.mapper"; -import { Result } from "src/common/errors/result-error.factory"; -import { overlaps, toDateFromHHmm } from "src/common/utils/date-utils"; + import { SchedulePresetsDto } from "src/time-and-attendance/schedule-presets/dtos/create-schedule-presets.dto"; +import { overlaps, toDateFromHHmm } from "src/common/utils/date-utils"; +import { BankCodesResolver } from "src/common/mappers/bank-type-id.mapper"; +import { Result } from "src/common/errors/result-error.factory"; + @Injectable() export class SchedulePresetsCreateService { constructor( private readonly prisma: PrismaService, private readonly typeResolver: BankCodesResolver, - private readonly emailResolver: EmailToIdResolver, ) { } //_________________________________________________________________ // CREATE //_________________________________________________________________ - async createPreset(email: string, dto: SchedulePresetsDto): Promise> { + async createPreset(dto: SchedulePresetsDto): Promise> { try { - - //validate email and fetch employee_id - const employee_id = await this.emailResolver.findIdByEmail(email); - if (!employee_id.success) return { success: false, error: employee_id.error }; - //validate new unique name const existing = await this.prisma.schedulePresets.findFirst({ - where: { name: dto.name, employee_id: employee_id.data }, + where: { name: dto.name }, select: { name: true }, }); - if (!existing) return { success: false, error: 'INVALID_SCHEDULE_PRESET' }; + if (existing) return { success: false, error: 'INVALID_SCHEDULE_PRESET' }; const normalized_shifts = dto.preset_shifts.map((shift) => ({ ...shift, @@ -63,14 +58,13 @@ export class SchedulePresetsCreateService { //check if employee chose this preset has a default preset and ensure all others are false if (dto.is_default) { await tx.schedulePresets.updateMany({ - where: { employee_id: employee_id.data, is_default: true }, + where: { is_default: true }, data: { is_default: false }, }); } await tx.schedulePresets.create({ data: { - employee_id: employee_id.data, name: dto.name, is_default: dto.is_default ?? false, shifts: { diff --git a/src/time-and-attendance/schedule-presets/services/schedule-presets-delete.service.ts b/src/time-and-attendance/schedule-presets/services/schedule-presets-delete.service.ts new file mode 100644 index 0000000..b8f1d0b --- /dev/null +++ b/src/time-and-attendance/schedule-presets/services/schedule-presets-delete.service.ts @@ -0,0 +1,23 @@ +import { Result } from "src/common/errors/result-error.factory"; +import { PrismaService } from "src/prisma/prisma.service"; + +export class SchedulePresetDeleteService { + constructor(private readonly prisma: PrismaService) { } + + //_________________________________________________________________ + // DELETE + //_________________________________________________________________ + async deletePreset(preset_id: number): Promise> { + const preset = await this.prisma.schedulePresets.findFirst({ + where: { id: preset_id }, + select: { id: true }, + }); + if (!preset) return { success: false, error: `SCHEDULE_PRESET_NOT_FOUND` }; + + await this.prisma.$transaction(async (tx) => { + await tx.schedulePresetShifts.deleteMany({ where: { preset_id: preset_id } }); + await tx.schedulePresets.delete({ where: { id: preset_id } }); + }); + return { success: true, data: true }; + } +} \ No newline at end of file diff --git a/src/time-and-attendance/schedule-presets/services/schedule-presets-get.service.ts b/src/time-and-attendance/schedule-presets/services/schedule-presets-get.service.ts index e7cac2f..211d64d 100644 --- a/src/time-and-attendance/schedule-presets/services/schedule-presets-get.service.ts +++ b/src/time-and-attendance/schedule-presets/services/schedule-presets-get.service.ts @@ -1,23 +1,20 @@ -import { PresetResponse, ShiftResponse } from "src/time-and-attendance/utils/type.utils"; -import { PrismaService } from "src/prisma/prisma.service"; import { Injectable } from "@nestjs/common"; -import { EmailToIdResolver } from "src/common/mappers/email-id.mapper"; + +import { PrismaService } from "src/prisma/prisma.service"; + +import { PresetResponse, ShiftResponse } from "src/time-and-attendance/utils/type.utils"; + import { Result } from "src/common/errors/result-error.factory"; @Injectable() export class SchedulePresetsGetService { constructor( private readonly prisma: PrismaService, - private readonly emailResolver: EmailToIdResolver, ) { } - async getSchedulePresets(email: string): Promise> { + async getSchedulePresets(): Promise> { try { - const employee_id = await this.emailResolver.findIdByEmail(email); - if (!employee_id.success) return { success: false, error: employee_id.error }; - const presets = await this.prisma.schedulePresets.findMany({ - where: { employee_id: employee_id.data }, orderBy: [{ is_default: 'desc' }, { name: 'asc' }], include: { shifts: { diff --git a/src/time-and-attendance/schedule-presets/services/schedule-presets-update-delete.service.ts b/src/time-and-attendance/schedule-presets/services/schedule-presets-update.service.ts similarity index 61% rename from src/time-and-attendance/schedule-presets/services/schedule-presets-update-delete.service.ts rename to src/time-and-attendance/schedule-presets/services/schedule-presets-update.service.ts index fef84de..740ff49 100644 --- a/src/time-and-attendance/schedule-presets/services/schedule-presets-update-delete.service.ts +++ b/src/time-and-attendance/schedule-presets/services/schedule-presets-update.service.ts @@ -1,38 +1,32 @@ import { Injectable } from "@nestjs/common"; -import { Result } from "src/common/errors/result-error.factory"; -import { BankCodesResolver } from "src/common/mappers/bank-type-id.mapper"; -import { EmailToIdResolver } from "src/common/mappers/email-id.mapper"; -import { overlaps, toDateFromHHmm } from "src/common/utils/date-utils"; import { PrismaService } from "src/prisma/prisma.service"; + import { SchedulePresetsDto } from "src/time-and-attendance/schedule-presets/dtos/create-schedule-presets.dto"; +import { overlaps, toDateFromHHmm } from "src/common/utils/date-utils"; +import { BankCodesResolver } from "src/common/mappers/bank-type-id.mapper"; +import { Result } from "src/common/errors/result-error.factory"; + @Injectable() -export class SchedulePresetUpdateDeleteService { +export class SchedulePresetUpdateService { constructor( private readonly prisma: PrismaService, private readonly typeResolver: BankCodesResolver, - private readonly emailResolver: EmailToIdResolver, ) { } //_________________________________________________________________ // UPDATE //_________________________________________________________________ - async updatePreset(preset_id: number, dto: SchedulePresetsDto, email: string): Promise> { - - const employee_id = await this.emailResolver.findIdByEmail(email); - if (!employee_id.success) return { success: false, error: 'EMPLOYEE_NOT_FOUND' } - //look for existing schedule_preset and return OG's data + async updatePreset(dto: SchedulePresetsDto): Promise> { const existing = await this.prisma.schedulePresets.findFirst({ - where: { id: preset_id, name: dto.name, employee_id: employee_id.data }, + where: { id: dto.id, name: dto.name }, select: { id: true, is_default: true, - employee_id: true, shifts: true, }, }); if (!existing) return { success: false, error: `SCHEDULE_PRESET_NOT_FOUND` }; - //normalized shifts start and end time to make an overlap check with other shifts const normalized_shifts = dto.preset_shifts.map((shift) => ({ ...shift, start: toDateFromHHmm(shift.start_time), @@ -41,10 +35,8 @@ export class SchedulePresetUpdateDeleteService { for (const preset_shifts of normalized_shifts) { for (const other_shifts of normalized_shifts) { - //skip if same object or id week_day is not the same if (preset_shifts === other_shifts) continue; if (preset_shifts.week_day !== other_shifts.week_day) continue; - //check overlaping possibilities const has_overlap = overlaps( { start: preset_shifts.start, end: preset_shifts.end }, { start: other_shifts.start, end: other_shifts.end }, @@ -52,7 +44,6 @@ export class SchedulePresetUpdateDeleteService { if (has_overlap) return { success: false, error: 'SCHEDULE_PRESET_OVERLAP' }; } } - //validate bank_code_id/type and map them const bank_code_results = await Promise.all(dto.preset_shifts.map((shift) => this.typeResolver.findBankCodeIDByType(shift.type), )); @@ -61,18 +52,15 @@ export class SchedulePresetUpdateDeleteService { } await this.prisma.$transaction(async (tx) => { - //check if employee chose this preset has a default preset and ensure all others are false if (dto.is_default) { await tx.schedulePresets.updateMany({ where: { - employee_id: existing.employee_id, is_default: true, NOT: { id: existing.id }, }, data: { is_default: false }, }); } - //deletes old preset shifts to make place to new ones await tx.schedulePresetShifts.deleteMany({ where: { preset_id: existing.id } }); await tx.schedulePresets.update({ @@ -82,7 +70,6 @@ export class SchedulePresetUpdateDeleteService { is_default: dto.is_default ?? false, shifts: { create: dto.preset_shifts.map((shift, index) => { - //validated bank_codes sent as a Result Array to access its data const result = bank_code_results[index] as { success: true, data: number }; return { week_day: shift.week_day, @@ -91,7 +78,6 @@ export class SchedulePresetUpdateDeleteService { end_time: toDateFromHHmm(shift.end_time), is_remote: shift.is_remote ?? false, bank_code: { - //connect uses the FK links to set the bank_code_id connect: { id: result.data }, }, } @@ -103,23 +89,4 @@ export class SchedulePresetUpdateDeleteService { return { success: true, data: true }; } - //_________________________________________________________________ - // DELETE - //_________________________________________________________________ - async deletePreset(preset_id: number, email: string): Promise> { - const employee_id = await this.emailResolver.findIdByEmail(email); - if (!employee_id.success) return { success: false, error: 'EMPLOYEE_NOT_FOUND' } - - const preset = await this.prisma.schedulePresets.findFirst({ - where: { id: preset_id, employee_id: employee_id.data }, - select: { id: true }, - }); - if (!preset) return { success: false, error: `SCHEDULE_PRESET_NOT_FOUND` }; - - await this.prisma.$transaction(async (tx) => { - await tx.schedulePresetShifts.deleteMany({ where: { preset_id: preset_id } }); - await tx.schedulePresets.delete({ where: { id: preset_id } }); - }); - return { success: true, data: true }; - } } \ No newline at end of file diff --git a/src/time-and-attendance/shifts/services/shifts-create.service.ts b/src/time-and-attendance/shifts/services/shifts-create.service.ts index 7c8ec2c..e769e45 100644 --- a/src/time-and-attendance/shifts/services/shifts-create.service.ts +++ b/src/time-and-attendance/shifts/services/shifts-create.service.ts @@ -19,7 +19,7 @@ export class ShiftsCreateService { //_________________________________________________________________ // CREATE WRAPPER FUNCTION FOR ONE OR MANY INPUT //_________________________________________________________________ - async createOneOrManyShifts(email: string, shifts: ShiftDto[]): Promise> { + async createOneOrManyShifts(email: string, shifts: ShiftDto[]): Promise> { try { //verify if array is empty or not if (!Array.isArray(shifts) || shifts.length === 0) return { success: false, error: 'No data received' }; @@ -51,7 +51,7 @@ export class ShiftsCreateService { if (created_shifts.length === 0) return { success: false, error: errors.join(' | ') || 'No shift created' }; // returns array of created shifts - return { success: true, data: created_shifts } + return { success: true, data: true } } catch (error) { return { success: false, error } } diff --git a/src/time-and-attendance/shifts/services/shifts-update-delete.service.ts b/src/time-and-attendance/shifts/services/shifts-update-delete.service.ts index ed602b0..292b268 100644 --- a/src/time-and-attendance/shifts/services/shifts-update-delete.service.ts +++ b/src/time-and-attendance/shifts/services/shifts-update-delete.service.ts @@ -16,7 +16,7 @@ export class ShiftsUpdateDeleteService { private readonly timesheetResolver: EmployeeTimesheetResolver, ) { } - async updateOneOrManyShifts(shifts: ShiftDto[], email: string): Promise> { + async updateOneOrManyShifts(shifts: ShiftDto[], email: string): Promise> { try { //verify if array is empty or not if (!Array.isArray(shifts) || shifts.length === 0) return { success: false, error: 'No data received' }; @@ -48,7 +48,7 @@ export class ShiftsUpdateDeleteService { if (updated_shifts.length === 0) return { success: false, error: errors.join(' | ') || 'No shift updated' }; // returns array of updated shifts - return { success: true, data: updated_shifts } + return { success: true, data: true } } catch (error) { return { success: false, error } } diff --git a/src/time-and-attendance/time-and-attendance.module.ts b/src/time-and-attendance/time-and-attendance.module.ts index 2364b9a..6c7ba61 100644 --- a/src/time-and-attendance/time-and-attendance.module.ts +++ b/src/time-and-attendance/time-and-attendance.module.ts @@ -1,31 +1,41 @@ import { Module } from "@nestjs/common"; import { BusinessLogicsModule } from "src/time-and-attendance/domains/business-logics.module"; + import { ExpenseController } from "src/time-and-attendance/expenses/controllers/expense.controller"; import { ExpenseUpsertService } from "src/time-and-attendance/expenses/services/expense-upsert.service"; -import { PayperiodsModule } from "src/time-and-attendance/pay-period/pay-periods.module"; +import { ExpensesModule } from "src/time-and-attendance/expenses/expenses.module"; import { TimesheetController } from "src/time-and-attendance/timesheets/controllers/timesheet.controller"; import { TimesheetApprovalService } from "src/time-and-attendance/timesheets/services/timesheet-approval.service"; import { GetTimesheetsOverviewService } from "src/time-and-attendance/timesheets/services/timesheet-get-overview.service"; import { TimesheetsModule } from "src/time-and-attendance/timesheets/timesheets.module"; + import { BankCodesResolver } from "src/common/mappers/bank-type-id.mapper"; import { EmailToIdResolver } from "src/common/mappers/email-id.mapper"; import { EmployeeTimesheetResolver } from "src/common/mappers/timesheet.mapper"; + +import { PayperiodsModule } from "src/time-and-attendance/pay-period/pay-periods.module"; import { PayPeriodsController } from "src/time-and-attendance/pay-period/controllers/pay-periods.controller"; -import { ExpensesModule } from "src/time-and-attendance/expenses/expenses.module"; import { PayPeriodsQueryService } from "src/time-and-attendance/pay-period/services/pay-periods-query.service"; import { PayPeriodsCommandService } from "src/time-and-attendance/pay-period/services/pay-periods-command.service"; + import { CsvExportModule } from "src/modules/exports/csv-exports.module"; import { CsvExportService } from "src/modules/exports/services/csv-exports.service"; import { CsvExportController } from "src/modules/exports/controllers/csv-exports.controller"; -import { SchedulePresetsApplyService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-apply.service"; -import { SchedulePresetsGetService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-get.service"; + import { ShiftController } from "src/time-and-attendance/shifts/controllers/shift.controller"; import { ShiftsCreateService } from "src/time-and-attendance/shifts/services/shifts-create.service"; import { ShiftsGetService } from "src/time-and-attendance/shifts/services/shifts-get.service"; import { ShiftsUpdateDeleteService } from "src/time-and-attendance/shifts/services/shifts-update-delete.service"; +import { SchedulePresetsGetService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-get.service"; +import { SchedulePresetsController } from "src/time-and-attendance/schedule-presets/controller/schedule-presets.controller"; +import { SchedulePresetsModule } from "src/time-and-attendance/schedule-presets/schedule-presets.module"; +import { SchedulePresetDeleteService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-delete.service"; +import { SchedulePresetUpdateService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-update.service"; +import { SchedulePresetsCreateService } from "src/time-and-attendance/schedule-presets/services/schedule-presets-create.service"; + @Module({ imports: [ BusinessLogicsModule, @@ -33,12 +43,13 @@ import { ShiftsUpdateDeleteService } from "src/time-and-attendance/shifts/servic TimesheetsModule, ExpensesModule, PayperiodsModule, - CsvExportModule, + CsvExportModule, + SchedulePresetsModule, ], controllers: [ TimesheetController, ShiftController, - // SchedulePresetsController, + SchedulePresetsController, ExpenseController, PayPeriodsController, CsvExportController, @@ -50,9 +61,10 @@ import { ShiftsUpdateDeleteService } from "src/time-and-attendance/shifts/servic ShiftsCreateService, ShiftsUpdateDeleteService, ExpenseUpsertService, - // SchedulePresetsUpsertService, SchedulePresetsGetService, - SchedulePresetsApplyService, + SchedulePresetDeleteService, + SchedulePresetUpdateService, + SchedulePresetsCreateService, EmailToIdResolver, BankCodesResolver, TimesheetApprovalService, diff --git a/src/time-and-attendance/schedule-presets/services/schedule-presets-apply.service.ts b/src/~misc_deprecated-files/schedule-presets-apply.service.ts similarity index 100% rename from src/time-and-attendance/schedule-presets/services/schedule-presets-apply.service.ts rename to src/~misc_deprecated-files/schedule-presets-apply.service.ts