import { Injectable } from "@nestjs/common"; import { PrismaService } from "src/prisma/prisma.service"; 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 { 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/paid-time-off/paid-time-off.dto"; @Injectable() export class EmployeesUpdateService { constructor( private readonly prisma: PrismaService, private readonly emailResolver: EmailToIdResolver, ) { } 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'} 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); const normalized_access = toBooleanFromString(dto.user_module_access); const last_work_day = dto.last_work_day ? toDateFromString(dto.last_work_day) : null; await this.prisma.$transaction(async (tx) => { await tx.users.update({ where: { id: user_id.data }, data: { first_name: dto.first_name, last_name: dto.last_name, email: dto.email, phone_number: dto.phone_number, residence: dto.residence, }, }); await tx.userModuleAccess.upsert({ where: { user_id: user_id.data }, update: { dashboard: normalized_access.dashboard, employee_list: normalized_access.employee_list, employee_management: normalized_access.employee_management, personal_profile: normalized_access.personal_profile, timesheets: normalized_access.timesheets, timesheets_approval: normalized_access.timesheets_approval, }, create: { user_id: user_id.data, dashboard: normalized_access.dashboard, employee_list: normalized_access.employee_list, employee_management: normalized_access.employee_management, personal_profile: normalized_access.personal_profile, timesheets: normalized_access.timesheets, timesheets_approval: normalized_access.timesheets_approval, }, }); const employee_pto = dto.paid_time_off ?? new PaidTimeOffDto(employee.id); const last_updated = employee_pto.last_updated ? toDateFromString(employee_pto.last_updated) : null; 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: 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: last_updated, } }) return tx.employees.update({ where: { user_id: user_id.data }, data: { company_code: company_code, job_title: dto.job_title, daily_expected_hours: dto.daily_expected_hours, first_work_day: toDateFromString(dto.first_work_day), last_work_day: 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, }, }); }); return { success: true, data: true }; } private toIdFromFullName = async (full_name: string) => { const [first_name, last_name] = full_name.split(' ', 2); let supervisor = await this.prisma.users.findFirst({ where: { first_name, last_name }, select: { employee: { select: { id: true } } } }); if (!supervisor) supervisor = null; return supervisor?.employee?.id; } }