diff --git a/src/identity-and-account/employees/employee-detailed.dto.ts b/src/identity-and-account/employees/employee-detailed.dto.ts index 2e03d92..5441fdb 100644 --- a/src/identity-and-account/employees/employee-detailed.dto.ts +++ b/src/identity-and-account/employees/employee-detailed.dto.ts @@ -16,7 +16,27 @@ export class EmployeeDetailedDto { @IsInt() daily_expected_hours: number; @IsDateString() @IsOptional() last_work_day?: string | null; @IsString() @IsOptional() residence?: string; - @IsOptional() @Type(() => PaidTimeOffDto) paid_time_off?: Partial | null; + @IsOptional() @Type(() => PaidTimeOffDto) paid_time_off?: Partial; + @IsInt() @IsPositive() @Type(() => Number) external_payroll_id: number; + @IsArray() @IsString({ each: true }) user_module_access: string[]; + @IsInt() @IsOptional() preset_id?: number; +} + +export class EmployeeDetailedUpsertDto { + @IsString() @IsNotEmpty() first_name: string; + @IsString() @IsNotEmpty() last_name: string; + @IsString() @IsOptional() employee_full_name: string; + @IsString() @IsOptional() supervisor_full_name: string; + @IsOptional() @IsBoolean() is_supervisor: boolean; + @IsString() company_name: string; + @IsString() @IsOptional() job_title: string; + @IsEmail() @IsOptional() email: string; + @IsString() phone_number: string; + @IsDateString() first_work_day: string; + @IsInt() daily_expected_hours: number; + @IsDateString() @IsOptional() last_work_day?: string | null; + @IsString() @IsOptional() residence?: string; + @IsOptional() @Type(() => PaidTimeOffDto) paid_time_off?: PaidTimeOffDto; @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/employees.controller.ts b/src/identity-and-account/employees/employees.controller.ts index 7b68d6d..5771a06 100644 --- a/src/identity-and-account/employees/employees.controller.ts +++ b/src/identity-and-account/employees/employees.controller.ts @@ -3,7 +3,7 @@ import { Modules as ModulesEnum } from ".prisma/client"; import { ModuleAccessAllowed } from "src/common/decorators/modules-guard.decorators"; import { Access } from "src/common/decorators/module-access.decorators"; import { Result } from "src/common/errors/result-error.factory"; -import { EmployeeDetailedDto } from "src/identity-and-account/employees/employee-detailed.dto"; +import { EmployeeDetailedDto, EmployeeDetailedUpsertDto } from "src/identity-and-account/employees/employee-detailed.dto"; import { EmployeesGetService } from "src/identity-and-account/employees/services/employees-get.service"; import { EmployeesCreateService } from "src/identity-and-account/employees/services/employees-create.service"; import { EmployeesUpdateService } from "src/identity-and-account/employees/services/employees-update.service"; @@ -37,13 +37,13 @@ export class EmployeesController { @Post('create') @ModuleAccessAllowed(ModulesEnum.employee_management) - async createEmployee(@Body() dto: EmployeeDetailedDto): Promise> { + async createEmployee(@Body() dto: EmployeeDetailedUpsertDto): Promise> { return await this.createService.createEmployee(dto); } @Patch('update') @ModuleAccessAllowed(ModulesEnum.employee_management) - async updateEmployee(@Body() dto:EmployeeDetailedDto){ + async updateEmployee(@Body() dto:EmployeeDetailedUpsertDto){ return await this.updateService.updateEmployee(dto); } } 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 d617eb3..7bb28e1 100644 --- a/src/identity-and-account/employees/services/employees-update.service.ts +++ b/src/identity-and-account/employees/services/employees-update.service.ts @@ -1,14 +1,14 @@ import { Injectable } from "@nestjs/common"; import { PrismaService } from "src/prisma/prisma.service"; -import { Modules } 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/employee.utils"; -import { EmployeeDetailedDto } from "src/identity-and-account/employees/employee-detailed.dto"; +import { EmployeeDetailedUpsertDto } from "src/identity-and-account/employees/employee-detailed.dto"; import { toBooleanFromString } from "src/identity-and-account/employees/services/employees-get.service"; +import { PaidTimeOffDto } from "src/time-and-attendance/domains/paid-time-off.dto"; @Injectable() export class EmployeesUpdateService { @@ -17,9 +17,16 @@ export class EmployeesUpdateService { private readonly emailResolver: EmailToIdResolver, ) { } - async updateEmployee(dto: EmployeeDetailedDto): Promise> { + async updateEmployee(dto: EmployeeDetailedUpsertDto): Promise> { const user_id = await this.emailResolver.resolveUserIdWithEmail(dto.email); - if (!user_id.success) return { success: false, error: 'EMPLOYEE_NOT_FOUND' } + if (!user_id.success) return { success: false, error: 'EMPLOYEE_NOT_FOUND'} + + const employee = await this.prisma.employees.findFirst({ + where: { user_id: user_id.data }, + select: { id: true }, + }) + + if (!employee) return { success: false, error: 'EMPLOYEE_NOT_FOUND'}; const company_code = toCompanyCodeFromString(dto.company_name); const supervisor_id = await this.toIdFromFullName(dto.supervisor_full_name); @@ -37,6 +44,7 @@ export class EmployeesUpdateService { residence: dto.residence, }, }); + await tx.userModuleAccess.upsert({ where: { user_id: user_id.data }, update: { @@ -57,6 +65,26 @@ export class EmployeesUpdateService { timesheets_approval: normalized_access.timesheets_approval, }, }); + + const employee_pto = dto.paid_time_off ?? new PaidTimeOffDto(employee.id); + + await tx.paidTimeOff.upsert({ + where: { employee_id: employee_pto.employee_id }, + update: { + sick_hours: employee_pto.sick_hours, + vacation_hours: employee_pto.vacation_hours, + banked_hours: employee_pto.banked_hours, + last_updated: employee_pto.last_updated, + }, + create: { + employee_id: employee_pto.employee_id, + sick_hours: employee_pto.sick_hours, + vacation_hours: employee_pto.vacation_hours, + banked_hours: employee_pto.banked_hours, + last_updated: employee_pto.last_updated, + } + }) + return tx.employees.update({ where: { user_id: user_id.data }, data: { diff --git a/src/time-and-attendance/domains/paid-time-off.dto.ts b/src/time-and-attendance/domains/paid-time-off.dto.ts index 8f56175..3dd12c0 100644 --- a/src/time-and-attendance/domains/paid-time-off.dto.ts +++ b/src/time-and-attendance/domains/paid-time-off.dto.ts @@ -2,10 +2,18 @@ import { Type } from "class-transformer"; import { IsDateString, IsDecimal, IsInt, IsNotEmpty, IsNumber, IsOptional } from "class-validator"; export class PaidTimeOffDto { - @IsInt() @IsNotEmpty() id: number; + @IsInt() id: number; @IsInt() @IsNotEmpty() employee_id: number; @IsOptional() @Type(() => Number) vacation_hours?: number; @IsOptional() @Type(() => Number) sick_hours?: number; @IsOptional() @Type(() => Number) banked_hours?: number; @IsDateString() @IsOptional() last_updated: string; + + constructor(employee_id: number) { + this.employee_id = employee_id; + this.banked_hours = 0; + this.sick_hours = 0; + this.vacation_hours = 0; + this.last_updated = new Date().toISOString(); + } } \ No newline at end of file